PageSourceSearch

https://www.nadiakadek.com/js/moment.js

js nadiakadek.com collected 2026-10-04 22:08:09 UTC 173,825 bytes, 5,668 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.