momentJS 1.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 477552285d91991a86bb07853b768e2e638d5719
4
+ data.tar.gz: deef11f43cd31226e414f3bc842741a18cfa0bf5
5
+ SHA512:
6
+ metadata.gz: 14aad23b9754e42a209012c1430436fff67ae1f805c2b561317e9a67066ff5f7e9a98637b4ad5bb9f7750f351eab37753010727c804a28ec291dc218307bb5cc
7
+ data.tar.gz: ad729bfd32035d4758980732653ca301c20de6c41eb14cb539c391bfe8b88b5cdd7f6fb29aff5264a4308690e9ba49013e082b89eae85db96d6b27c49a66d21e
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .DS_Store
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in momentJS.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 stillnaughty
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # MomentJS
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'momentJS'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install momentJS
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ require "momentJS/version"
2
+ require "momentJS/engine"
@@ -0,0 +1,6 @@
1
+ module MomentJS
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module MomentJS
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'momentJS/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "momentJS"
8
+ spec.version = MomentJS::VERSION
9
+ spec.authors = ["stillnaughty"]
10
+ spec.email = ["ying@stillnaughty.com"]
11
+ spec.description = "Rails asset gems for momentJS"
12
+ spec.summary = "Rails asset gems for the customized momentJS based on v2.1.0"
13
+ spec.homepage = ""
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_development_dependency "bundler", "~> 1.3"
19
+ spec.add_development_dependency "rake"
20
+ end
@@ -0,0 +1,1664 @@
1
+ //= require moment.plugin
2
+
3
+ // moment.js
4
+ // version : 2.1.0
5
+ // author : Tim Wood
6
+ // license : MIT
7
+ // momentjs.com
8
+
9
+ (function (undefined) {
10
+
11
+ /************************************
12
+ Constants
13
+ ************************************/
14
+
15
+ var moment,
16
+ VERSION = "2.1.0",
17
+ round = Math.round, i,
18
+ // internal storage for language config files
19
+ languages = {},
20
+
21
+ // check for nodeJS
22
+ hasModule = (typeof module !== 'undefined' && module.exports),
23
+
24
+ // ASP.NET json date format regex
25
+ aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
26
+ aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
27
+
28
+ // format tokens
29
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
30
+ localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
31
+
32
+ // parsing token regexes
33
+ parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
34
+ parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
35
+ parseTokenThreeDigits = /\d{3}/, // 000 - 999
36
+ parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
37
+ parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
38
+ parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
39
+ parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
40
+ parseTokenT = /T/i, // T (ISO seperator)
41
+ parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
42
+
43
+ // preliminary iso regex
44
+ // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
45
+ isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
46
+ isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
47
+
48
+ // iso time formats and regexes
49
+ isoTimes = [
50
+ ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
51
+ ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
52
+ ['HH:mm', /(T| )\d\d:\d\d/],
53
+ ['HH', /(T| )\d\d/]
54
+ ],
55
+
56
+ // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
57
+ parseTimezoneChunker = /([\+\-]|\d\d)/gi,
58
+
59
+ // getter and setter names
60
+ proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
+ unitMillisecondFactors = {
62
+ 'Milliseconds' : 1,
63
+ 'Seconds' : 1e3,
64
+ 'Minutes' : 6e4,
65
+ 'Hours' : 36e5,
66
+ 'Days' : 864e5,
67
+ 'Months' : 2592e6,
68
+ 'Years' : 31536e6
69
+ },
70
+
71
+ unitAliases = {
72
+ ms : 'millisecond',
73
+ s : 'second',
74
+ m : 'minute',
75
+ h : 'hour',
76
+ d : 'day',
77
+ w : 'week',
78
+ M : 'month',
79
+ y : 'year'
80
+ },
81
+
82
+ // format function strings
83
+ formatFunctions = {},
84
+
85
+ // tokens to ordinalize and pad
86
+ ordinalizeTokens = 'DDD w W M D d'.split(' '),
87
+ paddedTokens = 'M D H h m s w W'.split(' '),
88
+
89
+ formatTokenFunctions = {
90
+ M : function () {
91
+ return this.month() + 1;
92
+ },
93
+ MMM : function (format) {
94
+ return this.lang().monthsShort(this, format);
95
+ },
96
+ MMMM : function (format) {
97
+ return this.lang().months(this, format);
98
+ },
99
+ D : function () {
100
+ return this.date();
101
+ },
102
+ DDD : function () {
103
+ return this.dayOfYear();
104
+ },
105
+ d : function () {
106
+ return this.day();
107
+ },
108
+ dd : function (format) {
109
+ return this.lang().weekdaysMin(this, format);
110
+ },
111
+ ddd : function (format) {
112
+ return this.lang().weekdaysShort(this, format);
113
+ },
114
+ dddd : function (format) {
115
+ return this.lang().weekdays(this, format);
116
+ },
117
+ w : function () {
118
+ return this.week();
119
+ },
120
+ W : function () {
121
+ return this.isoWeek();
122
+ },
123
+ YY : function () {
124
+ return leftZeroFill(this.year() % 100, 2);
125
+ },
126
+ YYYY : function () {
127
+ return leftZeroFill(this.year(), 4);
128
+ },
129
+ YYYYY : function () {
130
+ return leftZeroFill(this.year(), 5);
131
+ },
132
+ gg : function () {
133
+ return leftZeroFill(this.weekYear() % 100, 2);
134
+ },
135
+ gggg : function () {
136
+ return this.weekYear();
137
+ },
138
+ ggggg : function () {
139
+ return leftZeroFill(this.weekYear(), 5);
140
+ },
141
+ GG : function () {
142
+ return leftZeroFill(this.isoWeekYear() % 100, 2);
143
+ },
144
+ GGGG : function () {
145
+ return this.isoWeekYear();
146
+ },
147
+ GGGGG : function () {
148
+ return leftZeroFill(this.isoWeekYear(), 5);
149
+ },
150
+ e : function () {
151
+ return this.weekday();
152
+ },
153
+ E : function () {
154
+ return this.isoWeekday();
155
+ },
156
+ a : function () {
157
+ return this.lang().meridiem(this.hours(), this.minutes(), true);
158
+ },
159
+ A : function () {
160
+ return this.lang().meridiem(this.hours(), this.minutes(), false);
161
+ },
162
+ H : function () {
163
+ return this.hours();
164
+ },
165
+ h : function () {
166
+ return this.hours() % 12 || 12;
167
+ },
168
+ m : function () {
169
+ return this.minutes();
170
+ },
171
+ s : function () {
172
+ return this.seconds();
173
+ },
174
+ S : function () {
175
+ return ~~(this.milliseconds() / 100);
176
+ },
177
+ SS : function () {
178
+ return leftZeroFill(~~(this.milliseconds() / 10), 2);
179
+ },
180
+ SSS : function () {
181
+ return leftZeroFill(this.milliseconds(), 3);
182
+ },
183
+ Z : function () {
184
+ var a = -this.zone(),
185
+ b = "+";
186
+ if (a < 0) {
187
+ a = -a;
188
+ b = "-";
189
+ }
190
+ return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
191
+ },
192
+ ZZ : function () {
193
+ var a = -this.zone(),
194
+ b = "+";
195
+ if (a < 0) {
196
+ a = -a;
197
+ b = "-";
198
+ }
199
+ return b + leftZeroFill(~~(10 * a / 6), 4);
200
+ },
201
+ z : function () {
202
+ return this.zoneAbbr();
203
+ },
204
+ zz : function () {
205
+ return this.zoneName();
206
+ },
207
+ X : function () {
208
+ return this.unix();
209
+ }
210
+ };
211
+
212
+ function padToken(func, count) {
213
+ return function (a) {
214
+ return leftZeroFill(func.call(this, a), count);
215
+ };
216
+ }
217
+ function ordinalizeToken(func, period) {
218
+ return function (a) {
219
+ return this.lang().ordinal(func.call(this, a), period);
220
+ };
221
+ }
222
+
223
+ while (ordinalizeTokens.length) {
224
+ i = ordinalizeTokens.pop();
225
+ formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
226
+ }
227
+ while (paddedTokens.length) {
228
+ i = paddedTokens.pop();
229
+ formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
230
+ }
231
+ formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
232
+
233
+
234
+ /************************************
235
+ Constructors
236
+ ************************************/
237
+
238
+ function Language() {
239
+
240
+ }
241
+
242
+ // Moment prototype object
243
+ function Moment(config) {
244
+ extend(this, config);
245
+ }
246
+
247
+ // Duration Constructor
248
+ function Duration(duration) {
249
+ var years = duration.years || duration.year || duration.y || 0,
250
+ months = duration.months || duration.month || duration.M || 0,
251
+ weeks = duration.weeks || duration.week || duration.w || 0,
252
+ days = duration.days || duration.day || duration.d || 0,
253
+ hours = duration.hours || duration.hour || duration.h || 0,
254
+ minutes = duration.minutes || duration.minute || duration.m || 0,
255
+ seconds = duration.seconds || duration.second || duration.s || 0,
256
+ milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
257
+
258
+ // store reference to input for deterministic cloning
259
+ this._input = duration;
260
+
261
+ // representation for dateAddRemove
262
+ this._milliseconds = milliseconds +
263
+ seconds * 1e3 + // 1000
264
+ minutes * 6e4 + // 1000 * 60
265
+ hours * 36e5; // 1000 * 60 * 60
266
+ // Because of dateAddRemove treats 24 hours as different from a
267
+ // day when working around DST, we need to store them separately
268
+ this._days = days +
269
+ weeks * 7;
270
+ // It is impossible translate months into days without knowing
271
+ // which months you are are talking about, so we have to store
272
+ // it separately.
273
+ this._months = months +
274
+ years * 12;
275
+
276
+ this._data = {};
277
+
278
+ this._bubble();
279
+ }
280
+
281
+
282
+ /************************************
283
+ Helpers
284
+ ************************************/
285
+
286
+
287
+ function extend(a, b) {
288
+ for (var i in b) {
289
+ if (b.hasOwnProperty(i)) {
290
+ a[i] = b[i];
291
+ }
292
+ }
293
+ return a;
294
+ }
295
+
296
+ function absRound(number) {
297
+ if (number < 0) {
298
+ return Math.ceil(number);
299
+ } else {
300
+ return Math.floor(number);
301
+ }
302
+ }
303
+
304
+ // left zero fill a number
305
+ // see http://jsperf.com/left-zero-filling for performance comparison
306
+ function leftZeroFill(number, targetLength) {
307
+ var output = number + '';
308
+ while (output.length < targetLength) {
309
+ output = '0' + output;
310
+ }
311
+ return output;
312
+ }
313
+
314
+ // helper function for _.addTime and _.subtractTime
315
+ function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
316
+ var milliseconds = duration._milliseconds,
317
+ days = duration._days,
318
+ months = duration._months,
319
+ minutes,
320
+ hours,
321
+ currentDate;
322
+
323
+ if (milliseconds) {
324
+ mom._d.setTime(+mom._d + milliseconds * isAdding);
325
+ }
326
+ // store the minutes and hours so we can restore them
327
+ if (days || months) {
328
+ minutes = mom.minute();
329
+ hours = mom.hour();
330
+ }
331
+ if (days) {
332
+ mom.date(mom.date() + days * isAdding);
333
+ }
334
+ if (months) {
335
+ mom.month(mom.month() + months * isAdding);
336
+ }
337
+ if (milliseconds && !ignoreUpdateOffset) {
338
+ moment.updateOffset(mom);
339
+ }
340
+ // restore the minutes and hours after possibly changing dst
341
+ if (days || months) {
342
+ mom.minute(minutes);
343
+ mom.hour(hours);
344
+ }
345
+ }
346
+
347
+ // check if is an array
348
+ function isArray(input) {
349
+ return Object.prototype.toString.call(input) === '[object Array]';
350
+ }
351
+
352
+ // compare two arrays, return the number of differences
353
+ function compareArrays(array1, array2) {
354
+ var len = Math.min(array1.length, array2.length),
355
+ lengthDiff = Math.abs(array1.length - array2.length),
356
+ diffs = 0,
357
+ i;
358
+ for (i = 0; i < len; i++) {
359
+ if (~~array1[i] !== ~~array2[i]) {
360
+ diffs++;
361
+ }
362
+ }
363
+ return diffs + lengthDiff;
364
+ }
365
+
366
+ function normalizeUnits(units) {
367
+ return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
368
+ }
369
+
370
+
371
+ /************************************
372
+ Languages
373
+ ************************************/
374
+
375
+
376
+ Language.prototype = {
377
+ set : function (config) {
378
+ var prop, i;
379
+ for (i in config) {
380
+ prop = config[i];
381
+ if (typeof prop === 'function') {
382
+ this[i] = prop;
383
+ } else {
384
+ this['_' + i] = prop;
385
+ }
386
+ }
387
+ },
388
+
389
+ _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
390
+ months : function (m) {
391
+ return this._months[m.month()];
392
+ },
393
+
394
+ _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
395
+ monthsShort : function (m) {
396
+ return this._monthsShort[m.month()];
397
+ },
398
+
399
+ monthsParse : function (monthName) {
400
+ var i, mom, regex;
401
+
402
+ if (!this._monthsParse) {
403
+ this._monthsParse = [];
404
+ }
405
+
406
+ for (i = 0; i < 12; i++) {
407
+ // make the regex if we don't have it already
408
+ if (!this._monthsParse[i]) {
409
+ mom = moment([2000, i]);
410
+ regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
411
+ this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
412
+ }
413
+ // test the regex
414
+ if (this._monthsParse[i].test(monthName)) {
415
+ return i;
416
+ }
417
+ }
418
+ },
419
+
420
+ _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
421
+ weekdays : function (m) {
422
+ return this._weekdays[m.day()];
423
+ },
424
+
425
+ _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
426
+ weekdaysShort : function (m) {
427
+ return this._weekdaysShort[m.day()];
428
+ },
429
+
430
+ _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
431
+ weekdaysMin : function (m) {
432
+ return this._weekdaysMin[m.day()];
433
+ },
434
+
435
+ weekdaysParse : function (weekdayName) {
436
+ var i, mom, regex;
437
+
438
+ if (!this._weekdaysParse) {
439
+ this._weekdaysParse = [];
440
+ }
441
+
442
+ for (i = 0; i < 7; i++) {
443
+ // make the regex if we don't have it already
444
+ if (!this._weekdaysParse[i]) {
445
+ mom = moment([2000, 1]).day(i);
446
+ regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
447
+ this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
448
+ }
449
+ // test the regex
450
+ if (this._weekdaysParse[i].test(weekdayName)) {
451
+ return i;
452
+ }
453
+ }
454
+ },
455
+
456
+ _longDateFormat : {
457
+ LT : "h:mm A",
458
+ L : "MM/DD/YYYY",
459
+ LL : "MMMM D YYYY",
460
+ LLL : "MMMM D YYYY LT",
461
+ LLLL : "dddd, MMMM D YYYY LT"
462
+ },
463
+ longDateFormat : function (key) {
464
+ var output = this._longDateFormat[key];
465
+ if (!output && this._longDateFormat[key.toUpperCase()]) {
466
+ output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
467
+ return val.slice(1);
468
+ });
469
+ this._longDateFormat[key] = output;
470
+ }
471
+ return output;
472
+ },
473
+
474
+ isPM : function (input) {
475
+ return ((input + '').toLowerCase()[0] === 'p');
476
+ },
477
+
478
+ _meridiemParse : /[ap]\.?m?\.?/i,
479
+ meridiem : function (hours, minutes, isLower) {
480
+ if (hours > 11) {
481
+ return isLower ? 'pm' : 'PM';
482
+ } else {
483
+ return isLower ? 'am' : 'AM';
484
+ }
485
+ },
486
+
487
+ _calendar : {
488
+ sameDay : '[Today at] LT',
489
+ nextDay : '[Tomorrow at] LT',
490
+ nextWeek : 'dddd [at] LT',
491
+ lastDay : '[Yesterday at] LT',
492
+ lastWeek : '[Last] dddd [at] LT',
493
+ sameElse : 'L'
494
+ },
495
+ calendar : function (key, mom) {
496
+ var output = this._calendar[key];
497
+ return typeof output === 'function' ? output.apply(mom) : output;
498
+ },
499
+
500
+ _relativeTime : {
501
+ future : "in %s",
502
+ past : "%s ago",
503
+ s : "a few seconds",
504
+ m : "a minute",
505
+ mm : "%d minutes",
506
+ h : "an hour",
507
+ hh : "%d hours",
508
+ d : "a day",
509
+ dd : "%d days",
510
+ M : "a month",
511
+ MM : "%d months",
512
+ y : "a year",
513
+ yy : "%d years"
514
+ },
515
+ relativeTime : function (number, withoutSuffix, string, isFuture) {
516
+ var output = this._relativeTime[string];
517
+ return (typeof output === 'function') ?
518
+ output(number, withoutSuffix, string, isFuture) :
519
+ output.replace(/%d/i, number);
520
+ },
521
+ pastFuture : function (diff, output) {
522
+ var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
523
+ return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
524
+ },
525
+
526
+ ordinal : function (number) {
527
+ return this._ordinal.replace("%d", number);
528
+ },
529
+ _ordinal : "%d",
530
+
531
+ preparse : function (string) {
532
+ return string;
533
+ },
534
+
535
+ postformat : function (string) {
536
+ return string;
537
+ },
538
+
539
+ week : function (mom) {
540
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
541
+ },
542
+ _week : {
543
+ dow : 0, // Sunday is the first day of the week.
544
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
545
+ }
546
+ };
547
+
548
+ // Loads a language definition into the `languages` cache. The function
549
+ // takes a key and optionally values. If not in the browser and no values
550
+ // are provided, it will load the language file module. As a convenience,
551
+ // this function also returns the language values.
552
+ function loadLang(key, values) {
553
+ values.abbr = key;
554
+ if (!languages[key]) {
555
+ languages[key] = new Language();
556
+ }
557
+ languages[key].set(values);
558
+ return languages[key];
559
+ }
560
+
561
+ // Determines which language definition to use and returns it.
562
+ //
563
+ // With no parameters, it will return the global language. If you
564
+ // pass in a language key, such as 'en', it will return the
565
+ // definition for 'en', so long as 'en' has already been loaded using
566
+ // moment.lang.
567
+ function getLangDefinition(key) {
568
+ if (!key) {
569
+ return moment.fn._lang;
570
+ }
571
+ if (!languages[key] && hasModule) {
572
+ try {
573
+ require('./lang/' + key);
574
+ } catch (e) {
575
+ // call with no params to set to default
576
+ return moment.fn._lang;
577
+ }
578
+ }
579
+ return languages[key];
580
+ }
581
+
582
+
583
+ /************************************
584
+ Formatting
585
+ ************************************/
586
+
587
+
588
+ function removeFormattingTokens(input) {
589
+ if (input.match(/\[.*\]/)) {
590
+ return input.replace(/^\[|\]$/g, "");
591
+ }
592
+ return input.replace(/\\/g, "");
593
+ }
594
+
595
+ function makeFormatFunction(format) {
596
+ var array = format.match(formattingTokens), i, length;
597
+
598
+ for (i = 0, length = array.length; i < length; i++) {
599
+ if (formatTokenFunctions[array[i]]) {
600
+ array[i] = formatTokenFunctions[array[i]];
601
+ } else {
602
+ array[i] = removeFormattingTokens(array[i]);
603
+ }
604
+ }
605
+
606
+ return function (mom) {
607
+ var output = "";
608
+ for (i = 0; i < length; i++) {
609
+ output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
610
+ }
611
+ return output;
612
+ };
613
+ }
614
+
615
+ // format date using native date object
616
+ function formatMoment(m, format) {
617
+ var i = 5;
618
+
619
+ function replaceLongDateFormatTokens(input) {
620
+ return m.lang().longDateFormat(input) || input;
621
+ }
622
+
623
+ while (i-- && localFormattingTokens.test(format)) {
624
+ format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
625
+ }
626
+
627
+ if (!formatFunctions[format]) {
628
+ formatFunctions[format] = makeFormatFunction(format);
629
+ }
630
+
631
+ return formatFunctions[format](m);
632
+ }
633
+
634
+
635
+ /************************************
636
+ Parsing
637
+ ************************************/
638
+
639
+
640
+ // get the regex to find the next token
641
+ function getParseRegexForToken(token, config) {
642
+ switch (token) {
643
+ case 'DDDD':
644
+ return parseTokenThreeDigits;
645
+ case 'YYYY':
646
+ return parseTokenFourDigits;
647
+ case 'YYYYY':
648
+ return parseTokenSixDigits;
649
+ case 'S':
650
+ case 'SS':
651
+ case 'SSS':
652
+ case 'DDD':
653
+ return parseTokenOneToThreeDigits;
654
+ case 'MMM':
655
+ case 'MMMM':
656
+ case 'dd':
657
+ case 'ddd':
658
+ case 'dddd':
659
+ return parseTokenWord;
660
+ case 'a':
661
+ case 'A':
662
+ return getLangDefinition(config._l)._meridiemParse;
663
+ case 'X':
664
+ return parseTokenTimestampMs;
665
+ case 'Z':
666
+ case 'ZZ':
667
+ return parseTokenTimezone;
668
+ case 'T':
669
+ return parseTokenT;
670
+ case 'MM':
671
+ case 'DD':
672
+ case 'YY':
673
+ case 'HH':
674
+ case 'hh':
675
+ case 'mm':
676
+ case 'ss':
677
+ case 'M':
678
+ case 'D':
679
+ case 'd':
680
+ case 'H':
681
+ case 'h':
682
+ case 'm':
683
+ case 's':
684
+ return parseTokenOneOrTwoDigits;
685
+ default :
686
+ return new RegExp(token.replace('\\', ''));
687
+ }
688
+ }
689
+
690
+ function timezoneMinutesFromString(string) {
691
+ var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
692
+ parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
693
+ minutes = +(parts[1] * 60) + ~~parts[2];
694
+
695
+ return parts[0] === '+' ? -minutes : minutes;
696
+ }
697
+
698
+ // function to convert string input to date
699
+ function addTimeToArrayFromToken(token, input, config) {
700
+ var a, datePartArray = config._a;
701
+
702
+ switch (token) {
703
+ // MONTH
704
+ case 'M' : // fall through to MM
705
+ case 'MM' :
706
+ datePartArray[1] = (input == null) ? 0 : ~~input - 1;
707
+ break;
708
+ case 'MMM' : // fall through to MMMM
709
+ case 'MMMM' :
710
+ a = getLangDefinition(config._l).monthsParse(input);
711
+ // if we didn't find a month name, mark the date as invalid.
712
+ if (a != null) {
713
+ datePartArray[1] = a;
714
+ } else {
715
+ config._isValid = false;
716
+ }
717
+ break;
718
+ // DAY OF MONTH
719
+ case 'D' : // fall through to DDDD
720
+ case 'DD' : // fall through to DDDD
721
+ case 'DDD' : // fall through to DDDD
722
+ case 'DDDD' :
723
+ if (input != null) {
724
+ datePartArray[2] = ~~input;
725
+ }
726
+ break;
727
+ // YEAR
728
+ case 'YY' :
729
+ datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
730
+ break;
731
+ case 'YYYY' :
732
+ case 'YYYYY' :
733
+ datePartArray[0] = ~~input;
734
+ break;
735
+ // AM / PM
736
+ case 'a' : // fall through to A
737
+ case 'A' :
738
+ config._isPm = getLangDefinition(config._l).isPM(input);
739
+ break;
740
+ // 24 HOUR
741
+ case 'H' : // fall through to hh
742
+ case 'HH' : // fall through to hh
743
+ case 'h' : // fall through to hh
744
+ case 'hh' :
745
+ datePartArray[3] = ~~input;
746
+ break;
747
+ // MINUTE
748
+ case 'm' : // fall through to mm
749
+ case 'mm' :
750
+ datePartArray[4] = ~~input;
751
+ break;
752
+ // SECOND
753
+ case 's' : // fall through to ss
754
+ case 'ss' :
755
+ datePartArray[5] = ~~input;
756
+ break;
757
+ // MILLISECOND
758
+ case 'S' :
759
+ case 'SS' :
760
+ case 'SSS' :
761
+ datePartArray[6] = ~~ (('0.' + input) * 1000);
762
+ break;
763
+ // UNIX TIMESTAMP WITH MS
764
+ case 'X':
765
+ config._d = new Date(parseFloat(input) * 1000);
766
+ break;
767
+ // TIMEZONE
768
+ case 'Z' : // fall through to ZZ
769
+ case 'ZZ' :
770
+ config._useUTC = true;
771
+ config._tzm = timezoneMinutesFromString(input);
772
+ break;
773
+ }
774
+
775
+ // if the input is null, the date is not valid
776
+ if (input == null) {
777
+ config._isValid = false;
778
+ }
779
+ }
780
+
781
+ // convert an array to a date.
782
+ // the array should mirror the parameters below
783
+ // note: all values past the year are optional and will default to the lowest possible value.
784
+ // [year, month, day , hour, minute, second, millisecond]
785
+ function dateFromArray(config) {
786
+ var i, date, input = [];
787
+
788
+ if (config._d) {
789
+ return;
790
+ }
791
+
792
+ for (i = 0; i < 7; i++) {
793
+ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
794
+ }
795
+
796
+ // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
797
+ input[3] += ~~((config._tzm || 0) / 60);
798
+ input[4] += ~~((config._tzm || 0) % 60);
799
+
800
+ date = new Date(0);
801
+
802
+ if (config._useUTC) {
803
+ date.setUTCFullYear(input[0], input[1], input[2]);
804
+ date.setUTCHours(input[3], input[4], input[5], input[6]);
805
+ } else {
806
+ date.setFullYear(input[0], input[1], input[2]);
807
+ date.setHours(input[3], input[4], input[5], input[6]);
808
+ }
809
+
810
+ config._d = date;
811
+ }
812
+
813
+ // date from string and format string
814
+ function makeDateFromStringAndFormat(config) {
815
+ // This array is used to make a Date, either with `new Date` or `Date.UTC`
816
+ var tokens = config._f.match(formattingTokens),
817
+ string = config._i,
818
+ i, parsedInput;
819
+
820
+ config._a = [];
821
+
822
+ for (i = 0; i < tokens.length; i++) {
823
+ parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
824
+ if (parsedInput) {
825
+ string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
826
+ }
827
+ // don't parse if its not a known token
828
+ if (formatTokenFunctions[tokens[i]]) {
829
+ addTimeToArrayFromToken(tokens[i], parsedInput, config);
830
+ }
831
+ }
832
+
833
+ // add remaining unparsed input to the string
834
+ if (string) {
835
+ config._il = string;
836
+ }
837
+
838
+ // handle am pm
839
+ if (config._isPm && config._a[3] < 12) {
840
+ config._a[3] += 12;
841
+ }
842
+ // if is 12 am, change hours to 0
843
+ if (config._isPm === false && config._a[3] === 12) {
844
+ config._a[3] = 0;
845
+ }
846
+ // return
847
+ dateFromArray(config);
848
+ }
849
+
850
+ // date from string and array of format strings
851
+ function makeDateFromStringAndArray(config) {
852
+ var tempConfig,
853
+ tempMoment,
854
+ bestMoment,
855
+
856
+ scoreToBeat = 99,
857
+ i,
858
+ currentScore;
859
+
860
+ for (i = 0; i < config._f.length; i++) {
861
+ tempConfig = extend({}, config);
862
+ tempConfig._f = config._f[i];
863
+ makeDateFromStringAndFormat(tempConfig);
864
+ tempMoment = new Moment(tempConfig);
865
+
866
+ currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
867
+
868
+ // if there is any input that was not parsed
869
+ // add a penalty for that format
870
+ if (tempMoment._il) {
871
+ currentScore += tempMoment._il.length;
872
+ }
873
+
874
+ if (currentScore < scoreToBeat) {
875
+ scoreToBeat = currentScore;
876
+ bestMoment = tempMoment;
877
+ }
878
+ }
879
+
880
+ extend(config, bestMoment);
881
+ }
882
+
883
+ // date from iso format
884
+ function makeDateFromString(config) {
885
+ var i,
886
+ string = config._i,
887
+ match = isoRegex.exec(string);
888
+
889
+ if (match) {
890
+ // match[2] should be "T" or undefined
891
+ config._f = 'YYYY-MM-DD' + (match[2] || " ");
892
+ for (i = 0; i < 4; i++) {
893
+ if (isoTimes[i][1].exec(string)) {
894
+ config._f += isoTimes[i][0];
895
+ break;
896
+ }
897
+ }
898
+ if (parseTokenTimezone.exec(string)) {
899
+ config._f += " Z";
900
+ }
901
+ makeDateFromStringAndFormat(config);
902
+ } else {
903
+ config._d = new Date(string);
904
+ }
905
+ }
906
+
907
+ function makeDateFromInput(config) {
908
+ var input = config._i,
909
+ matched = aspNetJsonRegex.exec(input);
910
+
911
+ if (input === undefined) {
912
+ config._d = new Date();
913
+ } else if (matched) {
914
+ config._d = new Date(+matched[1]);
915
+ } else if (typeof input === 'string') {
916
+ makeDateFromString(config);
917
+ } else if (isArray(input)) {
918
+ config._a = input.slice(0);
919
+ dateFromArray(config);
920
+ } else {
921
+ config._d = input instanceof Date ? new Date(+input) : new Date(input);
922
+ }
923
+ }
924
+
925
+
926
+ /************************************
927
+ Relative Time
928
+ ************************************/
929
+
930
+
931
+ // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
932
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
933
+ return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
934
+ }
935
+
936
+ function relativeTime(milliseconds, withoutSuffix, lang) {
937
+ var seconds = round(Math.abs(milliseconds) / 1000),
938
+ minutes = round(seconds / 60),
939
+ hours = round(minutes / 60),
940
+ days = round(hours / 24),
941
+ years = round(days / 365),
942
+ args = seconds < 45 && ['s', seconds] ||
943
+ minutes === 1 && ['m'] ||
944
+ minutes < 45 && ['mm', minutes] ||
945
+ hours === 1 && ['h'] ||
946
+ hours < 22 && ['hh', hours] ||
947
+ days === 1 && ['d'] ||
948
+ days <= 25 && ['dd', days] ||
949
+ days <= 45 && ['M'] ||
950
+ days < 345 && ['MM', round(days / 30)] ||
951
+ years === 1 && ['y'] || ['yy', years];
952
+ args[2] = withoutSuffix;
953
+ args[3] = milliseconds > 0;
954
+ args[4] = lang;
955
+ return substituteTimeAgo.apply({}, args);
956
+ }
957
+
958
+
959
+ /************************************
960
+ Week of Year
961
+ ************************************/
962
+
963
+
964
+ // firstDayOfWeek 0 = sun, 6 = sat
965
+ // the day of the week that starts the week
966
+ // (usually sunday or monday)
967
+ // firstDayOfWeekOfYear 0 = sun, 6 = sat
968
+ // the first week is the week that contains the first
969
+ // of this day of the week
970
+ // (eg. ISO weeks use thursday (4))
971
+ function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
972
+ var end = firstDayOfWeekOfYear - firstDayOfWeek,
973
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
974
+ adjustedMoment;
975
+
976
+
977
+ if (daysToDayOfWeek > end) {
978
+ daysToDayOfWeek -= 7;
979
+ }
980
+
981
+ if (daysToDayOfWeek < end - 7) {
982
+ daysToDayOfWeek += 7;
983
+ }
984
+
985
+ adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
986
+ return {
987
+ week: Math.ceil(adjustedMoment.dayOfYear() / 7),
988
+ year: adjustedMoment.year()
989
+ };
990
+ }
991
+
992
+
993
+ /************************************
994
+ Top Level Functions
995
+ ************************************/
996
+
997
+ function makeMoment(config) {
998
+ var input = config._i,
999
+ format = config._f;
1000
+
1001
+ if (input === null || input === '') {
1002
+ return null;
1003
+ }
1004
+
1005
+ if (typeof input === 'string') {
1006
+ config._i = input = getLangDefinition().preparse(input);
1007
+ }
1008
+
1009
+ if (moment.isMoment(input)) {
1010
+ config = extend({}, input);
1011
+ config._d = new Date(+input._d);
1012
+ } else if (format) {
1013
+ if (isArray(format)) {
1014
+ makeDateFromStringAndArray(config);
1015
+ } else {
1016
+ makeDateFromStringAndFormat(config);
1017
+ }
1018
+ } else {
1019
+ makeDateFromInput(config);
1020
+ }
1021
+
1022
+ return new Moment(config);
1023
+ }
1024
+
1025
+ moment = function (input, format, lang) {
1026
+ return makeMoment({
1027
+ _i : input,
1028
+ _f : format,
1029
+ _l : lang,
1030
+ _isUTC : false
1031
+ });
1032
+ };
1033
+
1034
+ // creating with utc
1035
+ moment.utc = function (input, format, lang) {
1036
+ return makeMoment({
1037
+ _useUTC : true,
1038
+ _isUTC : true,
1039
+ _l : lang,
1040
+ _i : input,
1041
+ _f : format
1042
+ });
1043
+ };
1044
+
1045
+ // creating with unix timestamp (in seconds)
1046
+ moment.unix = function (input) {
1047
+ return moment(input * 1000);
1048
+ };
1049
+
1050
+ // duration
1051
+ moment.duration = function (input, key) {
1052
+ var isDuration = moment.isDuration(input),
1053
+ isNumber = (typeof input === 'number'),
1054
+ duration = (isDuration ? input._input : (isNumber ? {} : input)),
1055
+ matched = aspNetTimeSpanJsonRegex.exec(input),
1056
+ sign,
1057
+ ret;
1058
+
1059
+ if (isNumber) {
1060
+ if (key) {
1061
+ duration[key] = input;
1062
+ } else {
1063
+ duration.milliseconds = input;
1064
+ }
1065
+ } else if (matched) {
1066
+ sign = (matched[1] === "-") ? -1 : 1;
1067
+ duration = {
1068
+ y: 0,
1069
+ d: ~~matched[2] * sign,
1070
+ h: ~~matched[3] * sign,
1071
+ m: ~~matched[4] * sign,
1072
+ s: ~~matched[5] * sign,
1073
+ ms: ~~matched[6] * sign
1074
+ };
1075
+ }
1076
+
1077
+ ret = new Duration(duration);
1078
+
1079
+ if (isDuration && input.hasOwnProperty('_lang')) {
1080
+ ret._lang = input._lang;
1081
+ }
1082
+
1083
+ return ret;
1084
+ };
1085
+
1086
+ // version number
1087
+ moment.version = VERSION;
1088
+
1089
+ // default format
1090
+ moment.defaultFormat = isoFormat;
1091
+
1092
+ // This function will be called whenever a moment is mutated.
1093
+ // It is intended to keep the offset in sync with the timezone.
1094
+ moment.updateOffset = function () {};
1095
+
1096
+ // This function will load languages and then set the global language. If
1097
+ // no arguments are passed in, it will simply return the current global
1098
+ // language key.
1099
+ moment.lang = function (key, values) {
1100
+ if (!key) {
1101
+ return moment.fn._lang._abbr;
1102
+ }
1103
+ if (values) {
1104
+ loadLang(key, values);
1105
+ } else if (!languages[key]) {
1106
+ getLangDefinition(key);
1107
+ }
1108
+ moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1109
+ };
1110
+
1111
+ // returns language data
1112
+ moment.langData = function (key) {
1113
+ if (key && key._lang && key._lang._abbr) {
1114
+ key = key._lang._abbr;
1115
+ }
1116
+ return getLangDefinition(key);
1117
+ };
1118
+
1119
+ // compare moment object
1120
+ moment.isMoment = function (obj) {
1121
+ return obj instanceof Moment;
1122
+ };
1123
+
1124
+ // for typechecking Duration objects
1125
+ moment.isDuration = function (obj) {
1126
+ return obj instanceof Duration;
1127
+ };
1128
+
1129
+
1130
+ /************************************
1131
+ Moment Prototype
1132
+ ************************************/
1133
+
1134
+
1135
+ moment.fn = Moment.prototype = {
1136
+
1137
+ clone : function () {
1138
+ return moment(this);
1139
+ },
1140
+
1141
+ valueOf : function () {
1142
+ return +this._d + ((this._offset || 0) * 60000);
1143
+ },
1144
+
1145
+ unix : function () {
1146
+ return Math.floor(+this / 1000);
1147
+ },
1148
+
1149
+ toString : function () {
1150
+ return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1151
+ },
1152
+
1153
+ toDate : function () {
1154
+ return this._offset ? new Date(+this) : this._d;
1155
+ },
1156
+
1157
+ toISOString : function () {
1158
+ return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1159
+ },
1160
+
1161
+ toArray : function () {
1162
+ var m = this;
1163
+ return [
1164
+ m.year(),
1165
+ m.month(),
1166
+ m.date(),
1167
+ m.hours(),
1168
+ m.minutes(),
1169
+ m.seconds(),
1170
+ m.milliseconds()
1171
+ ];
1172
+ },
1173
+
1174
+ isValid : function () {
1175
+ if (this._isValid == null) {
1176
+ if (this._a) {
1177
+ this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray());
1178
+ } else {
1179
+ this._isValid = !isNaN(this._d.getTime());
1180
+ }
1181
+ }
1182
+ return !!this._isValid;
1183
+ },
1184
+
1185
+ utc : function () {
1186
+ return this.zone(0);
1187
+ },
1188
+
1189
+ local : function () {
1190
+ this.zone(0);
1191
+ this._isUTC = false;
1192
+ return this;
1193
+ },
1194
+
1195
+ format : function (inputString) {
1196
+ var output = formatMoment(this, inputString || moment.defaultFormat);
1197
+ return this.lang().postformat(output);
1198
+ },
1199
+
1200
+ add : function (input, val) {
1201
+ var dur;
1202
+ // switch args to support add('s', 1) and add(1, 's')
1203
+ if (typeof input === 'string') {
1204
+ dur = moment.duration(+val, input);
1205
+ } else {
1206
+ dur = moment.duration(input, val);
1207
+ }
1208
+ addOrSubtractDurationFromMoment(this, dur, 1);
1209
+ return this;
1210
+ },
1211
+
1212
+ subtract : function (input, val) {
1213
+ var dur;
1214
+ // switch args to support subtract('s', 1) and subtract(1, 's')
1215
+ if (typeof input === 'string') {
1216
+ dur = moment.duration(+val, input);
1217
+ } else {
1218
+ dur = moment.duration(input, val);
1219
+ }
1220
+ addOrSubtractDurationFromMoment(this, dur, -1);
1221
+ return this;
1222
+ },
1223
+
1224
+ diff : function (input, units, asFloat) {
1225
+ var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(),
1226
+ zoneDiff = (this.zone() - that.zone()) * 6e4,
1227
+ diff, output;
1228
+
1229
+ units = normalizeUnits(units);
1230
+
1231
+ if (units === 'year' || units === 'month') {
1232
+ // average number of days in the months in the given dates
1233
+ diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
1234
+ // difference in months
1235
+ output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
1236
+ // adjust by taking difference in days, average number of days
1237
+ // and dst in the given months.
1238
+ output += ((this - moment(this).startOf('month')) -
1239
+ (that - moment(that).startOf('month'))) / diff;
1240
+ // same as above but with zones, to negate all dst
1241
+ output -= ((this.zone() - moment(this).startOf('month').zone()) -
1242
+ (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
1243
+ if (units === 'year') {
1244
+ output = output / 12;
1245
+ }
1246
+ } else {
1247
+ diff = (this - that);
1248
+ output = units === 'second' ? diff / 1e3 : // 1000
1249
+ units === 'minute' ? diff / 6e4 : // 1000 * 60
1250
+ units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
1251
+ units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
1252
+ units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
1253
+ diff;
1254
+ }
1255
+ return asFloat ? output : absRound(output);
1256
+ },
1257
+
1258
+ from : function (time, withoutSuffix) {
1259
+ return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
1260
+ },
1261
+
1262
+ fromNow : function (withoutSuffix) {
1263
+ return this.from(moment(), withoutSuffix);
1264
+ },
1265
+
1266
+ calendar : function () {
1267
+ var diff = this.diff(moment().startOf('day'), 'days', true),
1268
+ format = diff < -6 ? 'sameElse' :
1269
+ diff < -1 ? 'lastWeek' :
1270
+ diff < 0 ? 'lastDay' :
1271
+ diff < 1 ? 'sameDay' :
1272
+ diff < 2 ? 'nextDay' :
1273
+ diff < 7 ? 'nextWeek' : 'sameElse';
1274
+ return this.format(this.lang().calendar(format, this));
1275
+ },
1276
+
1277
+ isLeapYear : function () {
1278
+ var year = this.year();
1279
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1280
+ },
1281
+
1282
+ isDST : function () {
1283
+ return (this.zone() < this.clone().month(0).zone() ||
1284
+ this.zone() < this.clone().month(5).zone());
1285
+ },
1286
+
1287
+ day : function (input) {
1288
+ var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1289
+ if (input != null) {
1290
+ if (typeof input === 'string') {
1291
+ input = this.lang().weekdaysParse(input);
1292
+ if (typeof input !== 'number') {
1293
+ return this;
1294
+ }
1295
+ }
1296
+ return this.add({ d : input - day });
1297
+ } else {
1298
+ return day;
1299
+ }
1300
+ },
1301
+
1302
+ month : function (input) {
1303
+ var utc = this._isUTC ? 'UTC' : '',
1304
+ dayOfMonth,
1305
+ daysInMonth;
1306
+
1307
+ if (input != null) {
1308
+ if (typeof input === 'string') {
1309
+ input = this.lang().monthsParse(input);
1310
+ if (typeof input !== 'number') {
1311
+ return this;
1312
+ }
1313
+ }
1314
+
1315
+ dayOfMonth = this.date();
1316
+ this.date(1);
1317
+ this._d['set' + utc + 'Month'](input);
1318
+ this.date(Math.min(dayOfMonth, this.daysInMonth()));
1319
+
1320
+ moment.updateOffset(this);
1321
+ return this;
1322
+ } else {
1323
+ return this._d['get' + utc + 'Month']();
1324
+ }
1325
+ },
1326
+
1327
+ startOf: function (units) {
1328
+ units = normalizeUnits(units);
1329
+ // the following switch intentionally omits break keywords
1330
+ // to utilize falling through the cases.
1331
+ switch (units) {
1332
+ case 'year':
1333
+ this.month(0);
1334
+ /* falls through */
1335
+ case 'month':
1336
+ this.date(1);
1337
+ /* falls through */
1338
+ case 'week':
1339
+ case 'day':
1340
+ this.hours(0);
1341
+ /* falls through */
1342
+ case 'hour':
1343
+ this.minutes(0);
1344
+ /* falls through */
1345
+ case 'minute':
1346
+ this.seconds(0);
1347
+ /* falls through */
1348
+ case 'second':
1349
+ this.milliseconds(0);
1350
+ /* falls through */
1351
+ }
1352
+
1353
+ // weeks are a special case
1354
+ if (units === 'week') {
1355
+ this.weekday(0);
1356
+ }
1357
+
1358
+ return this;
1359
+ },
1360
+
1361
+ endOf: function (units) {
1362
+ return this.startOf(units).add(units, 1).subtract('ms', 1);
1363
+ },
1364
+
1365
+ isAfter: function (input, units) {
1366
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1367
+ return +this.clone().startOf(units) > +moment(input).startOf(units);
1368
+ },
1369
+
1370
+ isBefore: function (input, units) {
1371
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1372
+ return +this.clone().startOf(units) < +moment(input).startOf(units);
1373
+ },
1374
+
1375
+ isSame: function (input, units) {
1376
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1377
+ return +this.clone().startOf(units) === +moment(input).startOf(units);
1378
+ },
1379
+
1380
+ min: function (other) {
1381
+ other = moment.apply(null, arguments);
1382
+ return other < this ? this : other;
1383
+ },
1384
+
1385
+ max: function (other) {
1386
+ other = moment.apply(null, arguments);
1387
+ return other > this ? this : other;
1388
+ },
1389
+
1390
+ zone : function (input) {
1391
+ var offset = this._offset || 0;
1392
+ if (input != null) {
1393
+ if (typeof input === "string") {
1394
+ input = timezoneMinutesFromString(input);
1395
+ }
1396
+ if (Math.abs(input) < 16) {
1397
+ input = input * 60;
1398
+ }
1399
+ this._offset = input;
1400
+ this._isUTC = true;
1401
+ if (offset !== input) {
1402
+ addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
1403
+ }
1404
+ } else {
1405
+ return this._isUTC ? offset : this._d.getTimezoneOffset();
1406
+ }
1407
+ return this;
1408
+ },
1409
+
1410
+ zoneAbbr : function () {
1411
+ return this._isUTC ? "UTC" : "";
1412
+ },
1413
+
1414
+ zoneName : function () {
1415
+ return this._isUTC ? "Coordinated Universal Time" : "";
1416
+ },
1417
+
1418
+ daysInMonth : function () {
1419
+ return moment.utc([this.year(), this.month() + 1, 0]).date();
1420
+ },
1421
+
1422
+ dayOfYear : function (input) {
1423
+ var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
1424
+ return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
1425
+ },
1426
+
1427
+ weekYear : function (input) {
1428
+ var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
1429
+ return input == null ? year : this.add("y", (input - year));
1430
+ },
1431
+
1432
+ isoWeekYear : function (input) {
1433
+ var year = weekOfYear(this, 1, 4).year;
1434
+ return input == null ? year : this.add("y", (input - year));
1435
+ },
1436
+
1437
+ week : function (input) {
1438
+ var week = this.lang().week(this);
1439
+ return input == null ? week : this.add("d", (input - week) * 7);
1440
+ },
1441
+
1442
+ isoWeek : function (input) {
1443
+ var week = weekOfYear(this, 1, 4).week;
1444
+ return input == null ? week : this.add("d", (input - week) * 7);
1445
+ },
1446
+
1447
+ weekday : function (input) {
1448
+ var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
1449
+ return input == null ? weekday : this.add("d", input - weekday);
1450
+ },
1451
+
1452
+ isoWeekday : function (input) {
1453
+ // behaves the same as moment#day except
1454
+ // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1455
+ // as a setter, sunday should belong to the previous week.
1456
+ return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
1457
+ },
1458
+
1459
+ // If passed a language key, it will set the language for this
1460
+ // instance. Otherwise, it will return the language configuration
1461
+ // variables for this instance.
1462
+ lang : function (key) {
1463
+ if (key === undefined) {
1464
+ return this._lang;
1465
+ } else {
1466
+ this._lang = getLangDefinition(key);
1467
+ return this;
1468
+ }
1469
+ }
1470
+ };
1471
+
1472
+ // helper for adding shortcuts
1473
+ function makeGetterAndSetter(name, key) {
1474
+ moment.fn[name] = moment.fn[name + 's'] = function (input) {
1475
+ var utc = this._isUTC ? 'UTC' : '';
1476
+ if (input != null) {
1477
+ this._d['set' + utc + key](input);
1478
+ moment.updateOffset(this);
1479
+ return this;
1480
+ } else {
1481
+ return this._d['get' + utc + key]();
1482
+ }
1483
+ };
1484
+ }
1485
+
1486
+ // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
1487
+ for (i = 0; i < proxyGettersAndSetters.length; i ++) {
1488
+ makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
1489
+ }
1490
+
1491
+ // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
1492
+ makeGetterAndSetter('year', 'FullYear');
1493
+
1494
+ // add plural methods
1495
+ moment.fn.days = moment.fn.day;
1496
+ moment.fn.months = moment.fn.month;
1497
+ moment.fn.weeks = moment.fn.week;
1498
+ moment.fn.isoWeeks = moment.fn.isoWeek;
1499
+
1500
+ // add aliased format methods
1501
+ moment.fn.toJSON = moment.fn.toISOString;
1502
+
1503
+ /************************************
1504
+ Duration Prototype
1505
+ ************************************/
1506
+
1507
+
1508
+ moment.duration.fn = Duration.prototype = {
1509
+ _bubble : function () {
1510
+ var milliseconds = this._milliseconds,
1511
+ days = this._days,
1512
+ months = this._months,
1513
+ data = this._data,
1514
+ seconds, minutes, hours, years;
1515
+
1516
+ // The following code bubbles up values, see the tests for
1517
+ // examples of what that means.
1518
+ data.milliseconds = milliseconds % 1000;
1519
+
1520
+ seconds = absRound(milliseconds / 1000);
1521
+ data.seconds = seconds % 60;
1522
+
1523
+ minutes = absRound(seconds / 60);
1524
+ data.minutes = minutes % 60;
1525
+
1526
+ hours = absRound(minutes / 60);
1527
+ data.hours = hours % 24;
1528
+
1529
+ days += absRound(hours / 24);
1530
+ data.days = days % 30;
1531
+
1532
+ months += absRound(days / 30);
1533
+ data.months = months % 12;
1534
+
1535
+ years = absRound(months / 12);
1536
+ data.years = years;
1537
+ },
1538
+
1539
+ weeks : function () {
1540
+ return absRound(this.days() / 7);
1541
+ },
1542
+
1543
+ valueOf : function () {
1544
+ return this._milliseconds +
1545
+ this._days * 864e5 +
1546
+ (this._months % 12) * 2592e6 +
1547
+ ~~(this._months / 12) * 31536e6;
1548
+ },
1549
+
1550
+ humanize : function (withSuffix) {
1551
+ var difference = +this,
1552
+ output = relativeTime(difference, !withSuffix, this.lang());
1553
+
1554
+ if (withSuffix) {
1555
+ output = this.lang().pastFuture(difference, output);
1556
+ }
1557
+
1558
+ return this.lang().postformat(output);
1559
+ },
1560
+
1561
+ add : function (input, val) {
1562
+ // supports only 2.0-style add(1, 's') or add(moment)
1563
+ var dur = moment.duration(input, val);
1564
+
1565
+ this._milliseconds += dur._milliseconds;
1566
+ this._days += dur._days;
1567
+ this._months += dur._months;
1568
+
1569
+ this._bubble();
1570
+
1571
+ return this;
1572
+ },
1573
+
1574
+ subtract : function (input, val) {
1575
+ var dur = moment.duration(input, val);
1576
+
1577
+ this._milliseconds -= dur._milliseconds;
1578
+ this._days -= dur._days;
1579
+ this._months -= dur._months;
1580
+
1581
+ this._bubble();
1582
+
1583
+ return this;
1584
+ },
1585
+
1586
+ get : function (units) {
1587
+ units = normalizeUnits(units);
1588
+ return this[units.toLowerCase() + 's']();
1589
+ },
1590
+
1591
+ as : function (units) {
1592
+ units = normalizeUnits(units);
1593
+ return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
1594
+ },
1595
+
1596
+ lang : moment.fn.lang
1597
+ };
1598
+
1599
+ function makeDurationGetter(name) {
1600
+ moment.duration.fn[name] = function () {
1601
+ return this._data[name];
1602
+ };
1603
+ }
1604
+
1605
+ function makeDurationAsGetter(name, factor) {
1606
+ moment.duration.fn['as' + name] = function () {
1607
+ return +this / factor;
1608
+ };
1609
+ }
1610
+
1611
+ for (i in unitMillisecondFactors) {
1612
+ if (unitMillisecondFactors.hasOwnProperty(i)) {
1613
+ makeDurationAsGetter(i, unitMillisecondFactors[i]);
1614
+ makeDurationGetter(i.toLowerCase());
1615
+ }
1616
+ }
1617
+
1618
+ makeDurationAsGetter('Weeks', 6048e5);
1619
+ moment.duration.fn.asMonths = function () {
1620
+ return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
1621
+ };
1622
+
1623
+
1624
+ /************************************
1625
+ Default Lang
1626
+ ************************************/
1627
+
1628
+
1629
+ // Set default language, other languages will inherit from English.
1630
+ moment.lang('en', {
1631
+ ordinal : function (number) {
1632
+ var b = number % 10,
1633
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
1634
+ (b === 1) ? 'st' :
1635
+ (b === 2) ? 'nd' :
1636
+ (b === 3) ? 'rd' : 'th';
1637
+ return number + output;
1638
+ }
1639
+ });
1640
+
1641
+
1642
+ /************************************
1643
+ Exposing Moment
1644
+ ************************************/
1645
+
1646
+
1647
+ // CommonJS module is defined
1648
+ if (hasModule) {
1649
+ module.exports = moment;
1650
+ }
1651
+ /*global ender:false */
1652
+ if (typeof ender === 'undefined') {
1653
+ // here, `this` means `window` in the browser, or `global` on the server
1654
+ // add `moment` as a global object via a string identifier,
1655
+ // for Closure Compiler "advanced" mode
1656
+ this['moment'] = moment;
1657
+ }
1658
+ /*global define:false */
1659
+ if (typeof define === "function" && define.amd) {
1660
+ define("moment", [], function () {
1661
+ return moment;
1662
+ });
1663
+ }
1664
+ }).call(this);