flashgrid-ext 2.2.5 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc8a1562a0f9ca9b276bd7bef00f80e9d5a2531e
4
- data.tar.gz: 13c4541874fa7f0485f119607e712edce102d9ce
3
+ metadata.gz: 48ae2c233d0dacccc45dabd1b60d01c3c7464a74
4
+ data.tar.gz: d325508a8a57ed51924a41f2f91c311dcfb360a1
5
5
  SHA512:
6
- metadata.gz: ca8c0ef30b07bd35f87468b97cc56076962232c8c43cdc7e511d307fec60e09f46a78934f77d4694164d7bcdd3b44af6a5b3f6fd4479d061a70cc784d81c8b38
7
- data.tar.gz: eef1e631a8cfbc71fd9b7fe18b0cdeacc3ce767fd016a100682ac55b1c39ff653cb1bc3ba68dcbfd1a345e1bcc674a7d0ac81576d9ee4a6866b934c67a94de80
6
+ metadata.gz: 4de3c3dc7c88cf21b19306f979e78aca31878d86f882498aeb795270ccbe37f0051fbd79bb7351e92dca56d6b0851ac99fc530c66ec85fc027301612b43ae16f
7
+ data.tar.gz: 80ca03e9046cfef7359be5970355a0d864fc7e62cd00c13882a6155782617fd35a95c4fe12e169d632613a0385d7d4a3187acb8aed21fe9d0acd7f51596cdb19
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Flashgrid Ext.
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/flashgrid-ext.svg)](http://badge.fury.io/rb/flashgrid-ext)
4
+
3
5
  [Flashgrid Ext.](http://flashgrid-ext.drexed.com) is an extention of useful and cool javascripts for Flashgrid framework
4
6
 
5
7
  To get started, check out [http://flashgrid-ext.drexed.com](http://flashgrid-ext.drexed.com)!
@@ -1,5 +1,5 @@
1
1
  module Flashgrid
2
2
  module Ext
3
- VERSION = "2.2.5"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -1,15 +1,15 @@
1
1
  (function (undefined) {
2
-
3
2
  /************************************
4
3
  Constants
5
4
  ************************************/
6
5
 
7
6
  var moment,
8
- VERSION = "2.7.0",
7
+ VERSION = '2.8.2',
9
8
  // the global-scope this is NOT the global object in Node.js
10
9
  globalScope = typeof global !== 'undefined' ? global : this,
11
10
  oldGlobalMoment,
12
11
  round = Math.round,
12
+ hasOwnProperty = Object.prototype.hasOwnProperty,
13
13
  i,
14
14
 
15
15
  YEAR = 0,
@@ -20,22 +20,11 @@
20
20
  SECOND = 5,
21
21
  MILLISECOND = 6,
22
22
 
23
- // internal storage for language config files
24
- languages = {},
23
+ // internal storage for locale config files
24
+ locales = {},
25
25
 
26
- // moment internal properties
27
- momentProperties = {
28
- _isAMomentObject: null,
29
- _i : null,
30
- _f : null,
31
- _l : null,
32
- _strict : null,
33
- _tzm : null,
34
- _isUTC : null,
35
- _offset : null, // optional. Combine with _isUTC
36
- _pf : null,
37
- _lang : null // optional
38
- },
26
+ // extra moment internal properties (plugins register props here)
27
+ momentProperties = [],
39
28
 
40
29
  // check for nodeJS
41
30
  hasModule = (typeof module !== 'undefined' && module.exports),
@@ -94,7 +83,7 @@
94
83
  ['HH', /(T| )\d\d/]
95
84
  ],
96
85
 
97
- // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
86
+ // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30']
98
87
  parseTimezoneChunker = /([\+\-]|\d\d)/gi,
99
88
 
100
89
  // getter and setter names
@@ -141,12 +130,11 @@
141
130
 
142
131
  // default relative time thresholds
143
132
  relativeTimeThresholds = {
144
- s: 45, //seconds to minutes
145
- m: 45, //minutes to hours
146
- h: 22, //hours to days
147
- dd: 25, //days to month (month == 1)
148
- dm: 45, //days to months (months > 1)
149
- dy: 345 //days to year
133
+ s: 45, // seconds to minute
134
+ m: 45, // minutes to hour
135
+ h: 22, // hours to day
136
+ d: 26, // days to month
137
+ M: 11 // months to year
150
138
  },
151
139
 
152
140
  // tokens to ordinalize and pad
@@ -158,10 +146,10 @@
158
146
  return this.month() + 1;
159
147
  },
160
148
  MMM : function (format) {
161
- return this.lang().monthsShort(this, format);
149
+ return this.localeData().monthsShort(this, format);
162
150
  },
163
151
  MMMM : function (format) {
164
- return this.lang().months(this, format);
152
+ return this.localeData().months(this, format);
165
153
  },
166
154
  D : function () {
167
155
  return this.date();
@@ -173,13 +161,13 @@
173
161
  return this.day();
174
162
  },
175
163
  dd : function (format) {
176
- return this.lang().weekdaysMin(this, format);
164
+ return this.localeData().weekdaysMin(this, format);
177
165
  },
178
166
  ddd : function (format) {
179
- return this.lang().weekdaysShort(this, format);
167
+ return this.localeData().weekdaysShort(this, format);
180
168
  },
181
169
  dddd : function (format) {
182
- return this.lang().weekdays(this, format);
170
+ return this.localeData().weekdays(this, format);
183
171
  },
184
172
  w : function () {
185
173
  return this.week();
@@ -225,10 +213,10 @@
225
213
  return this.isoWeekday();
226
214
  },
227
215
  a : function () {
228
- return this.lang().meridiem(this.hours(), this.minutes(), true);
216
+ return this.localeData().meridiem(this.hours(), this.minutes(), true);
229
217
  },
230
218
  A : function () {
231
- return this.lang().meridiem(this.hours(), this.minutes(), false);
219
+ return this.localeData().meridiem(this.hours(), this.minutes(), false);
232
220
  },
233
221
  H : function () {
234
222
  return this.hours();
@@ -256,19 +244,19 @@
256
244
  },
257
245
  Z : function () {
258
246
  var a = -this.zone(),
259
- b = "+";
247
+ b = '+';
260
248
  if (a < 0) {
261
249
  a = -a;
262
- b = "-";
250
+ b = '-';
263
251
  }
264
- return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
252
+ return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
265
253
  },
266
254
  ZZ : function () {
267
255
  var a = -this.zone(),
268
- b = "+";
256
+ b = '+';
269
257
  if (a < 0) {
270
258
  a = -a;
271
- b = "-";
259
+ b = '-';
272
260
  }
273
261
  return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
274
262
  },
@@ -286,6 +274,8 @@
286
274
  }
287
275
  },
288
276
 
277
+ deprecations = {},
278
+
289
279
  lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
290
280
 
291
281
  // Pick the first defined of two or three arguments. dfl comes from
@@ -294,10 +284,14 @@
294
284
  switch (arguments.length) {
295
285
  case 2: return a != null ? a : b;
296
286
  case 3: return a != null ? a : b != null ? b : c;
297
- default: throw new Error("Implement me");
287
+ default: throw new Error('Implement me');
298
288
  }
299
289
  }
300
290
 
291
+ function hasOwnProp(a, b) {
292
+ return hasOwnProperty.call(a, b);
293
+ }
294
+
301
295
  function defaultParsingFlags() {
302
296
  // We need to deep clone this object, and es5 standard is not very
303
297
  // helpful.
@@ -315,23 +309,31 @@
315
309
  };
316
310
  }
317
311
 
312
+ function printMsg(msg) {
313
+ if (moment.suppressDeprecationWarnings === false &&
314
+ typeof console !== 'undefined' && console.warn) {
315
+ console.warn('Deprecation warning: ' + msg);
316
+ }
317
+ }
318
+
318
319
  function deprecate(msg, fn) {
319
320
  var firstTime = true;
320
- function printMsg() {
321
- if (moment.suppressDeprecationWarnings === false &&
322
- typeof console !== 'undefined' && console.warn) {
323
- console.warn("Deprecation warning: " + msg);
324
- }
325
- }
326
321
  return extend(function () {
327
322
  if (firstTime) {
328
- printMsg();
323
+ printMsg(msg);
329
324
  firstTime = false;
330
325
  }
331
326
  return fn.apply(this, arguments);
332
327
  }, fn);
333
328
  }
