[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

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


Generated : Fri Apr 19 08:20:01 2024 Cross-referenced by PHPXref