PageSourceSearch

https://arhitekti-hka.hr/js/moment.js

js arhitekti-hka.hr collected 2026-09-24 19:51:09 UTC 145,981 bytes, 4,464 lines download raw bytes

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

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.