rsence-pre 2.3.0.16 → 2.3.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/VERSION +1 -1
  2. data/conf/default_conf.yaml +53 -200
  3. data/js/chat/chat_panel/chat_panel.coffee +120 -0
  4. data/js/chat/speech_bubble/speech_bubble.coffee +56 -0
  5. data/js/chat/speech_bubble/themes/default/speech_bubble.css +84 -0
  6. data/js/chat/speech_bubble/themes/default/speech_bubble.html +7 -0
  7. data/js/chat/speech_bubble/themes/default/user_anon.png +0 -0
  8. data/js/comm/sessionwatcher/sessionwatcher.js +1 -1
  9. data/js/comm/values/values.js +2 -34
  10. data/js/controls/numerictextcontrol/numerictextcontrol.coffee +109 -0
  11. data/js/controls/onoffbutton/onoffbutton.coffee +44 -0
  12. data/js/controls/onoffbutton/themes/default/onoffbutton.css +50 -0
  13. data/js/controls/onoffbutton/themes/default/onoffbutton.html +10 -0
  14. data/js/controls/textcontrol/textcontrol.coffee +291 -0
  15. data/js/core/class/class.js +1 -1
  16. data/js/core/elem/elem.coffee +83 -1
  17. data/js/core/util/util_methods/util_methods.coffee +103 -0
  18. data/js/datetime/calendar/calendar.coffee +3 -0
  19. data/js/datetime/calendar_pulldown/calendar_pulldown.coffee +62 -0
  20. data/js/datetime/calendar_pulldown/themes/default/calendar_pulldown.css +16 -0
  21. data/js/datetime/calendar_pulldown/themes/default/calendar_pulldown.html +1 -0
  22. data/js/datetime/calendar_pulldown/themes/default/calendar_pulldown.png +0 -0
  23. data/js/datetime/datepicker/datepicker.coffee +59 -0
  24. data/js/datetime/datetimepicker/datetimepicker.coffee +7 -0
  25. data/js/datetime/datetimepicker/datetimepicker.js +2 -2
  26. data/js/datetime/momentjs/momentjs.js +1400 -0
  27. data/js/datetime/timepicker/timepicker.coffee +7 -0
  28. data/js/foundation/application/application.js +1 -1
  29. data/js/foundation/control/valueaction/valueaction.js +8 -1
  30. data/js/foundation/control/valueresponder/valueresponder.js +1 -1
  31. data/js/foundation/view/morphanimation/morphanimation.js +9 -3
  32. data/js/foundation/view/view.js +43 -33
  33. data/js/views/scrollview/scrollview.js +10 -0
  34. data/lib/rsence/default_config.rb +10 -6
  35. data/plugins/client_pkg/lib/client_pkg_build.rb +2 -2
  36. metadata +22 -4
  37. data/js/controls/textcontrol/textcontrol.js +0 -420