334
329
 
330
+ function deprecateSimple(name, msg) {
331
+ if (!deprecations[name]) {
332
+ printMsg(msg);
333
+ deprecations[name] = true;
334
+ }
335
+ }
336
+
335
337
  function padToken(func, count) {
336
338
  return function (a) {
337
339
  return leftZeroFill(func.call(this, a), count);
@@ -339,7 +341,7 @@
339
341
  }
340
342
  function ordinalizeToken(func, period) {
341
343
  return function (a) {
342
- return this.lang().ordinal(func.call(this, a), period);
344
+ return this.localeData().ordinal(func.call(this, a), period);
343
345
  };
344
346
  }
345
347
 
@@ -358,14 +360,16 @@
358
360
  Constructors
359
361
  ************************************/
360
362
 
361
- function Language() {
362
-
363
+ function Locale() {
363
364
  }
364
365
 
365
366
  // Moment prototype object
366
- function Moment(config) {
367
- checkOverflow(config);
368
- extend(this, config);
367
+ function Moment(config, skipOverflow) {
368
+ if (skipOverflow !== false) {
369
+ checkOverflow(config);
370
+ }
371
+ copyConfig(this, config);
372
+ this._d = new Date(+config._d);
369
373
  }
370
374
 
371
375
  // Duration Constructor
@@ -399,6 +403,8 @@
399
403
 
400
404
  this._data = {};
401
405
 
406
+ this._locale = moment.localeData();
407
+
402
408
  this._bubble();
403
409
  }
404
410
 
@@ -409,31 +415,67 @@
409
415
 
410
416
  function extend(a, b) {
411
417
  for (var i in b) {
412
- if (b.hasOwnProperty(i)) {
418
+ if (hasOwnProp(b, i)) {
413
419
  a[i] = b[i];
414
420
  }
415
421
  }
416
422
 
417
- if (b.hasOwnProperty("toString")) {
423
+ if (hasOwnProp(b, 'toString')) {
418
424
  a.toString = b.toString;
419
425
  }
420
426
 
421
- if (b.hasOwnProperty("valueOf")) {
427
+ if (hasOwnProp(b, 'valueOf')) {
422
428
  a.valueOf = b.valueOf;
423
429
  }
424
430
 
425
431
  return a;
426
432
  }
427
433
 
428
- function cloneMoment(m) {
429
- var result = {}, i;
430
- for (i in m) {
431
- if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
432
- result[i] = m[i];
434
+ function copyConfig(to, from) {
435
+ var i, prop, val;
436
+
437
+ if (typeof from._isAMomentObject !== 'undefined') {
438
+ to._isAMomentObject = from._isAMomentObject;
439
+ }
440
+ if (typeof from._i !== 'undefined') {
441
+ to._i = from._i;
442
+ }
443
+ if (typeof from._f !== 'undefined') {
444
+ to._f = from._f;
445
+ }
446
+ if (typeof from._l !== 'undefined') {
447
+ to._l = from._l;
448
+ }
449
+ if (typeof from._strict !== 'undefined') {
450
+ to._strict = from._strict;
451
+ }
452
+ if (typeof from._tzm !== 'undefined') {
453
+ to._tzm = from._tzm;
454
+ }
455
+ if (typeof from._isUTC !== 'undefined') {
456
+ to._isUTC = from._isUTC;
457
+ }
458
+ if (typeof from._offset !== 'undefined') {
459
+ to._offset = from._offset;
460
+ }
461
+ if (typeof from._pf !== 'undefined') {
462
+ to._pf = from._pf;
463
+ }
464
+ if (typeof from._locale !== 'undefined') {
465
+ to._locale = from._locale;
466
+ }
467
+
468
+ if (momentProperties.length > 0) {
469
+ for (i in momentProperties) {
470
+ prop = momentProperties[i];
471
+ val = from[prop];
472
+ if (typeof val !== 'undefined') {
473
+ to[prop] = val;
474
+ }
433
475
  }
434
476
  }
435
477
 
436
- return result;
478
+ return to;
437
479
  }
438
480
 
439
481
  function absRound(number) {
@@ -456,7 +498,51 @@
456
498
  return (sign ? (forceSign ? '+' : '') : '-') + output;
457
499
  }
458
500
 
459
- // helper function for _.addTime and _.subtractTime
501
+ function positiveMomentsDifference(base, other) {
502
+ var res = {milliseconds: 0, months: 0};
503
+
504
+ res.months = other.month() - base.month() +
505
+ (other.year() - base.year()) * 12;
506
+ if (base.clone().add(res.months, 'M').isAfter(other)) {
507
+ --res.months;
508
+ }
509
+
510
+ res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
511
+
512
+ return res;
513
+ }
514
+
515
+ function momentsDifference(base, other) {
516
+ var res;
517
+ other = makeAs(other, base);
518
+ if (base.isBefore(other)) {
519
+ res = positiveMomentsDifference(base, other);
520
+ } else {
521
+ res = positiveMomentsDifference(other, base);
522
+ res.milliseconds = -res.milliseconds;
523
+ res.months = -res.months;
524
+ }
525
+
526
+ return res;
527
+ }
528
+
529
+ // TODO: remove 'name' arg after deprecation is removed
530
+ function createAdder(direction, name) {
531
+ return function (val, period) {
532
+ var dur, tmp;
533
+ //invert the arguments, but complain about it
534
+ if (period !== null && !isNaN(+period)) {
535
+ deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
536
+ tmp = val; val = period; period = tmp;
537
+ }
538
+
539
+ val = typeof val === 'string' ? +val : val;
540
+ dur = moment.duration(val, period);
541
+ addOrSubtractDurationFromMoment(this, dur, direction);
542
+ return this;
543
+ };
544
+ }
545
+
460
546
  function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
461
547
  var milliseconds = duration._milliseconds,
462
548
  days = duration._days,
@@ -483,8 +569,8 @@
483
569
  }
484
570
 
485
571
  function isDate(input) {
486
- return Object.prototype.toString.call(input) === '[object Date]' ||
487
- input instanceof Date;
572
+ return Object.prototype.toString.call(input) === '[object Date]' ||
573
+ input instanceof Date;
488
574
  }
489
575
 
490
576
  // compare two arrays, return the number of differences
@@ -516,7 +602,7 @@
516
602
  prop;
517
603
 
518
604
  for (prop in inputObject) {
519
- if (inputObject.hasOwnProperty(prop)) {
605
+ if (hasOwnProp(inputObject, prop)) {
520
606
  normalizedProp = normalizeUnits(prop);
521
607
  if (normalizedProp) {
522
608
  normalizedInput[normalizedProp] = inputObject[prop];
@@ -544,7 +630,7 @@
544
630
 
545
631
  moment[field] = function (format, index) {
546
632
  var i, getter,
547
- method = moment.fn._lang[field],
633
+ method = moment._locale[field],
548
634
  results = [];
549
635
 
550
636
  if (typeof format === 'number') {
@@ -554,7 +640,7 @@
554
640
 
555
641
  getter = function (i) {
556
642
  var m = moment().utc().set(setter, i);
557
- return method.call(moment.fn._lang, m, format || '');
643
+ return method.call(moment._locale, m, format || '');
558
644
  };
559
645
 
560
646
  if (index != null) {
@@ -639,10 +725,50 @@
639
725
  return m._isValid;
640
726
  }
641
727
 
642
- function normalizeLanguage(key) {
728
+ function normalizeLocale(key) {
643
729
  return key ? key.toLowerCase().replace('_', '-') : key;
644
730
  }
645
731
 
732
+ // pick the locale from the array
733
+ // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
734
+ // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
735
+ function chooseLocale(names) {
736
+ var i = 0, j, next, locale, split;
737
+
738
+ while (i < names.length) {
739
+ split = normalizeLocale(names[i]).split('-');
740
+ j = split.length;
741
+ next = normalizeLocale(names[i + 1]);
742
+ next = next ? next.split('-') : null;
743
+ while (j > 0) {
744
+ locale = loadLocale(split.slice(0, j).join('-'));
745
+ if (locale) {
746
+ return locale;
747
+ }
748
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
749
+ //the next array item is better than a shallower substring of this one
750
+ break;
751
+ }
752
+ j--;
753
+ }
754
+ i++;
755
+ }
756
+ return null;
757
+ }
758
+
759
+ function loadLocale(name) {
760
+ var oldLocale = null;
761
+ if (!locales[name] && hasModule) {
762
+ try {
763
+ oldLocale = moment.locale();
764
+ require('./locale/' + name);
765
+ // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
766
+ moment.locale(oldLocale);
767
+ } catch (e) { }
768
+ }
769
+ return locales[name];
770
+ }
771
+
646
772
  // Return a moment from input, that is local/utc/zone equivalent to model.
647
773
  function makeAs(input, model) {
648
774
  return model._isUTC ? moment(input).zone(model._offset || 0) :
@@ -650,11 +776,11 @@
650
776
  }
651
777
 
652
778
  /************************************
653
- Languages
779
+ Locale
654
780
  ************************************/
655
781
 
656
782
 
657
- extend(Language.prototype, {
783
+ extend(Locale.prototype, {
658
784
 
659
785
  set : function (config) {
660
786
  var prop, i;
@@ -668,12 +794,12 @@
668
794
  }
669
795
  },
670
796
 
671
- _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
797
+ _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
672
798
  months : function (m) {
673
799
  return this._months[m.month()];
674
800
  },
675
801
 
676
- _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
802
+ _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
677
803
  monthsShort : function (m) {
678
804
  return this._monthsShort[m.month()];
679
805
  },
@@ -699,17 +825,17 @@
699
825
  }
700
826
  },
701
827
 
702
- _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
828
+ _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
703
829
  weekdays : function (m) {
704
830
  return this._weekdays[m.day()];
705
831
  },
706
832
 
707
- _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
833
+ _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
708
834
  weekdaysShort : function (m) {
709
835
  return this._weekdaysShort[m.day()];
710
836
  },
711
837
 
712
- _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
838
+ _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
713
839
  weekdaysMin : function (m) {
714
840
  return this._weekdaysMin[m.day()];
715
841
  },
@@ -736,11 +862,11 @@
736
862
  },
737
863
 
738
864
  _longDateFormat : {
739
- LT : "h:mm A",
740
- L : "MM/DD/YYYY",
741
- LL : "MMMM D YYYY",
742
- LLL : "MMMM D YYYY LT",
743
- LLLL : "dddd, MMMM D YYYY LT"
865
+ LT : 'h:mm A',
866
+ L : 'MM/DD/YYYY',
867
+ LL : 'MMMM D, YYYY',
868
+ LLL : 'MMMM D, YYYY LT',
869
+ LLLL : 'dddd, MMMM D, YYYY LT'
744
870
  },
745
871
  longDateFormat : function (key) {
746
872
  var output = this._longDateFormat[key];
@@ -782,35 +908,37 @@
782
908
  },
783
909
 
784
910
  _relativeTime : {
785
- future : "in %s",
786
- past : "%s ago",
787
- s : "a few seconds",
788
- m : "a minute",
789
- mm : "%d minutes",
790
- h : "an hour",
791
- hh : "%d hours",
792
- d : "a day",
793
- dd : "%d days",
794
- M : "a month",
795
- MM : "%d months",
796
- y : "a year",
797
- yy : "%d years"
911
+ future : 'in %s',
912
+ past : '%s ago',
913
+ s : 'a few seconds',
914
+ m : 'a minute',
915
+ mm : '%d minutes',
916
+ h : 'an hour',
917
+ hh : '%d hours',
918
+ d : 'a day',
919
+ dd : '%d days',
920
+ M : 'a month',
921
+ MM : '%d months',
922
+ y : 'a year',
923
+ yy : '%d years'
798
924
  },
925
+
799
926
  relativeTime : function (number, withoutSuffix, string, isFuture) {
800
927
  var output = this._relativeTime[string];
801
928
  return (typeof output === 'function') ?
802
929
  output(number, withoutSuffix, string, isFuture) :
803
930
  output.replace(/%d/i, number);
804
931
  },
932
+
805
933
  pastFuture : function (diff, output) {
806
934
  var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
807
935
  return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
808
936
  },
809
937
 
810
938
  ordinal : function (number) {
811
- return this._ordinal.replace("%d", number);
939
+ return this._ordinal.replace('%d', number);
812
940
  },
813
- _ordinal : "%d",
941
+ _ordinal : '%d',
814
942
 
815
943
  preparse : function (string) {
816
944
  return string;
@@ -835,78 +963,6 @@
835
963
  }
836
964
  });
837
965
 
838
- // Loads a language definition into the `languages` cache. The function
839
- // takes a key and optionally values. If not in the browser and no values
840
- // are provided, it will load the language file module. As a convenience,
841
- // this function also returns the language values.
842
- function loadLang(key, values) {
843
- values.abbr = key;
844
- if (!languages[key]) {
845
- languages[key] = new Language();
846
- }
847
- languages[key].set(values);
848
- return languages[key];
849
- }
850
-
851
- // Remove a language from the `languages` cache. Mostly useful in tests.
852
- function unloadLang(key) {
853
- delete languages[key];
854
- }
855
-
856
- // Determines which language definition to use and returns it.
857
- //
858
- // With no parameters, it will return the global language. If you
859
- // pass in a language key, such as 'en', it will return the
860
- // definition for 'en', so long as 'en' has already been loaded using
861
- // moment.lang.
862
- function getLangDefinition(key) {
863
- var i = 0, j, lang, next, split,
864
- get = function (k) {
865
- if (!languages[k] && hasModule) {
866
- try {
867
- require('./lang/' + k);
868
- } catch (e) { }
869
- }
870
- return languages[k];
871
- };
872
-
873
- if (!key) {
874
- return moment.fn._lang;
875
- }
876
-
877
- if (!isArray(key)) {
878
- //short-circuit everything else
879
- lang = get(key);
880
- if (lang) {
881
- return lang;
882
- }
883
- key = [key];
884
- }
885
-
886
- //pick the language from the array
887
- //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
888
- //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
889
- while (i < key.length) {
890
- split = normalizeLanguage(key[i]).split('-');
891
- j = split.length;
892
- next = normalizeLanguage(key[i + 1]);
893
- next = next ? next.split('-') : null;
894
- while (j > 0) {
895
- lang = get(split.slice(0, j).join('-'));
896
- if (lang) {
897
- return lang;
898
- }
899
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
900
- //the next array item is better than a shallower substring of this one
901
- break;
902
- }
903
- j--;
904
- }
905
- i++;
906
- }
907
- return moment.fn._lang;
908
- }
909
-
910
966
  /************************************
911
967
  Formatting
912
968
  ************************************/
@@ -914,9 +970,9 @@
914
970
 
915
971
  function removeFormattingTokens(input) {
916
972
  if (input.match(/\[[\s\S]/)) {
917
- return input.replace(/^\[|\]$/g, "");
973
+ return input.replace(/^\[|\]$/g, '');
918
974
  }
919
- return input.replace(/\\/g, "");
975
+ return input.replace(/\\/g, '');
920
976
  }
921
977
 
922
978
  function makeFormatFunction(format) {
@@ -931,7 +987,7 @@
931
987
  }
932
988
 
933
989
  return function (mom) {
934
- var output = "";
990
+ var output = '';
935
991
  for (i = 0; i < length; i++) {
936
992
  output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
937
993
  }
@@ -941,12 +997,11 @@
941
997
 
942
998
  // format date using native date object
943
999
  function formatMoment(m, format) {
944
-
945
1000
  if (!m.isValid()) {
946
- return m.lang().invalidDate();
1001
+ return m.localeData().invalidDate();
947
1002
  }
948
1003
 
949
- format = expandFormat(format, m.lang());
1004
+ format = expandFormat(format, m.localeData());
950
1005
 
951
1006
  if (!formatFunctions[format]) {
952
1007
  formatFunctions[format] = makeFormatFunction(format);
@@ -955,11 +1010,11 @@
955
1010
  return formatFunctions[format](m);
956
1011
  }
957
1012
 
958
- function expandFormat(format, lang) {
1013
+ function expandFormat(format, locale) {
959
1014
  var i = 5;
960
1015
 
961
1016
  function replaceLongDateFormatTokens(input) {
962
- return lang.longDateFormat(input) || input;
1017
+ return locale.longDateFormat(input) || input;
963
1018
  }
964
1019
 
965
1020
  localFormattingTokens.lastIndex = 0;
@@ -1000,13 +1055,19 @@
1000
1055
  case 'ggggg':
1001
1056
  return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
1002
1057
  case 'S':
1003
- if (strict) { return parseTokenOneDigit; }
1058
+ if (strict) {
1059
+ return parseTokenOneDigit;
1060
+ }
1004
1061
  /* falls through */
1005
1062
  case 'SS':
1006
- if (strict) { return parseTokenTwoDigits; }
1063
+ if (strict) {
1064
+ return parseTokenTwoDigits;
1065
+ }
1007
1066
  /* falls through */
1008
1067
  case 'SSS':
1009
- if (strict) { return parseTokenThreeDigits; }
1068
+ if (strict) {
1069
+ return parseTokenThreeDigits;
1070
+ }
1010
1071
  /* falls through */
1011
1072
  case 'DDD':
1012
1073
  return parseTokenOneToThreeDigits;
@@ -1018,7 +1079,7 @@
1018
1079
  return parseTokenWord;
1019
1080
  case 'a':
1020
1081
  case 'A':
1021
- return getLangDefinition(config._l)._meridiemParse;
1082
+ return config._locale._meridiemParse;
1022
1083
  case 'X':
1023
1084
  return parseTokenTimestampMs;
1024
1085
  case 'Z':
@@ -1055,13 +1116,13 @@
1055
1116
  case 'Do':
1056
1117
  return parseTokenOrdinal;
1057
1118
  default :
1058
- a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
1119
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
1059
1120
  return a;
1060
1121
  }
1061
1122
  }
1062
1123
 
1063
1124
  function timezoneMinutesFromString(string) {
1064
- string = string || "";
1125
+ string = string || '';
1065
1126
  var possibleTzMatches = (string.match(parseTokenTimezone) || []),
1066
1127
  tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
1067
1128
  parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
@@ -1090,7 +1151,7 @@
1090
1151
  break;
1091
1152
  case 'MMM' : // fall through to MMMM
1092
1153
  case 'MMMM' :
1093
- a = getLangDefinition(config._l).monthsParse(input);
1154
+ a = config._locale.monthsParse(input);
1094
1155
  // if we didn't find a month name, mark the date as invalid.
1095
1156
  if (a != null) {
1096
1157
  datePartArray[MONTH] = a;
@@ -1130,7 +1191,7 @@
1130
1191
  // AM / PM
1131
1192
  case 'a' : // fall through to A
1132
1193
  case 'A' :
1133
- config._isPm = getLangDefinition(config._l).isPM(input);
1194
+ config._isPm = config._locale.isPM(input);
1134
1195
  break;
1135
1196
  // 24 HOUR
1136
1197
  case 'H' : // fall through to hh
@@ -1170,7 +1231,7 @@
1170
1231
  case 'dd':
1171
1232
  case 'ddd':
1172
1233
  case 'dddd':
1173
- a = getLangDefinition(config._l).weekdaysParse(input);
1234
+ a = config._locale.weekdaysParse(input);
1174
1235
  // if we didn't get a weekday name, mark the date as invalid
1175
1236
  if (a != null) {
1176
1237
  config._w = config._w || {};
@@ -1206,7 +1267,7 @@
1206
1267
  }
1207
1268
 
1208
1269
  function dayOfYearFromWeekInfo(config) {
1209
- var w, weekYear, week, weekday, dow, doy, temp, lang;
1270
+ var w, weekYear, week, weekday, dow, doy, temp;
1210
1271
 
1211
1272
  w = config._w;
1212
1273
  if (w.GG != null || w.W != null || w.E != null) {
@@ -1221,9 +1282,8 @@
1221
1282
  week = dfl(w.W, 1);
1222
1283
  weekday = dfl(w.E, 1);
1223
1284
  } else {
1224
- lang = getLangDefinition(config._l);
1225
- dow = lang._week.dow;
1226
- doy = lang._week.doy;
1285
+ dow = config._locale._week.dow;
1286
+ doy = config._locale._week.doy;
1227
1287
 
1228
1288
  weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
1229
1289
  week = dfl(w.w, 1);
@@ -1337,7 +1397,6 @@
1337
1397
 
1338
1398
  // date from string and format string
1339
1399
  function makeDateFromStringAndFormat(config) {
1340
-
1341
1400
  if (config._f === moment.ISO_8601) {
1342
1401
  parseISO(config);
1343
1402
  return;
@@ -1347,13 +1406,12 @@
1347
1406
  config._pf.empty = true;
1348
1407
 
1349
1408
  // This array is used to make a Date, either with `new Date` or `Date.UTC`
1350
- var lang = getLangDefinition(config._l),
1351
- string = '' + config._i,
1409
+ var string = '' + config._i,
1352
1410
  i, parsedInput, tokens, token, skipped,
1353
1411
  stringLength = string.length,
1354
1412
  totalParsedInputLength = 0;
1355
1413
 
1356
- tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
1414
+ tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
1357
1415
 
1358
1416
  for (i = 0; i < tokens.length; i++) {
1359
1417
  token = tokens[i];
@@ -1428,7 +1486,7 @@
1428
1486
 
1429
1487
  for (i = 0; i < config._f.length; i++) {
1430
1488
  currentScore = 0;
1431
- tempConfig = extend({}, config);
1489
+ tempConfig = copyConfig({}, config);
1432
1490
  tempConfig._pf = defaultParsingFlags();
1433
1491
  tempConfig._f = config._f[i];
1434
1492
  makeDateFromStringAndFormat(tempConfig);
@@ -1464,8 +1522,8 @@
1464
1522
  config._pf.iso = true;
1465
1523
  for (i = 0, l = isoDates.length; i < l; i++) {
1466
1524
  if (isoDates[i][1].exec(string)) {
1467
- // match[5] should be "T" or undefined
1468
- config._f = isoDates[i][0] + (match[6] || " ");
1525
+ // match[5] should be 'T' or undefined
1526
+ config._f = isoDates[i][0] + (match[6] || ' ');
1469
1527
  break;
1470
1528
  }
1471
1529
  }
@@ -1476,7 +1534,7 @@
1476
1534
  }
1477
1535
  }
1478
1536
  if (string.match(parseTokenTimezone)) {
1479
- config._f += "Z";
1537
+ config._f += 'Z';
1480
1538
  }
1481
1539
  makeDateFromStringAndFormat(config);
1482
1540
  } else {
@@ -1494,20 +1552,18 @@
1494
1552
  }
1495
1553
 
1496
1554
  function makeDateFromInput(config) {
1497
- var input = config._i,
1498
- matched = aspNetJsonRegex.exec(input);
1499
-
1555
+ var input = config._i, matched;
1500
1556
  if (input === undefined) {
1501
1557
  config._d = new Date();
1502
- } else if (matched) {
1558
+ } else if (isDate(input)) {
1559
+ config._d = new Date(+input);
1560
+ } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
1503
1561
  config._d = new Date(+matched[1]);
1504
1562
  } else if (typeof input === 'string') {
1505
1563
  makeDateFromString(config);
1506
1564
  } else if (isArray(input)) {
1507
1565
  config._a = input.slice(0);
1508
1566
  dateFromConfig(config);
1509
- } else if (isDate(input)) {
1510
- config._d = new Date(+input);
1511
1567
  } else if (typeof(input) === 'object') {
1512
1568
  dateFromObject(config);
1513
1569
  } else if (typeof(input) === 'number') {
@@ -1538,13 +1594,13 @@
1538
1594
  return date;
1539
1595
  }
1540
1596
 
1541
- function parseWeekday(input, language) {
1597
+ function parseWeekday(input, locale) {
1542
1598
  if (typeof input === 'string') {
1543
1599
  if (!isNaN(input)) {
1544
1600
  input = parseInt(input, 10);
1545
1601
  }
1546
1602
  else {
1547
- input = language.weekdaysParse(input);
1603
+ input = locale.weekdaysParse(input);
1548
1604
  if (typeof input !== 'number') {
1549
1605
  return null;
1550
1606
  }
@@ -1559,29 +1615,33 @@
1559
1615
 
1560
1616
 
1561
1617
  // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
1562
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
1563
- return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1618
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
1619
+ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1564
1620
  }
1565
1621
 
1566
- function relativeTime(milliseconds, withoutSuffix, lang) {
1567
- var seconds = round(Math.abs(milliseconds) / 1000),
1568
- minutes = round(seconds / 60),
1569
- hours = round(minutes / 60),
1570
- days = round(hours / 24),
1571
- years = round(days / 365),
1572
- args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1622
+ function relativeTime(posNegDuration, withoutSuffix, locale) {
1623
+ var duration = moment.duration(posNegDuration).abs(),
1624
+ seconds = round(duration.as('s')),
1625
+ minutes = round(duration.as('m')),
1626
+ hours = round(duration.as('h')),
1627
+ days = round(duration.as('d')),
1628
+ months = round(duration.as('M')),
1629
+ years = round(duration.as('y')),
1630
+
1631
+ args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1573
1632
  minutes === 1 && ['m'] ||
1574
1633
  minutes < relativeTimeThresholds.m && ['mm', minutes] ||
1575
1634
  hours === 1 && ['h'] ||
1576
1635
  hours < relativeTimeThresholds.h && ['hh', hours] ||
1577
1636
  days === 1 && ['d'] ||
1578
- days <= relativeTimeThresholds.dd && ['dd', days] ||
1579
- days <= relativeTimeThresholds.dm && ['M'] ||
1580
- days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
1637
+ days < relativeTimeThresholds.d && ['dd', days] ||
1638
+ months === 1 && ['M'] ||
1639
+ months < relativeTimeThresholds.M && ['MM', months] ||
1581
1640
  years === 1 && ['y'] || ['yy', years];
1641
+
1582
1642
  args[2] = withoutSuffix;
1583
- args[3] = milliseconds > 0;
1584
- args[4] = lang;
1643
+ args[3] = +posNegDuration > 0;
1644
+ args[4] = locale;
1585
1645
  return substituteTimeAgo.apply({}, args);
1586
1646
  }
1587
1647
 
@@ -1612,7 +1672,7 @@
1612
1672
  daysToDayOfWeek += 7;
1613
1673
  }
1614
1674
 
1615
- adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
1675
+ adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
1616
1676
  return {
1617
1677
  week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1618
1678
  year: adjustedMoment.year()
@@ -1642,18 +1702,18 @@
1642
1702
  var input = config._i,
1643
1703
  format = config._f;
1644
1704
 
1705
+ config._locale = config._locale || moment.localeData(config._l);
1706
+
1645
1707
  if (input === null || (format === undefined && input === '')) {
1646
1708
  return moment.invalid({nullInput: true});
1647
1709
  }
1648
1710
 
1649
1711
  if (typeof input === 'string') {
1650
- config._i = input = getLangDefinition().preparse(input);
1712
+ config._i = input = config._locale.preparse(input);
1651
1713
  }
1652
1714
 
1653
1715
  if (moment.isMoment(input)) {
1654
- config = cloneMoment(input);
1655
-
1656
- config._d = new Date(+input._d);
1716
+ return new Moment(input, true);
1657
1717
  } else if (format) {
1658
1718
  if (isArray(format)) {
1659
1719
  makeDateFromStringAndArray(config);
@@ -1667,12 +1727,12 @@
1667
1727
  return new Moment(config);
1668
1728
  }
1669
1729
 
1670
- moment = function (input, format, lang, strict) {
1730
+ moment = function (input, format, locale, strict) {
1671
1731
  var c;
1672
1732
 
1673
- if (typeof(lang) === "boolean") {
1674
- strict = lang;
1675
- lang = undefined;
1733
+ if (typeof(locale) === 'boolean') {
1734
+ strict = locale;
1735
+ locale = undefined;
1676
1736
  }
1677
1737
  // object construction must be done this way.
1678
1738
  // https://github.com/moment/moment/issues/1423
@@ -1680,7 +1740,7 @@
1680
1740
  c._isAMomentObject = true;
1681
1741
  c._i = input;
1682
1742
  c._f = format;
1683
- c._l = lang;
1743
+ c._l = locale;
1684
1744
  c._strict = strict;
1685
1745
  c._isUTC = false;
1686
1746
  c._pf = defaultParsingFlags();
@@ -1691,13 +1751,14 @@
1691
1751
  moment.suppressDeprecationWarnings = false;
1692
1752
 
1693
1753
  moment.createFromInputFallback = deprecate(
1694
- "moment construction falls back to js Date. This is " +
1695
- "discouraged and will be removed in upcoming major " +
1696
- "release. Please refer to " +
1697
- "https://github.com/moment/moment/issues/1407 for more info.",
1698
- function (config) {
1699
- config._d = new Date(config._i);
1700
- });
1754
+ 'moment construction falls back to js Date. This is ' +
1755
+ 'discouraged and will be removed in upcoming major ' +
1756
+ 'release. Please refer to ' +
1757
+ 'https://github.com/moment/moment/issues/1407 for more info.',
1758
+ function (config) {
1759
+ config._d = new Date(config._i);
1760
+ }
1761
+ );
1701
1762
 
1702
1763
  // Pick a moment m from moments so that m[fn](other) is true for all
1703
1764
  // other. This relies on the function fn to be transitive.
@@ -1734,12 +1795,12 @@
1734
1795
  };
1735
1796
 
1736
1797
  // creating with utc
1737
- moment.utc = function (input, format, lang, strict) {
1798
+ moment.utc = function (input, format, locale, strict) {
1738
1799
  var c;
1739
1800
 
1740
- if (typeof(lang) === "boolean") {
1741
- strict = lang;
1742
- lang = undefined;
1801
+ if (typeof(locale) === 'boolean') {
1802
+ strict = locale;
1803
+ locale = undefined;
1743
1804
  }
1744
1805
  // object construction must be done this way.
1745
1806
  // https://github.com/moment/moment/issues/1423
@@ -1747,7 +1808,7 @@
1747
1808
  c._isAMomentObject = true;
1748
1809
  c._useUTC = true;
1749
1810
  c._isUTC = true;
1750
- c._l = lang;
1811
+ c._l = locale;
1751
1812
  c._i = input;
1752
1813
  c._f = format;
1753
1814
  c._strict = strict;
@@ -1768,7 +1829,8 @@
1768
1829
  match = null,
1769
1830
  sign,
1770
1831
  ret,
1771
- parseIso;
1832
+ parseIso,
1833
+ diffRes;
1772
1834
 
1773
1835
  if (moment.isDuration(input)) {
1774
1836
  duration = {
@@ -1784,7 +1846,7 @@
1784
1846
  duration.milliseconds = input;
1785
1847
  }
1786
1848
  } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1787
- sign = (match[1] === "-") ? -1 : 1;
1849
+ sign = (match[1] === '-') ? -1 : 1;
1788
1850
  duration = {
1789
1851
  y: 0,
1790
1852
  d: toInt(match[DATE]) * sign,
@@ -1794,7 +1856,7 @@
1794
1856
  ms: toInt(match[MILLISECOND]) * sign
1795
1857
  };
1796
1858
  } else if (!!(match = isoDurationRegex.exec(input))) {
1797
- sign = (match[1] === "-") ? -1 : 1;
1859
+ sign = (match[1] === '-') ? -1 : 1;
1798
1860
  parseIso = function (inp) {
1799
1861
  // We'd normally use ~~inp for this, but unfortunately it also
1800
1862
  // converts floats to ints.
@@ -1812,12 +1874,19 @@
1812
1874
  s: parseIso(match[7]),
1813
1875
  w: parseIso(match[8])
1814
1876
  };
1877
+ } else if (typeof duration === 'object' &&
1878
+ ('from' in duration || 'to' in duration)) {
1879
+ diffRes = momentsDifference(moment(duration.from), moment(duration.to));
1880
+
1881
+ duration = {};
1882
+ duration.ms = diffRes.milliseconds;
1883
+ duration.M = diffRes.months;
1815
1884
  }
1816
1885
 
1817
1886
  ret = new Duration(duration);
1818
1887
 
1819
- if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
1820
- ret._lang = input._lang;
1888
+ if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
1889
+ ret._locale = input._locale;
1821
1890
  }
1822
1891
 
1823
1892
  return ret;
@@ -1841,46 +1910,99 @@
1841
1910
  moment.updateOffset = function () {};
1842
1911
 
1843
1912
  // This function allows you to set a threshold for relative time strings
1844
- moment.relativeTimeThreshold = function(threshold, limit) {
1845
- if (relativeTimeThresholds[threshold] === undefined) {
1846
- return false;
1847
- }
1848
- relativeTimeThresholds[threshold] = limit;
1849
- return true;
1913
+ moment.relativeTimeThreshold = function (threshold, limit) {
1914
+ if (relativeTimeThresholds[threshold] === undefined) {
1915
+ return false;
1916
+ }
1917
+ if (limit === undefined) {
1918
+ return relativeTimeThresholds[threshold];
1919
+ }
1920
+ relativeTimeThresholds[threshold] = limit;
1921
+ return true;
1850
1922
  };
1851
1923
 
1852
- // This function will load languages and then set the global language. If
1924
+ moment.lang = deprecate(
1925
+ 'moment.lang is deprecated. Use moment.locale instead.',
1926
+ function (key, value) {
1927
+ return moment.locale(key, value);
1928
+ }
1929
+ );
1930
+
1931
+ // This function will load locale and then set the global locale. If
1853
1932
  // no arguments are passed in, it will simply return the current global
1854
- // language key.
1855
- moment.lang = function (key, values) {
1856
- var r;
1857
- if (!key) {
1858
- return moment.fn._lang._abbr;
1859
- }
1860
- if (values) {
1861
- loadLang(normalizeLanguage(key), values);
1862
- } else if (values === null) {
1863
- unloadLang(key);
1864
- key = 'en';
1865
- } else if (!languages[key]) {
1866
- getLangDefinition(key);
1867
- }
1868
- r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1869
- return r._abbr;
1933
+ // locale key.
1934
+ moment.locale = function (key, values) {
1935
+ var data;
1936
+ if (key) {
1937
+ if (typeof(values) !== 'undefined') {
1938
+ data = moment.defineLocale(key, values);
1939
+ }
1940
+ else {
1941
+ data = moment.localeData(key);
1942
+ }
1943
+
1944
+ if (data) {
1945
+ moment.duration._locale = moment._locale = data;
1946
+ }
1947
+ }
1948
+
1949
+ return moment._locale._abbr;
1870
1950
  };
1871
1951
 
1872
- // returns language data
1873
- moment.langData = function (key) {
1874
- if (key && key._lang && key._lang._abbr) {
1875
- key = key._lang._abbr;
1952
+ moment.defineLocale = function (name, values) {
1953
+ if (values !== null) {
1954
+ values.abbr = name;
1955
+ if (!locales[name]) {
1956
+ locales[name] = new Locale();
1957
+ }
1958
+ locales[name].set(values);
1959
+
1960
+ // backwards compat for now: also set the locale
1961
+ moment.locale(name);
1962
+
1963
+ return locales[name];
1964
+ } else {
1965
+ // useful for testing
1966
+ delete locales[name];
1967
+ return null;
1968
+ }
1969
+ };
1970
+
1971
+ moment.langData = deprecate(
1972
+ 'moment.langData is deprecated. Use moment.localeData instead.',
1973
+ function (key) {
1974
+ return moment.localeData(key);
1975
+ }
1976
+ );
1977
+
1978
+ // returns locale data
1979
+ moment.localeData = function (key) {
1980
+ var locale;
1981
+
1982
+ if (key && key._locale && key._locale._abbr) {
1983
+ key = key._locale._abbr;
1984
+ }
1985
+
1986
+ if (!key) {
1987
+ return moment._locale;
1876
1988
  }
1877
- return getLangDefinition(key);
1989
+
1990
+ if (!isArray(key)) {
1991
+ //short-circuit everything else
1992
+ locale = loadLocale(key);
1993
+ if (locale) {
1994
+ return locale;
1995
+ }
1996
+ key = [key];
1997
+ }
1998
+
1999
+ return chooseLocale(key);
1878
2000
  };
1879
2001
 
1880
2002
  // compare moment object
1881
2003
  moment.isMoment = function (obj) {
1882
2004
  return obj instanceof Moment ||
1883
- (obj != null && obj.hasOwnProperty('_isAMomentObject'));
2005
+ (obj != null && hasOwnProp(obj, '_isAMomentObject'));
1884
2006
  };
1885
2007
 
1886
2008
  // for typechecking Duration objects
@@ -1936,7 +2058,7 @@
1936
2058
  },
1937
2059
 
1938
2060
  toString : function () {
1939
- return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
2061
+ return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
1940
2062
  },
1941
2063
 
1942
2064
  toDate : function () {
@@ -1970,7 +2092,6 @@
1970
2092
  },
1971
2093
 
1972
2094
  isDSTShifted : function () {
1973
-
1974
2095
  if (this._a) {
1975
2096
  return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
1976
2097
  }
@@ -1986,48 +2107,30 @@
1986
2107
  return this._pf.overflow;
1987
2108
  },
1988
2109
 
1989
- utc : function () {
1990
- return this.zone(0);
2110
+ utc : function (keepLocalTime) {
2111
+ return this.zone(0, keepLocalTime);
1991
2112
  },
1992
2113
 
1993
- local : function () {
1994
- this.zone(0);
1995
- this._isUTC = false;
2114
+ local : function (keepLocalTime) {
2115
+ if (this._isUTC) {
2116
+ this.zone(0, keepLocalTime);
2117
+ this._isUTC = false;
2118
+
2119
+ if (keepLocalTime) {
2120
+ this.add(this._d.getTimezoneOffset(), 'm');
2121
+ }
2122
+ }
1996
2123
  return this;
1997
2124
  },
1998
2125
 
1999
2126
  format : function (inputString) {
2000
2127
  var output = formatMoment(this, inputString || moment.defaultFormat);
2001
- return this.lang().postformat(output);
2128
+ return this.localeData().postformat(output);
2002
2129
  },
2003
2130
 
2004
- add : function (input, val) {
2005
- var dur;
2006
- // switch args to support add('s', 1) and add(1, 's')
2007
- if (typeof input === 'string' && typeof val === 'string') {
2008
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2009
- } else if (typeof input === 'string') {
2010
- dur = moment.duration(+val, input);
2011
- } else {
2012
- dur = moment.duration(input, val);
2013
- }
2014
- addOrSubtractDurationFromMoment(this, dur, 1);
2015
- return this;
2016
- },
2131
+ add : createAdder(1, 'add'),
2017
2132
 
2018
- subtract : function (input, val) {
2019
- var dur;
2020
- // switch args to support subtract('s', 1) and subtract(1, 's')
2021
- if (typeof input === 'string' && typeof val === 'string') {
2022
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2023
- } else if (typeof input === 'string') {
2024
- dur = moment.duration(+val, input);
2025
- } else {
2026
- dur = moment.duration(input, val);
2027
- }
2028
- addOrSubtractDurationFromMoment(this, dur, -1);
2029
- return this;
2030
- },
2133
+ subtract : createAdder(-1, 'subtract'),
2031
2134
 
2032
2135
  diff : function (input, units, asFloat) {
2033
2136
  var that = makeAs(input, this),
@@ -2064,7 +2167,7 @@
2064
2167
  },
2065
2168
 
2066
2169
  from : function (time, withoutSuffix) {
2067
- return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
2170
+ return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2068
2171
  },
2069
2172
 
2070
2173
  fromNow : function (withoutSuffix) {
@@ -2083,7 +2186,7 @@
2083
2186
  diff < 1 ? 'sameDay' :
2084
2187
  diff < 2 ? 'nextDay' :
2085
2188
  diff < 7 ? 'nextWeek' : 'sameElse';
2086
- return this.format(this.lang().calendar(format, this));
2189
+ return this.format(this.localeData().calendar(format, this));
2087
2190
  },
2088
2191
 
2089
2192
  isLeapYear : function () {
@@ -2098,8 +2201,8 @@
2098
2201
  day : function (input) {
2099
2202
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2100
2203
  if (input != null) {
2101
- input = parseWeekday(input, this.lang());
2102
- return this.add({ d : input - day });
2204
+ input = parseWeekday(input, this.localeData());
2205
+ return this.add(input - day, 'd');
2103
2206
  } else {
2104
2207
  return day;
2105
2208
  }
@@ -2107,7 +2210,7 @@
2107
2210
 
2108
2211
  month : makeAccessor('Month', true),
2109
2212
 
2110
- startOf: function (units) {
2213
+ startOf : function (units) {
2111
2214
  units = normalizeUnits(units);
2112
2215
  // the following switch intentionally omits break keywords
2113
2216
  // to utilize falling through the cases.
@@ -2152,7 +2255,7 @@
2152
2255
 
2153
2256
  endOf: function (units) {
2154
2257
  units = normalizeUnits(units);
2155
- return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
2258
+ return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
2156
2259
  },
2157
2260
 
2158
2261
  isAfter: function (input, units) {
@@ -2171,7 +2274,7 @@
2171
2274
  },
2172
2275
 
2173
2276
  min: deprecate(
2174
- "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
2277
+ 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
2175
2278
  function (other) {
2176
2279
  other = moment.apply(null, arguments);
2177
2280
  return other < this ? this : other;
@@ -2179,36 +2282,43 @@
2179
2282
  ),
2180
2283
 
2181
2284
  max: deprecate(
2182
- "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
2285
+ 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
2183
2286
  function (other) {
2184
2287
  other = moment.apply(null, arguments);
2185
2288
  return other > this ? this : other;
2186
2289
  }
2187
2290
  ),
2188
2291
 
2189
- // keepTime = true means only change the timezone, without affecting
2190
- // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
2191
- // It is possible that 5:31:26 doesn't exist int zone +0200, so we
2192
- // adjust the time as needed, to be valid.
2292
+ // keepLocalTime = true means only change the timezone, without
2293
+ // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
2294
+ // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
2295
+ // +0200, so we adjust the time as needed, to be valid.
2193
2296
  //
2194
2297
  // Keeping the time actually adds/subtracts (one hour)
2195
2298
  // from the actual represented time. That is why we call updateOffset
2196
2299
  // a second time. In case it wants us to change the offset again
2197
2300
  // _changeInProgress == true case, then we have to adjust, because
2198
2301
  // there is no such time in the given timezone.
2199
- zone : function (input, keepTime) {
2200
- var offset = this._offset || 0;
2302
+ zone : function (input, keepLocalTime) {
2303
+ var offset = this._offset || 0,
2304
+ localAdjust;
2201
2305
  if (input != null) {
2202
- if (typeof input === "string") {
2306
+ if (typeof input === 'string') {
2203
2307
  input = timezoneMinutesFromString(input);
2204
2308
  }
2205
2309
  if (Math.abs(input) < 16) {
2206
2310
  input = input * 60;
2207
2311
  }
2312
+ if (!this._isUTC && keepLocalTime) {
2313
+ localAdjust = this._d.getTimezoneOffset();
2314
+ }
2208
2315
  this._offset = input;
2209
2316
  this._isUTC = true;
2317
+ if (localAdjust != null) {
2318
+ this.subtract(localAdjust, 'm');
2319
+ }
2210
2320
  if (offset !== input) {
2211
- if (!keepTime || this._changeInProgress) {
2321
+ if (!keepLocalTime || this._changeInProgress) {
2212
2322
  addOrSubtractDurationFromMoment(this,
2213
2323
  moment.duration(offset - input, 'm'), 1, false);
2214
2324
  } else if (!this._changeInProgress) {
@@ -2224,11 +2334,11 @@
2224
2334
  },
2225
2335
 
2226
2336
  zoneAbbr : function () {
2227
- return this._isUTC ? "UTC" : "";
2337
+ return this._isUTC ? 'UTC' : '';
2228
2338
  },
2229
2339
 
2230
2340
  zoneName : function () {
2231
- return this._isUTC ? "Coordinated Universal Time" : "";
2341
+ return this._isUTC ? 'Coordinated Universal Time' : '';
2232
2342
  },
2233
2343
 
2234
2344
  parseZone : function () {
@@ -2257,7 +2367,7 @@
2257
2367
 
2258
2368
  dayOfYear : function (input) {
2259
2369
  var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
2260
- return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
2370
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2261
2371
  },
2262
2372
 
2263
2373
  quarter : function (input) {
@@ -2265,28 +2375,28 @@
2265
2375
  },
2266
2376
 
2267
2377
  weekYear : function (input) {
2268
- var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
2269
- return input == null ? year : this.add("y", (input - year));
2378
+ var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2379
+ return input == null ? year : this.add((input - year), 'y');
2270
2380
  },
2271
2381
 
2272
2382
  isoWeekYear : function (input) {
2273
2383
  var year = weekOfYear(this, 1, 4).year;
2274
- return input == null ? year : this.add("y", (input - year));
2384
+ return input == null ? year : this.add((input - year), 'y');
2275
2385
  },
2276
2386
 
2277
2387
  week : function (input) {
2278
- var week = this.lang().week(this);
2279
- return input == null ? week : this.add("d", (input - week) * 7);
2388
+ var week = this.localeData().week(this);
2389
+ return input == null ? week : this.add((input - week) * 7, 'd');
2280
2390
  },
2281
2391
 
2282
2392
  isoWeek : function (input) {
2283
2393
  var week = weekOfYear(this, 1, 4).week;
2284
- return input == null ? week : this.add("d", (input - week) * 7);
2394
+ return input == null ? week : this.add((input - week) * 7, 'd');
2285
2395
  },
2286
2396
 
2287
2397
  weekday : function (input) {
2288
- var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
2289
- return input == null ? weekday : this.add("d", input - weekday);
2398
+ var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2399
+ return input == null ? weekday : this.add(input - weekday, 'd');
2290
2400
  },
2291
2401
 
2292
2402
  isoWeekday : function (input) {
@@ -2301,7 +2411,7 @@
2301
2411
  },
2302
2412
 
2303
2413
  weeksInYear : function () {
2304
- var weekInfo = this._lang._week;
2414
+ var weekInfo = this.localeData()._week;
2305
2415
  return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2306
2416
  },
2307
2417
 
@@ -2318,16 +2428,32 @@
2318
2428
  return this;
2319
2429
  },
2320
2430
 
2321
- // If passed a language key, it will set the language for this
2322
- // instance. Otherwise, it will return the language configuration
2431
+ // If passed a locale key, it will set the locale for this
2432
+ // instance. Otherwise, it will return the locale configuration
2323
2433
  // variables for this instance.
2324
- lang : function (key) {
2434
+ locale : function (key) {
2325
2435
  if (key === undefined) {
2326
- return this._lang;
2436
+ return this._locale._abbr;
2327
2437
  } else {
2328
- this._lang = getLangDefinition(key);
2438
+ this._locale = moment.localeData(key);
2329
2439
  return this;
2330
2440
  }
2441
+ },
2442
+
2443
+ lang : deprecate(
2444
+ 'moment().lang() is deprecated. Use moment().localeData() instead.',
2445
+ function (key) {
2446
+ if (key === undefined) {
2447
+ return this.localeData();
2448
+ } else {
2449
+ this._locale = moment.localeData(key);
2450
+ return this;
2451
+ }
2452
+ }
2453
+ ),
2454
+
2455
+ localeData : function () {
2456
+ return this._locale;
2331
2457
  }
2332
2458
  });
2333
2459
 
@@ -2336,7 +2462,7 @@
2336
2462
 
2337
2463
  // TODO: Move this out of here!
2338
2464
  if (typeof value === 'string') {
2339
- value = mom.lang().monthsParse(value);
2465
+ value = mom.localeData().monthsParse(value);
2340
2466
  // TODO: Another silent failure?
2341
2467
  if (typeof value !== 'number') {
2342
2468
  return mom;
@@ -2383,9 +2509,9 @@
2383
2509
  moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
2384
2510
  // moment.fn.month is defined separately
2385
2511
  moment.fn.date = makeAccessor('Date', true);
2386
- moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
2512
+ moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
2387
2513
  moment.fn.year = makeAccessor('FullYear', true);
2388
- moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
2514
+ moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
2389
2515
 
2390
2516
  // add plural methods
2391
2517
  moment.fn.days = moment.fn.day;
@@ -2402,6 +2528,17 @@
2402
2528
  ************************************/
2403
2529
 
2404
2530
 
2531
+ function daysToYears (days) {
2532
+ // 400 years have 146097 days (taking into account leap year rules)
2533
+ return days * 400 / 146097;
2534
+ }
2535
+
2536
+ function yearsToDays (years) {
2537
+ // years * 365 + absRound(years / 4) -
2538
+ // absRound(years / 100) + absRound(years / 400);
2539
+ return years * 146097 / 400;
2540
+ }
2541
+
2405
2542
  extend(moment.duration.fn = Duration.prototype, {
2406
2543
 
2407
2544
  _bubble : function () {
@@ -2409,7 +2546,7 @@
2409
2546
  days = this._days,
2410
2547
  months = this._months,
2411
2548
  data = this._data,
2412
- seconds, minutes, hours, years;
2549
+ seconds, minutes, hours, years = 0;
2413
2550
 
2414
2551
  // The following code bubbles up values, see the tests for
2415
2552
  // examples of what that means.
@@ -2425,15 +2562,40 @@
2425
2562
  data.hours = hours % 24;
2426
2563
 
2427
2564
  days += absRound(hours / 24);
2428
- data.days = days % 30;
2429
2565
 
2566
+ // Accurately convert days to years, assume start from year 0.
2567
+ years = absRound(daysToYears(days));
2568
+ days -= absRound(yearsToDays(years));
2569
+
2570
+ // 30 days to a month
2571
+ // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2430
2572
  months += absRound(days / 30);
2431
- data.months = months % 12;
2573
+ days %= 30;
2574
+
2575
+ // 12 months -> 1 year
2576
+ years += absRound(months / 12);
2577
+ months %= 12;
2432
2578
 
2433
- years = absRound(months / 12);
2579
+ data.days = days;
2580
+ data.months = months;
2434
2581
  data.years = years;
2435
2582
  },
2436
2583
 
2584
+ abs : function () {
2585
+ this._milliseconds = Math.abs(this._milliseconds);
2586
+ this._days = Math.abs(this._days);
2587
+ this._months = Math.abs(this._months);
2588
+
2589
+ this._data.milliseconds = Math.abs(this._data.milliseconds);
2590
+ this._data.seconds = Math.abs(this._data.seconds);
2591
+ this._data.minutes = Math.abs(this._data.minutes);
2592
+ this._data.hours = Math.abs(this._data.hours);
2593
+ this._data.months = Math.abs(this._data.months);
2594
+ this._data.years = Math.abs(this._data.years);
2595
+
2596
+ return this;
2597
+ },
2598
+
2437
2599
  weeks : function () {
2438
2600
  return absRound(this.days() / 7);
2439
2601
  },
@@ -2446,14 +2608,13 @@
2446
2608
  },
2447
2609
 
2448
2610
  humanize : function (withSuffix) {
2449
- var difference = +this,
2450
- output = relativeTime(difference, !withSuffix, this.lang());
2611
+ var output = relativeTime(this, !withSuffix, this.localeData());
2451
2612
 
2452
2613
  if (withSuffix) {
2453
- output = this.lang().pastFuture(difference, output);
2614
+ output = this.localeData().pastFuture(+this, output);
2454
2615
  }
2455
2616
 
2456
- return this.lang().postformat(output);
2617
+ return this.localeData().postformat(output);
2457
2618
  },
2458
2619
 
2459
2620
  add : function (input, val) {
@@ -2487,13 +2648,39 @@
2487
2648
  },
2488
2649
 
2489
2650
  as : function (units) {
2651
+ var days, months;
2490
2652
  units = normalizeUnits(units);
2491
- return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
2653
+
2654
+ days = this._days + this._milliseconds / 864e5;
2655
+ if (units === 'month' || units === 'year') {
2656
+ months = this._months + daysToYears(days) * 12;
2657
+ return units === 'month' ? months : months / 12;
2658
+ } else {
2659
+ days += yearsToDays(this._months / 12);
2660
+ switch (units) {
2661
+ case 'week': return days / 7;
2662
+ case 'day': return days;
2663
+ case 'hour': return days * 24;
2664
+ case 'minute': return days * 24 * 60;
2665
+ case 'second': return days * 24 * 60 * 60;
2666
+ case 'millisecond': return days * 24 * 60 * 60 * 1000;
2667
+ default: throw new Error('Unknown unit ' + units);
2668
+ }
2669
+ }
2492
2670
  },
2493
2671
 
2494
2672
  lang : moment.fn.lang,
2673
+ locale : moment.fn.locale,
2674
+
2675
+ toIsoString : deprecate(
2676
+ 'toIsoString() is deprecated. Please use toISOString() instead ' +
2677
+ '(notice the capitals)',
2678
+ function () {
2679
+ return this.toISOString();
2680
+ }
2681
+ ),
2495
2682
 
2496
- toIsoString : function () {
2683
+ toISOString : function () {
2497
2684
  // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2498
2685
  var years = Math.abs(this.years()),
2499
2686
  months = Math.abs(this.months()),
@@ -2517,41 +2704,59 @@
2517
2704
  (hours ? hours + 'H' : '') +
2518
2705
  (minutes ? minutes + 'M' : '') +
2519
2706
  (seconds ? seconds + 'S' : '');
2707
+ },
2708
+
2709
+ localeData : function () {
2710
+ return this._locale;
2520
2711
  }
2521
2712
  });
2522
2713
 
2714
+ moment.duration.fn.toString = moment.duration.fn.toISOString;
2715
+
2523
2716
  function makeDurationGetter(name) {
2524
2717
  moment.duration.fn[name] = function () {
2525
2718
  return this._data[name];
2526
2719
  };
2527
2720
  }
2528
2721
 
2529
- function makeDurationAsGetter(name, factor) {
2530
- moment.duration.fn['as' + name] = function () {
2531
- return +this / factor;
2532
- };
2533
- }
2534
-
2535
2722
  for (i in unitMillisecondFactors) {
2536
- if (unitMillisecondFactors.hasOwnProperty(i)) {
2537
- makeDurationAsGetter(i, unitMillisecondFactors[i]);
2723
+ if (hasOwnProp(unitMillisecondFactors, i)) {
2538
2724
  makeDurationGetter(i.toLowerCase());
2539
2725
  }
2540
2726
  }
2541
2727
 
2542
- makeDurationAsGetter('Weeks', 6048e5);
2728
+ moment.duration.fn.asMilliseconds = function () {
2729
+ return this.as('ms');
2730
+ };
2731
+ moment.duration.fn.asSeconds = function () {
2732
+ return this.as('s');
2733
+ };
2734
+ moment.duration.fn.asMinutes = function () {
2735
+ return this.as('m');
2736
+ };
2737
+ moment.duration.fn.asHours = function () {
2738
+ return this.as('h');
2739
+ };
2740
+ moment.duration.fn.asDays = function () {
2741
+ return this.as('d');
2742
+ };
2743
+ moment.duration.fn.asWeeks = function () {
2744
+ return this.as('weeks');
2745
+ };
2543
2746
  moment.duration.fn.asMonths = function () {
2544
- return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
2747
+ return this.as('M');
2748
+ };
2749
+ moment.duration.fn.asYears = function () {
2750
+ return this.as('y');
2545
2751
  };
2546
-
2547
2752
 
2548
2753
  /************************************
2549
- Default Lang
2754
+ Default Locale
2550
2755
  ************************************/
2551
2756
 
2552
2757
 
2553
- // Set default language, other languages will inherit from English.
2554
- moment.lang('en', {
2758
+ // Set default locale, other locale will inherit from English.
2759
+ moment.locale('en', {
2555
2760
  ordinal : function (number) {
2556
2761
  var b = number % 10,
2557
2762
  output = (toInt(number % 100 / 10) === 1) ? 'th' :
@@ -2562,7 +2767,7 @@
2562
2767
  }
2563
2768
  });
2564
2769
 
2565
- /* EMBED_LANGUAGES */
2770
+ /* EMBED_LOCALES */
2566
2771
 
2567
2772
  /************************************
2568
2773
  Exposing Moment
@@ -2576,9 +2781,9 @@
2576
2781
  oldGlobalMoment = globalScope.moment;
2577
2782
  if (shouldDeprecate) {
2578
2783
  globalScope.moment = deprecate(
2579
- "Accessing Moment through the global scope is " +
2580
- "deprecated, and will be removed in an upcoming " +
2581
- "release.",
2784
+ 'Accessing Moment through the global scope is ' +
2785
+ 'deprecated, and will be removed in an upcoming ' +
2786
+ 'release.',
2582
2787
  moment);
2583
2788
  } else {
2584
2789
  globalScope.moment = moment;
@@ -2588,8 +2793,8 @@
2588
2793
  // CommonJS module is defined
2589
2794
  if (hasModule) {
2590
2795
  module.exports = moment;
2591
- } else if (typeof define === "function" && define.amd) {
2592
- define("moment", function (require, exports, module) {
2796
+ } else if (typeof define === 'function' && define.amd) {
2797
+ define('moment', function (require, exports, module) {
2593
2798
  if (module.config && module.config() && module.config().noGlobal === true) {
2594
2799
  // release the global variable
2595
2800
  globalScope.moment = oldGlobalMoment;