[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/js/dist/vendor/ -> moment.js (source)

   1  //! moment.js
   2  
   3  ;(function (global, factory) {
   4      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   5      typeof define === 'function' && define.amd ? define(factory) :
   6      global.moment = factory()
   7  }(this, (function () { 'use strict';
   8  
   9      var hookCallback;
  10  
  11      function hooks () {
  12          return hookCallback.apply(null, arguments);
  13      }
  14  
  15      // This is done to register the method called with moment()
  16      // without creating circular dependencies.
  17      function setHookCallback (callback) {
  18          hookCallback = callback;
  19      }
  20  
  21      function isArray(input) {
  22          return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
  23      }
  24  
  25      function isObject(input) {
  26          // IE8 will treat undefined and null as object if it wasn't for
  27          // input != null
  28          return input != null && Object.prototype.toString.call(input) === '[object Object]';
  29      }
  30  
  31      function isObjectEmpty(obj) {
  32          if (Object.getOwnPropertyNames) {
  33              return (Object.getOwnPropertyNames(obj).length === 0);
  34          } else {
  35              var k;
  36              for (k in obj) {
  37                  if (obj.hasOwnProperty(k)) {
  38                      return false;
  39                  }
  40              }
  41              return true;
  42          }
  43      }
  44  
  45      function isUndefined(input) {
  46          return input === void 0;
  47      }
  48  
  49      function isNumber(input) {
  50          return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
  51      }
  52  
  53      function isDate(input) {
  54          return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
  55      }
  56  
  57      function map(arr, fn) {
  58          var res = [], i;
  59          for (i = 0; i < arr.length; ++i) {
  60              res.push(fn(arr[i], i));
  61          }
  62          return res;
  63      }
  64  
  65      function hasOwnProp(a, b) {
  66          return Object.prototype.hasOwnProperty.call(a, b);
  67      }
  68  
  69      function extend(a, b) {
  70          for (var i in b) {
  71              if (hasOwnProp(b, i)) {
  72                  a[i] = b[i];
  73              }
  74          }
  75  
  76          if (hasOwnProp(b, 'toString')) {
  77              a.toString = b.toString;
  78          }
  79  
  80          if (hasOwnProp(b, 'valueOf')) {
  81              a.valueOf = b.valueOf;
  82          }
  83  
  84          return a;
  85      }
  86  
  87      function createUTC (input, format, locale, strict) {
  88          return createLocalOrUTC(input, format, locale, strict, true).utc();
  89      }
  90  
  91      function defaultParsingFlags() {
  92          // We need to deep clone this object.
  93          return {
  94              empty           : false,
  95              unusedTokens    : [],
  96              unusedInput     : [],
  97              overflow        : -2,
  98              charsLeftOver   : 0,
  99              nullInput       : false,
 100              invalidMonth    : null,
 101              invalidFormat   : false,
 102              userInvalidated : false,
 103              iso             : false,
 104              parsedDateParts : [],
 105              meridiem        : null,
 106              rfc2822         : false,
 107              weekdayMismatch : false
 108          };
 109      }
 110  
 111      function getParsingFlags(m) {
 112          if (m._pf == null) {
 113              m._pf = defaultParsingFlags();
 114          }
 115          return m._pf;
 116      }
 117  
 118      var some;
 119      if (Array.prototype.some) {
 120          some = Array.prototype.some;
 121      } else {
 122          some = function (fun) {
 123              var t = Object(this);
 124              var len = t.length >>> 0;
 125  
 126              for (var i = 0; i < len; i++) {
 127                  if (i in t && fun.call(this, t[i], i, t)) {
 128                      return true;
 129                  }
 130              }
 131  
 132              return false;
 133          };
 134      }
 135  
 136      function isValid(m) {
 137          if (m._isValid == null) {
 138              var flags = getParsingFlags(m);
 139              var parsedParts = some.call(flags.parsedDateParts, function (i) {
 140                  return i != null;
 141              });
 142              var isNowValid = !isNaN(m._d.getTime()) &&
 143                  flags.overflow < 0 &&
 144                  !flags.empty &&
 145                  !flags.invalidMonth &&
 146                  !flags.invalidWeekday &&
 147                  !flags.weekdayMismatch &&
 148                  !flags.nullInput &&
 149                  !flags.invalidFormat &&
 150                  !flags.userInvalidated &&
 151                  (!flags.meridiem || (flags.meridiem && parsedParts));
 152  
 153              if (m._strict) {
 154                  isNowValid = isNowValid &&
 155                      flags.charsLeftOver === 0 &&
 156                      flags.unusedTokens.length === 0 &&
 157                      flags.bigHour === undefined;
 158              }
 159  
 160              if (Object.isFrozen == null || !Object.isFrozen(m)) {
 161                  m._isValid = isNowValid;
 162              }
 163              else {
 164                  return isNowValid;
 165              }
 166          }
 167          return m._isValid;
 168      }
 169  
 170      function createInvalid (flags) {
 171          var m = createUTC(NaN);
 172          if (flags != null) {
 173              extend(getParsingFlags(m), flags);
 174          }
 175          else {
 176              getParsingFlags(m).userInvalidated = true;
 177          }
 178  
 179          return m;
 180      }
 181  
 182      // Plugins that add properties should also add the key here (null value),
 183      // so we can properly clone ourselves.
 184      var momentProperties = hooks.momentProperties = [];
 185  
 186      function copyConfig(to, from) {
 187          var i, prop, val;
 188  
 189          if (!isUndefined(from._isAMomentObject)) {
 190              to._isAMomentObject = from._isAMomentObject;
 191          }
 192          if (!isUndefined(from._i)) {
 193              to._i = from._i;
 194          }
 195          if (!isUndefined(from._f)) {
 196              to._f = from._f;
 197          }
 198          if (!isUndefined(from._l)) {
 199              to._l = from._l;
 200          }
 201          if (!isUndefined(from._strict)) {
 202              to._strict = from._strict;
 203          }
 204          if (!isUndefined(from._tzm)) {
 205              to._tzm = from._tzm;
 206          }
 207          if (!isUndefined(from._isUTC)) {
 208              to._isUTC = from._isUTC;
 209          }
 210          if (!isUndefined(from._offset)) {
 211              to._offset = from._offset;
 212          }
 213          if (!isUndefined(from._pf)) {
 214              to._pf = getParsingFlags(from);
 215          }
 216          if (!isUndefined(from._locale)) {
 217              to._locale = from._locale;
 218          }
 219  
 220          if (momentProperties.length > 0) {
 221              for (i = 0; i < momentProperties.length; i++) {
 222                  prop = momentProperties[i];
 223                  val = from[prop];
 224                  if (!isUndefined(val)) {
 225                      to[prop] = val;
 226                  }
 227              }
 228          }
 229  
 230          return to;
 231      }
 232  
 233      var updateInProgress = false;
 234  
 235      // Moment prototype object
 236      function Moment(config) {
 237          copyConfig(this, config);
 238          this._d = new Date(config._d != null ? config._d.getTime() : NaN);
 239          if (!this.isValid()) {
 240              this._d = new Date(NaN);
 241          }
 242          // Prevent infinite loop in case updateOffset creates new moment
 243          // objects.
 244          if (updateInProgress === false) {
 245              updateInProgress = true;
 246              hooks.updateOffset(this);
 247              updateInProgress = false;
 248          }
 249      }
 250  
 251      function isMoment (obj) {
 252          return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
 253      }
 254  
 255      function absFloor (number) {
 256          if (number < 0) {
 257              // -0 -> 0
 258              return Math.ceil(number) || 0;
 259          } else {
 260              return Math.floor(number);
 261          }
 262      }
 263  
 264      function toInt(argumentForCoercion) {
 265          var coercedNumber = +argumentForCoercion,
 266              value = 0;
 267  
 268          if (coercedNumber !== 0 && isFinite(coercedNumber)) {
 269              value = absFloor(coercedNumber);
 270          }
 271  
 272          return value;
 273      }
 274  
 275      // compare two arrays, return the number of differences
 276      function compareArrays(array1, array2, dontConvert) {
 277          var len = Math.min(array1.length, array2.length),
 278              lengthDiff = Math.abs(array1.length - array2.length),
 279              diffs = 0,
 280              i;
 281          for (i = 0; i < len; i++) {
 282              if ((dontConvert && array1[i] !== array2[i]) ||
 283                  (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
 284                  diffs++;
 285              }
 286          }
 287          return diffs + lengthDiff;
 288      }
 289  
 290      function warn(msg) {
 291          if (hooks.suppressDeprecationWarnings === false &&
 292                  (typeof console !==  'undefined') && console.warn) {
 293              console.warn('Deprecation warning: ' + msg);
 294          }
 295      }
 296  
 297      function deprecate(msg, fn) {
 298          var firstTime = true;
 299  
 300          return extend(function () {
 301              if (hooks.deprecationHandler != null) {
 302                  hooks.deprecationHandler(null, msg);
 303              }
 304              if (firstTime) {
 305                  var args = [];
 306                  var arg;
 307                  for (var i = 0; i < arguments.length; i++) {
 308                      arg = '';
 309                      if (typeof arguments[i] === 'object') {
 310                          arg += '\n[' + i + '] ';
 311                          for (var key in arguments[0]) {
 312                              arg += key + ': ' + arguments[0][key] + ', ';
 313                          }
 314                          arg = arg.slice(0, -2); // Remove trailing comma and space
 315                      } else {
 316                          arg = arguments[i];
 317                      }
 318                      args.push(arg);
 319                  }
 320                  warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
 321                  firstTime = false;
 322              }
 323              return fn.apply(this, arguments);
 324          }, fn);
 325      }
 326  
 327      var deprecations = {};
 328  
 329      function deprecateSimple(name, msg) {
 330          if (hooks.deprecationHandler != null) {
 331              hooks.deprecationHandler(name, msg);
 332          }
 333          if (!deprecations[name]) {
 334              warn(msg);
 335              deprecations[name] = true;
 336          }
 337      }
 338  
 339      hooks.suppressDeprecationWarnings = false;
 340      hooks.deprecationHandler = null;
 341  
 342      function isFunction(input) {
 343          return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
 344      }
 345  
 346      function set (config) {
 347          var prop, i;
 348          for (i in config) {
 349              prop = config[i];
 350              if (isFunction(prop)) {
 351                  this[i] = prop;
 352              } else {
 353                  this['_' + i] = prop;
 354              }
 355          }
 356          this._config = config;
 357          // Lenient ordinal parsing accepts just a number in addition to
 358          // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
 359          // TODO: Remove "ordinalParse" fallback in next major release.
 360          this._dayOfMonthOrdinalParseLenient = new RegExp(
 361              (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
 362                  '|' + (/\d{1,2}/).source);
 363      }
 364  
 365      function mergeConfigs(parentConfig, childConfig) {
 366          var res = extend({}, parentConfig), prop;
 367          for (prop in childConfig) {
 368              if (hasOwnProp(childConfig, prop)) {
 369                  if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
 370                      res[prop] = {};
 371                      extend(res[prop], parentConfig[prop]);
 372                      extend(res[prop], childConfig[prop]);
 373                  } else if (childConfig[prop] != null) {
 374                      res[prop] = childConfig[prop];
 375                  } else {
 376                      delete res[prop];
 377                  }
 378              }
 379          }
 380          for (prop in parentConfig) {
 381              if (hasOwnProp(parentConfig, prop) &&
 382                      !hasOwnProp(childConfig, prop) &&
 383                      isObject(parentConfig[prop])) {
 384                  // make sure changes to properties don't modify parent config
 385                  res[prop] = extend({}, res[prop]);
 386              }
 387          }
 388          return res;
 389      }
 390  
 391      function Locale(config) {
 392          if (config != null) {
 393              this.set(config);
 394          }
 395      }
 396  
 397      var keys;
 398  
 399      if (Object.keys) {
 400          keys = Object.keys;
 401      } else {
 402          keys = function (obj) {
 403              var i, res = [];
 404              for (i in obj) {
 405                  if (hasOwnProp(obj, i)) {
 406                      res.push(i);
 407                  }
 408              }
 409              return res;
 410          };
 411      }
 412  
 413      var defaultCalendar = {
 414          sameDay : '[Today at] LT',
 415          nextDay : '[Tomorrow at] LT',
 416          nextWeek : 'dddd [at] LT',
 417          lastDay : '[Yesterday at] LT',
 418          lastWeek : '[Last] dddd [at] LT',
 419          sameElse : 'L'
 420      };
 421  
 422      function calendar (key, mom, now) {
 423          var output = this._calendar[key] || this._calendar['sameElse'];
 424          return isFunction(output) ? output.call(mom, now) : output;
 425      }
 426  
 427      var defaultLongDateFormat = {
 428          LTS  : 'h:mm:ss A',
 429          LT   : 'h:mm A',
 430          L    : 'MM/DD/YYYY',
 431          LL   : 'MMMM D, YYYY',
 432          LLL  : 'MMMM D, YYYY h:mm A',
 433          LLLL : 'dddd, MMMM D, YYYY h:mm A'
 434      };
 435  
 436      function longDateFormat (key) {
 437          var format = this._longDateFormat[key],
 438              formatUpper = this._longDateFormat[key.toUpperCase()];
 439  
 440          if (format || !formatUpper) {
 441              return format;
 442          }
 443  
 444          this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
 445              return val.slice(1);
 446          });
 447  
 448          return this._longDateFormat[key];
 449      }
 450  
 451      var defaultInvalidDate = 'Invalid date';
 452  
 453      function invalidDate () {
 454          return this._invalidDate;
 455      }
 456  
 457      var defaultOrdinal = '%d';
 458      var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
 459  
 460      function ordinal (number) {
 461          return this._ordinal.replace('%d', number);
 462      }
 463  
 464      var defaultRelativeTime = {
 465          future : 'in %s',
 466          past   : '%s ago',
 467          s  : 'a few seconds',
 468          ss : '%d seconds',
 469          m  : 'a minute',
 470          mm : '%d minutes',
 471          h  : 'an hour',
 472          hh : '%d hours',
 473          d  : 'a day',
 474          dd : '%d days',
 475          M  : 'a month',
 476          MM : '%d months',
 477          y  : 'a year',
 478          yy : '%d years'
 479      };
 480  
 481      function relativeTime (number, withoutSuffix, string, isFuture) {
 482          var output = this._relativeTime[string];
 483          return (isFunction(output)) ?
 484              output(number, withoutSuffix, string, isFuture) :
 485              output.replace(/%d/i, number);
 486      }
 487  
 488      function pastFuture (diff, output) {
 489          var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
 490          return isFunction(format) ? format(output) : format.replace(/%s/i, output);
 491      }
 492  
 493      var aliases = {};
 494  
 495      function addUnitAlias (unit, shorthand) {
 496          var lowerCase = unit.toLowerCase();
 497          aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
 498      }
 499  
 500      function normalizeUnits(units) {
 501          return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
 502      }
 503  
 504      function normalizeObjectUnits(inputObject) {
 505          var normalizedInput = {},
 506              normalizedProp,
 507              prop;
 508  
 509          for (prop in inputObject) {
 510              if (hasOwnProp(inputObject, prop)) {
 511                  normalizedProp = normalizeUnits(prop);
 512                  if (normalizedProp) {
 513                      normalizedInput[normalizedProp] = inputObject[prop];
 514                  }
 515              }
 516          }
 517  
 518          return normalizedInput;
 519      }
 520  
 521      var priorities = {};
 522  
 523      function addUnitPriority(unit, priority) {
 524          priorities[unit] = priority;
 525      }
 526  
 527      function getPrioritizedUnits(unitsObj) {
 528          var units = [];
 529          for (var u in unitsObj) {
 530              units.push({unit: u, priority: priorities[u]});
 531          }
 532          units.sort(function (a, b) {
 533              return a.priority - b.priority;
 534          });
 535          return units;
 536      }
 537  
 538      function zeroFill(number, targetLength, forceSign) {
 539          var absNumber = '' + Math.abs(number),
 540              zerosToFill = targetLength - absNumber.length,
 541              sign = number >= 0;
 542          return (sign ? (forceSign ? '+' : '') : '-') +
 543              Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
 544      }
 545  
 546      var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
 547  
 548      var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
 549  
 550      var formatFunctions = {};
 551  
 552      var formatTokenFunctions = {};
 553  
 554      // token:    'M'
 555      // padded:   ['MM', 2]
 556      // ordinal:  'Mo'
 557      // callback: function () { this.month() + 1 }
 558      function addFormatToken (token, padded, ordinal, callback) {
 559          var func = callback;
 560          if (typeof callback === 'string') {
 561              func = function () {
 562                  return this[callback]();
 563              };
 564          }
 565          if (token) {
 566              formatTokenFunctions[token] = func;
 567          }
 568          if (padded) {
 569              formatTokenFunctions[padded[0]] = function () {
 570                  return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
 571              };
 572          }
 573          if (ordinal) {
 574              formatTokenFunctions[ordinal] = function () {
 575                  return this.localeData().ordinal(func.apply(this, arguments), token);
 576              };
 577          }
 578      }
 579  
 580      function removeFormattingTokens(input) {
 581          if (input.match(/\[[\s\S]/)) {
 582              return input.replace(/^\[|\]$/g, '');
 583          }
 584          return input.replace(/\\/g, '');
 585      }
 586  
 587      function makeFormatFunction(format) {
 588          var array = format.match(formattingTokens), i, length;
 589  
 590          for (i = 0, length = array.length; i < length; i++) {
 591              if (formatTokenFunctions[array[i]]) {
 592                  array[i] = formatTokenFunctions[array[i]];
 593              } else {
 594                  array[i] = removeFormattingTokens(array[i]);
 595              }
 596          }
 597  
 598          return function (mom) {
 599              var output = '', i;
 600              for (i = 0; i < length; i++) {
 601                  output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
 602              }
 603              return output;
 604          };
 605      }
 606  
 607      // format date using native date object
 608      function formatMoment(m, format) {
 609          if (!m.isValid()) {
 610              return m.localeData().invalidDate();
 611          }
 612  
 613          format = expandFormat(format, m.localeData());
 614          formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
 615  
 616          return formatFunctions[format](m);
 617      }
 618  
 619      function expandFormat(format, locale) {
 620          var i = 5;
 621  
 622          function replaceLongDateFormatTokens(input) {
 623              return locale.longDateFormat(input) || input;
 624          }
 625  
 626          localFormattingTokens.lastIndex = 0;
 627          while (i >= 0 && localFormattingTokens.test(format)) {
 628              format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
 629              localFormattingTokens.lastIndex = 0;
 630              i -= 1;
 631          }
 632  
 633          return format;
 634      }
 635  
 636      var match1         = /\d/;            //       0 - 9
 637      var match2         = /\d\d/;          //      00 - 99
 638      var match3         = /\d{3}/;         //     000 - 999
 639      var match4         = /\d{4}/;         //    0000 - 9999
 640      var match6         = /[+-]?\d{6}/;    // -999999 - 999999
 641      var match1to2      = /\d\d?/;         //       0 - 99
 642      var match3to4      = /\d\d\d\d?/;     //     999 - 9999
 643      var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
 644      var match1to3      = /\d{1,3}/;       //       0 - 999
 645      var match1to4      = /\d{1,4}/;       //       0 - 9999
 646      var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
 647  
 648      var matchUnsigned  = /\d+/;           //       0 - inf
 649      var matchSigned    = /[+-]?\d+/;      //    -inf - inf
 650  
 651      var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
 652      var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
 653  
 654      var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
 655  
 656      // any word (or two) characters or numbers including two/three word month in arabic.
 657      // includes scottish gaelic two word and hyphenated months
 658      var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
 659  
 660      var regexes = {};
 661  
 662      function addRegexToken (token, regex, strictRegex) {
 663          regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
 664              return (isStrict && strictRegex) ? strictRegex : regex;
 665          };
 666      }
 667  
 668      function getParseRegexForToken (token, config) {
 669          if (!hasOwnProp(regexes, token)) {
 670              return new RegExp(unescapeFormat(token));
 671          }
 672  
 673          return regexes[token](config._strict, config._locale);
 674      }
 675  
 676      // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
 677      function unescapeFormat(s) {
 678          return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
 679              return p1 || p2 || p3 || p4;
 680          }));
 681      }
 682  
 683      function regexEscape(s) {
 684          return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
 685      }
 686  
 687      var tokens = {};
 688  
 689      function addParseToken (token, callback) {
 690          var i, func = callback;
 691          if (typeof token === 'string') {
 692              token = [token];
 693          }
 694          if (isNumber(callback)) {
 695              func = function (input, array) {
 696                  array[callback] = toInt(input);
 697              };
 698          }
 699          for (i = 0; i < token.length; i++) {
 700              tokens[token[i]] = func;
 701          }
 702      }
 703  
 704      function addWeekParseToken (token, callback) {
 705          addParseToken(token, function (input, array, config, token) {
 706              config._w = config._w || {};
 707              callback(input, config._w, config, token);
 708          });
 709      }
 710  
 711      function addTimeToArrayFromToken(token, input, config) {
 712          if (input != null && hasOwnProp(tokens, token)) {
 713              tokens[token](input, config._a, config, token);
 714          }
 715      }
 716  
 717      var YEAR = 0;
 718      var MONTH = 1;
 719      var DATE = 2;
 720      var HOUR = 3;
 721      var MINUTE = 4;
 722      var SECOND = 5;
 723      var MILLISECOND = 6;
 724      var WEEK = 7;
 725      var WEEKDAY = 8;
 726  
 727      // FORMATTING
 728  
 729      addFormatToken('Y', 0, 0, function () {
 730          var y = this.year();
 731          return y <= 9999 ? '' + y : '+' + y;
 732      });
 733  
 734      addFormatToken(0, ['YY', 2], 0, function () {
 735          return this.year() % 100;
 736      });
 737  
 738      addFormatToken(0, ['YYYY',   4],       0, 'year');
 739      addFormatToken(0, ['YYYYY',  5],       0, 'year');
 740      addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
 741  
 742      // ALIASES
 743  
 744      addUnitAlias('year', 'y');
 745  
 746      // PRIORITIES
 747  
 748      addUnitPriority('year', 1);
 749  
 750      // PARSING
 751  
 752      addRegexToken('Y',      matchSigned);
 753      addRegexToken('YY',     match1to2, match2);
 754      addRegexToken('YYYY',   match1to4, match4);
 755      addRegexToken('YYYYY',  match1to6, match6);
 756      addRegexToken('YYYYYY', match1to6, match6);
 757  
 758      addParseToken(['YYYYY', 'YYYYYY'], YEAR);
 759      addParseToken('YYYY', function (input, array) {
 760          array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
 761      });
 762      addParseToken('YY', function (input, array) {
 763          array[YEAR] = hooks.parseTwoDigitYear(input);
 764      });
 765      addParseToken('Y', function (input, array) {
 766          array[YEAR] = parseInt(input, 10);
 767      });
 768  
 769      // HELPERS
 770  
 771      function daysInYear(year) {
 772          return isLeapYear(year) ? 366 : 365;
 773      }
 774  
 775      function isLeapYear(year) {
 776          return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
 777      }
 778  
 779      // HOOKS
 780  
 781      hooks.parseTwoDigitYear = function (input) {
 782          return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
 783      };
 784  
 785      // MOMENTS
 786  
 787      var getSetYear = makeGetSet('FullYear', true);
 788  
 789      function getIsLeapYear () {
 790          return isLeapYear(this.year());
 791      }
 792  
 793      function makeGetSet (unit, keepTime) {
 794          return function (value) {
 795              if (value != null) {
 796                  set$1(this, unit, value);
 797                  hooks.updateOffset(this, keepTime);
 798                  return this;
 799              } else {
 800                  return get(this, unit);
 801              }
 802          };
 803      }
 804  
 805      function get (mom, unit) {
 806          return mom.isValid() ?
 807              mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
 808      }
 809  
 810      function set$1 (mom, unit, value) {
 811          if (mom.isValid() && !isNaN(value)) {
 812              if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
 813                  mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
 814              }
 815              else {
 816                  mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
 817              }
 818          }
 819      }
 820  
 821      // MOMENTS
 822  
 823      function stringGet (units) {
 824          units = normalizeUnits(units);
 825          if (isFunction(this[units])) {
 826              return this[units]();
 827          }
 828          return this;
 829      }
 830  
 831  
 832      function stringSet (units, value) {
 833          if (typeof units === 'object') {
 834              units = normalizeObjectUnits(units);
 835              var prioritized = getPrioritizedUnits(units);
 836              for (var i = 0; i < prioritized.length; i++) {
 837                  this[prioritized[i].unit](units[prioritized[i].unit]);
 838              }
 839          } else {
 840              units = normalizeUnits(units);
 841              if (isFunction(this[units])) {
 842                  return this[units](value);
 843              }
 844          }
 845          return this;
 846      }
 847  
 848      function mod(n, x) {
 849          return ((n % x) + x) % x;
 850      }
 851  
 852      var indexOf;
 853  
 854      if (Array.prototype.indexOf) {
 855          indexOf = Array.prototype.indexOf;
 856      } else {
 857          indexOf = function (o) {
 858              // I know
 859              var i;
 860              for (i = 0; i < this.length; ++i) {
 861                  if (this[i] === o) {
 862                      return i;
 863                  }
 864              }
 865              return -1;
 866          };
 867      }
 868  
 869      function daysInMonth(year, month) {
 870          if (isNaN(year) || isNaN(month)) {
 871              return NaN;
 872          }
 873          var modMonth = mod(month, 12);
 874          year += (month - modMonth) / 12;
 875          return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
 876      }
 877  
 878      // FORMATTING
 879  
 880      addFormatToken('M', ['MM', 2], 'Mo', function () {
 881          return this.month() + 1;
 882      });
 883  
 884      addFormatToken('MMM', 0, 0, function (format) {
 885          return this.localeData().monthsShort(this, format);
 886      });
 887  
 888      addFormatToken('MMMM', 0, 0, function (format) {
 889          return this.localeData().months(this, format);
 890      });
 891  
 892      // ALIASES
 893  
 894      addUnitAlias('month', 'M');
 895  
 896      // PRIORITY
 897  
 898      addUnitPriority('month', 8);
 899  
 900      // PARSING
 901  
 902      addRegexToken('M',    match1to2);
 903      addRegexToken('MM',   match1to2, match2);
 904      addRegexToken('MMM',  function (isStrict, locale) {
 905          return locale.monthsShortRegex(isStrict);
 906      });
 907      addRegexToken('MMMM', function (isStrict, locale) {
 908          return locale.monthsRegex(isStrict);
 909      });
 910  
 911      addParseToken(['M', 'MM'], function (input, array) {
 912          array[MONTH] = toInt(input) - 1;
 913      });
 914  
 915      addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
 916          var month = config._locale.monthsParse(input, token, config._strict);
 917          // if we didn't find a month name, mark the date as invalid.
 918          if (month != null) {
 919              array[MONTH] = month;
 920          } else {
 921              getParsingFlags(config).invalidMonth = input;
 922          }
 923      });
 924  
 925      // LOCALES
 926  
 927      var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
 928      var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
 929      function localeMonths (m, format) {
 930          if (!m) {
 931              return isArray(this._months) ? this._months :
 932                  this._months['standalone'];
 933          }
 934          return isArray(this._months) ? this._months[m.month()] :
 935              this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
 936      }
 937  
 938      var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
 939      function localeMonthsShort (m, format) {
 940          if (!m) {
 941              return isArray(this._monthsShort) ? this._monthsShort :
 942                  this._monthsShort['standalone'];
 943          }
 944          return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
 945              this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
 946      }
 947  
 948      function handleStrictParse(monthName, format, strict) {
 949          var i, ii, mom, llc = monthName.toLocaleLowerCase();
 950          if (!this._monthsParse) {
 951              // this is not used
 952              this._monthsParse = [];
 953              this._longMonthsParse = [];
 954              this._shortMonthsParse = [];
 955              for (i = 0; i < 12; ++i) {
 956                  mom = createUTC([2000, i]);
 957                  this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
 958                  this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
 959              }
 960          }
 961  
 962          if (strict) {
 963              if (format === 'MMM') {
 964                  ii = indexOf.call(this._shortMonthsParse, llc);
 965                  return ii !== -1 ? ii : null;
 966              } else {
 967                  ii = indexOf.call(this._longMonthsParse, llc);
 968                  return ii !== -1 ? ii : null;
 969              }
 970          } else {
 971              if (format === 'MMM') {
 972                  ii = indexOf.call(this._shortMonthsParse, llc);
 973                  if (ii !== -1) {
 974                      return ii;
 975                  }
 976                  ii = indexOf.call(this._longMonthsParse, llc);
 977                  return ii !== -1 ? ii : null;
 978              } else {
 979                  ii = indexOf.call(this._longMonthsParse, llc);
 980                  if (ii !== -1) {
 981                      return ii;
 982                  }
 983                  ii = indexOf.call(this._shortMonthsParse, llc);
 984                  return ii !== -1 ? ii : null;
 985              }
 986          }
 987      }
 988  
 989      function localeMonthsParse (monthName, format, strict) {
 990          var i, mom, regex;
 991  
 992          if (this._monthsParseExact) {
 993              return handleStrictParse.call(this, monthName, format, strict);
 994          }
 995  
 996          if (!this._monthsParse) {
 997              this._monthsParse = [];
 998              this._longMonthsParse = [];
 999              this._shortMonthsParse = [];
1000          }
1001  
1002          // TODO: add sorting
1003          // Sorting makes sure if one month (or abbr) is a prefix of another
1004          // see sorting in computeMonthsParse
1005          for (i = 0; i < 12; i++) {
1006              // make the regex if we don't have it already
1007              mom = createUTC([2000, i]);
1008              if (strict && !this._longMonthsParse[i]) {
1009                  this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
1010                  this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
1011              }
1012              if (!strict && !this._monthsParse[i]) {
1013                  regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
1014                  this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
1015              }
1016              // test the regex
1017              if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
1018                  return i;
1019              } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
1020                  return i;
1021              } else if (!strict && this._monthsParse[i].test(monthName)) {
1022                  return i;
1023              }
1024          }
1025      }
1026  
1027      // MOMENTS
1028  
1029      function setMonth (mom, value) {
1030          var dayOfMonth;
1031  
1032          if (!mom.isValid()) {
1033              // No op
1034              return mom;
1035          }
1036  
1037          if (typeof value === 'string') {
1038              if (/^\d+$/.test(value)) {
1039                  value = toInt(value);
1040              } else {
1041                  value = mom.localeData().monthsParse(value);
1042                  // TODO: Another silent failure?
1043                  if (!isNumber(value)) {
1044                      return mom;
1045                  }
1046              }
1047          }
1048  
1049          dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
1050          mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
1051          return mom;
1052      }
1053  
1054      function getSetMonth (value) {
1055          if (value != null) {
1056              setMonth(this, value);
1057              hooks.updateOffset(this, true);
1058              return this;
1059          } else {
1060              return get(this, 'Month');
1061          }
1062      }
1063  
1064      function getDaysInMonth () {
1065          return daysInMonth(this.year(), this.month());
1066      }
1067  
1068      var defaultMonthsShortRegex = matchWord;
1069      function monthsShortRegex (isStrict) {
1070          if (this._monthsParseExact) {
1071              if (!hasOwnProp(this, '_monthsRegex')) {
1072                  computeMonthsParse.call(this);
1073              }
1074              if (isStrict) {
1075                  return this._monthsShortStrictRegex;
1076              } else {
1077                  return this._monthsShortRegex;
1078              }
1079          } else {
1080              if (!hasOwnProp(this, '_monthsShortRegex')) {
1081                  this._monthsShortRegex = defaultMonthsShortRegex;
1082              }
1083              return this._monthsShortStrictRegex && isStrict ?
1084                  this._monthsShortStrictRegex : this._monthsShortRegex;
1085          }
1086      }
1087  
1088      var defaultMonthsRegex = matchWord;
1089      function monthsRegex (isStrict) {
1090          if (this._monthsParseExact) {
1091              if (!hasOwnProp(this, '_monthsRegex')) {
1092                  computeMonthsParse.call(this);
1093              }
1094              if (isStrict) {
1095                  return this._monthsStrictRegex;
1096              } else {
1097                  return this._monthsRegex;
1098              }
1099          } else {
1100              if (!hasOwnProp(this, '_monthsRegex')) {
1101                  this._monthsRegex = defaultMonthsRegex;
1102              }
1103              return this._monthsStrictRegex && isStrict ?
1104                  this._monthsStrictRegex : this._monthsRegex;
1105          }
1106      }
1107  
1108      function computeMonthsParse () {
1109          function cmpLenRev(a, b) {
1110              return b.length - a.length;
1111          }
1112  
1113          var shortPieces = [], longPieces = [], mixedPieces = [],
1114              i, mom;
1115          for (i = 0; i < 12; i++) {
1116              // make the regex if we don't have it already
1117              mom = createUTC([2000, i]);
1118              shortPieces.push(this.monthsShort(mom, ''));
1119              longPieces.push(this.months(mom, ''));
1120              mixedPieces.push(this.months(mom, ''));
1121              mixedPieces.push(this.monthsShort(mom, ''));
1122          }
1123          // Sorting makes sure if one month (or abbr) is a prefix of another it
1124          // will match the longer piece.
1125          shortPieces.sort(cmpLenRev);
1126          longPieces.sort(cmpLenRev);
1127          mixedPieces.sort(cmpLenRev);
1128          for (i = 0; i < 12; i++) {
1129              shortPieces[i] = regexEscape(shortPieces[i]);
1130              longPieces[i] = regexEscape(longPieces[i]);
1131          }
1132          for (i = 0; i < 24; i++) {
1133              mixedPieces[i] = regexEscape(mixedPieces[i]);
1134          }
1135  
1136          this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1137          this._monthsShortRegex = this._monthsRegex;
1138          this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
1139          this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1140      }
1141  
1142      function createDate (y, m, d, h, M, s, ms) {
1143          // can't just apply() to create a date:
1144          // https://stackoverflow.com/q/181348
1145          var date = new Date(y, m, d, h, M, s, ms);
1146  
1147          // the date constructor remaps years 0-99 to 1900-1999
1148          if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
1149              date.setFullYear(y);
1150          }
1151          return date;
1152      }
1153  
1154      function createUTCDate (y) {
1155          var date = new Date(Date.UTC.apply(null, arguments));
1156  
1157          // the Date.UTC function remaps years 0-99 to 1900-1999
1158          if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
1159              date.setUTCFullYear(y);
1160          }
1161          return date;
1162      }
1163  
1164      // start-of-first-week - start-of-year
1165      function firstWeekOffset(year, dow, doy) {
1166          var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
1167              fwd = 7 + dow - doy,
1168              // first-week day local weekday -- which local weekday is fwd
1169              fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1170  
1171          return -fwdlw + fwd - 1;
1172      }
1173  
1174      // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1175      function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1176          var localWeekday = (7 + weekday - dow) % 7,
1177              weekOffset = firstWeekOffset(year, dow, doy),
1178              dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
1179              resYear, resDayOfYear;
1180  
1181          if (dayOfYear <= 0) {
1182              resYear = year - 1;
1183              resDayOfYear = daysInYear(resYear) + dayOfYear;
1184          } else if (dayOfYear > daysInYear(year)) {
1185              resYear = year + 1;
1186              resDayOfYear = dayOfYear - daysInYear(year);
1187          } else {
1188              resYear = year;
1189              resDayOfYear = dayOfYear;
1190          }
1191  
1192          return {
1193              year: resYear,
1194              dayOfYear: resDayOfYear
1195          };
1196      }
1197  
1198      function weekOfYear(mom, dow, doy) {
1199          var weekOffset = firstWeekOffset(mom.year(), dow, doy),
1200              week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
1201              resWeek, resYear;
1202  
1203          if (week < 1) {
1204              resYear = mom.year() - 1;
1205              resWeek = week + weeksInYear(resYear, dow, doy);
1206          } else if (week > weeksInYear(mom.year(), dow, doy)) {
1207              resWeek = week - weeksInYear(mom.year(), dow, doy);
1208              resYear = mom.year() + 1;
1209          } else {
1210              resYear = mom.year();
1211              resWeek = week;
1212          }
1213  
1214          return {
1215              week: resWeek,
1216              year: resYear
1217          };
1218      }
1219  
1220      function weeksInYear(year, dow, doy) {
1221          var weekOffset = firstWeekOffset(year, dow, doy),
1222              weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
1223          return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1224      }
1225  
1226      // FORMATTING
1227  
1228      addFormatToken('w', ['ww', 2], 'wo', 'week');
1229      addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1230  
1231      // ALIASES
1232  
1233      addUnitAlias('week', 'w');
1234      addUnitAlias('isoWeek', 'W');
1235  
1236      // PRIORITIES
1237  
1238      addUnitPriority('week', 5);
1239      addUnitPriority('isoWeek', 5);
1240  
1241      // PARSING
1242  
1243      addRegexToken('w',  match1to2);
1244      addRegexToken('ww', match1to2, match2);
1245      addRegexToken('W',  match1to2);
1246      addRegexToken('WW', match1to2, match2);
1247  
1248      addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
1249          week[token.substr(0, 1)] = toInt(input);
1250      });
1251  
1252      // HELPERS
1253  
1254      // LOCALES
1255  
1256      function localeWeek (mom) {
1257          return weekOfYear(mom, this._week.dow, this._week.doy).week;
1258      }
1259  
1260      var defaultLocaleWeek = {
1261          dow : 0, // Sunday is the first day of the week.
1262          doy : 6  // The week that contains Jan 1st is the first week of the year.
1263      };
1264  
1265      function localeFirstDayOfWeek () {
1266          return this._week.dow;
1267      }
1268  
1269      function localeFirstDayOfYear () {
1270          return this._week.doy;
1271      }
1272  
1273      // MOMENTS
1274  
1275      function getSetWeek (input) {
1276          var week = this.localeData().week(this);
1277          return input == null ? week : this.add((input - week) * 7, 'd');
1278      }
1279  
1280      function getSetISOWeek (input) {
1281          var week = weekOfYear(this, 1, 4).week;
1282          return input == null ? week : this.add((input - week) * 7, 'd');
1283      }
1284  
1285      // FORMATTING
1286  
1287      addFormatToken('d', 0, 'do', 'day');
1288  
1289      addFormatToken('dd', 0, 0, function (format) {
1290          return this.localeData().weekdaysMin(this, format);
1291      });
1292  
1293      addFormatToken('ddd', 0, 0, function (format) {
1294          return this.localeData().weekdaysShort(this, format);
1295      });
1296  
1297      addFormatToken('dddd', 0, 0, function (format) {
1298          return this.localeData().weekdays(this, format);
1299      });
1300  
1301      addFormatToken('e', 0, 0, 'weekday');
1302      addFormatToken('E', 0, 0, 'isoWeekday');
1303  
1304      // ALIASES
1305  
1306      addUnitAlias('day', 'd');
1307      addUnitAlias('weekday', 'e');
1308      addUnitAlias('isoWeekday', 'E');
1309  
1310      // PRIORITY
1311      addUnitPriority('day', 11);
1312      addUnitPriority('weekday', 11);
1313      addUnitPriority('isoWeekday', 11);
1314  
1315      // PARSING
1316  
1317      addRegexToken('d',    match1to2);
1318      addRegexToken('e',    match1to2);
1319      addRegexToken('E',    match1to2);
1320      addRegexToken('dd',   function (isStrict, locale) {
1321          return locale.weekdaysMinRegex(isStrict);
1322      });
1323      addRegexToken('ddd',   function (isStrict, locale) {
1324          return locale.weekdaysShortRegex(isStrict);
1325      });
1326      addRegexToken('dddd',   function (isStrict, locale) {
1327          return locale.weekdaysRegex(isStrict);
1328      });
1329  
1330      addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1331          var weekday = config._locale.weekdaysParse(input, token, config._strict);
1332          // if we didn't get a weekday name, mark the date as invalid
1333          if (weekday != null) {
1334              week.d = weekday;
1335          } else {
1336              getParsingFlags(config).invalidWeekday = input;
1337          }
1338      });
1339  
1340      addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
1341          week[token] = toInt(input);
1342      });
1343  
1344      // HELPERS
1345  
1346      function parseWeekday(input, locale) {
1347          if (typeof input !== 'string') {
1348              return input;
1349          }
1350  
1351          if (!isNaN(input)) {
1352              return parseInt(input, 10);
1353          }
1354  
1355          input = locale.weekdaysParse(input);
1356          if (typeof input === 'number') {
1357              return input;
1358          }
1359  
1360          return null;
1361      }
1362  
1363      function parseIsoWeekday(input, locale) {
1364          if (typeof input === 'string') {
1365              return locale.weekdaysParse(input) % 7 || 7;
1366          }
1367          return isNaN(input) ? null : input;
1368      }
1369  
1370      // LOCALES
1371  
1372      var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
1373      function localeWeekdays (m, format) {
1374          if (!m) {
1375              return isArray(this._weekdays) ? this._weekdays :
1376                  this._weekdays['standalone'];
1377          }
1378          return isArray(this._weekdays) ? this._weekdays[m.day()] :
1379              this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
1380      }
1381  
1382      var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
1383      function localeWeekdaysShort (m) {
1384          return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
1385      }
1386  
1387      var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
1388      function localeWeekdaysMin (m) {
1389          return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
1390      }
1391  
1392      function handleStrictParse$1(weekdayName, format, strict) {
1393          var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
1394          if (!this._weekdaysParse) {
1395              this._weekdaysParse = [];
1396              this._shortWeekdaysParse = [];
1397              this._minWeekdaysParse = [];
1398  
1399              for (i = 0; i < 7; ++i) {
1400                  mom = createUTC([2000, 1]).day(i);
1401                  this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
1402                  this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
1403                  this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
1404              }
1405          }
1406  
1407          if (strict) {
1408              if (format === 'dddd') {
1409                  ii = indexOf.call(this._weekdaysParse, llc);
1410                  return ii !== -1 ? ii : null;
1411              } else if (format === 'ddd') {
1412                  ii = indexOf.call(this._shortWeekdaysParse, llc);
1413                  return ii !== -1 ? ii : null;
1414              } else {
1415                  ii = indexOf.call(this._minWeekdaysParse, llc);
1416                  return ii !== -1 ? ii : null;
1417              }
1418          } else {
1419              if (format === 'dddd') {
1420                  ii = indexOf.call(this._weekdaysParse, llc);
1421                  if (ii !== -1) {
1422                      return ii;
1423                  }
1424                  ii = indexOf.call(this._shortWeekdaysParse, llc);
1425                  if (ii !== -1) {
1426                      return ii;
1427                  }
1428                  ii = indexOf.call(this._minWeekdaysParse, llc);
1429                  return ii !== -1 ? ii : null;
1430              } else if (format === 'ddd') {
1431                  ii = indexOf.call(this._shortWeekdaysParse, llc);
1432                  if (ii !== -1) {
1433                      return ii;
1434                  }
1435                  ii = indexOf.call(this._weekdaysParse, llc);
1436                  if (ii !== -1) {
1437                      return ii;
1438                  }
1439                  ii = indexOf.call(this._minWeekdaysParse, llc);
1440                  return ii !== -1 ? ii : null;
1441              } else {
1442                  ii = indexOf.call(this._minWeekdaysParse, llc);
1443                  if (ii !== -1) {
1444                      return ii;
1445                  }
1446                  ii = indexOf.call(this._weekdaysParse, llc);
1447                  if (ii !== -1) {
1448                      return ii;
1449                  }
1450                  ii = indexOf.call(this._shortWeekdaysParse, llc);
1451                  return ii !== -1 ? ii : null;
1452              }
1453          }
1454      }
1455  
1456      function localeWeekdaysParse (weekdayName, format, strict) {
1457          var i, mom, regex;
1458  
1459          if (this._weekdaysParseExact) {
1460              return handleStrictParse$1.call(this, weekdayName, format, strict);
1461          }
1462  
1463          if (!this._weekdaysParse) {
1464              this._weekdaysParse = [];
1465              this._minWeekdaysParse = [];
1466              this._shortWeekdaysParse = [];
1467              this._fullWeekdaysParse = [];
1468          }
1469  
1470          for (i = 0; i < 7; i++) {
1471              // make the regex if we don't have it already
1472  
1473              mom = createUTC([2000, 1]).day(i);
1474              if (strict && !this._fullWeekdaysParse[i]) {
1475                  this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
1476                  this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
1477                  this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
1478              }
1479              if (!this._weekdaysParse[i]) {
1480                  regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
1481                  this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1482              }
1483              // test the regex
1484              if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
1485                  return i;
1486              } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
1487                  return i;
1488              } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
1489                  return i;
1490              } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
1491                  return i;
1492              }
1493          }
1494      }
1495  
1496      // MOMENTS
1497  
1498      function getSetDayOfWeek (input) {
1499          if (!this.isValid()) {
1500              return input != null ? this : NaN;
1501          }
1502          var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1503          if (input != null) {
1504              input = parseWeekday(input, this.localeData());
1505              return this.add(input - day, 'd');
1506          } else {
1507              return day;
1508          }
1509      }
1510  
1511      function getSetLocaleDayOfWeek (input) {
1512          if (!this.isValid()) {
1513              return input != null ? this : NaN;
1514          }
1515          var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
1516          return input == null ? weekday : this.add(input - weekday, 'd');
1517      }
1518  
1519      function getSetISODayOfWeek (input) {
1520          if (!this.isValid()) {
1521              return input != null ? this : NaN;
1522          }
1523  
1524          // behaves the same as moment#day except
1525          // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1526          // as a setter, sunday should belong to the previous week.
1527  
1528          if (input != null) {
1529              var weekday = parseIsoWeekday(input, this.localeData());
1530              return this.day(this.day() % 7 ? weekday : weekday - 7);
1531          } else {
1532              return this.day() || 7;
1533          }
1534      }
1535  
1536      var defaultWeekdaysRegex = matchWord;
1537      function weekdaysRegex (isStrict) {
1538          if (this._weekdaysParseExact) {
1539              if (!hasOwnProp(this, '_weekdaysRegex')) {
1540                  computeWeekdaysParse.call(this);
1541              }
1542              if (isStrict) {
1543                  return this._weekdaysStrictRegex;
1544              } else {
1545                  return this._weekdaysRegex;
1546              }
1547          } else {
1548              if (!hasOwnProp(this, '_weekdaysRegex')) {
1549                  this._weekdaysRegex = defaultWeekdaysRegex;
1550              }
1551              return this._weekdaysStrictRegex && isStrict ?
1552                  this._weekdaysStrictRegex : this._weekdaysRegex;
1553          }
1554      }
1555  
1556      var defaultWeekdaysShortRegex = matchWord;
1557      function weekdaysShortRegex (isStrict) {
1558          if (this._weekdaysParseExact) {
1559              if (!hasOwnProp(this, '_weekdaysRegex')) {
1560                  computeWeekdaysParse.call(this);
1561              }
1562              if (isStrict) {
1563                  return this._weekdaysShortStrictRegex;
1564              } else {
1565                  return this._weekdaysShortRegex;
1566              }
1567          } else {
1568              if (!hasOwnProp(this, '_weekdaysShortRegex')) {
1569                  this._weekdaysShortRegex = defaultWeekdaysShortRegex;
1570              }
1571              return this._weekdaysShortStrictRegex && isStrict ?
1572                  this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
1573          }
1574      }
1575  
1576      var defaultWeekdaysMinRegex = matchWord;
1577      function weekdaysMinRegex (isStrict) {
1578          if (this._weekdaysParseExact) {
1579              if (!hasOwnProp(this, '_weekdaysRegex')) {
1580                  computeWeekdaysParse.call(this);
1581              }
1582              if (isStrict) {
1583                  return this._weekdaysMinStrictRegex;
1584              } else {
1585                  return this._weekdaysMinRegex;
1586              }
1587          } else {
1588              if (!hasOwnProp(this, '_weekdaysMinRegex')) {
1589                  this._weekdaysMinRegex = defaultWeekdaysMinRegex;
1590              }
1591              return this._weekdaysMinStrictRegex && isStrict ?
1592                  this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
1593          }
1594      }
1595  
1596  
1597      function computeWeekdaysParse () {
1598          function cmpLenRev(a, b) {
1599              return b.length - a.length;
1600          }
1601  
1602          var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
1603              i, mom, minp, shortp, longp;
1604          for (i = 0; i < 7; i++) {
1605              // make the regex if we don't have it already
1606              mom = createUTC([2000, 1]).day(i);
1607              minp = this.weekdaysMin(mom, '');
1608              shortp = this.weekdaysShort(mom, '');
1609              longp = this.weekdays(mom, '');
1610              minPieces.push(minp);
1611              shortPieces.push(shortp);
1612              longPieces.push(longp);
1613              mixedPieces.push(minp);
1614              mixedPieces.push(shortp);
1615              mixedPieces.push(longp);
1616          }
1617          // Sorting makes sure if one weekday (or abbr) is a prefix of another it
1618          // will match the longer piece.
1619          minPieces.sort(cmpLenRev);
1620          shortPieces.sort(cmpLenRev);
1621          longPieces.sort(cmpLenRev);
1622          mixedPieces.sort(cmpLenRev);
1623          for (i = 0; i < 7; i++) {
1624              shortPieces[i] = regexEscape(shortPieces[i]);
1625              longPieces[i] = regexEscape(longPieces[i]);
1626              mixedPieces[i] = regexEscape(mixedPieces[i]);
1627          }
1628  
1629          this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1630          this._weekdaysShortRegex = this._weekdaysRegex;
1631          this._weekdaysMinRegex = this._weekdaysRegex;
1632  
1633          this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
1634          this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1635          this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
1636      }
1637  
1638      // FORMATTING
1639  
1640      function hFormat() {
1641          return this.hours() % 12 || 12;
1642      }
1643  
1644      function kFormat() {
1645          return this.hours() || 24;
1646      }
1647  
1648      addFormatToken('H', ['HH', 2], 0, 'hour');
1649      addFormatToken('h', ['hh', 2], 0, hFormat);
1650      addFormatToken('k', ['kk', 2], 0, kFormat);
1651  
1652      addFormatToken('hmm', 0, 0, function () {
1653          return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
1654      });
1655  
1656      addFormatToken('hmmss', 0, 0, function () {
1657          return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
1658              zeroFill(this.seconds(), 2);
1659      });
1660  
1661      addFormatToken('Hmm', 0, 0, function () {
1662          return '' + this.hours() + zeroFill(this.minutes(), 2);
1663      });
1664  
1665      addFormatToken('Hmmss', 0, 0, function () {
1666          return '' + this.hours() + zeroFill(this.minutes(), 2) +
1667              zeroFill(this.seconds(), 2);
1668      });
1669  
1670      function meridiem (token, lowercase) {
1671          addFormatToken(token, 0, 0, function () {
1672              return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
1673          });
1674      }
1675  
1676      meridiem('a', true);
1677      meridiem('A', false);
1678  
1679      // ALIASES
1680  
1681      addUnitAlias('hour', 'h');
1682  
1683      // PRIORITY
1684      addUnitPriority('hour', 13);
1685  
1686      // PARSING
1687  
1688      function matchMeridiem (isStrict, locale) {
1689          return locale._meridiemParse;
1690      }
1691  
1692      addRegexToken('a',  matchMeridiem);
1693      addRegexToken('A',  matchMeridiem);
1694      addRegexToken('H',  match1to2);
1695      addRegexToken('h',  match1to2);
1696      addRegexToken('k',  match1to2);
1697      addRegexToken('HH', match1to2, match2);
1698      addRegexToken('hh', match1to2, match2);
1699      addRegexToken('kk', match1to2, match2);
1700  
1701      addRegexToken('hmm', match3to4);
1702      addRegexToken('hmmss', match5to6);
1703      addRegexToken('Hmm', match3to4);
1704      addRegexToken('Hmmss', match5to6);
1705  
1706      addParseToken(['H', 'HH'], HOUR);
1707      addParseToken(['k', 'kk'], function (input, array, config) {
1708          var kInput = toInt(input);
1709          array[HOUR] = kInput === 24 ? 0 : kInput;
1710      });
1711      addParseToken(['a', 'A'], function (input, array, config) {
1712          config._isPm = config._locale.isPM(input);
1713          config._meridiem = input;
1714      });
1715      addParseToken(['h', 'hh'], function (input, array, config) {
1716          array[HOUR] = toInt(input);
1717          getParsingFlags(config).bigHour = true;
1718      });
1719      addParseToken('hmm', function (input, array, config) {
1720          var pos = input.length - 2;
1721          array[HOUR] = toInt(input.substr(0, pos));
1722          array[MINUTE] = toInt(input.substr(pos));
1723          getParsingFlags(config).bigHour = true;
1724      });
1725      addParseToken('hmmss', function (input, array, config) {
1726          var pos1 = input.length - 4;
1727          var pos2 = input.length - 2;
1728          array[HOUR] = toInt(input.substr(0, pos1));
1729          array[MINUTE] = toInt(input.substr(pos1, 2));
1730          array[SECOND] = toInt(input.substr(pos2));
1731          getParsingFlags(config).bigHour = true;
1732      });
1733      addParseToken('Hmm', function (input, array, config) {
1734          var pos = input.length - 2;
1735          array[HOUR] = toInt(input.substr(0, pos));
1736          array[MINUTE] = toInt(input.substr(pos));
1737      });
1738      addParseToken('Hmmss', function (input, array, config) {
1739          var pos1 = input.length - 4;
1740          var pos2 = input.length - 2;
1741          array[HOUR] = toInt(input.substr(0, pos1));
1742          array[MINUTE] = toInt(input.substr(pos1, 2));
1743          array[SECOND] = toInt(input.substr(pos2));
1744      });
1745  
1746      // LOCALES
1747  
1748      function localeIsPM (input) {
1749          // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
1750          // Using charAt should be more compatible.
1751          return ((input + '').toLowerCase().charAt(0) === 'p');
1752      }
1753  
1754      var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
1755      function localeMeridiem (hours, minutes, isLower) {
1756          if (hours > 11) {
1757              return isLower ? 'pm' : 'PM';
1758          } else {
1759              return isLower ? 'am' : 'AM';
1760          }
1761      }
1762  
1763  
1764      // MOMENTS
1765  
1766      // Setting the hour should keep the time, because the user explicitly
1767      // specified which hour they want. So trying to maintain the same hour (in
1768      // a new timezone) makes sense. Adding/subtracting hours does not follow
1769      // this rule.
1770      var getSetHour = makeGetSet('Hours', true);
1771  
1772      var baseConfig = {
1773          calendar: defaultCalendar,
1774          longDateFormat: defaultLongDateFormat,
1775          invalidDate: defaultInvalidDate,
1776          ordinal: defaultOrdinal,
1777          dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
1778          relativeTime: defaultRelativeTime,
1779  
1780          months: defaultLocaleMonths,
1781          monthsShort: defaultLocaleMonthsShort,
1782  
1783          week: defaultLocaleWeek,
1784  
1785          weekdays: defaultLocaleWeekdays,
1786          weekdaysMin: defaultLocaleWeekdaysMin,
1787          weekdaysShort: defaultLocaleWeekdaysShort,
1788  
1789          meridiemParse: defaultLocaleMeridiemParse
1790      };
1791  
1792      // internal storage for locale config files
1793      var locales = {};
1794      var localeFamilies = {};
1795      var globalLocale;
1796  
1797      function normalizeLocale(key) {
1798          return key ? key.toLowerCase().replace('_', '-') : key;
1799      }
1800  
1801      // pick the locale from the array
1802      // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
1803      // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
1804      function chooseLocale(names) {
1805          var i = 0, j, next, locale, split;
1806  
1807          while (i < names.length) {
1808              split = normalizeLocale(names[i]).split('-');
1809              j = split.length;
1810              next = normalizeLocale(names[i + 1]);
1811              next = next ? next.split('-') : null;
1812              while (j > 0) {
1813                  locale = loadLocale(split.slice(0, j).join('-'));
1814                  if (locale) {
1815                      return locale;
1816                  }
1817                  if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
1818                      //the next array item is better than a shallower substring of this one
1819                      break;
1820                  }
1821                  j--;
1822              }
1823              i++;
1824          }
1825          return globalLocale;
1826      }
1827  
1828      function loadLocale(name) {
1829          var oldLocale = null;
1830          // TODO: Find a better way to register and load all the locales in Node
1831          if (!locales[name] && (typeof module !== 'undefined') &&
1832                  module && module.exports) {
1833              try {
1834                  oldLocale = globalLocale._abbr;
1835                  var aliasedRequire = require;
1836                  aliasedRequire('./locale/' + name);
1837                  getSetGlobalLocale(oldLocale);
1838              } catch (e) {}
1839          }
1840          return locales[name];
1841      }
1842  
1843      // This function will load locale and then set the global locale.  If
1844      // no arguments are passed in, it will simply return the current global
1845      // locale key.
1846      function getSetGlobalLocale (key, values) {
1847          var data;
1848          if (key) {
1849              if (isUndefined(values)) {
1850                  data = getLocale(key);
1851              }
1852              else {
1853                  data = defineLocale(key, values);
1854              }
1855  
1856              if (data) {
1857                  // moment.duration._locale = moment._locale = data;
1858                  globalLocale = data;
1859              }
1860              else {
1861                  if ((typeof console !==  'undefined') && console.warn) {
1862                      //warn user if arguments are passed but the locale could not be set
1863                      console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
1864                  }
1865              }
1866          }
1867  
1868          return globalLocale._abbr;
1869      }
1870  
1871      function defineLocale (name, config) {
1872          if (config !== null) {
1873              var locale, parentConfig = baseConfig;
1874              config.abbr = name;
1875              if (locales[name] != null) {
1876                  deprecateSimple('defineLocaleOverride',
1877                          'use moment.updateLocale(localeName, config) to change ' +
1878                          'an existing locale. moment.defineLocale(localeName, ' +
1879                          'config) should only be used for creating a new locale ' +
1880                          'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
1881                  parentConfig = locales[name]._config;
1882              } else if (config.parentLocale != null) {
1883                  if (locales[config.parentLocale] != null) {
1884                      parentConfig = locales[config.parentLocale]._config;
1885                  } else {
1886                      locale = loadLocale(config.parentLocale);
1887                      if (locale != null) {
1888                          parentConfig = locale._config;
1889                      } else {
1890                          if (!localeFamilies[config.parentLocale]) {
1891                              localeFamilies[config.parentLocale] = [];
1892                          }
1893                          localeFamilies[config.parentLocale].push({
1894                              name: name,
1895                              config: config
1896                          });
1897                          return null;
1898                      }
1899                  }
1900              }
1901              locales[name] = new Locale(mergeConfigs(parentConfig, config));
1902  
1903              if (localeFamilies[name]) {
1904                  localeFamilies[name].forEach(function (x) {
1905                      defineLocale(x.name, x.config);
1906                  });
1907              }
1908  
1909              // backwards compat for now: also set the locale
1910              // make sure we set the locale AFTER all child locales have been
1911              // created, so we won't end up with the child locale set.
1912              getSetGlobalLocale(name);
1913  
1914  
1915              return locales[name];
1916          } else {
1917              // useful for testing
1918              delete locales[name];
1919              return null;
1920          }
1921      }
1922  
1923      function updateLocale(name, config) {
1924          if (config != null) {
1925              var locale, tmpLocale, parentConfig = baseConfig;
1926              // MERGE
1927              tmpLocale = loadLocale(name);
1928              if (tmpLocale != null) {
1929                  parentConfig = tmpLocale._config;
1930              }
1931              config = mergeConfigs(parentConfig, config);
1932              locale = new Locale(config);
1933              locale.parentLocale = locales[name];
1934              locales[name] = locale;
1935  
1936              // backwards compat for now: also set the locale
1937              getSetGlobalLocale(name);
1938          } else {
1939              // pass null for config to unupdate, useful for tests
1940              if (locales[name] != null) {
1941                  if (locales[name].parentLocale != null) {
1942                      locales[name] = locales[name].parentLocale;
1943                  } else if (locales[name] != null) {
1944                      delete locales[name];
1945                  }
1946              }
1947          }
1948          return locales[name];
1949      }
1950  
1951      // returns locale data
1952      function getLocale (key) {
1953          var locale;
1954  
1955          if (key && key._locale && key._locale._abbr) {
1956              key = key._locale._abbr;
1957          }
1958  
1959          if (!key) {
1960              return globalLocale;
1961          }
1962  
1963          if (!isArray(key)) {
1964              //short-circuit everything else
1965              locale = loadLocale(key);
1966              if (locale) {
1967                  return locale;
1968              }
1969              key = [key];
1970          }
1971  
1972          return chooseLocale(key);
1973      }
1974  
1975      function listLocales() {
1976          return keys(locales);
1977      }
1978  
1979      function checkOverflow (m) {
1980          var overflow;
1981          var a = m._a;
1982  
1983          if (a && getParsingFlags(m).overflow === -2) {
1984              overflow =
1985                  a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
1986                  a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
1987                  a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
1988                  a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
1989                  a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
1990                  a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
1991                  -1;
1992  
1993              if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
1994                  overflow = DATE;
1995              }
1996              if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
1997                  overflow = WEEK;
1998              }
1999              if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
2000                  overflow = WEEKDAY;
2001              }
2002  
2003              getParsingFlags(m).overflow = overflow;
2004          }
2005  
2006          return m;
2007      }
2008  
2009      // Pick the first defined of two or three arguments.
2010      function defaults(a, b, c) {
2011          if (a != null) {
2012              return a;
2013          }
2014          if (b != null) {
2015              return b;
2016          }
2017          return c;
2018      }
2019  
2020      function currentDateArray(config) {
2021          // hooks is actually the exported moment object
2022          var nowValue = new Date(hooks.now());
2023          if (config._useUTC) {
2024              return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
2025          }
2026          return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2027      }
2028  
2029      // convert an array to a date.
2030      // the array should mirror the parameters below
2031      // note: all values past the year are optional and will default to the lowest possible value.
2032      // [year, month, day , hour, minute, second, millisecond]
2033      function configFromArray (config) {
2034          var i, date, input = [], currentDate, expectedWeekday, yearToUse;
2035  
2036          if (config._d) {
2037              return;
2038          }
2039  
2040          currentDate = currentDateArray(config);
2041  
2042          //compute day of the year from weeks and weekdays
2043          if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2044              dayOfYearFromWeekInfo(config);
2045          }
2046  
2047          //if the day of the year is set, figure out what it is
2048          if (config._dayOfYear != null) {
2049              yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2050  
2051              if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
2052                  getParsingFlags(config)._overflowDayOfYear = true;
2053              }
2054  
2055              date = createUTCDate(yearToUse, 0, config._dayOfYear);
2056              config._a[MONTH] = date.getUTCMonth();
2057              config._a[DATE] = date.getUTCDate();
2058          }
2059  
2060          // Default to current date.
2061          // * if no year, month, day of month are given, default to today
2062          // * if day of month is given, default month and year
2063          // * if month is given, default only year
2064          // * if year is given, don't default anything
2065          for (i = 0; i < 3 && config._a[i] == null; ++i) {
2066              config._a[i] = input[i] = currentDate[i];
2067          }
2068  
2069          // Zero out whatever was not defaulted, including time
2070          for (; i < 7; i++) {
2071              config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
2072          }
2073  
2074          // Check for 24:00:00.000
2075          if (config._a[HOUR] === 24 &&
2076                  config._a[MINUTE] === 0 &&
2077                  config._a[SECOND] === 0 &&
2078                  config._a[MILLISECOND] === 0) {
2079              config._nextDay = true;
2080              config._a[HOUR] = 0;
2081          }
2082  
2083          config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
2084          expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();
2085  
2086          // Apply timezone offset from input. The actual utcOffset can be changed
2087          // with parseZone.
2088          if (config._tzm != null) {
2089              config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2090          }
2091  
2092          if (config._nextDay) {
2093              config._a[HOUR] = 24;
2094          }
2095  
2096          // check for mismatching day of week
2097          if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
2098              getParsingFlags(config).weekdayMismatch = true;
2099          }
2100      }
2101  
2102      function dayOfYearFromWeekInfo(config) {
2103          var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
2104  
2105          w = config._w;
2106          if (w.GG != null || w.W != null || w.E != null) {
2107              dow = 1;
2108              doy = 4;
2109  
2110              // TODO: We need to take the current isoWeekYear, but that depends on
2111              // how we interpret now (local, utc, fixed offset). So create
2112              // a now version of current config (take local/utc/offset flags, and
2113              // create now).
2114              weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
2115              week = defaults(w.W, 1);
2116              weekday = defaults(w.E, 1);
2117              if (weekday < 1 || weekday > 7) {
2118                  weekdayOverflow = true;
2119              }
2120          } else {
2121              dow = config._locale._week.dow;
2122              doy = config._locale._week.doy;
2123  
2124              var curWeek = weekOfYear(createLocal(), dow, doy);
2125  
2126              weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
2127  
2128              // Default to current week.
2129              week = defaults(w.w, curWeek.week);
2130  
2131              if (w.d != null) {
2132                  // weekday -- low day numbers are considered next week
2133                  weekday = w.d;
2134                  if (weekday < 0 || weekday > 6) {
2135                      weekdayOverflow = true;
2136                  }
2137              } else if (w.e != null) {
2138                  // local weekday -- counting starts from begining of week
2139                  weekday = w.e + dow;
2140                  if (w.e < 0 || w.e > 6) {
2141                      weekdayOverflow = true;
2142                  }
2143              } else {
2144                  // default to begining of week
2145                  weekday = dow;
2146              }
2147          }
2148          if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
2149              getParsingFlags(config)._overflowWeeks = true;
2150          } else if (weekdayOverflow != null) {
2151              getParsingFlags(config)._overflowWeekday = true;
2152          } else {
2153              temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
2154              config._a[YEAR] = temp.year;
2155              config._dayOfYear = temp.dayOfYear;
2156          }
2157      }
2158  
2159      // iso 8601 regex
2160      // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
2161      var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
2162      var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
2163  
2164      var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
2165  
2166      var isoDates = [
2167          ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
2168          ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
2169          ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
2170          ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
2171          ['YYYY-DDD', /\d{4}-\d{3}/],
2172          ['YYYY-MM', /\d{4}-\d\d/, false],
2173          ['YYYYYYMMDD', /[+-]\d{10}/],
2174          ['YYYYMMDD', /\d{8}/],
2175          // YYYYMM is NOT allowed by the standard
2176          ['GGGG[W]WWE', /\d{4}W\d{3}/],
2177          ['GGGG[W]WW', /\d{4}W\d{2}/, false],
2178          ['YYYYDDD', /\d{7}/]
2179      ];
2180  
2181      // iso time formats and regexes
2182      var isoTimes = [
2183          ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
2184          ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
2185          ['HH:mm:ss', /\d\d:\d\d:\d\d/],
2186          ['HH:mm', /\d\d:\d\d/],
2187          ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
2188          ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
2189          ['HHmmss', /\d\d\d\d\d\d/],
2190          ['HHmm', /\d\d\d\d/],
2191          ['HH', /\d\d/]
2192      ];
2193  
2194      var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
2195  
2196      // date from iso format
2197      function configFromISO(config) {
2198          var i, l,
2199              string = config._i,
2200              match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
2201              allowTime, dateFormat, timeFormat, tzFormat;
2202  
2203          if (match) {
2204              getParsingFlags(config).iso = true;
2205  
2206              for (i = 0, l = isoDates.length; i < l; i++) {
2207                  if (isoDates[i][1].exec(match[1])) {
2208                      dateFormat = isoDates[i][0];
2209                      allowTime = isoDates[i][2] !== false;
2210                      break;
2211                  }
2212              }
2213              if (dateFormat == null) {
2214                  config._isValid = false;
2215                  return;
2216              }
2217              if (match[3]) {
2218                  for (i = 0, l = isoTimes.length; i < l; i++) {
2219                      if (isoTimes[i][1].exec(match[3])) {
2220                          // match[2] should be 'T' or space
2221                          timeFormat = (match[2] || ' ') + isoTimes[i][0];
2222                          break;
2223                      }
2224                  }
2225                  if (timeFormat == null) {
2226                      config._isValid = false;
2227                      return;
2228                  }
2229              }
2230              if (!allowTime && timeFormat != null) {
2231                  config._isValid = false;
2232                  return;
2233              }
2234              if (match[4]) {
2235                  if (tzRegex.exec(match[4])) {
2236                      tzFormat = 'Z';
2237                  } else {
2238                      config._isValid = false;
2239                      return;
2240                  }
2241              }
2242              config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
2243              configFromStringAndFormat(config);
2244          } else {
2245              config._isValid = false;
2246          }
2247      }
2248  
2249      // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
2250      var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
2251  
2252      function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
2253          var result = [
2254              untruncateYear(yearStr),
2255              defaultLocaleMonthsShort.indexOf(monthStr),
2256              parseInt(dayStr, 10),
2257              parseInt(hourStr, 10),
2258              parseInt(minuteStr, 10)
2259          ];
2260  
2261          if (secondStr) {
2262              result.push(parseInt(secondStr, 10));
2263          }
2264  
2265          return result;
2266      }
2267  
2268      function untruncateYear(yearStr) {
2269          var year = parseInt(yearStr, 10);
2270          if (year <= 49) {
2271              return 2000 + year;
2272          } else if (year <= 999) {
2273              return 1900 + year;
2274          }
2275          return year;
2276      }
2277  
2278      function preprocessRFC2822(s) {
2279          // Remove comments and folding whitespace and replace multiple-spaces with a single space
2280          return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
2281      }
2282  
2283      function checkWeekday(weekdayStr, parsedInput, config) {
2284          if (weekdayStr) {
2285              // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
2286              var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
2287                  weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
2288              if (weekdayProvided !== weekdayActual) {
2289                  getParsingFlags(config).weekdayMismatch = true;
2290                  config._isValid = false;
2291                  return false;
2292              }
2293          }
2294          return true;
2295      }
2296  
2297      var obsOffsets = {
2298          UT: 0,
2299          GMT: 0,
2300          EDT: -4 * 60,
2301          EST: -5 * 60,
2302          CDT: -5 * 60,
2303          CST: -6 * 60,
2304          MDT: -6 * 60,
2305          MST: -7 * 60,
2306          PDT: -7 * 60,
2307          PST: -8 * 60
2308      };
2309  
2310      function calculateOffset(obsOffset, militaryOffset, numOffset) {
2311          if (obsOffset) {
2312              return obsOffsets[obsOffset];
2313          } else if (militaryOffset) {
2314              // the only allowed military tz is Z
2315              return 0;
2316          } else {
2317              var hm = parseInt(numOffset, 10);
2318              var m = hm % 100, h = (hm - m) / 100;
2319              return h * 60 + m;
2320          }
2321      }
2322  
2323      // date and time from ref 2822 format
2324      function configFromRFC2822(config) {
2325          var match = rfc2822.exec(preprocessRFC2822(config._i));
2326          if (match) {
2327              var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
2328              if (!checkWeekday(match[1], parsedArray, config)) {
2329                  return;
2330              }
2331  
2332              config._a = parsedArray;
2333              config._tzm = calculateOffset(match[8], match[9], match[10]);
2334  
2335              config._d = createUTCDate.apply(null, config._a);
2336              config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2337  
2338              getParsingFlags(config).rfc2822 = true;
2339          } else {
2340              config._isValid = false;
2341          }
2342      }
2343  
2344      // date from iso format or fallback
2345      function configFromString(config) {
2346          var matched = aspNetJsonRegex.exec(config._i);
2347  
2348          if (matched !== null) {
2349              config._d = new Date(+matched[1]);
2350              return;
2351          }
2352  
2353          configFromISO(config);
2354          if (config._isValid === false) {
2355              delete config._isValid;
2356          } else {
2357              return;
2358          }
2359  
2360          configFromRFC2822(config);
2361          if (config._isValid === false) {
2362              delete config._isValid;
2363          } else {
2364              return;
2365          }
2366  
2367          // Final attempt, use Input Fallback
2368          hooks.createFromInputFallback(config);
2369      }
2370  
2371      hooks.createFromInputFallback = deprecate(
2372          'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
2373          'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
2374          'discouraged and will be removed in an upcoming major release. Please refer to ' +
2375          'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
2376          function (config) {
2377              config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
2378          }
2379      );
2380  
2381      // constant that refers to the ISO standard
2382      hooks.ISO_8601 = function () {};
2383  
2384      // constant that refers to the RFC 2822 form
2385      hooks.RFC_2822 = function () {};
2386  
2387      // date from string and format string
2388      function configFromStringAndFormat(config) {
2389          // TODO: Move this to another part of the creation flow to prevent circular deps
2390          if (config._f === hooks.ISO_8601) {
2391              configFromISO(config);
2392              return;
2393          }
2394          if (config._f === hooks.RFC_2822) {
2395              configFromRFC2822(config);
2396              return;
2397          }
2398          config._a = [];
2399          getParsingFlags(config).empty = true;
2400  
2401          // This array is used to make a Date, either with `new Date` or `Date.UTC`
2402          var string = '' + config._i,
2403              i, parsedInput, tokens, token, skipped,
2404              stringLength = string.length,
2405              totalParsedInputLength = 0;
2406  
2407          tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
2408  
2409          for (i = 0; i < tokens.length; i++) {
2410              token = tokens[i];
2411              parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
2412              // console.log('token', token, 'parsedInput', parsedInput,
2413              //         'regex', getParseRegexForToken(token, config));
2414              if (parsedInput) {
2415                  skipped = string.substr(0, string.indexOf(parsedInput));
2416                  if (skipped.length > 0) {
2417                      getParsingFlags(config).unusedInput.push(skipped);
2418                  }
2419                  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
2420                  totalParsedInputLength += parsedInput.length;
2421              }
2422              // don't parse if it's not a known token
2423              if (formatTokenFunctions[token]) {
2424                  if (parsedInput) {
2425                      getParsingFlags(config).empty = false;
2426                  }
2427                  else {
2428                      getParsingFlags(config).unusedTokens.push(token);
2429                  }
2430                  addTimeToArrayFromToken(token, parsedInput, config);
2431              }
2432              else if (config._strict && !parsedInput) {
2433                  getParsingFlags(config).unusedTokens.push(token);
2434              }
2435          }
2436  
2437          // add remaining unparsed input length to the string
2438          getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
2439          if (string.length > 0) {
2440              getParsingFlags(config).unusedInput.push(string);
2441          }
2442  
2443          // clear _12h flag if hour is <= 12
2444          if (config._a[HOUR] <= 12 &&
2445              getParsingFlags(config).bigHour === true &&
2446              config._a[HOUR] > 0) {
2447              getParsingFlags(config).bigHour = undefined;
2448          }
2449  
2450          getParsingFlags(config).parsedDateParts = config._a.slice(0);
2451          getParsingFlags(config).meridiem = config._meridiem;
2452          // handle meridiem
2453          config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
2454  
2455          configFromArray(config);
2456          checkOverflow(config);
2457      }
2458  
2459  
2460      function meridiemFixWrap (locale, hour, meridiem) {
2461          var isPm;
2462  
2463          if (meridiem == null) {
2464              // nothing to do
2465              return hour;
2466          }
2467          if (locale.meridiemHour != null) {
2468              return locale.meridiemHour(hour, meridiem);
2469          } else if (locale.isPM != null) {
2470              // Fallback
2471              isPm = locale.isPM(meridiem);
2472              if (isPm && hour < 12) {
2473                  hour += 12;
2474              }
2475              if (!isPm && hour === 12) {
2476                  hour = 0;
2477              }
2478              return hour;
2479          } else {
2480              // this is not supposed to happen
2481              return hour;
2482          }
2483      }
2484  
2485      // date from string and array of format strings
2486      function configFromStringAndArray(config) {
2487          var tempConfig,
2488              bestMoment,
2489  
2490              scoreToBeat,
2491              i,
2492              currentScore;
2493  
2494          if (config._f.length === 0) {
2495              getParsingFlags(config).invalidFormat = true;
2496              config._d = new Date(NaN);
2497              return;
2498          }
2499  
2500          for (i = 0; i < config._f.length; i++) {
2501              currentScore = 0;
2502              tempConfig = copyConfig({}, config);
2503              if (config._useUTC != null) {
2504                  tempConfig._useUTC = config._useUTC;
2505              }
2506              tempConfig._f = config._f[i];
2507              configFromStringAndFormat(tempConfig);
2508  
2509              if (!isValid(tempConfig)) {
2510                  continue;
2511              }
2512  
2513              // if there is any input that was not parsed add a penalty for that format
2514              currentScore += getParsingFlags(tempConfig).charsLeftOver;
2515  
2516              //or tokens
2517              currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2518  
2519              getParsingFlags(tempConfig).score = currentScore;
2520  
2521              if (scoreToBeat == null || currentScore < scoreToBeat) {
2522                  scoreToBeat = currentScore;
2523                  bestMoment = tempConfig;
2524              }
2525          }
2526  
2527          extend(config, bestMoment || tempConfig);
2528      }
2529  
2530      function configFromObject(config) {
2531          if (config._d) {
2532              return;
2533          }
2534  
2535          var i = normalizeObjectUnits(config._i);
2536          config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
2537              return obj && parseInt(obj, 10);
2538          });
2539  
2540          configFromArray(config);
2541      }
2542  
2543      function createFromConfig (config) {
2544          var res = new Moment(checkOverflow(prepareConfig(config)));
2545          if (res._nextDay) {
2546              // Adding is smart enough around DST
2547              res.add(1, 'd');
2548              res._nextDay = undefined;
2549          }
2550  
2551          return res;
2552      }
2553  
2554      function prepareConfig (config) {
2555          var input = config._i,
2556              format = config._f;
2557  
2558          config._locale = config._locale || getLocale(config._l);
2559  
2560          if (input === null || (format === undefined && input === '')) {
2561              return createInvalid({nullInput: true});
2562          }
2563  
2564          if (typeof input === 'string') {
2565              config._i = input = config._locale.preparse(input);
2566          }
2567  
2568          if (isMoment(input)) {
2569              return new Moment(checkOverflow(input));
2570          } else if (isDate(input)) {
2571              config._d = input;
2572          } else if (isArray(format)) {
2573              configFromStringAndArray(config);
2574          } else if (format) {
2575              configFromStringAndFormat(config);
2576          }  else {
2577              configFromInput(config);
2578          }
2579  
2580          if (!isValid(config)) {
2581              config._d = null;
2582          }
2583  
2584          return config;
2585      }
2586  
2587      function configFromInput(config) {
2588          var input = config._i;
2589          if (isUndefined(input)) {
2590              config._d = new Date(hooks.now());
2591          } else if (isDate(input)) {
2592              config._d = new Date(input.valueOf());
2593          } else if (typeof input === 'string') {
2594              configFromString(config);
2595          } else if (isArray(input)) {
2596              config._a = map(input.slice(0), function (obj) {
2597                  return parseInt(obj, 10);
2598              });
2599              configFromArray(config);
2600          } else if (isObject(input)) {
2601              configFromObject(config);
2602          } else if (isNumber(input)) {
2603              // from milliseconds
2604              config._d = new Date(input);
2605          } else {
2606              hooks.createFromInputFallback(config);
2607          }
2608      }
2609  
2610      function createLocalOrUTC (input, format, locale, strict, isUTC) {
2611          var c = {};
2612  
2613          if (locale === true || locale === false) {
2614              strict = locale;
2615              locale = undefined;
2616          }
2617  
2618          if ((isObject(input) && isObjectEmpty(input)) ||
2619                  (isArray(input) && input.length === 0)) {
2620              input = undefined;
2621          }
2622          // object construction must be done this way.
2623          // https://github.com/moment/moment/issues/1423
2624          c._isAMomentObject = true;
2625          c._useUTC = c._isUTC = isUTC;
2626          c._l = locale;
2627          c._i = input;
2628          c._f = format;
2629          c._strict = strict;
2630  
2631          return createFromConfig(c);
2632      }
2633  
2634      function createLocal (input, format, locale, strict) {
2635          return createLocalOrUTC(input, format, locale, strict, false);
2636      }
2637  
2638      var prototypeMin = deprecate(
2639          'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
2640          function () {
2641              var other = createLocal.apply(null, arguments);
2642              if (this.isValid() && other.isValid()) {
2643                  return other < this ? this : other;
2644              } else {
2645                  return createInvalid();
2646              }
2647          }
2648      );
2649  
2650      var prototypeMax = deprecate(
2651          'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
2652          function () {
2653              var other = createLocal.apply(null, arguments);
2654              if (this.isValid() && other.isValid()) {
2655                  return other > this ? this : other;
2656              } else {
2657                  return createInvalid();
2658              }
2659          }
2660      );
2661  
2662      // Pick a moment m from moments so that m[fn](other) is true for all
2663      // other. This relies on the function fn to be transitive.
2664      //
2665      // moments should either be an array of moment objects or an array, whose
2666      // first element is an array of moment objects.
2667      function pickBy(fn, moments) {
2668          var res, i;
2669          if (moments.length === 1 && isArray(moments[0])) {
2670              moments = moments[0];
2671          }
2672          if (!moments.length) {
2673              return createLocal();
2674          }
2675          res = moments[0];
2676          for (i = 1; i < moments.length; ++i) {
2677              if (!moments[i].isValid() || moments[i][fn](res)) {
2678                  res = moments[i];
2679              }
2680          }
2681          return res;
2682      }
2683  
2684      // TODO: Use [].sort instead?
2685      function min () {
2686          var args = [].slice.call(arguments, 0);
2687  
2688          return pickBy('isBefore', args);
2689      }
2690  
2691      function max () {
2692          var args = [].slice.call(arguments, 0);
2693  
2694          return pickBy('isAfter', args);
2695      }
2696  
2697      var now = function () {
2698          return Date.now ? Date.now() : +(new Date());
2699      };
2700  
2701      var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
2702  
2703      function isDurationValid(m) {
2704          for (var key in m) {
2705              if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
2706                  return false;
2707              }
2708          }
2709  
2710          var unitHasDecimal = false;
2711          for (var i = 0; i < ordering.length; ++i) {
2712              if (m[ordering[i]]) {
2713                  if (unitHasDecimal) {
2714                      return false; // only allow non-integers for smallest unit
2715                  }
2716                  if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
2717                      unitHasDecimal = true;
2718                  }
2719              }
2720          }
2721  
2722          return true;
2723      }
2724  
2725      function isValid$1() {
2726          return this._isValid;
2727      }
2728  
2729      function createInvalid$1() {
2730          return createDuration(NaN);
2731      }
2732  
2733      function Duration (duration) {
2734          var normalizedInput = normalizeObjectUnits(duration),
2735              years = normalizedInput.year || 0,
2736              quarters = normalizedInput.quarter || 0,
2737              months = normalizedInput.month || 0,
2738              weeks = normalizedInput.week || 0,
2739              days = normalizedInput.day || 0,
2740              hours = normalizedInput.hour || 0,
2741              minutes = normalizedInput.minute || 0,
2742              seconds = normalizedInput.second || 0,
2743              milliseconds = normalizedInput.millisecond || 0;
2744  
2745          this._isValid = isDurationValid(normalizedInput);
2746  
2747          // representation for dateAddRemove
2748          this._milliseconds = +milliseconds +
2749              seconds * 1e3 + // 1000
2750              minutes * 6e4 + // 1000 * 60
2751              hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
2752          // Because of dateAddRemove treats 24 hours as different from a
2753          // day when working around DST, we need to store them separately
2754          this._days = +days +
2755              weeks * 7;
2756          // It is impossible to translate months into days without knowing
2757          // which months you are are talking about, so we have to store
2758          // it separately.
2759          this._months = +months +
2760              quarters * 3 +
2761              years * 12;
2762  
2763          this._data = {};
2764  
2765          this._locale = getLocale();
2766  
2767          this._bubble();
2768      }
2769  
2770      function isDuration (obj) {
2771          return obj instanceof Duration;
2772      }
2773  
2774      function absRound (number) {
2775          if (number < 0) {
2776              return Math.round(-1 * number) * -1;
2777          } else {
2778              return Math.round(number);
2779          }
2780      }
2781  
2782      // FORMATTING
2783  
2784      function offset (token, separator) {
2785          addFormatToken(token, 0, 0, function () {
2786              var offset = this.utcOffset();
2787              var sign = '+';
2788              if (offset < 0) {
2789                  offset = -offset;
2790                  sign = '-';
2791              }
2792              return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
2793          });
2794      }
2795  
2796      offset('Z', ':');
2797      offset('ZZ', '');
2798  
2799      // PARSING
2800  
2801      addRegexToken('Z',  matchShortOffset);
2802      addRegexToken('ZZ', matchShortOffset);
2803      addParseToken(['Z', 'ZZ'], function (input, array, config) {
2804          config._useUTC = true;
2805          config._tzm = offsetFromString(matchShortOffset, input);
2806      });
2807  
2808      // HELPERS
2809  
2810      // timezone chunker
2811      // '+10:00' > ['10',  '00']
2812      // '-1530'  > ['-15', '30']
2813      var chunkOffset = /([\+\-]|\d\d)/gi;
2814  
2815      function offsetFromString(matcher, string) {
2816          var matches = (string || '').match(matcher);
2817  
2818          if (matches === null) {
2819              return null;
2820          }
2821  
2822          var chunk   = matches[matches.length - 1] || [];
2823          var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
2824          var minutes = +(parts[1] * 60) + toInt(parts[2]);
2825  
2826          return minutes === 0 ?
2827            0 :
2828            parts[0] === '+' ? minutes : -minutes;
2829      }
2830  
2831      // Return a moment from input, that is local/utc/zone equivalent to model.
2832      function cloneWithOffset(input, model) {
2833          var res, diff;
2834          if (model._isUTC) {
2835              res = model.clone();
2836              diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
2837              // Use low-level api, because this fn is low-level api.
2838              res._d.setTime(res._d.valueOf() + diff);
2839              hooks.updateOffset(res, false);
2840              return res;
2841          } else {
2842              return createLocal(input).local();
2843          }
2844      }
2845  
2846      function getDateOffset (m) {
2847          // On Firefox.24 Date#getTimezoneOffset returns a floating point.
2848          // https://github.com/moment/moment/pull/1871
2849          return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
2850      }
2851  
2852      // HOOKS
2853  
2854      // This function will be called whenever a moment is mutated.
2855      // It is intended to keep the offset in sync with the timezone.
2856      hooks.updateOffset = function () {};
2857  
2858      // MOMENTS
2859  
2860      // keepLocalTime = true means only change the timezone, without
2861      // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
2862      // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
2863      // +0200, so we adjust the time as needed, to be valid.
2864      //
2865      // Keeping the time actually adds/subtracts (one hour)
2866      // from the actual represented time. That is why we call updateOffset
2867      // a second time. In case it wants us to change the offset again
2868      // _changeInProgress == true case, then we have to adjust, because
2869      // there is no such time in the given timezone.
2870      function getSetOffset (input, keepLocalTime, keepMinutes) {
2871          var offset = this._offset || 0,
2872              localAdjust;
2873          if (!this.isValid()) {
2874              return input != null ? this : NaN;
2875          }
2876          if (input != null) {
2877              if (typeof input === 'string') {
2878                  input = offsetFromString(matchShortOffset, input);
2879                  if (input === null) {
2880                      return this;
2881                  }
2882              } else if (Math.abs(input) < 16 && !keepMinutes) {
2883                  input = input * 60;
2884              }
2885              if (!this._isUTC && keepLocalTime) {
2886                  localAdjust = getDateOffset(this);
2887              }
2888              this._offset = input;
2889              this._isUTC = true;
2890              if (localAdjust != null) {
2891                  this.add(localAdjust, 'm');
2892              }
2893              if (offset !== input) {
2894                  if (!keepLocalTime || this._changeInProgress) {
2895                      addSubtract(this, createDuration(input - offset, 'm'), 1, false);
2896                  } else if (!this._changeInProgress) {
2897                      this._changeInProgress = true;
2898                      hooks.updateOffset(this, true);
2899                      this._changeInProgress = null;
2900                  }
2901              }
2902              return this;
2903          } else {
2904              return this._isUTC ? offset : getDateOffset(this);
2905          }
2906      }
2907  
2908      function getSetZone (input, keepLocalTime) {
2909          if (input != null) {
2910              if (typeof input !== 'string') {
2911                  input = -input;
2912              }
2913  
2914              this.utcOffset(input, keepLocalTime);
2915  
2916              return this;
2917          } else {
2918              return -this.utcOffset();
2919          }
2920      }
2921  
2922      function setOffsetToUTC (keepLocalTime) {
2923          return this.utcOffset(0, keepLocalTime);
2924      }
2925  
2926      function setOffsetToLocal (keepLocalTime) {
2927          if (this._isUTC) {
2928              this.utcOffset(0, keepLocalTime);
2929              this._isUTC = false;
2930  
2931              if (keepLocalTime) {
2932                  this.subtract(getDateOffset(this), 'm');
2933              }
2934          }
2935          return this;
2936      }
2937  
2938      function setOffsetToParsedOffset () {
2939          if (this._tzm != null) {
2940              this.utcOffset(this._tzm, false, true);
2941          } else if (typeof this._i === 'string') {
2942              var tZone = offsetFromString(matchOffset, this._i);
2943              if (tZone != null) {
2944                  this.utcOffset(tZone);
2945              }
2946              else {
2947                  this.utcOffset(0, true);
2948              }
2949          }
2950          return this;
2951      }
2952  
2953      function hasAlignedHourOffset (input) {
2954          if (!this.isValid()) {
2955              return false;
2956          }
2957          input = input ? createLocal(input).utcOffset() : 0;
2958  
2959          return (this.utcOffset() - input) % 60 === 0;
2960      }
2961  
2962      function isDaylightSavingTime () {
2963          return (
2964              this.utcOffset() > this.clone().month(0).utcOffset() ||
2965              this.utcOffset() > this.clone().month(5).utcOffset()
2966          );
2967      }
2968  
2969      function isDaylightSavingTimeShifted () {
2970          if (!isUndefined(this._isDSTShifted)) {
2971              return this._isDSTShifted;
2972          }
2973  
2974          var c = {};
2975  
2976          copyConfig(c, this);
2977          c = prepareConfig(c);
2978  
2979          if (c._a) {
2980              var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
2981              this._isDSTShifted = this.isValid() &&
2982                  compareArrays(c._a, other.toArray()) > 0;
2983          } else {
2984              this._isDSTShifted = false;
2985          }
2986  
2987          return this._isDSTShifted;
2988      }
2989  
2990      function isLocal () {
2991          return this.isValid() ? !this._isUTC : false;
2992      }
2993  
2994      function isUtcOffset () {
2995          return this.isValid() ? this._isUTC : false;
2996      }
2997  
2998      function isUtc () {
2999          return this.isValid() ? this._isUTC && this._offset === 0 : false;
3000      }
3001  
3002      // ASP.NET json date format regex
3003      var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
3004  
3005      // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
3006      // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
3007      // and further modified to allow for strings containing both week and day
3008      var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
3009  
3010      function createDuration (input, key) {
3011          var duration = input,
3012              // matching against regexp is expensive, do it on demand
3013              match = null,
3014              sign,
3015              ret,
3016              diffRes;
3017  
3018          if (isDuration(input)) {
3019              duration = {
3020                  ms : input._milliseconds,
3021                  d  : input._days,
3022                  M  : input._months
3023              };
3024          } else if (isNumber(input)) {
3025              duration = {};
3026              if (key) {
3027                  duration[key] = input;
3028              } else {
3029                  duration.milliseconds = input;
3030              }
3031          } else if (!!(match = aspNetRegex.exec(input))) {
3032              sign = (match[1] === '-') ? -1 : 1;
3033              duration = {
3034                  y  : 0,
3035                  d  : toInt(match[DATE])                         * sign,
3036                  h  : toInt(match[HOUR])                         * sign,
3037                  m  : toInt(match[MINUTE])                       * sign,
3038                  s  : toInt(match[SECOND])                       * sign,
3039                  ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
3040              };
3041          } else if (!!(match = isoRegex.exec(input))) {
3042              sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
3043              duration = {
3044                  y : parseIso(match[2], sign),
3045                  M : parseIso(match[3], sign),
3046                  w : parseIso(match[4], sign),
3047                  d : parseIso(match[5], sign),
3048                  h : parseIso(match[6], sign),
3049                  m : parseIso(match[7], sign),
3050                  s : parseIso(match[8], sign)
3051              };
3052          } else if (duration == null) {// checks for null or undefined
3053              duration = {};
3054          } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
3055              diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
3056  
3057              duration = {};
3058              duration.ms = diffRes.milliseconds;
3059              duration.M = diffRes.months;
3060          }
3061  
3062          ret = new Duration(duration);
3063  
3064          if (isDuration(input) && hasOwnProp(input, '_locale')) {
3065              ret._locale = input._locale;
3066          }
3067  
3068          return ret;
3069      }
3070  
3071      createDuration.fn = Duration.prototype;
3072      createDuration.invalid = createInvalid$1;
3073  
3074      function parseIso (inp, sign) {
3075          // We'd normally use ~~inp for this, but unfortunately it also
3076          // converts floats to ints.
3077          // inp may be undefined, so careful calling replace on it.
3078          var res = inp && parseFloat(inp.replace(',', '.'));
3079          // apply sign while we're at it
3080          return (isNaN(res) ? 0 : res) * sign;
3081      }
3082  
3083      function positiveMomentsDifference(base, other) {
3084          var res = {milliseconds: 0, months: 0};
3085  
3086          res.months = other.month() - base.month() +
3087              (other.year() - base.year()) * 12;
3088          if (base.clone().add(res.months, 'M').isAfter(other)) {
3089              --res.months;
3090          }
3091  
3092          res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
3093  
3094          return res;
3095      }
3096  
3097      function momentsDifference(base, other) {
3098          var res;
3099          if (!(base.isValid() && other.isValid())) {
3100              return {milliseconds: 0, months: 0};
3101          }
3102  
3103          other = cloneWithOffset(other, base);
3104          if (base.isBefore(other)) {
3105              res = positiveMomentsDifference(base, other);
3106          } else {
3107              res = positiveMomentsDifference(other, base);
3108              res.milliseconds = -res.milliseconds;
3109              res.months = -res.months;
3110          }
3111  
3112          return res;
3113      }
3114  
3115      // TODO: remove 'name' arg after deprecation is removed
3116      function createAdder(direction, name) {
3117          return function (val, period) {
3118              var dur, tmp;
3119              //invert the arguments, but complain about it
3120              if (period !== null && !isNaN(+period)) {
3121                  deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
3122                  'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
3123                  tmp = val; val = period; period = tmp;
3124              }
3125  
3126              val = typeof val === 'string' ? +val : val;
3127              dur = createDuration(val, period);
3128              addSubtract(this, dur, direction);
3129              return this;
3130          };
3131      }
3132  
3133      function addSubtract (mom, duration, isAdding, updateOffset) {
3134          var milliseconds = duration._milliseconds,
3135              days = absRound(duration._days),
3136              months = absRound(duration._months);
3137  
3138          if (!mom.isValid()) {
3139              // No op
3140              return;
3141          }
3142  
3143          updateOffset = updateOffset == null ? true : updateOffset;
3144  
3145          if (months) {
3146              setMonth(mom, get(mom, 'Month') + months * isAdding);
3147          }
3148          if (days) {
3149              set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
3150          }
3151          if (milliseconds) {
3152              mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
3153          }
3154          if (updateOffset) {
3155              hooks.updateOffset(mom, days || months);
3156          }
3157      }
3158  
3159      var add      = createAdder(1, 'add');
3160      var subtract = createAdder(-1, 'subtract');
3161  
3162      function getCalendarFormat(myMoment, now) {
3163          var diff = myMoment.diff(now, 'days', true);
3164          return diff < -6 ? 'sameElse' :
3165                  diff < -1 ? 'lastWeek' :
3166                  diff < 0 ? 'lastDay' :
3167                  diff < 1 ? 'sameDay' :
3168                  diff < 2 ? 'nextDay' :
3169                  diff < 7 ? 'nextWeek' : 'sameElse';
3170      }
3171  
3172      function calendar$1 (time, formats) {
3173          // We want to compare the start of today, vs this.
3174          // Getting start-of-today depends on whether we're local/utc/offset or not.
3175          var now = time || createLocal(),
3176              sod = cloneWithOffset(now, this).startOf('day'),
3177              format = hooks.calendarFormat(this, sod) || 'sameElse';
3178  
3179          var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
3180  
3181          return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
3182      }
3183  
3184      function clone () {
3185          return new Moment(this);
3186      }
3187  
3188      function isAfter (input, units) {
3189          var localInput = isMoment(input) ? input : createLocal(input);
3190          if (!(this.isValid() && localInput.isValid())) {
3191              return false;
3192          }
3193          units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
3194          if (units === 'millisecond') {
3195              return this.valueOf() > localInput.valueOf();
3196          } else {
3197              return localInput.valueOf() < this.clone().startOf(units).valueOf();
3198          }
3199      }
3200  
3201      function isBefore (input, units) {
3202          var localInput = isMoment(input) ? input : createLocal(input);
3203          if (!(this.isValid() && localInput.isValid())) {
3204              return false;
3205          }
3206          units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
3207          if (units === 'millisecond') {
3208              return this.valueOf() < localInput.valueOf();
3209          } else {
3210              return this.clone().endOf(units).valueOf() < localInput.valueOf();
3211          }
3212      }
3213  
3214      function isBetween (from, to, units, inclusivity) {
3215          inclusivity = inclusivity || '()';
3216          return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
3217              (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
3218      }
3219  
3220      function isSame (input, units) {
3221          var localInput = isMoment(input) ? input : createLocal(input),
3222              inputMs;
3223          if (!(this.isValid() && localInput.isValid())) {
3224              return false;
3225          }
3226          units = normalizeUnits(units || 'millisecond');
3227          if (units === 'millisecond') {
3228              return this.valueOf() === localInput.valueOf();
3229          } else {
3230              inputMs = localInput.valueOf();
3231              return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
3232          }
3233      }
3234  
3235      function isSameOrAfter (input, units) {
3236          return this.isSame(input, units) || this.isAfter(input,units);
3237      }
3238  
3239      function isSameOrBefore (input, units) {
3240          return this.isSame(input, units) || this.isBefore(input,units);
3241      }
3242  
3243      function diff (input, units, asFloat) {
3244          var that,
3245              zoneDelta,
3246              output;
3247  
3248          if (!this.isValid()) {
3249              return NaN;
3250          }
3251  
3252          that = cloneWithOffset(input, this);
3253  
3254          if (!that.isValid()) {
3255              return NaN;
3256          }
3257  
3258          zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
3259  
3260          units = normalizeUnits(units);
3261  
3262          switch (units) {
3263              case 'year': output = monthDiff(this, that) / 12; break;
3264              case 'month': output = monthDiff(this, that); break;
3265              case 'quarter': output = monthDiff(this, that) / 3; break;
3266              case 'second': output = (this - that) / 1e3; break; // 1000
3267              case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
3268              case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
3269              case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
3270              case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
3271              default: output = this - that;
3272          }
3273  
3274          return asFloat ? output : absFloor(output);
3275      }
3276  
3277      function monthDiff (a, b) {
3278          // difference in months
3279          var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
3280              // b is in (anchor - 1 month, anchor + 1 month)
3281              anchor = a.clone().add(wholeMonthDiff, 'months'),
3282              anchor2, adjust;
3283  
3284          if (b - anchor < 0) {
3285              anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3286              // linear across the month
3287              adjust = (b - anchor) / (anchor - anchor2);
3288          } else {
3289              anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3290              // linear across the month
3291              adjust = (b - anchor) / (anchor2 - anchor);
3292          }
3293  
3294          //check for negative zero, return zero if negative zero
3295          return -(wholeMonthDiff + adjust) || 0;
3296      }
3297  
3298      hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
3299      hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
3300  
3301      function toString () {
3302          return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
3303      }
3304  
3305      function toISOString(keepOffset) {
3306          if (!this.isValid()) {
3307              return null;
3308          }
3309          var utc = keepOffset !== true;
3310          var m = utc ? this.clone().utc() : this;
3311          if (m.year() < 0 || m.year() > 9999) {
3312              return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
3313          }
3314          if (isFunction(Date.prototype.toISOString)) {
3315              // native implementation is ~50x faster, use it when we can
3316              if (utc) {
3317                  return this.toDate().toISOString();
3318              } else {
3319                  return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
3320              }
3321          }
3322          return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
3323      }
3324  
3325      /**
3326       * Return a human readable representation of a moment that can
3327       * also be evaluated to get a new moment which is the same
3328       *
3329       * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
3330       */
3331      function inspect () {
3332          if (!this.isValid()) {
3333              return 'moment.invalid(/* ' + this._i + ' */)';
3334          }
3335          var func = 'moment';
3336          var zone = '';
3337          if (!this.isLocal()) {
3338              func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
3339              zone = 'Z';
3340          }
3341          var prefix = '[' + func + '("]';
3342          var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
3343          var datetime = '-MM-DD[T]HH:mm:ss.SSS';
3344          var suffix = zone + '[")]';
3345  
3346          return this.format(prefix + year + datetime + suffix);
3347      }
3348  
3349      function format (inputString) {
3350          if (!inputString) {
3351              inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
3352          }
3353          var output = formatMoment(this, inputString);
3354          return this.localeData().postformat(output);
3355      }
3356  
3357      function from (time, withoutSuffix) {
3358          if (this.isValid() &&
3359                  ((isMoment(time) && time.isValid()) ||
3360                   createLocal(time).isValid())) {
3361              return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
3362          } else {
3363              return this.localeData().invalidDate();
3364          }
3365      }
3366  
3367      function fromNow (withoutSuffix) {
3368          return this.from(createLocal(), withoutSuffix);
3369      }
3370  
3371      function to (time, withoutSuffix) {
3372          if (this.isValid() &&
3373                  ((isMoment(time) && time.isValid()) ||
3374                   createLocal(time).isValid())) {
3375              return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
3376          } else {
3377              return this.localeData().invalidDate();
3378          }
3379      }
3380  
3381      function toNow (withoutSuffix) {
3382          return this.to(createLocal(), withoutSuffix);
3383      }
3384  
3385      // If passed a locale key, it will set the locale for this
3386      // instance.  Otherwise, it will return the locale configuration
3387      // variables for this instance.
3388      function locale (key) {
3389          var newLocaleData;
3390  
3391          if (key === undefined) {
3392              return this._locale._abbr;
3393          } else {
3394              newLocaleData = getLocale(key);
3395              if (newLocaleData != null) {
3396                  this._locale = newLocaleData;
3397              }
3398              return this;
3399          }
3400      }
3401  
3402      var lang = deprecate(
3403          'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
3404          function (key) {
3405              if (key === undefined) {
3406                  return this.localeData();
3407              } else {
3408                  return this.locale(key);
3409              }
3410          }
3411      );
3412  
3413      function localeData () {
3414          return this._locale;
3415      }
3416  
3417      function startOf (units) {
3418          units = normalizeUnits(units);
3419          // the following switch intentionally omits break keywords
3420          // to utilize falling through the cases.
3421          switch (units) {
3422              case 'year':
3423                  this.month(0);
3424                  /* falls through */
3425              case 'quarter':
3426              case 'month':
3427                  this.date(1);
3428                  /* falls through */
3429              case 'week':
3430              case 'isoWeek':
3431              case 'day':
3432              case 'date':
3433                  this.hours(0);
3434                  /* falls through */
3435              case 'hour':
3436                  this.minutes(0);
3437                  /* falls through */
3438              case 'minute':
3439                  this.seconds(0);
3440                  /* falls through */
3441              case 'second':
3442                  this.milliseconds(0);
3443          }
3444  
3445          // weeks are a special case
3446          if (units === 'week') {
3447              this.weekday(0);
3448          }
3449          if (units === 'isoWeek') {
3450              this.isoWeekday(1);
3451          }
3452  
3453          // quarters are also special
3454          if (units === 'quarter') {
3455              this.month(Math.floor(this.month() / 3) * 3);
3456          }
3457  
3458          return this;
3459      }
3460  
3461      function endOf (units) {
3462          units = normalizeUnits(units);
3463          if (units === undefined || units === 'millisecond') {
3464              return this;
3465          }
3466  
3467          // 'date' is an alias for 'day', so it should be considered as such.
3468          if (units === 'date') {
3469              units = 'day';
3470          }
3471  
3472          return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
3473      }
3474  
3475      function valueOf () {
3476          return this._d.valueOf() - ((this._offset || 0) * 60000);
3477      }
3478  
3479      function unix () {
3480          return Math.floor(this.valueOf() / 1000);
3481      }
3482  
3483      function toDate () {
3484          return new Date(this.valueOf());
3485      }
3486  
3487      function toArray () {
3488          var m = this;
3489          return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
3490      }
3491  
3492      function toObject () {
3493          var m = this;
3494          return {
3495              years: m.year(),
3496              months: m.month(),
3497              date: m.date(),
3498              hours: m.hours(),
3499              minutes: m.minutes(),
3500              seconds: m.seconds(),
3501              milliseconds: m.milliseconds()
3502          };
3503      }
3504  
3505      function toJSON () {
3506          // new Date(NaN).toJSON() === null
3507          return this.isValid() ? this.toISOString() : null;
3508      }
3509  
3510      function isValid$2 () {
3511          return isValid(this);
3512      }
3513  
3514      function parsingFlags () {
3515          return extend({}, getParsingFlags(this));
3516      }
3517  
3518      function invalidAt () {
3519          return getParsingFlags(this).overflow;
3520      }
3521  
3522      function creationData() {
3523          return {
3524              input: this._i,
3525              format: this._f,
3526              locale: this._locale,
3527              isUTC: this._isUTC,
3528              strict: this._strict
3529          };
3530      }
3531  
3532      // FORMATTING
3533  
3534      addFormatToken(0, ['gg', 2], 0, function () {
3535          return this.weekYear() % 100;
3536      });
3537  
3538      addFormatToken(0, ['GG', 2], 0, function () {
3539          return this.isoWeekYear() % 100;
3540      });
3541  
3542      function addWeekYearFormatToken (token, getter) {
3543          addFormatToken(0, [token, token.length], 0, getter);
3544      }
3545  
3546      addWeekYearFormatToken('gggg',     'weekYear');
3547      addWeekYearFormatToken('ggggg',    'weekYear');
3548      addWeekYearFormatToken('GGGG',  'isoWeekYear');
3549      addWeekYearFormatToken('GGGGG', 'isoWeekYear');
3550  
3551      // ALIASES
3552  
3553      addUnitAlias('weekYear', 'gg');
3554      addUnitAlias('isoWeekYear', 'GG');
3555  
3556      // PRIORITY
3557  
3558      addUnitPriority('weekYear', 1);
3559      addUnitPriority('isoWeekYear', 1);
3560  
3561  
3562      // PARSING
3563  
3564      addRegexToken('G',      matchSigned);
3565      addRegexToken('g',      matchSigned);
3566      addRegexToken('GG',     match1to2, match2);
3567      addRegexToken('gg',     match1to2, match2);
3568      addRegexToken('GGGG',   match1to4, match4);
3569      addRegexToken('gggg',   match1to4, match4);
3570      addRegexToken('GGGGG',  match1to6, match6);
3571      addRegexToken('ggggg',  match1to6, match6);
3572  
3573      addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
3574          week[token.substr(0, 2)] = toInt(input);
3575      });
3576  
3577      addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
3578          week[token] = hooks.parseTwoDigitYear(input);
3579      });
3580  
3581      // MOMENTS
3582  
3583      function getSetWeekYear (input) {
3584          return getSetWeekYearHelper.call(this,
3585                  input,
3586                  this.week(),
3587                  this.weekday(),
3588                  this.localeData()._week.dow,
3589                  this.localeData()._week.doy);
3590      }
3591  
3592      function getSetISOWeekYear (input) {
3593          return getSetWeekYearHelper.call(this,
3594                  input, this.isoWeek(), this.isoWeekday(), 1, 4);
3595      }
3596  
3597      function getISOWeeksInYear () {
3598          return weeksInYear(this.year(), 1, 4);
3599      }
3600  
3601      function getWeeksInYear () {
3602          var weekInfo = this.localeData()._week;
3603          return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
3604      }
3605  
3606      function getSetWeekYearHelper(input, week, weekday, dow, doy) {
3607          var weeksTarget;
3608          if (input == null) {
3609              return weekOfYear(this, dow, doy).year;
3610          } else {
3611              weeksTarget = weeksInYear(input, dow, doy);
3612              if (week > weeksTarget) {
3613                  week = weeksTarget;
3614              }
3615              return setWeekAll.call(this, input, week, weekday, dow, doy);
3616          }
3617      }
3618  
3619      function setWeekAll(weekYear, week, weekday, dow, doy) {
3620          var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
3621              date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
3622  
3623          this.year(date.getUTCFullYear());
3624          this.month(date.getUTCMonth());
3625          this.date(date.getUTCDate());
3626          return this;
3627      }
3628  
3629      // FORMATTING
3630  
3631      addFormatToken('Q', 0, 'Qo', 'quarter');
3632  
3633      // ALIASES
3634  
3635      addUnitAlias('quarter', 'Q');
3636  
3637      // PRIORITY
3638  
3639      addUnitPriority('quarter', 7);
3640  
3641      // PARSING
3642  
3643      addRegexToken('Q', match1);
3644      addParseToken('Q', function (input, array) {
3645          array[MONTH] = (toInt(input) - 1) * 3;
3646      });
3647  
3648      // MOMENTS
3649  
3650      function getSetQuarter (input) {
3651          return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
3652      }
3653  
3654      // FORMATTING
3655  
3656      addFormatToken('D', ['DD', 2], 'Do', 'date');
3657  
3658      // ALIASES
3659  
3660      addUnitAlias('date', 'D');
3661  
3662      // PRIORITY
3663      addUnitPriority('date', 9);
3664  
3665      // PARSING
3666  
3667      addRegexToken('D',  match1to2);
3668      addRegexToken('DD', match1to2, match2);
3669      addRegexToken('Do', function (isStrict, locale) {
3670          // TODO: Remove "ordinalParse" fallback in next major release.
3671          return isStrict ?
3672            (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
3673            locale._dayOfMonthOrdinalParseLenient;
3674      });
3675  
3676      addParseToken(['D', 'DD'], DATE);
3677      addParseToken('Do', function (input, array) {
3678          array[DATE] = toInt(input.match(match1to2)[0]);
3679      });
3680  
3681      // MOMENTS
3682  
3683      var getSetDayOfMonth = makeGetSet('Date', true);
3684  
3685      // FORMATTING
3686  
3687      addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
3688  
3689      // ALIASES
3690  
3691      addUnitAlias('dayOfYear', 'DDD');
3692  
3693      // PRIORITY
3694      addUnitPriority('dayOfYear', 4);
3695  
3696      // PARSING
3697  
3698      addRegexToken('DDD',  match1to3);
3699      addRegexToken('DDDD', match3);
3700      addParseToken(['DDD', 'DDDD'], function (input, array, config) {
3701          config._dayOfYear = toInt(input);
3702      });
3703  
3704      // HELPERS
3705  
3706      // MOMENTS
3707  
3708      function getSetDayOfYear (input) {
3709          var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
3710          return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
3711      }
3712  
3713      // FORMATTING
3714  
3715      addFormatToken('m', ['mm', 2], 0, 'minute');
3716  
3717      // ALIASES
3718  
3719      addUnitAlias('minute', 'm');
3720  
3721      // PRIORITY
3722  
3723      addUnitPriority('minute', 14);
3724  
3725      // PARSING
3726  
3727      addRegexToken('m',  match1to2);
3728      addRegexToken('mm', match1to2, match2);
3729      addParseToken(['m', 'mm'], MINUTE);
3730  
3731      // MOMENTS
3732  
3733      var getSetMinute = makeGetSet('Minutes', false);
3734  
3735      // FORMATTING
3736  
3737      addFormatToken('s', ['ss', 2], 0, 'second');
3738  
3739      // ALIASES
3740  
3741      addUnitAlias('second', 's');
3742  
3743      // PRIORITY
3744  
3745      addUnitPriority('second', 15);
3746  
3747      // PARSING
3748  
3749      addRegexToken('s',  match1to2);
3750      addRegexToken('ss', match1to2, match2);
3751      addParseToken(['s', 'ss'], SECOND);
3752  
3753      // MOMENTS
3754  
3755      var getSetSecond = makeGetSet('Seconds', false);
3756  
3757      // FORMATTING
3758  
3759      addFormatToken('S', 0, 0, function () {
3760          return ~~(this.millisecond() / 100);
3761      });
3762  
3763      addFormatToken(0, ['SS', 2], 0, function () {
3764          return ~~(this.millisecond() / 10);
3765      });
3766  
3767      addFormatToken(0, ['SSS', 3], 0, 'millisecond');
3768      addFormatToken(0, ['SSSS', 4], 0, function () {
3769          return this.millisecond() * 10;
3770      });
3771      addFormatToken(0, ['SSSSS', 5], 0, function () {
3772          return this.millisecond() * 100;
3773      });
3774      addFormatToken(0, ['SSSSSS', 6], 0, function () {
3775          return this.millisecond() * 1000;
3776      });
3777      addFormatToken(0, ['SSSSSSS', 7], 0, function () {
3778          return this.millisecond() * 10000;
3779      });
3780      addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
3781          return this.millisecond() * 100000;
3782      });
3783      addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
3784          return this.millisecond() * 1000000;
3785      });
3786  
3787  
3788      // ALIASES
3789  
3790      addUnitAlias('millisecond', 'ms');
3791  
3792      // PRIORITY
3793  
3794      addUnitPriority('millisecond', 16);
3795  
3796      // PARSING
3797  
3798      addRegexToken('S',    match1to3, match1);
3799      addRegexToken('SS',   match1to3, match2);
3800      addRegexToken('SSS',  match1to3, match3);
3801  
3802      var token;
3803      for (token = 'SSSS'; token.length <= 9; token += 'S') {
3804          addRegexToken(token, matchUnsigned);
3805      }
3806  
3807      function parseMs(input, array) {
3808          array[MILLISECOND] = toInt(('0.' + input) * 1000);
3809      }
3810  
3811      for (token = 'S'; token.length <= 9; token += 'S') {
3812          addParseToken(token, parseMs);
3813      }
3814      // MOMENTS
3815  
3816      var getSetMillisecond = makeGetSet('Milliseconds', false);
3817  
3818      // FORMATTING
3819  
3820      addFormatToken('z',  0, 0, 'zoneAbbr');
3821      addFormatToken('zz', 0, 0, 'zoneName');
3822  
3823      // MOMENTS
3824  
3825      function getZoneAbbr () {
3826          return this._isUTC ? 'UTC' : '';
3827      }
3828  
3829      function getZoneName () {
3830          return this._isUTC ? 'Coordinated Universal Time' : '';
3831      }
3832  
3833      var proto = Moment.prototype;
3834  
3835      proto.add               = add;
3836      proto.calendar          = calendar$1;
3837      proto.clone             = clone;
3838      proto.diff              = diff;
3839      proto.endOf             = endOf;
3840      proto.format            = format;
3841      proto.from              = from;
3842      proto.fromNow           = fromNow;
3843      proto.to                = to;
3844      proto.toNow             = toNow;
3845      proto.get               = stringGet;
3846      proto.invalidAt         = invalidAt;
3847      proto.isAfter           = isAfter;
3848      proto.isBefore          = isBefore;
3849      proto.isBetween         = isBetween;
3850      proto.isSame            = isSame;
3851      proto.isSameOrAfter     = isSameOrAfter;
3852      proto.isSameOrBefore    = isSameOrBefore;
3853      proto.isValid           = isValid$2;
3854      proto.lang              = lang;
3855      proto.locale            = locale;
3856      proto.localeData        = localeData;
3857      proto.max               = prototypeMax;
3858      proto.min               = prototypeMin;
3859      proto.parsingFlags      = parsingFlags;
3860      proto.set               = stringSet;
3861      proto.startOf           = startOf;
3862      proto.subtract          = subtract;
3863      proto.toArray           = toArray;
3864      proto.toObject          = toObject;
3865      proto.toDate            = toDate;
3866      proto.toISOString       = toISOString;
3867      proto.inspect           = inspect;
3868      proto.toJSON            = toJSON;
3869      proto.toString          = toString;
3870      proto.unix              = unix;
3871      proto.valueOf           = valueOf;
3872      proto.creationData      = creationData;
3873      proto.year       = getSetYear;
3874      proto.isLeapYear = getIsLeapYear;
3875      proto.weekYear    = getSetWeekYear;
3876      proto.isoWeekYear = getSetISOWeekYear;
3877      proto.quarter = proto.quarters = getSetQuarter;
3878      proto.month       = getSetMonth;
3879      proto.daysInMonth = getDaysInMonth;
3880      proto.week           = proto.weeks        = getSetWeek;
3881      proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
3882      proto.weeksInYear    = getWeeksInYear;
3883      proto.isoWeeksInYear = getISOWeeksInYear;
3884      proto.date       = getSetDayOfMonth;
3885      proto.day        = proto.days             = getSetDayOfWeek;
3886      proto.weekday    = getSetLocaleDayOfWeek;
3887      proto.isoWeekday = getSetISODayOfWeek;
3888      proto.dayOfYear  = getSetDayOfYear;
3889      proto.hour = proto.hours = getSetHour;
3890      proto.minute = proto.minutes = getSetMinute;
3891      proto.second = proto.seconds = getSetSecond;
3892      proto.millisecond = proto.milliseconds = getSetMillisecond;
3893      proto.utcOffset            = getSetOffset;
3894      proto.utc                  = setOffsetToUTC;
3895      proto.local                = setOffsetToLocal;
3896      proto.parseZone            = setOffsetToParsedOffset;
3897      proto.hasAlignedHourOffset = hasAlignedHourOffset;
3898      proto.isDST                = isDaylightSavingTime;
3899      proto.isLocal              = isLocal;
3900      proto.isUtcOffset          = isUtcOffset;
3901      proto.isUtc                = isUtc;
3902      proto.isUTC                = isUtc;
3903      proto.zoneAbbr = getZoneAbbr;
3904      proto.zoneName = getZoneName;
3905      proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
3906      proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
3907      proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
3908      proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
3909      proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
3910  
3911      function createUnix (input) {
3912          return createLocal(input * 1000);
3913      }
3914  
3915      function createInZone () {
3916          return createLocal.apply(null, arguments).parseZone();
3917      }
3918  
3919      function preParsePostFormat (string) {
3920          return string;
3921      }
3922  
3923      var proto$1 = Locale.prototype;
3924  
3925      proto$1.calendar        = calendar;
3926      proto$1.longDateFormat  = longDateFormat;
3927      proto$1.invalidDate     = invalidDate;
3928      proto$1.ordinal         = ordinal;
3929      proto$1.preparse        = preParsePostFormat;
3930      proto$1.postformat      = preParsePostFormat;
3931      proto$1.relativeTime    = relativeTime;
3932      proto$1.pastFuture      = pastFuture;
3933      proto$1.set             = set;
3934  
3935      proto$1.months            =        localeMonths;
3936      proto$1.monthsShort       =        localeMonthsShort;
3937      proto$1.monthsParse       =        localeMonthsParse;
3938      proto$1.monthsRegex       = monthsRegex;
3939      proto$1.monthsShortRegex  = monthsShortRegex;
3940      proto$1.week = localeWeek;
3941      proto$1.firstDayOfYear = localeFirstDayOfYear;
3942      proto$1.firstDayOfWeek = localeFirstDayOfWeek;
3943  
3944      proto$1.weekdays       =        localeWeekdays;
3945      proto$1.weekdaysMin    =        localeWeekdaysMin;
3946      proto$1.weekdaysShort  =        localeWeekdaysShort;
3947      proto$1.weekdaysParse  =        localeWeekdaysParse;
3948  
3949      proto$1.weekdaysRegex       =        weekdaysRegex;
3950      proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
3951      proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
3952  
3953      proto$1.isPM = localeIsPM;
3954      proto$1.meridiem = localeMeridiem;
3955  
3956      function get$1 (format, index, field, setter) {
3957          var locale = getLocale();
3958          var utc = createUTC().set(setter, index);
3959          return locale[field](utc, format);
3960      }
3961  
3962      function listMonthsImpl (format, index, field) {
3963          if (isNumber(format)) {
3964              index = format;
3965              format = undefined;
3966          }
3967  
3968          format = format || '';
3969  
3970          if (index != null) {
3971              return get$1(format, index, field, 'month');
3972          }
3973  
3974          var i;
3975          var out = [];
3976          for (i = 0; i < 12; i++) {
3977              out[i] = get$1(format, i, field, 'month');
3978          }
3979          return out;
3980      }
3981  
3982      // ()
3983      // (5)
3984      // (fmt, 5)
3985      // (fmt)
3986      // (true)
3987      // (true, 5)
3988      // (true, fmt, 5)
3989      // (true, fmt)
3990      function listWeekdaysImpl (localeSorted, format, index, field) {
3991          if (typeof localeSorted === 'boolean') {
3992              if (isNumber(format)) {
3993                  index = format;
3994                  format = undefined;
3995              }
3996  
3997              format = format || '';
3998          } else {
3999              format = localeSorted;
4000              index = format;
4001              localeSorted = false;
4002  
4003              if (isNumber(format)) {
4004                  index = format;
4005                  format = undefined;
4006              }
4007  
4008              format = format || '';
4009          }
4010  
4011          var locale = getLocale(),
4012              shift = localeSorted ? locale._week.dow : 0;
4013  
4014          if (index != null) {
4015              return get$1(format, (index + shift) % 7, field, 'day');
4016          }
4017  
4018          var i;
4019          var out = [];
4020          for (i = 0; i < 7; i++) {
4021              out[i] = get$1(format, (i + shift) % 7, field, 'day');
4022          }
4023          return out;
4024      }
4025  
4026      function listMonths (format, index) {
4027          return listMonthsImpl(format, index, 'months');
4028      }
4029  
4030      function listMonthsShort (format, index) {
4031          return listMonthsImpl(format, index, 'monthsShort');
4032      }
4033  
4034      function listWeekdays (localeSorted, format, index) {
4035          return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
4036      }
4037  
4038      function listWeekdaysShort (localeSorted, format, index) {
4039          return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
4040      }
4041  
4042      function listWeekdaysMin (localeSorted, format, index) {
4043          return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
4044      }
4045  
4046      getSetGlobalLocale('en', {
4047          dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
4048          ordinal : function (number) {
4049              var b = number % 10,
4050                  output = (toInt(number % 100 / 10) === 1) ? 'th' :
4051                  (b === 1) ? 'st' :
4052                  (b === 2) ? 'nd' :
4053                  (b === 3) ? 'rd' : 'th';
4054              return number + output;
4055          }
4056      });
4057  
4058      // Side effect imports
4059  
4060      hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
4061      hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
4062  
4063      var mathAbs = Math.abs;
4064  
4065      function abs () {
4066          var data           = this._data;
4067  
4068          this._milliseconds = mathAbs(this._milliseconds);
4069          this._days         = mathAbs(this._days);
4070          this._months       = mathAbs(this._months);
4071  
4072          data.milliseconds  = mathAbs(data.milliseconds);
4073          data.seconds       = mathAbs(data.seconds);
4074          data.minutes       = mathAbs(data.minutes);
4075          data.hours         = mathAbs(data.hours);
4076          data.months        = mathAbs(data.months);
4077          data.years         = mathAbs(data.years);
4078  
4079          return this;
4080      }
4081  
4082      function addSubtract$1 (duration, input, value, direction) {
4083          var other = createDuration(input, value);
4084  
4085          duration._milliseconds += direction * other._milliseconds;
4086          duration._days         += direction * other._days;
4087          duration._months       += direction * other._months;
4088  
4089          return duration._bubble();
4090      }
4091  
4092      // supports only 2.0-style add(1, 's') or add(duration)
4093      function add$1 (input, value) {
4094          return addSubtract$1(this, input, value, 1);
4095      }
4096  
4097      // supports only 2.0-style subtract(1, 's') or subtract(duration)
4098      function subtract$1 (input, value) {
4099          return addSubtract$1(this, input, value, -1);
4100      }
4101  
4102      function absCeil (number) {
4103          if (number < 0) {
4104              return Math.floor(number);
4105          } else {
4106              return Math.ceil(number);
4107          }
4108      }
4109  
4110      function bubble () {
4111          var milliseconds = this._milliseconds;
4112          var days         = this._days;
4113          var months       = this._months;
4114          var data         = this._data;
4115          var seconds, minutes, hours, years, monthsFromDays;
4116  
4117          // if we have a mix of positive and negative values, bubble down first
4118          // check: https://github.com/moment/moment/issues/2166
4119          if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
4120                  (milliseconds <= 0 && days <= 0 && months <= 0))) {
4121              milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
4122              days = 0;
4123              months = 0;
4124          }
4125  
4126          // The following code bubbles up values, see the tests for
4127          // examples of what that means.
4128          data.milliseconds = milliseconds % 1000;
4129  
4130          seconds           = absFloor(milliseconds / 1000);
4131          data.seconds      = seconds % 60;
4132  
4133          minutes           = absFloor(seconds / 60);
4134          data.minutes      = minutes % 60;
4135  
4136          hours             = absFloor(minutes / 60);
4137          data.hours        = hours % 24;
4138  
4139          days += absFloor(hours / 24);
4140  
4141          // convert days to months
4142          monthsFromDays = absFloor(daysToMonths(days));
4143          months += monthsFromDays;
4144          days -= absCeil(monthsToDays(monthsFromDays));
4145  
4146          // 12 months -> 1 year
4147          years = absFloor(months / 12);
4148          months %= 12;
4149  
4150          data.days   = days;
4151          data.months = months;
4152          data.years  = years;
4153  
4154          return this;
4155      }
4156  
4157      function daysToMonths (days) {
4158          // 400 years have 146097 days (taking into account leap year rules)
4159          // 400 years have 12 months === 4800
4160          return days * 4800 / 146097;
4161      }
4162  
4163      function monthsToDays (months) {
4164          // the reverse of daysToMonths
4165          return months * 146097 / 4800;
4166      }
4167  
4168      function as (units) {
4169          if (!this.isValid()) {
4170              return NaN;
4171          }
4172          var days;
4173          var months;
4174          var milliseconds = this._milliseconds;
4175  
4176          units = normalizeUnits(units);
4177  
4178          if (units === 'month' || units === 'year') {
4179              days   = this._days   + milliseconds / 864e5;
4180              months = this._months + daysToMonths(days);
4181              return units === 'month' ? months : months / 12;
4182          } else {
4183              // handle milliseconds separately because of floating point math errors (issue #1867)
4184              days = this._days + Math.round(monthsToDays(this._months));
4185              switch (units) {
4186                  case 'week'   : return days / 7     + milliseconds / 6048e5;
4187                  case 'day'    : return days         + milliseconds / 864e5;
4188                  case 'hour'   : return days * 24    + milliseconds / 36e5;
4189                  case 'minute' : return days * 1440  + milliseconds / 6e4;
4190                  case 'second' : return days * 86400 + milliseconds / 1000;
4191                  // Math.floor prevents floating point math errors here
4192                  case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
4193                  default: throw new Error('Unknown unit ' + units);
4194              }
4195          }
4196      }
4197  
4198      // TODO: Use this.as('ms')?
4199      function valueOf$1 () {
4200          if (!this.isValid()) {
4201              return NaN;
4202          }
4203          return (
4204              this._milliseconds +
4205              this._days * 864e5 +
4206              (this._months % 12) * 2592e6 +
4207              toInt(this._months / 12) * 31536e6
4208          );
4209      }
4210  
4211      function makeAs (alias) {
4212          return function () {
4213              return this.as(alias);
4214          };
4215      }
4216  
4217      var asMilliseconds = makeAs('ms');
4218      var asSeconds      = makeAs('s');
4219      var asMinutes      = makeAs('m');
4220      var asHours        = makeAs('h');
4221      var asDays         = makeAs('d');
4222      var asWeeks        = makeAs('w');
4223      var asMonths       = makeAs('M');
4224      var asYears        = makeAs('y');
4225  
4226      function clone$1 () {
4227          return createDuration(this);
4228      }
4229  
4230      function get$2 (units) {
4231          units = normalizeUnits(units);
4232          return this.isValid() ? this[units + 's']() : NaN;
4233      }
4234  
4235      function makeGetter(name) {
4236          return function () {
4237              return this.isValid() ? this._data[name] : NaN;
4238          };
4239      }
4240  
4241      var milliseconds = makeGetter('milliseconds');
4242      var seconds      = makeGetter('seconds');
4243      var minutes      = makeGetter('minutes');
4244      var hours        = makeGetter('hours');
4245      var days         = makeGetter('days');
4246      var months       = makeGetter('months');
4247      var years        = makeGetter('years');
4248  
4249      function weeks () {
4250          return absFloor(this.days() / 7);
4251      }
4252  
4253      var round = Math.round;
4254      var thresholds = {
4255          ss: 44,         // a few seconds to seconds
4256          s : 45,         // seconds to minute
4257          m : 45,         // minutes to hour
4258          h : 22,         // hours to day
4259          d : 26,         // days to month
4260          M : 11          // months to year
4261      };
4262  
4263      // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
4264      function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
4265          return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
4266      }
4267  
4268      function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
4269          var duration = createDuration(posNegDuration).abs();
4270          var seconds  = round(duration.as('s'));
4271          var minutes  = round(duration.as('m'));
4272          var hours    = round(duration.as('h'));
4273          var days     = round(duration.as('d'));
4274          var months   = round(duration.as('M'));
4275          var years    = round(duration.as('y'));
4276  
4277          var a = seconds <= thresholds.ss && ['s', seconds]  ||
4278                  seconds < thresholds.s   && ['ss', seconds] ||
4279                  minutes <= 1             && ['m']           ||
4280                  minutes < thresholds.m   && ['mm', minutes] ||
4281                  hours   <= 1             && ['h']           ||
4282                  hours   < thresholds.h   && ['hh', hours]   ||
4283                  days    <= 1             && ['d']           ||
4284                  days    < thresholds.d   && ['dd', days]    ||
4285                  months  <= 1             && ['M']           ||
4286                  months  < thresholds.M   && ['MM', months]  ||
4287                  years   <= 1             && ['y']           || ['yy', years];
4288  
4289          a[2] = withoutSuffix;
4290          a[3] = +posNegDuration > 0;
4291          a[4] = locale;
4292          return substituteTimeAgo.apply(null, a);
4293      }
4294  
4295      // This function allows you to set the rounding function for relative time strings
4296      function getSetRelativeTimeRounding (roundingFunction) {
4297          if (roundingFunction === undefined) {
4298              return round;
4299          }
4300          if (typeof(roundingFunction) === 'function') {
4301              round = roundingFunction;
4302              return true;
4303          }
4304          return false;
4305      }
4306  
4307      // This function allows you to set a threshold for relative time strings
4308      function getSetRelativeTimeThreshold (threshold, limit) {
4309          if (thresholds[threshold] === undefined) {
4310              return false;
4311          }
4312          if (limit === undefined) {
4313              return thresholds[threshold];
4314          }
4315          thresholds[threshold] = limit;
4316          if (threshold === 's') {
4317              thresholds.ss = limit - 1;
4318          }
4319          return true;
4320      }
4321  
4322      function humanize (withSuffix) {
4323          if (!this.isValid()) {
4324              return this.localeData().invalidDate();
4325          }
4326  
4327          var locale = this.localeData();
4328          var output = relativeTime$1(this, !withSuffix, locale);
4329  
4330          if (withSuffix) {
4331              output = locale.pastFuture(+this, output);
4332          }
4333  
4334          return locale.postformat(output);
4335      }
4336  
4337      var abs$1 = Math.abs;
4338  
4339      function sign(x) {
4340          return ((x > 0) - (x < 0)) || +x;
4341      }
4342  
4343      function toISOString$1() {
4344          // for ISO strings we do not use the normal bubbling rules:
4345          //  * milliseconds bubble up until they become hours
4346          //  * days do not bubble at all
4347          //  * months bubble up until they become years
4348          // This is because there is no context-free conversion between hours and days
4349          // (think of clock changes)
4350          // and also not between days and months (28-31 days per month)
4351          if (!this.isValid()) {
4352              return this.localeData().invalidDate();
4353          }
4354  
4355          var seconds = abs$1(this._milliseconds) / 1000;
4356          var days         = abs$1(this._days);
4357          var months       = abs$1(this._months);
4358          var minutes, hours, years;
4359  
4360          // 3600 seconds -> 60 minutes -> 1 hour
4361          minutes           = absFloor(seconds / 60);
4362          hours             = absFloor(minutes / 60);
4363          seconds %= 60;
4364          minutes %= 60;
4365  
4366          // 12 months -> 1 year
4367          years  = absFloor(months / 12);
4368          months %= 12;
4369  
4370  
4371          // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
4372          var Y = years;
4373          var M = months;
4374          var D = days;
4375          var h = hours;
4376          var m = minutes;
4377          var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
4378          var total = this.asSeconds();
4379  
4380          if (!total) {
4381              // this is the same as C#'s (Noda) and python (isodate)...
4382              // but not other JS (goog.date)
4383              return 'P0D';
4384          }
4385  
4386          var totalSign = total < 0 ? '-' : '';
4387          var ymSign = sign(this._months) !== sign(total) ? '-' : '';
4388          var daysSign = sign(this._days) !== sign(total) ? '-' : '';
4389          var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
4390  
4391          return totalSign + 'P' +
4392              (Y ? ymSign + Y + 'Y' : '') +
4393              (M ? ymSign + M + 'M' : '') +
4394              (D ? daysSign + D + 'D' : '') +
4395              ((h || m || s) ? 'T' : '') +
4396              (h ? hmsSign + h + 'H' : '') +
4397              (m ? hmsSign + m + 'M' : '') +
4398              (s ? hmsSign + s + 'S' : '');
4399      }
4400  
4401      var proto$2 = Duration.prototype;
4402  
4403      proto$2.isValid        = isValid$1;
4404      proto$2.abs            = abs;
4405      proto$2.add            = add$1;
4406      proto$2.subtract       = subtract$1;
4407      proto$2.as             = as;
4408      proto$2.asMilliseconds = asMilliseconds;
4409      proto$2.asSeconds      = asSeconds;
4410      proto$2.asMinutes      = asMinutes;
4411      proto$2.asHours        = asHours;
4412      proto$2.asDays         = asDays;
4413      proto$2.asWeeks        = asWeeks;
4414      proto$2.asMonths       = asMonths;
4415      proto$2.asYears        = asYears;
4416      proto$2.valueOf        = valueOf$1;
4417      proto$2._bubble        = bubble;
4418      proto$2.clone          = clone$1;
4419      proto$2.get            = get$2;
4420      proto$2.milliseconds   = milliseconds;
4421      proto$2.seconds        = seconds;
4422      proto$2.minutes        = minutes;
4423      proto$2.hours          = hours;
4424      proto$2.days           = days;
4425      proto$2.weeks          = weeks;
4426      proto$2.months         = months;
4427      proto$2.years          = years;
4428      proto$2.humanize       = humanize;
4429      proto$2.toISOString    = toISOString$1;
4430      proto$2.toString       = toISOString$1;
4431      proto$2.toJSON         = toISOString$1;
4432      proto$2.locale         = locale;
4433      proto$2.localeData     = localeData;
4434  
4435      proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
4436      proto$2.lang = lang;
4437  
4438      // Side effect imports
4439  
4440      // FORMATTING
4441  
4442      addFormatToken('X', 0, 0, 'unix');
4443      addFormatToken('x', 0, 0, 'valueOf');
4444  
4445      // PARSING
4446  
4447      addRegexToken('x', matchSigned);
4448      addRegexToken('X', matchTimestamp);
4449      addParseToken('X', function (input, array, config) {
4450          config._d = new Date(parseFloat(input, 10) * 1000);
4451      });
4452      addParseToken('x', function (input, array, config) {
4453          config._d = new Date(toInt(input));
4454      });
4455  
4456      // Side effect imports
4457  
4458  
4459      hooks.version = '2.22.2';
4460  
4461      setHookCallback(createLocal);
4462  
4463      hooks.fn                    = proto;
4464      hooks.min                   = min;
4465      hooks.max                   = max;
4466      hooks.now                   = now;
4467      hooks.utc                   = createUTC;
4468      hooks.unix                  = createUnix;
4469      hooks.months                = listMonths;
4470      hooks.isDate                = isDate;
4471      hooks.locale                = getSetGlobalLocale;
4472      hooks.invalid               = createInvalid;
4473      hooks.duration              = createDuration;
4474      hooks.isMoment              = isMoment;
4475      hooks.weekdays              = listWeekdays;
4476      hooks.parseZone             = createInZone;
4477      hooks.localeData            = getLocale;
4478      hooks.isDuration            = isDuration;
4479      hooks.monthsShort           = listMonthsShort;
4480      hooks.weekdaysMin           = listWeekdaysMin;
4481      hooks.defineLocale          = defineLocale;
4482      hooks.updateLocale          = updateLocale;
4483      hooks.locales               = listLocales;
4484      hooks.weekdaysShort         = listWeekdaysShort;
4485      hooks.normalizeUnits        = normalizeUnits;
4486      hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
4487      hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
4488      hooks.calendarFormat        = getCalendarFormat;
4489      hooks.prototype             = proto;
4490  
4491      // currently HTML5 input type only supports 24-hour formats
4492      hooks.HTML5_FMT = {
4493          DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
4494          DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
4495          DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
4496          DATE: 'YYYY-MM-DD',                             // <input type="date" />
4497          TIME: 'HH:mm',                                  // <input type="time" />
4498          TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
4499          TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
4500          WEEK: 'YYYY-[W]WW',                             // <input type="week" />
4501          MONTH: 'YYYY-MM'                                // <input type="month" />
4502      };
4503  
4504      return hooks;
4505  
4506  })));


Generated: Mon Jan 7 01:00:05 2019 Cross-referenced by PHPXref 0.7.1