@@ -0,0 +1,1400 @@
1
+ // moment.js
2
+ // version : 2.0.0
3
+ // author : Tim Wood
4
+ // license : MIT
5
+ // momentjs.com
6
+
7
+ (function (undefined) {
8
+
9
+ /************************************
10
+ Constants
11
+ ************************************/
12
+
13
+ var moment,
14
+ VERSION = "2.0.0",
15
+ round = Math.round, i,
16
+ // internal storage for language config files
17
+ languages = {},
18
+
19
+ // check for nodeJS
20
+ hasModule = (typeof module !== 'undefined' && module.exports),
21
+
22
+ // ASP.NET json date format regex
23
+ aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
24
+
25
+ // format tokens
26
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
27
+ localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
28
+
29
+ // parsing tokens
30
+ parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,
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]+/i, // any word (or two) characters or numbers including two 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 = 'Month|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
+ // format function strings
72
+ formatFunctions = {},
73
+
74
+ // tokens to ordinalize and pad
75
+ ordinalizeTokens = 'DDD w W M D d'.split(' '),
76
+ paddedTokens = 'M D H h m s w W'.split(' '),
77
+
78
+ formatTokenFunctions = {
79
+ M : function () {
80
+ return this.month() + 1;
81
+ },
82
+ MMM : function (format) {
83
+ return this.lang().monthsShort(this, format);
84
+ },
85
+ MMMM : function (format) {
86
+ return this.lang().months(this, format);
87
+ },
88
+ D : function () {
89
+ return this.date();
90
+ },
91
+ DDD : function () {
92
+ return this.dayOfYear();
93
+ },
94
+ d : function () {
95
+ return this.day();
96
+ },
97
+ dd : function (format) {
98
+ return this.lang().weekdaysMin(this, format);
99
+ },
100
+ ddd : function (format) {
101
+ return this.lang().weekdaysShort(this, format);
102
+ },
103
+ dddd : function (format) {
104
+ return this.lang().weekdays(this, format);
105
+ },
106
+ w : function () {
107
+ return this.week();
108
+ },
109
+ W : function () {
110
+ return this.isoWeek();
111
+ },
112
+ YY : function () {
113
+ return leftZeroFill(this.year() % 100, 2);
114
+ },
115
+ YYYY : function () {
116
+ return leftZeroFill(this.year(), 4);
117
+ },
118
+ YYYYY : function () {
119
+ return leftZeroFill(this.year(), 5);
120
+ },
121
+ a : function () {
122
+ return this.lang().meridiem(this.hours(), this.minutes(), true);
123
+ },
124
+ A : function () {
125
+ return this.lang().meridiem(this.hours(), this.minutes(), false);
126
+ },
127
+ H : function () {
128
+ return this.hours();
129
+ },
130
+ h : function () {
131
+ return this.hours() % 12 || 12;
132
+ },
133
+ m : function () {
134
+ return this.minutes();
135
+ },
136
+ s : function () {
137
+ return this.seconds();
138
+ },
139
+ S : function () {
140
+ return ~~(this.milliseconds() / 100);
141
+ },
142
+ SS : function () {
143
+ return leftZeroFill(~~(this.milliseconds() / 10), 2);
144
+ },
145
+ SSS : function () {
146
+ return leftZeroFill(this.milliseconds(), 3);
147
+ },
148
+ Z : function () {
149
+ var a = -this.zone(),
150
+ b = "+";
151
+ if (a < 0) {
152
+ a = -a;
153
+ b = "-";
154
+ }
155
+ return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
156
+ },
157
+ ZZ : function () {
158
+ var a = -this.zone(),
159
+ b = "+";
160
+ if (a < 0) {
161
+ a = -a;
162
+ b = "-";
163
+ }
164
+ return b + leftZeroFill(~~(10 * a / 6), 4);
165
+ },
166
+ X : function () {
167
+ return this.unix();
168
+ }
169
+ };
170
+
171
+ function padToken(func, count) {
172
+ return function (a) {
173
+ return leftZeroFill(func.call(this, a), count);
174
+ };
175
+ }
176
+ function ordinalizeToken(func) {
177
+ return function (a) {
178
+ return this.lang().ordinal(func.call(this, a));
179
+ };
180
+ }
181
+
182
+ while (ordinalizeTokens.length) {
183
+ i = ordinalizeTokens.pop();
184
+ formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]);
185
+ }
186
+ while (paddedTokens.length) {
187
+ i = paddedTokens.pop();
188
+ formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
189
+ }
190
+ formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
191
+
192
+
193
+ /************************************
194
+ Constructors
195
+ ************************************/
196
+
197
+ function Language() {
198
+
199
+ }
200
+
201
+ // Moment prototype object
202
+ function Moment(config) {
203
+ extend(this, config);
204
+ }
205
+
206
+ // Duration Constructor
207
+ function Duration(duration) {
208
+ var data = this._data = {},
209
+ years = duration.years || duration.year || duration.y || 0,
210
+ months = duration.months || duration.month || duration.M || 0,
211
+ weeks = duration.weeks || duration.week || duration.w || 0,
212
+ days = duration.days || duration.day || duration.d || 0,
213
+ hours = duration.hours || duration.hour || duration.h || 0,
214
+ minutes = duration.minutes || duration.minute || duration.m || 0,
215
+ seconds = duration.seconds || duration.second || duration.s || 0,
216
+ milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
217
+
218
+ // representation for dateAddRemove
219
+ this._milliseconds = milliseconds +
220
+ seconds * 1e3 + // 1000
221
+ minutes * 6e4 + // 1000 * 60
222
+ hours * 36e5; // 1000 * 60 * 60
223
+ // Because of dateAddRemove treats 24 hours as different from a
224
+ // day when working around DST, we need to store them separately
225
+ this._days = days +
226
+ weeks * 7;
227
+ // It is impossible translate months into days without knowing
228
+ // which months you are are talking about, so we have to store
229
+ // it separately.
230
+ this._months = months +
231
+ years * 12;
232
+
233
+ // The following code bubbles up values, see the tests for
234
+ // examples of what that means.
235
+ data.milliseconds = milliseconds % 1000;
236
+ seconds += absRound(milliseconds / 1000);
237
+
238
+ data.seconds = seconds % 60;
239
+ minutes += absRound(seconds / 60);
240
+
241
+ data.minutes = minutes % 60;
242
+ hours += absRound(minutes / 60);
243
+
244
+ data.hours = hours % 24;
245
+ days += absRound(hours / 24);
246
+
247
+ days += weeks * 7;
248
+ data.days = days % 30;
249
+
250
+ months += absRound(days / 30);
251
+
252
+ data.months = months % 12;
253
+ years += absRound(months / 12);
254
+
255
+ data.years = years;
256
+ }
257
+
258
+
259
+ /************************************
260
+ Helpers
261
+ ************************************/
262
+
263
+
264
+ function extend(a, b) {
265
+ for (var i in b) {
266
+ if (b.hasOwnProperty(i)) {
267
+ a[i] = b[i];
268
+ }
269
+ }
270
+ return a;
271
+ }
272
+
273
+ function absRound(number) {
274
+ if (number < 0) {
275
+ return Math.ceil(number);
276
+ } else {
277
+ return Math.floor(number);
278
+ }
279
+ }
280
+
281
+ // left zero fill a number
282
+ // see http://jsperf.com/left-zero-filling for performance comparison
283
+ function leftZeroFill(number, targetLength) {
284
+ var output = number + '';
285
+ while (output.length < targetLength) {
286
+ output = '0' + output;
287
+ }
288
+ return output;
289
+ }
290
+
291
+ // helper function for _.addTime and _.subtractTime
292
+ function addOrSubtractDurationFromMoment(mom, duration, isAdding) {
293
+ var ms = duration._milliseconds,
294
+ d = duration._days,
295
+ M = duration._months,
296
+ currentDate;
297
+
298
+ if (ms) {
299
+ mom._d.setTime(+mom + ms * isAdding);
300
+ }
301
+ if (d) {
302
+ mom.date(mom.date() + d * isAdding);
303
+ }
304
+ if (M) {
305
+ currentDate = mom.date();
306
+ mom.date(1)
307
+ .month(mom.month() + M * isAdding)
308
+ .date(Math.min(currentDate, mom.daysInMonth()));
309
+ }
310
+ }
311
+
312
+ // check if is an array
313
+ function isArray(input) {
314
+ return Object.prototype.toString.call(input) === '[object Array]';
315
+ }
316
+
317
+ // compare two arrays, return the number of differences
318
+ function compareArrays(array1, array2) {
319
+ var len = Math.min(array1.length, array2.length),
320
+ lengthDiff = Math.abs(array1.length - array2.length),
321
+ diffs = 0,
322
+ i;
323
+ for (i = 0; i < len; i++) {
324
+ if (~~array1[i] !== ~~array2[i]) {
325
+ diffs++;
326
+ }
327
+ }
328
+ return diffs + lengthDiff;
329
+ }
330
+
331
+
332
+ /************************************
333
+ Languages
334
+ ************************************/
335
+
336
+
337
+ Language.prototype = {
338
+ set : function (config) {
339
+ var prop, i;
340
+ for (i in config) {
341
+ prop = config[i];
342
+ if (typeof prop === 'function') {
343
+ this[i] = prop;
344
+ } else {
345
+ this['_' + i] = prop;
346
+ }
347
+ }
348
+ },
349
+
350
+ _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
351
+ months : function (m) {
352
+ return this._months[m.month()];
353
+ },
354
+
355
+ _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
356
+ monthsShort : function (m) {
357
+ return this._monthsShort[m.month()];
358
+ },
359
+
360
+ monthsParse : function (monthName) {
361
+ var i, mom, regex, output;
362
+
363
+ if (!this._monthsParse) {
364
+ this._monthsParse = [];
365
+ }
366
+
367
+ for (i = 0; i < 12; i++) {
368
+ // make the regex if we don't have it already
369
+ if (!this._monthsParse[i]) {
370
+ mom = moment([2000, i]);
371
+ regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
372
+ this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
373
+ }
374
+ // test the regex
375
+ if (this._monthsParse[i].test(monthName)) {
376
+ return i;
377
+ }
378
+ }
379
+ },
380
+
381
+ _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
382
+ weekdays : function (m) {
383
+ return this._weekdays[m.day()];
384
+ },
385
+
386
+ _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
387
+ weekdaysShort : function (m) {
388
+ return this._weekdaysShort[m.day()];
389
+ },
390
+
391
+ _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
392
+ weekdaysMin : function (m) {
393
+ return this._weekdaysMin[m.day()];
394
+ },
395
+
396
+ _longDateFormat : {
397
+ LT : "h:mm A",
398
+ L : "MM/DD/YYYY",
399
+ LL : "MMMM D YYYY",
400
+ LLL : "MMMM D YYYY LT",
401
+ LLLL : "dddd, MMMM D YYYY LT"
402
+ },
403
+ longDateFormat : function (key) {
404
+ var output = this._longDateFormat[key];
405
+ if (!output && this._longDateFormat[key.toUpperCase()]) {
406
+ output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
407
+ return val.slice(1);
408
+ });
409
+ this._longDateFormat[key] = output;
410
+ }
411
+ return output;
412
+ },
413
+
414
+ meridiem : function (hours, minutes, isLower) {
415
+ if (hours > 11) {
416
+ return isLower ? 'pm' : 'PM';
417
+ } else {
418
+ return isLower ? 'am' : 'AM';
419
+ }
420
+ },
421
+
422
+ _calendar : {
423
+ sameDay : '[Today at] LT',
424
+ nextDay : '[Tomorrow at] LT',
425
+ nextWeek : 'dddd [at] LT',
426
+ lastDay : '[Yesterday at] LT',
427
+ lastWeek : '[last] dddd [at] LT',
428
+ sameElse : 'L'
429
+ },
430
+ calendar : function (key, mom) {
431
+ var output = this._calendar[key];
432
+ return typeof output === 'function' ? output.apply(mom) : output;
433
+ },
434
+
435
+ _relativeTime : {
436
+ future : "in %s",
437
+ past : "%s ago",
438
+ s : "a few seconds",
439
+ m : "a minute",
440
+ mm : "%d minutes",
441
+ h : "an hour",
442
+ hh : "%d hours",
443
+ d : "a day",
444
+ dd : "%d days",
445
+ M : "a month",
446
+ MM : "%d months",
447
+ y : "a year",
448
+ yy : "%d years"
449
+ },
450
+ relativeTime : function (number, withoutSuffix, string, isFuture) {
451
+ var output = this._relativeTime[string];
452
+ return (typeof output === 'function') ?
453
+ output(number, withoutSuffix, string, isFuture) :
454
+ output.replace(/%d/i, number);
455
+ },
456
+ pastFuture : function (diff, output) {
457
+ var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
458
+ return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
459
+ },
460
+
461
+ ordinal : function (number) {
462
+ return this._ordinal.replace("%d", number);
463
+ },
464
+ _ordinal : "%d",
465
+
466
+ preparse : function (string) {
467
+ return string;
468
+ },
469
+
470
+ postformat : function (string) {
471
+ return string;
472
+ },
473
+
474
+ week : function (mom) {
475
+ return weekOfYear(mom, this._week.dow, this._week.doy);
476
+ },
477
+ _week : {
478
+ dow : 0, // Sunday is the first day of the week.
479
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
480
+ }
481
+ };
482
+
483
+ // Loads a language definition into the `languages` cache. The function
484
+ // takes a key and optionally values. If not in the browser and no values
485
+ // are provided, it will load the language file module. As a convenience,
486
+ // this function also returns the language values.
487
+ function loadLang(key, values) {
488
+ values.abbr = key;
489
+ if (!languages[key]) {
490
+ languages[key] = new Language();
491
+ }
492
+ languages[key].set(values);
493
+ return languages[key];
494
+ }
495
+
496
+ // Determines which language definition to use and returns it.
497
+ //
498
+ // With no parameters, it will return the global language. If you
499
+ // pass in a language key, such as 'en', it will return the
500
+ // definition for 'en', so long as 'en' has already been loaded using
501
+ // moment.lang.
502
+ function getLangDefinition(key) {
503
+ if (!key) {
504
+ return moment.fn._lang;
505
+ }
506
+ if (!languages[key] && hasModule) {
507
+ require('./lang/' + key);
508
+ }
509
+ return languages[key];
510
+ }
511
+
512
+
513
+ /************************************
514
+ Formatting
515
+ ************************************/
516
+
517
+
518
+ function removeFormattingTokens(input) {
519
+ if (input.match(/\[.*\]/)) {
520
+ return input.replace(/^\[|\]$/g, "");
521
+ }
522
+ return input.replace(/\\/g, "");
523
+ }
524
+
525
+ function makeFormatFunction(format) {
526
+ var array = format.match(formattingTokens), i, length;
527
+
528
+ for (i = 0, length = array.length; i < length; i++) {
529
+ if (formatTokenFunctions[array[i]]) {
530
+ array[i] = formatTokenFunctions[array[i]];
531
+ } else {
532
+ array[i] = removeFormattingTokens(array[i]);
533
+ }
534
+ }
535
+
536
+ return function (mom) {
537
+ var output = "";
538
+ for (i = 0; i < length; i++) {
539
+ output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i];
540
+ }
541
+ return output;
542
+ };
543
+ }
544
+
545
+ // format date using native date object
546
+ function formatMoment(m, format) {
547
+ var i = 5;
548
+
549
+ function replaceLongDateFormatTokens(input) {
550
+ return m.lang().longDateFormat(input) || input;
551
+ }
552
+
553
+ while (i-- && localFormattingTokens.test(format)) {
554
+ format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
555
+ }
556
+
557
+ if (!formatFunctions[format]) {
558
+ formatFunctions[format] = makeFormatFunction(format);
559
+ }
560
+
561
+ return formatFunctions[format](m);
562
+ }
563
+
564
+
565
+ /************************************
566
+ Parsing
567
+ ************************************/
568
+
569
+
570
+ // get the regex to find the next token
571
+ function getParseRegexForToken(token) {
572
+ switch (token) {
573
+ case 'DDDD':
574
+ return parseTokenThreeDigits;
575
+ case 'YYYY':
576
+ return parseTokenFourDigits;
577
+ case 'YYYYY':
578
+ return parseTokenSixDigits;
579
+ case 'S':
580
+ case 'SS':
581
+ case 'SSS':
582
+ case 'DDD':
583
+ return parseTokenOneToThreeDigits;
584
+ case 'MMM':
585
+ case 'MMMM':
586
+ case 'dd':
587
+ case 'ddd':
588
+ case 'dddd':
589
+ case 'a':
590
+ case 'A':
591
+ return parseTokenWord;
592
+ case 'X':
593
+ return parseTokenTimestampMs;
594
+ case 'Z':
595
+ case 'ZZ':
596
+ return parseTokenTimezone;
597
+ case 'T':
598
+ return parseTokenT;
599
+ case 'MM':
600
+ case 'DD':
601
+ case 'YY':
602
+ case 'HH':
603
+ case 'hh':
604
+ case 'mm':
605
+ case 'ss':
606
+ case 'M':
607
+ case 'D':
608
+ case 'd':
609
+ case 'H':
610
+ case 'h':
611
+ case 'm':
612
+ case 's':
613
+ return parseTokenOneOrTwoDigits;
614
+ default :
615
+ return new RegExp(token.replace('\\', ''));
616
+ }
617
+ }
618
+
619
+ // function to convert string input to date
620
+ function addTimeToArrayFromToken(token, input, config) {
621
+ var a, b,
622
+ datePartArray = config._a;
623
+
624
+ switch (token) {
625
+ // MONTH
626
+ case 'M' : // fall through to MM
627
+ case 'MM' :
628
+ datePartArray[1] = (input == null) ? 0 : ~~input - 1;
629
+ break;
630
+ case 'MMM' : // fall through to MMMM
631
+ case 'MMMM' :
632
+ a = getLangDefinition(config._l).monthsParse(input);
633
+ // if we didn't find a month name, mark the date as invalid.
634
+ if (a != null) {
635
+ datePartArray[1] = a;
636
+ } else {
637
+ config._isValid = false;
638
+ }
639
+ break;
640
+ // DAY OF MONTH
641
+ case 'D' : // fall through to DDDD
642
+ case 'DD' : // fall through to DDDD
643
+ case 'DDD' : // fall through to DDDD
644
+ case 'DDDD' :
645
+ if (input != null) {
646
+ datePartArray[2] = ~~input;
647
+ }
648
+ break;
649
+ // YEAR
650
+ case 'YY' :
651
+ datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
652
+ break;
653
+ case 'YYYY' :
654
+ case 'YYYYY' :
655
+ datePartArray[0] = ~~input;
656
+ break;
657
+ // AM / PM
658
+ case 'a' : // fall through to A
659
+ case 'A' :
660
+ config._isPm = ((input + '').toLowerCase() === 'pm');
661
+ break;
662
+ // 24 HOUR
663
+ case 'H' : // fall through to hh
664
+ case 'HH' : // fall through to hh
665
+ case 'h' : // fall through to hh
666
+ case 'hh' :
667
+ datePartArray[3] = ~~input;
668
+ break;
669
+ // MINUTE
670
+ case 'm' : // fall through to mm
671
+ case 'mm' :
672
+ datePartArray[4] = ~~input;
673
+ break;
674
+ // SECOND
675
+ case 's' : // fall through to ss
676
+ case 'ss' :
677
+ datePartArray[5] = ~~input;
678
+ break;
679
+ // MILLISECOND
680
+ case 'S' :
681
+ case 'SS' :
682
+ case 'SSS' :
683
+ datePartArray[6] = ~~ (('0.' + input) * 1000);
684
+ break;
685
+ // UNIX TIMESTAMP WITH MS
686
+ case 'X':
687
+ config._d = new Date(parseFloat(input) * 1000);
688
+ break;
689
+ // TIMEZONE
690
+ case 'Z' : // fall through to ZZ
691
+ case 'ZZ' :
692
+ config._useUTC = true;
693
+ a = (input + '').match(parseTimezoneChunker);
694
+ if (a && a[1]) {
695
+ config._tzh = ~~a[1];
696
+ }
697
+ if (a && a[2]) {
698
+ config._tzm = ~~a[2];
699
+ }
700
+ // reverse offsets
701
+ if (a && a[0] === '+') {
702
+ config._tzh = -config._tzh;
703
+ config._tzm = -config._tzm;
704
+ }
705
+ break;
706
+ }
707
+
708
+ // if the input is null, the date is not valid
709
+ if (input == null) {
710
+ config._isValid = false;
711
+ }
712
+ }
713
+
714
+ // convert an array to a date.
715
+ // the array should mirror the parameters below
716
+ // note: all values past the year are optional and will default to the lowest possible value.
717
+ // [year, month, day , hour, minute, second, millisecond]
718
+ function dateFromArray(config) {
719
+ var i, date, input = [];
720
+
721
+ if (config._d) {
722
+ return;
723
+ }
724
+
725
+ for (i = 0; i < 7; i++) {
726
+ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
727
+ }
728
+
729
+ // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
730
+ input[3] += config._tzh || 0;
731
+ input[4] += config._tzm || 0;
732
+
733
+ date = new Date(0);
734
+
735
+ if (config._useUTC) {
736
+ date.setUTCFullYear(input[0], input[1], input[2]);
737
+ date.setUTCHours(input[3], input[4], input[5], input[6]);
738
+ } else {
739
+ date.setFullYear(input[0], input[1], input[2]);
740
+ date.setHours(input[3], input[4], input[5], input[6]);
741
+ }
742
+
743
+ config._d = date;
744
+ }
745
+
746
+ // date from string and format string
747
+ function makeDateFromStringAndFormat(config) {
748
+ // This array is used to make a Date, either with `new Date` or `Date.UTC`
749
+ var tokens = config._f.match(formattingTokens),
750
+ string = config._i,
751
+ i, parsedInput;
752
+
753
+ config._a = [];
754
+
755
+ for (i = 0; i < tokens.length; i++) {
756
+ parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0];
757
+ if (parsedInput) {
758
+ string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
759
+ }
760
+ // don't parse if its not a known token
761
+ if (formatTokenFunctions[tokens[i]]) {
762
+ addTimeToArrayFromToken(tokens[i], parsedInput, config);
763
+ }
764
+ }
765
+ // handle am pm
766
+ if (config._isPm && config._a[3] < 12) {
767
+ config._a[3] += 12;
768
+ }
769
+ // if is 12 am, change hours to 0
770
+ if (config._isPm === false && config._a[3] === 12) {
771
+ config._a[3] = 0;
772
+ }
773
+ // return
774
+ dateFromArray(config);
775
+ }
776
+
777
+ // date from string and array of format strings
778
+ function makeDateFromStringAndArray(config) {
779
+ var tempConfig,
780
+ tempMoment,
781
+ bestMoment,
782
+
783
+ scoreToBeat = 99,
784
+ i,
785
+ currentDate,
786
+ currentScore;
787
+
788
+ while (config._f.length) {
789
+ tempConfig = extend({}, config);
790
+ tempConfig._f = config._f.pop();
791
+ makeDateFromStringAndFormat(tempConfig);
792
+ tempMoment = new Moment(tempConfig);
793
+
794
+ if (tempMoment.isValid()) {
795
+ bestMoment = tempMoment;
796
+ break;
797
+ }
798
+
799
+ currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
800
+
801
+ if (currentScore < scoreToBeat) {
802
+ scoreToBeat = currentScore;
803
+ bestMoment = tempMoment;
804
+ }
805
+ }
806
+
807
+ extend(config, bestMoment);
808
+ }
809
+
810
+ // date from iso format
811
+ function makeDateFromString(config) {
812
+ var i,
813
+ string = config._i;
814
+ if (isoRegex.exec(string)) {
815
+ config._f = 'YYYY-MM-DDT';
816
+ for (i = 0; i < 4; i++) {
817
+ if (isoTimes[i][1].exec(string)) {
818
+ config._f += isoTimes[i][0];
819
+ break;
820
+ }
821
+ }
822
+ if (parseTokenTimezone.exec(string)) {
823
+ config._f += " Z";
824
+ }
825
+ makeDateFromStringAndFormat(config);
826
+ } else {
827
+ config._d = new Date(string);
828
+ }
829
+ }
830
+
831
+ function makeDateFromInput(config) {
832
+ var input = config._i,
833
+ matched = aspNetJsonRegex.exec(input);
834
+
835
+ if (input === undefined) {
836
+ config._d = new Date();
837
+ } else if (matched) {
838
+ config._d = new Date(+matched[1]);
839
+ } else if (typeof input === 'string') {
840
+ makeDateFromString(config);
841
+ } else if (isArray(input)) {
842
+ config._a = input.slice(0);
843
+ dateFromArray(config);
844
+ } else {
845
+ config._d = input instanceof Date ? new Date(+input) : new Date(input);
846
+ }
847
+ }
848
+
849
+
850
+ /************************************
851
+ Relative Time
852
+ ************************************/
853
+
854
+
855
+ // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
856
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
857
+ return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
858
+ }
859
+
860
+ function relativeTime(milliseconds, withoutSuffix, lang) {
861
+ var seconds = round(Math.abs(milliseconds) / 1000),
862
+ minutes = round(seconds / 60),
863
+ hours = round(minutes / 60),
864
+ days = round(hours / 24),
865
+ years = round(days / 365),
866
+ args = seconds < 45 && ['s', seconds] ||
867
+ minutes === 1 && ['m'] ||
868
+ minutes < 45 && ['mm', minutes] ||
869
+ hours === 1 && ['h'] ||
870
+ hours < 22 && ['hh', hours] ||
871
+ days === 1 && ['d'] ||
872
+ days <= 25 && ['dd', days] ||
873
+ days <= 45 && ['M'] ||
874
+ days < 345 && ['MM', round(days / 30)] ||
875
+ years === 1 && ['y'] || ['yy', years];
876
+ args[2] = withoutSuffix;
877
+ args[3] = milliseconds > 0;
878
+ args[4] = lang;
879
+ return substituteTimeAgo.apply({}, args);
880
+ }
881
+
882
+
883
+ /************************************
884
+ Week of Year
885
+ ************************************/
886
+
887
+
888
+ // firstDayOfWeek 0 = sun, 6 = sat
889
+ // the day of the week that starts the week
890
+ // (usually sunday or monday)
891
+ // firstDayOfWeekOfYear 0 = sun, 6 = sat
892
+ // the first week is the week that contains the first
893
+ // of this day of the week
894
+ // (eg. ISO weeks use thursday (4))
895
+ function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
896
+ var end = firstDayOfWeekOfYear - firstDayOfWeek,
897
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day();
898
+
899
+
900
+ if (daysToDayOfWeek > end) {
901
+ daysToDayOfWeek -= 7;
902
+ }
903
+
904
+ if (daysToDayOfWeek < end - 7) {
905
+ daysToDayOfWeek += 7;
906
+ }
907
+
908
+ return Math.ceil(moment(mom).add('d', daysToDayOfWeek).dayOfYear() / 7);
909
+ }
910
+
911
+
912
+ /************************************
913
+ Top Level Functions
914
+ ************************************/
915
+
916
+ function makeMoment(config) {
917
+ var input = config._i,
918
+ format = config._f;
919
+
920
+ if (input === null || input === '') {
921
+ return null;
922
+ }
923
+
924
+ if (typeof input === 'string') {
925
+ config._i = input = getLangDefinition().preparse(input);
926
+ }
927
+
928
+ if (moment.isMoment(input)) {
929
+ config = extend({}, input);
930
+ config._d = new Date(+input._d);
931
+ } else if (format) {
932
+ if (isArray(format)) {
933
+ makeDateFromStringAndArray(config);
934
+ } else {
935
+ makeDateFromStringAndFormat(config);
936
+ }
937
+ } else {
938
+ makeDateFromInput(config);
939
+ }
940
+
941
+ return new Moment(config);
942
+ }
943
+
944
+ moment = function (input, format, lang) {
945
+ return makeMoment({
946
+ _i : input,
947
+ _f : format,
948
+ _l : lang,
949
+ _isUTC : false
950
+ });
951
+ };
952
+
953
+ // creating with utc
954
+ moment.utc = function (input, format, lang) {
955
+ return makeMoment({
956
+ _useUTC : true,
957
+ _isUTC : true,
958
+ _l : lang,
959
+ _i : input,
960
+ _f : format
961
+ });
962
+ };
963
+
964
+ // creating with unix timestamp (in seconds)
965
+ moment.unix = function (input) {
966
+ return moment(input * 1000);
967
+ };
968
+
969
+ // duration
970
+ moment.duration = function (input, key) {
971
+ var isDuration = moment.isDuration(input),
972
+ isNumber = (typeof input === 'number'),
973
+ duration = (isDuration ? input._data : (isNumber ? {} : input)),
974
+ ret;
975
+
976
+ if (isNumber) {
977
+ if (key) {
978
+ duration[key] = input;
979
+ } else {
980
+ duration.milliseconds = input;
981
+ }
982
+ }
983
+
984
+ ret = new Duration(duration);
985
+
986
+ if (isDuration && input.hasOwnProperty('_lang')) {
987
+ ret._lang = input._lang;
988
+ }
989
+
990
+ return ret;
991
+ };
992
+
993
+ // version number
994
+ moment.version = VERSION;
995
+
996
+ // default format
997
+ moment.defaultFormat = isoFormat;
998
+
999
+ // This function will load languages and then set the global language. If
1000
+ // no arguments are passed in, it will simply return the current global
1001
+ // language key.
1002
+ moment.lang = function (key, values) {
1003
+ var i;
1004
+
1005
+ if (!key) {
1006
+ return moment.fn._lang._abbr;
1007
+ }
1008
+ if (values) {
1009
+ loadLang(key, values);
1010
+ } else if (!languages[key]) {
1011
+ getLangDefinition(key);
1012
+ }
1013
+ moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1014
+ };
1015
+
1016
+ // returns language data
1017
+ moment.langData = function (key) {
1018
+ if (key && key._lang && key._lang._abbr) {
1019
+ key = key._lang._abbr;
1020
+ }
1021
+ return getLangDefinition(key);
1022
+ };
1023
+
1024
+ // compare moment object
1025
+ moment.isMoment = function (obj) {
1026
+ return obj instanceof Moment;
1027
+ };
1028
+
1029
+ // for typechecking Duration objects
1030
+ moment.isDuration = function (obj) {
1031
+ return obj instanceof Duration;
1032
+ };
1033
+
1034
+
1035
+ /************************************
1036
+ Moment Prototype
1037
+ ************************************/
1038
+
1039
+
1040
+ moment.fn = Moment.prototype = {
1041
+
1042
+ clone : function () {
1043
+ return moment(this);
1044
+ },
1045
+
1046
+ valueOf : function () {
1047
+ return +this._d;
1048
+ },
1049
+
1050
+ unix : function () {
1051
+ return Math.floor(+this._d / 1000);
1052
+ },
1053
+
1054
+ toString : function () {
1055
+ return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1056
+ },
1057
+
1058
+ toDate : function () {
1059
+ return this._d;
1060
+ },
1061
+
1062
+ toJSON : function () {
1063
+ return moment.utc(this).format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1064
+ },
1065
+
1066
+ toArray : function () {
1067
+ var m = this;
1068
+ return [
1069
+ m.year(),
1070
+ m.month(),
1071
+ m.date(),
1072
+ m.hours(),
1073
+ m.minutes(),
1074
+ m.seconds(),
1075
+ m.milliseconds()
1076
+ ];
1077
+ },
1078
+
1079
+ isValid : function () {
1080
+ if (this._isValid == null) {
1081
+ if (this._a) {
1082
+ this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray());
1083
+ } else {
1084
+ this._isValid = !isNaN(this._d.getTime());
1085
+ }
1086
+ }
1087
+ return !!this._isValid;
1088
+ },
1089
+
1090
+ utc : function () {
1091
+ this._isUTC = true;
1092
+ return this;
1093
+ },
1094
+
1095
+ local : function () {
1096
+ this._isUTC = false;
1097
+ return this;
1098
+ },
1099
+
1100
+ format : function (inputString) {
1101
+ var output = formatMoment(this, inputString || moment.defaultFormat);
1102
+ return this.lang().postformat(output);
1103
+ },
1104
+
1105
+ add : function (input, val) {
1106
+ var dur;
1107
+ // switch args to support add('s', 1) and add(1, 's')
1108
+ if (typeof input === 'string') {
1109
+ dur = moment.duration(+val, input);
1110
+ } else {
1111
+ dur = moment.duration(input, val);
1112
+ }
1113
+ addOrSubtractDurationFromMoment(this, dur, 1);
1114
+ return this;
1115
+ },
1116
+
1117
+ subtract : function (input, val) {
1118
+ var dur;
1119
+ // switch args to support subtract('s', 1) and subtract(1, 's')
1120
+ if (typeof input === 'string') {
1121
+ dur = moment.duration(+val, input);
1122
+ } else {
1123
+ dur = moment.duration(input, val);
1124
+ }
1125
+ addOrSubtractDurationFromMoment(this, dur, -1);
1126
+ return this;
1127
+ },
1128
+
1129
+ diff : function (input, units, asFloat) {
1130
+ var that = this._isUTC ? moment(input).utc() : moment(input).local(),
1131
+ zoneDiff = (this.zone() - that.zone()) * 6e4,
1132
+ diff, output;
1133
+
1134
+ if (units) {
1135
+ // standardize on singular form
1136
+ units = units.replace(/s$/, '');
1137
+ }
1138
+
1139
+ if (units === 'year' || units === 'month') {
1140
+ diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
1141
+ output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
1142
+ output += ((this - moment(this).startOf('month')) - (that - moment(that).startOf('month'))) / diff;
1143
+ if (units === 'year') {
1144
+ output = output / 12;
1145
+ }
1146
+ } else {
1147
+ diff = (this - that) - zoneDiff;
1148
+ output = units === 'second' ? diff / 1e3 : // 1000
1149
+ units === 'minute' ? diff / 6e4 : // 1000 * 60
1150
+ units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
1151
+ units === 'day' ? diff / 864e5 : // 1000 * 60 * 60 * 24
1152
+ units === 'week' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
1153
+ diff;
1154
+ }
1155
+ return asFloat ? output : absRound(output);
1156
+ },
1157
+
1158
+ from : function (time, withoutSuffix) {
1159
+ return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
1160
+ },
1161
+
1162
+ fromNow : function (withoutSuffix) {
1163
+ return this.from(moment(), withoutSuffix);
1164
+ },
1165
+
1166
+ calendar : function () {
1167
+ var diff = this.diff(moment().startOf('day'), 'days', true),
1168
+ format = diff < -6 ? 'sameElse' :
1169
+ diff < -1 ? 'lastWeek' :
1170
+ diff < 0 ? 'lastDay' :
1171
+ diff < 1 ? 'sameDay' :
1172
+ diff < 2 ? 'nextDay' :
1173
+ diff < 7 ? 'nextWeek' : 'sameElse';
1174
+ return this.format(this.lang().calendar(format, this));
1175
+ },
1176
+
1177
+ isLeapYear : function () {
1178
+ var year = this.year();
1179
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1180
+ },
1181
+
1182
+ isDST : function () {
1183
+ return (this.zone() < moment([this.year()]).zone() ||
1184
+ this.zone() < moment([this.year(), 5]).zone());
1185
+ },
1186
+
1187
+ day : function (input) {
1188
+ var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1189
+ return input == null ? day :
1190
+ this.add({ d : input - day });
1191
+ },
1192
+
1193
+ startOf: function (units) {
1194
+ units = units.replace(/s$/, '');
1195
+ // the following switch intentionally omits break keywords
1196
+ // to utilize falling through the cases.
1197
+ switch (units) {
1198
+ case 'year':
1199
+ this.month(0);
1200
+ /* falls through */
1201
+ case 'month':
1202
+ this.date(1);
1203
+ /* falls through */
1204
+ case 'week':
1205
+ case 'day':
1206
+ this.hours(0);
1207
+ /* falls through */
1208
+ case 'hour':
1209
+ this.minutes(0);
1210
+ /* falls through */
1211
+ case 'minute':
1212
+ this.seconds(0);
1213
+ /* falls through */
1214
+ case 'second':
1215
+ this.milliseconds(0);
1216
+ /* falls through */
1217
+ }
1218
+
1219
+ // weeks are a special case
1220
+ if (units === 'week') {
1221
+ this.day(0);
1222
+ }
1223
+
1224
+ return this;
1225
+ },
1226
+
1227
+ endOf: function (units) {
1228
+ return this.startOf(units).add(units.replace(/s?$/, 's'), 1).subtract('ms', 1);
1229
+ },
1230
+
1231
+ isAfter: function (input, units) {
1232
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1233
+ return +this.clone().startOf(units) > +moment(input).startOf(units);
1234
+ },
1235
+
1236
+ isBefore: function (input, units) {
1237
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1238
+ return +this.clone().startOf(units) < +moment(input).startOf(units);
1239
+ },
1240
+
1241
+ isSame: function (input, units) {
1242
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1243
+ return +this.clone().startOf(units) === +moment(input).startOf(units);
1244
+ },
1245
+
1246
+ zone : function () {
1247
+ return this._isUTC ? 0 : this._d.getTimezoneOffset();
1248
+ },
1249
+
1250
+ daysInMonth : function () {
1251
+ return moment.utc([this.year(), this.month() + 1, 0]).date();
1252
+ },
1253
+
1254
+ dayOfYear : function (input) {
1255
+ var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
1256
+ return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
1257
+ },
1258
+
1259
+ isoWeek : function (input) {
1260
+ var week = weekOfYear(this, 1, 4);
1261
+ return input == null ? week : this.add("d", (input - week) * 7);
1262
+ },
1263
+
1264
+ week : function (input) {
1265
+ var week = this.lang().week(this);
1266
+ return input == null ? week : this.add("d", (input - week) * 7);
1267
+ },
1268
+
1269
+ // If passed a language key, it will set the language for this
1270
+ // instance. Otherwise, it will return the language configuration
1271
+ // variables for this instance.
1272
+ lang : function (key) {
1273
+ if (key === undefined) {
1274
+ return this._lang;
1275
+ } else {
1276
+ this._lang = getLangDefinition(key);
1277
+ return this;
1278
+ }
1279
+ }
1280
+ };
1281
+
1282
+ // helper for adding shortcuts
1283
+ function makeGetterAndSetter(name, key) {
1284
+ moment.fn[name] = moment.fn[name + 's'] = function (input) {
1285
+ var utc = this._isUTC ? 'UTC' : '';
1286
+ if (input != null) {
1287
+ this._d['set' + utc + key](input);
1288
+ return this;
1289
+ } else {
1290
+ return this._d['get' + utc + key]();
1291
+ }
1292
+ };
1293
+ }
1294
+
1295
+ // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
1296
+ for (i = 0; i < proxyGettersAndSetters.length; i ++) {
1297
+ makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
1298
+ }
1299
+
1300
+ // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
1301
+ makeGetterAndSetter('year', 'FullYear');
1302
+
1303
+ // add plural methods
1304
+ moment.fn.days = moment.fn.day;
1305
+ moment.fn.weeks = moment.fn.week;
1306
+ moment.fn.isoWeeks = moment.fn.isoWeek;
1307
+
1308
+ /************************************
1309
+ Duration Prototype
1310
+ ************************************/
1311
+
1312
+
1313
+ moment.duration.fn = Duration.prototype = {
1314
+ weeks : function () {
1315
+ return absRound(this.days() / 7);
1316
+ },
1317
+
1318
+ valueOf : function () {
1319
+ return this._milliseconds +
1320
+ this._days * 864e5 +
1321
+ this._months * 2592e6;
1322
+ },
1323
+
1324
+ humanize : function (withSuffix) {
1325
+ var difference = +this,
1326
+ output = relativeTime(difference, !withSuffix, this.lang());
1327
+
1328
+ if (withSuffix) {
1329
+ output = this.lang().pastFuture(difference, output);
1330
+ }
1331
+
1332
+ return this.lang().postformat(output);
1333
+ },
1334
+
1335
+ lang : moment.fn.lang
1336
+ };
1337
+
1338
+ function makeDurationGetter(name) {
1339
+ moment.duration.fn[name] = function () {
1340
+ return this._data[name];
1341
+ };
1342
+ }
1343
+
1344
+ function makeDurationAsGetter(name, factor) {
1345
+ moment.duration.fn['as' + name] = function () {
1346
+ return +this / factor;
1347
+ };
1348
+ }
1349
+
1350
+ for (i in unitMillisecondFactors) {
1351
+ if (unitMillisecondFactors.hasOwnProperty(i)) {
1352
+ makeDurationAsGetter(i, unitMillisecondFactors[i]);
1353
+ makeDurationGetter(i.toLowerCase());
1354
+ }
1355
+ }
1356
+
1357
+ makeDurationAsGetter('Weeks', 6048e5);
1358
+
1359
+
1360
+ /************************************
1361
+ Default Lang
1362
+ ************************************/
1363
+
1364
+
1365
+ // Set default language, other languages will inherit from English.
1366
+ moment.lang('en', {
1367
+ ordinal : function (number) {
1368
+ var b = number % 10,
1369
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
1370
+ (b === 1) ? 'st' :
1371
+ (b === 2) ? 'nd' :
1372
+ (b === 3) ? 'rd' : 'th';
1373
+ return number + output;
1374
+ }
1375
+ });
1376
+
1377
+
1378
+ /************************************
1379
+ Exposing Moment
1380
+ ************************************/
1381
+
1382
+
1383
+ // CommonJS module is defined
1384
+ if (hasModule) {
1385
+ module.exports = moment;
1386
+ }
1387
+ /*global ender:false */
1388
+ if (typeof ender === 'undefined') {
1389
+ // here, `this` means `window` in the browser, or `global` on the server
1390
+ // add `moment` as a global object via a string identifier,
1391
+ // for Closure Compiler "advanced" mode
1392
+ this['moment'] = moment;
1393
+ }
1394
+ /*global define:false */
1395
+ if (typeof define === "function" && define.amd) {
1396
+ define("moment", [], function () {
1397
+ return moment;
1398
+ });
1399
+ }
1400
+ }).call(this);