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