UNPKG

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