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


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref