919 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			919 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // moment.js
 | |
| // version : 1.6.2
 | |
| // author : Tim Wood
 | |
| // license : MIT
 | |
| // momentjs.com
 | |
| 
 | |
| (function (Date, undefined) {
 | |
| 
 | |
|     var moment,
 | |
|         VERSION = "1.6.2",
 | |
|         round = Math.round, i,
 | |
|         // internal storage for language config files
 | |
|         languages = {},
 | |
|         currentLanguage = 'en',
 | |
| 
 | |
|         // check for nodeJS
 | |
|         hasModule = (typeof module !== 'undefined'),
 | |
| 
 | |
|         // parameters to check for on the lang config
 | |
|         langConfigProperties = 'months|monthsShort|monthsParse|weekdays|weekdaysShort|longDateFormat|calendar|relativeTime|ordinal|meridiem'.split('|'),
 | |
| 
 | |
|         // ASP.NET json date format regex
 | |
|         aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
 | |
| 
 | |
|         // format tokens
 | |
|         formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|LT|LL?L?L?)/g,
 | |
| 
 | |
|         // parsing tokens
 | |
|         parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,
 | |
| 
 | |
|         // parsing token regexes
 | |
|         parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
 | |
|         parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
 | |
|         parseTokenThreeDigits = /\d{3}/, // 000 - 999
 | |
|         parseTokenFourDigits = /\d{4}/, // 0000 - 9999
 | |
|         parseTokenWord = /[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i, // any word characters or numbers
 | |
|         parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
 | |
|         parseTokenT = /T/i, // T (ISO seperator)
 | |
| 
 | |
|         // preliminary iso regex 
 | |
|         // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
 | |
|         isoRegex = /^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
 | |
|         isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
 | |
| 
 | |
|         // iso time formats and regexes
 | |
|         isoTimes = [
 | |
|             ['HH:mm:ss.S', /T\d\d:\d\d:\d\d\.\d{1,3}/],
 | |
|             ['HH:mm:ss', /T\d\d:\d\d:\d\d/],
 | |
|             ['HH:mm', /T\d\d:\d\d/],
 | |
|             ['HH', /T\d\d/]
 | |
|         ],
 | |
| 
 | |
|         // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
 | |
|         parseTimezoneChunker = /([\+\-]|\d\d)/gi,
 | |
| 
 | |
|         // getter and setter names
 | |
|         proxyGettersAndSetters = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
 | |
|         unitMillisecondFactors = {
 | |
|             'Milliseconds' : 1,
 | |
|             'Seconds' : 1e3,
 | |
|             'Minutes' : 6e4,
 | |
|             'Hours' : 36e5,
 | |
|             'Days' : 864e5,
 | |
|             'Months' : 2592e6,
 | |
|             'Years' : 31536e6
 | |
|         };
 | |
| 
 | |
|     // Moment prototype object
 | |
|     function Moment(date, isUTC) {
 | |
|         this._d = date;
 | |
|         this._isUTC = !!isUTC;
 | |
|     }
 | |
| 
 | |
|     function absRound(number) {
 | |
|         if (number < 0) {
 | |
|             return Math.ceil(number);
 | |
|         } else {
 | |
|             return Math.floor(number);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Duration Constructor
 | |
|     function Duration(duration) {
 | |
|         var data = this._data = {},
 | |
|             years = duration.years || duration.y || 0,
 | |
|             months = duration.months || duration.M || 0, 
 | |
|             weeks = duration.weeks || duration.w || 0,
 | |
|             days = duration.days || duration.d || 0,
 | |
|             hours = duration.hours || duration.h || 0,
 | |
|             minutes = duration.minutes || duration.m || 0,
 | |
|             seconds = duration.seconds || duration.s || 0,
 | |
|             milliseconds = duration.milliseconds || duration.ms || 0;
 | |
| 
 | |
|         // representation for dateAddRemove
 | |
|         this._milliseconds = milliseconds +
 | |
|             seconds * 1e3 + // 1000
 | |
|             minutes * 6e4 + // 1000 * 60
 | |
|             hours * 36e5; // 1000 * 60 * 60
 | |
|         // Because of dateAddRemove treats 24 hours as different from a
 | |
|         // day when working around DST, we need to store them separately
 | |
|         this._days = days +
 | |
|             weeks * 7;
 | |
|         // It is impossible translate months into days without knowing
 | |
|         // which months you are are talking about, so we have to store
 | |
|         // it separately.
 | |
|         this._months = months +
 | |
|             years * 12;
 | |
|             
 | |
|         // The following code bubbles up values, see the tests for
 | |
|         // examples of what that means.
 | |
|         data.milliseconds = milliseconds % 1000;
 | |
|         seconds += absRound(milliseconds / 1000);
 | |
| 
 | |
|         data.seconds = seconds % 60;
 | |
|         minutes += absRound(seconds / 60);
 | |
| 
 | |
|         data.minutes = minutes % 60;
 | |
|         hours += absRound(minutes / 60);
 | |
| 
 | |
|         data.hours = hours % 24;
 | |
|         days += absRound(hours / 24);
 | |
| 
 | |
|         days += weeks * 7;
 | |
|         data.days = days % 30;
 | |
|         
 | |
|         months += absRound(days / 30);
 | |
| 
 | |
|         data.months = months % 12;
 | |
|         years += absRound(months / 12);
 | |
| 
 | |
|         data.years = years;
 | |
|     }
 | |
| 
 | |
|     // left zero fill a number
 | |
|     // see http://jsperf.com/left-zero-filling for performance comparison
 | |
|     function leftZeroFill(number, targetLength) {
 | |
|         var output = number + '';
 | |
|         while (output.length < targetLength) {
 | |
|             output = '0' + output;
 | |
|         }
 | |
|         return output;
 | |
|     }
 | |
| 
 | |
|     // helper function for _.addTime and _.subtractTime
 | |
|     function addOrSubtractDurationFromMoment(mom, duration, isAdding) {
 | |
|         var ms = duration._milliseconds,
 | |
|             d = duration._days,
 | |
|             M = duration._months,
 | |
|             currentDate;
 | |
| 
 | |
|         if (ms) {
 | |
|             mom._d.setTime(+mom + ms * isAdding);
 | |
|         }
 | |
|         if (d) {
 | |
|             mom.date(mom.date() + d * isAdding);
 | |
|         }
 | |
|         if (M) {
 | |
|             currentDate = mom.date();
 | |
|             mom.date(1)
 | |
|                 .month(mom.month() + M * isAdding)
 | |
|                 .date(Math.min(currentDate, mom.daysInMonth()));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // check if is an array
 | |
|     function isArray(input) {
 | |
|         return Object.prototype.toString.call(input) === '[object Array]';
 | |
|     }
 | |
| 
 | |
|     // convert an array to a date.
 | |
|     // the array should mirror the parameters below
 | |
|     // note: all values past the year are optional and will default to the lowest possible value.
 | |
|     // [year, month, day , hour, minute, second, millisecond]
 | |
|     function dateFromArray(input) {
 | |
|         return new Date(input[0], input[1] || 0, input[2] || 1, input[3] || 0, input[4] || 0, input[5] || 0, input[6] || 0);
 | |
|     }
 | |
| 
 | |
|     // format date using native date object
 | |
|     function formatMoment(m, inputString) {
 | |
|         var currentMonth = m.month(),
 | |
|             currentDate = m.date(),
 | |
|             currentYear = m.year(),
 | |
|             currentDay = m.day(),
 | |
|             currentHours = m.hours(),
 | |
|             currentMinutes = m.minutes(),
 | |
|             currentSeconds = m.seconds(),
 | |
|             currentMilliseconds = m.milliseconds(),
 | |
|             currentZone = -m.zone(),
 | |
|             ordinal = moment.ordinal,
 | |
|             meridiem = moment.meridiem;
 | |
|         // check if the character is a format
 | |
|         // return formatted string or non string.
 | |
|         //
 | |
|         // uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380)
 | |
|         // for minification and performance
 | |
|         // see http://jsperf.com/object-of-functions-vs-switch for performance comparison
 | |
|         function replaceFunction(input) {
 | |
|             // create a couple variables to be used later inside one of the cases.
 | |
|             var a, b;
 | |
|             switch (input) {
 | |
|                 // MONTH
 | |
|             case 'M' :
 | |
|                 return currentMonth + 1;
 | |
|             case 'Mo' :
 | |
|                 return (currentMonth + 1) + ordinal(currentMonth + 1);
 | |
|             case 'MM' :
 | |
|                 return leftZeroFill(currentMonth + 1, 2);
 | |
|             case 'MMM' :
 | |
|                 return moment.monthsShort[currentMonth];
 | |
|             case 'MMMM' :
 | |
|                 return moment.months[currentMonth];
 | |
|             // DAY OF MONTH
 | |
|             case 'D' :
 | |
|                 return currentDate;
 | |
|             case 'Do' :
 | |
|                 return currentDate + ordinal(currentDate);
 | |
|             case 'DD' :
 | |
|                 return leftZeroFill(currentDate, 2);
 | |
|             // DAY OF YEAR
 | |
|             case 'DDD' :
 | |
|                 a = new Date(currentYear, currentMonth, currentDate);
 | |
|                 b = new Date(currentYear, 0, 1);
 | |
|                 return ~~ (((a - b) / 864e5) + 1.5);
 | |
|             case 'DDDo' :
 | |
|                 a = replaceFunction('DDD');
 | |
|                 return a + ordinal(a);
 | |
|             case 'DDDD' :
 | |
|                 return leftZeroFill(replaceFunction('DDD'), 3);
 | |
|             // WEEKDAY
 | |
|             case 'd' :
 | |
|                 return currentDay;
 | |
|             case 'do' :
 | |
|                 return currentDay + ordinal(currentDay);
 | |
|             case 'ddd' :
 | |
|                 return moment.weekdaysShort[currentDay];
 | |
|             case 'dddd' :
 | |
|                 return moment.weekdays[currentDay];
 | |
|             // WEEK OF YEAR
 | |
|             case 'w' :
 | |
|                 a = new Date(currentYear, currentMonth, currentDate - currentDay + 5);
 | |
|                 b = new Date(a.getFullYear(), 0, 4);
 | |
|                 return ~~ ((a - b) / 864e5 / 7 + 1.5);
 | |
|             case 'wo' :
 | |
|                 a = replaceFunction('w');
 | |
|                 return a + ordinal(a);
 | |
|             case 'ww' :
 | |
|                 return leftZeroFill(replaceFunction('w'), 2);
 | |
|             // YEAR
 | |
|             case 'YY' :
 | |
|                 return leftZeroFill(currentYear % 100, 2);
 | |
|             case 'YYYY' :
 | |
|                 return currentYear;
 | |
|             // AM / PM
 | |
|             case 'a' :
 | |
|                 return meridiem ? meridiem(currentHours, currentMinutes, false) : (currentHours > 11 ? 'pm' : 'am');
 | |
|             case 'A' :
 | |
|                 return meridiem ? meridiem(currentHours, currentMinutes, true) : (currentHours > 11 ? 'PM' : 'AM');
 | |
|             // 24 HOUR
 | |
|             case 'H' :
 | |
|                 return currentHours;
 | |
|             case 'HH' :
 | |
|                 return leftZeroFill(currentHours, 2);
 | |
|             // 12 HOUR
 | |
|             case 'h' :
 | |
|                 return currentHours % 12 || 12;
 | |
|             case 'hh' :
 | |
|                 return leftZeroFill(currentHours % 12 || 12, 2);
 | |
|             // MINUTE
 | |
|             case 'm' :
 | |
|                 return currentMinutes;
 | |
|             case 'mm' :
 | |
|                 return leftZeroFill(currentMinutes, 2);
 | |
|             // SECOND
 | |
|             case 's' :
 | |
|                 return currentSeconds;
 | |
|             case 'ss' :
 | |
|                 return leftZeroFill(currentSeconds, 2);
 | |
|             // MILLISECONDS
 | |
|             case 'S' :
 | |
|                 return ~~ (currentMilliseconds / 100);
 | |
|             case 'SS' :
 | |
|                 return leftZeroFill(~~(currentMilliseconds / 10), 2);
 | |
|             case 'SSS' :
 | |
|                 return leftZeroFill(currentMilliseconds, 3);
 | |
|             // TIMEZONE
 | |
|             case 'Z' :
 | |
|                 return (currentZone < 0 ? '-' : '+') + leftZeroFill(~~(Math.abs(currentZone) / 60), 2) + ':' + leftZeroFill(~~(Math.abs(currentZone) % 60), 2);
 | |
|             case 'ZZ' :
 | |
|                 return (currentZone < 0 ? '-' : '+') + leftZeroFill(~~(10 * Math.abs(currentZone) / 6), 4);
 | |
|             // LONG DATES
 | |
|             case 'L' :
 | |
|             case 'LL' :
 | |
|             case 'LLL' :
 | |
|             case 'LLLL' :
 | |
|             case 'LT' :
 | |
|                 return formatMoment(m, moment.longDateFormat[input]);
 | |
|             // DEFAULT
 | |
|             default :
 | |
|                 return input.replace(/(^\[)|(\\)|\]$/g, "");
 | |
|             }
 | |
|         }
 | |
|         return inputString.replace(formattingTokens, replaceFunction);
 | |
|     }
 | |
| 
 | |
|     // get the regex to find the next token
 | |
|     function getParseRegexForToken(token) {
 | |
|         switch (token) {
 | |
|         case 'DDDD':
 | |
|             return parseTokenThreeDigits;
 | |
|         case 'YYYY':
 | |
|             return parseTokenFourDigits;
 | |
|         case 'S':
 | |
|         case 'SS':
 | |
|         case 'SSS':
 | |
|         case 'DDD':
 | |
|             return parseTokenOneToThreeDigits;
 | |
|         case 'MMM':
 | |
|         case 'MMMM':
 | |
|         case 'ddd':
 | |
|         case 'dddd':
 | |
|         case 'a':
 | |
|         case 'A':
 | |
|             return parseTokenWord;
 | |
|         case 'Z':
 | |
|         case 'ZZ':
 | |
|             return parseTokenTimezone;
 | |
|         case 'T':
 | |
|             return parseTokenT;
 | |
|         case 'MM':
 | |
|         case 'DD':
 | |
|         case 'dd':
 | |
|         case 'YY':
 | |
|         case 'HH':
 | |
|         case 'hh':
 | |
|         case 'mm':
 | |
|         case 'ss':
 | |
|         case 'M':
 | |
|         case 'D':
 | |
|         case 'd':
 | |
|         case 'H':
 | |
|         case 'h':
 | |
|         case 'm':
 | |
|         case 's':
 | |
|             return parseTokenOneOrTwoDigits;
 | |
|         default :
 | |
|             return new RegExp(token.replace('\\', ''));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // function to convert string input to date
 | |
|     function addTimeToArrayFromToken(token, input, datePartArray, config) {
 | |
|         var a;
 | |
|         //console.log('addTime', format, input);
 | |
|         switch (token) {
 | |
|         // MONTH
 | |
|         case 'M' : // fall through to MM
 | |
|         case 'MM' :
 | |
|             datePartArray[1] = (input == null) ? 0 : ~~input - 1;
 | |
|             break;
 | |
|         case 'MMM' : // fall through to MMMM
 | |
|         case 'MMMM' :
 | |
|             for (a = 0; a < 12; a++) {
 | |
|                 if (moment.monthsParse[a].test(input)) {
 | |
|                     datePartArray[1] = a;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         // DAY OF MONTH
 | |
|         case 'D' : // fall through to DDDD
 | |
|         case 'DD' : // fall through to DDDD
 | |
|         case 'DDD' : // fall through to DDDD
 | |
|         case 'DDDD' :
 | |
|             datePartArray[2] = ~~input;
 | |
|             break;
 | |
|         // YEAR
 | |
|         case 'YY' :
 | |
|             input = ~~input;
 | |
|             datePartArray[0] = input + (input > 70 ? 1900 : 2000);
 | |
|             break;
 | |
|         case 'YYYY' :
 | |
|             datePartArray[0] = ~~Math.abs(input);
 | |
|             break;
 | |
|         // AM / PM
 | |
|         case 'a' : // fall through to A
 | |
|         case 'A' :
 | |
|             config.isPm = ((input + '').toLowerCase() === 'pm');
 | |
|             break;
 | |
|         // 24 HOUR
 | |
|         case 'H' : // fall through to hh
 | |
|         case 'HH' : // fall through to hh
 | |
|         case 'h' : // fall through to hh
 | |
|         case 'hh' :
 | |
|             datePartArray[3] = ~~input;
 | |
|             break;
 | |
|         // MINUTE
 | |
|         case 'm' : // fall through to mm
 | |
|         case 'mm' :
 | |
|             datePartArray[4] = ~~input;
 | |
|             break;
 | |
|         // SECOND
 | |
|         case 's' : // fall through to ss
 | |
|         case 'ss' :
 | |
|             datePartArray[5] = ~~input;
 | |
|             break;
 | |
|         // MILLISECOND
 | |
|         case 'S' :
 | |
|         case 'SS' :
 | |
|         case 'SSS' :
 | |
|             datePartArray[6] = ~~ (('0.' + input) * 1000);
 | |
|             break;
 | |
|         // TIMEZONE
 | |
|         case 'Z' : // fall through to ZZ
 | |
|         case 'ZZ' :
 | |
|             config.isUTC = true;
 | |
|             a = (input + '').match(parseTimezoneChunker);
 | |
|             if (a && a[1]) {
 | |
|                 config.tzh = ~~a[1];
 | |
|             }
 | |
|             if (a && a[2]) {
 | |
|                 config.tzm = ~~a[2];
 | |
|             }
 | |
|             // reverse offsets
 | |
|             if (a && a[0] === '+') {
 | |
|                 config.tzh = -config.tzh;
 | |
|                 config.tzm = -config.tzm;
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // date from string and format string
 | |
|     function makeDateFromStringAndFormat(string, format) {
 | |
|         var datePartArray = [0, 0, 1, 0, 0, 0, 0],
 | |
|             config = {
 | |
|                 tzh : 0, // timezone hour offset
 | |
|                 tzm : 0  // timezone minute offset
 | |
|             },
 | |
|             tokens = format.match(formattingTokens),
 | |
|             i, parsedInput;
 | |
| 
 | |
|         for (i = 0; i < tokens.length; i++) {
 | |
|             parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0];
 | |
|             string = string.replace(getParseRegexForToken(tokens[i]), '');
 | |
|             addTimeToArrayFromToken(tokens[i], parsedInput, datePartArray, config);
 | |
|         }
 | |
|         // handle am pm
 | |
|         if (config.isPm && datePartArray[3] < 12) {
 | |
|             datePartArray[3] += 12;
 | |
|         }
 | |
|         // if is 12 am, change hours to 0
 | |
|         if (config.isPm === false && datePartArray[3] === 12) {
 | |
|             datePartArray[3] = 0;
 | |
|         }
 | |
|         // handle timezone
 | |
|         datePartArray[3] += config.tzh;
 | |
|         datePartArray[4] += config.tzm;
 | |
|         // return
 | |
|         return config.isUTC ? new Date(Date.UTC.apply({}, datePartArray)) : dateFromArray(datePartArray);
 | |
|     }
 | |
| 
 | |
|     // compare two arrays, return the number of differences
 | |
|     function compareArrays(array1, array2) {
 | |
|         var len = Math.min(array1.length, array2.length),
 | |
|             lengthDiff = Math.abs(array1.length - array2.length),
 | |
|             diffs = 0,
 | |
|             i;
 | |
|         for (i = 0; i < len; i++) {
 | |
|             if (~~array1[i] !== ~~array2[i]) {
 | |
|                 diffs++;
 | |
|             }
 | |
|         }
 | |
|         return diffs + lengthDiff;
 | |
|     }
 | |
| 
 | |
|     // date from string and array of format strings
 | |
|     function makeDateFromStringAndArray(string, formats) {
 | |
|         var output,
 | |
|             inputParts = string.match(parseMultipleFormatChunker) || [],
 | |
|             formattedInputParts,
 | |
|             scoreToBeat = 99,
 | |
|             i,
 | |
|             currentDate,
 | |
|             currentScore;
 | |
|         for (i = 0; i < formats.length; i++) {
 | |
|             currentDate = makeDateFromStringAndFormat(string, formats[i]);
 | |
|             formattedInputParts = formatMoment(new Moment(currentDate), formats[i]).match(parseMultipleFormatChunker) || [];
 | |
|             currentScore = compareArrays(inputParts, formattedInputParts);
 | |
|             if (currentScore < scoreToBeat) {
 | |
|                 scoreToBeat = currentScore;
 | |
|                 output = currentDate;
 | |
|             }
 | |
|         }
 | |
|         return output;
 | |
|     }
 | |
| 
 | |
|     // date from iso format
 | |
|     function makeDateFromString(string) {
 | |
|         var format = 'YYYY-MM-DDT',
 | |
|             i;
 | |
|         if (isoRegex.exec(string)) {
 | |
|             for (i = 0; i < 4; i++) {
 | |
|                 if (isoTimes[i][1].exec(string)) {
 | |
|                     format += isoTimes[i][0];
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             return parseTokenTimezone.exec(string) ? 
 | |
|                 makeDateFromStringAndFormat(string, format + ' Z') :
 | |
|                 makeDateFromStringAndFormat(string, format);
 | |
|         }
 | |
|         return new Date(string);
 | |
|     }
 | |
| 
 | |
|     // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
 | |
|     function substituteTimeAgo(string, number, withoutSuffix, isFuture) {
 | |
|         var rt = moment.relativeTime[string];
 | |
|         return (typeof rt === 'function') ?
 | |
|             rt(number || 1, !!withoutSuffix, string, isFuture) :
 | |
|             rt.replace(/%d/i, number || 1);
 | |
|     }
 | |
| 
 | |
|     function relativeTime(milliseconds, withoutSuffix) {
 | |
|         var seconds = round(Math.abs(milliseconds) / 1000),
 | |
|             minutes = round(seconds / 60),
 | |
|             hours = round(minutes / 60),
 | |
|             days = round(hours / 24),
 | |
|             years = round(days / 365),
 | |
|             args = seconds < 45 && ['s', seconds] ||
 | |
|                 minutes === 1 && ['m'] ||
 | |
|                 minutes < 45 && ['mm', minutes] ||
 | |
|                 hours === 1 && ['h'] ||
 | |
|                 hours < 22 && ['hh', hours] ||
 | |
|                 days === 1 && ['d'] ||
 | |
|                 days <= 25 && ['dd', days] ||
 | |
|                 days <= 45 && ['M'] ||
 | |
|                 days < 345 && ['MM', round(days / 30)] ||
 | |
|                 years === 1 && ['y'] || ['yy', years];
 | |
|         args[2] = withoutSuffix;
 | |
|         args[3] = milliseconds > 0;
 | |
|         return substituteTimeAgo.apply({}, args);
 | |
|     }
 | |
| 
 | |
|     moment = function (input, format) {
 | |
|         if (input === null || input === '') {
 | |
|             return null;
 | |
|         }
 | |
|         var date,
 | |
|             matched,
 | |
|             isUTC;
 | |
|         // parse Moment object
 | |
|         if (moment.isMoment(input)) {
 | |
|             date = new Date(+input._d);
 | |
|             isUTC = input._isUTC;
 | |
|         // parse string and format
 | |
|         } else if (format) {
 | |
|             if (isArray(format)) {
 | |
|                 date = makeDateFromStringAndArray(input, format);
 | |
|             } else {
 | |
|                 date = makeDateFromStringAndFormat(input, format);
 | |
|             }
 | |
|         // evaluate it as a JSON-encoded date
 | |
|         } else {
 | |
|             matched = aspNetJsonRegex.exec(input);
 | |
|             date = input === undefined ? new Date() :
 | |
|                 matched ? new Date(+matched[1]) :
 | |
|                 input instanceof Date ? input :
 | |
|                 isArray(input) ? dateFromArray(input) :
 | |
|                 typeof input === 'string' ? makeDateFromString(input) :
 | |
|                 new Date(input);
 | |
|         }
 | |
|         return new Moment(date, isUTC);
 | |
|     };
 | |
| 
 | |
|     // creating with utc
 | |
|     moment.utc = function (input, format) {
 | |
|         if (isArray(input)) {
 | |
|             return new Moment(new Date(Date.UTC.apply({}, input)), true);
 | |
|         }
 | |
|         return (format && input) ?
 | |
|             moment(input + ' +0000', format + ' Z').utc() :
 | |
|             moment(input && !parseTokenTimezone.exec(input) ? input + '+0000' : input).utc();
 | |
|     };
 | |
| 
 | |
|     // creating with unix timestamp (in seconds)
 | |
|     moment.unix = function (input) {
 | |
|         return moment(input * 1000);
 | |
|     };
 | |
| 
 | |
|     // duration
 | |
|     moment.duration = function (input, key) {
 | |
|         var isDuration = moment.isDuration(input),
 | |
|             isNumber = (typeof input === 'number'),
 | |
|             duration = (isDuration ? input._data : (isNumber ? {} : input));
 | |
| 
 | |
|         if (isNumber) {
 | |
|             if (key) {
 | |
|                 duration[key] = input;
 | |
|             } else {
 | |
|                 duration.milliseconds = input;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return new Duration(duration);
 | |
|     };
 | |
| 
 | |
|     // humanizeDuration
 | |
|     // This method is deprecated in favor of the new Duration object.  Please
 | |
|     // see the moment.duration method.
 | |
|     moment.humanizeDuration = function (num, type, withSuffix) {
 | |
|         return moment.duration(num, type === true ? null : type).humanize(type === true ? true : withSuffix);
 | |
|     };
 | |
| 
 | |
|     // version number
 | |
|     moment.version = VERSION;
 | |
| 
 | |
|     // default format
 | |
|     moment.defaultFormat = isoFormat;
 | |
| 
 | |
|     // language switching and caching
 | |
|     moment.lang = function (key, values) {
 | |
|         var i, req,
 | |
|             parse = [];
 | |
|         if (!key) {
 | |
|             return currentLanguage;
 | |
|         }
 | |
|         if (values) {
 | |
|             for (i = 0; i < 12; i++) {
 | |
|                 parse[i] = new RegExp('^' + values.months[i] + '|^' + values.monthsShort[i].replace('.', ''), 'i');
 | |
|             }
 | |
|             values.monthsParse = values.monthsParse || parse;
 | |
|             languages[key] = values;
 | |
|         }
 | |
|         if (languages[key]) {
 | |
|             for (i = 0; i < langConfigProperties.length; i++) {
 | |
|                 moment[langConfigProperties[i]] = languages[key][langConfigProperties[i]] || 
 | |
|                     languages.en[langConfigProperties[i]];
 | |
|             }
 | |
|             currentLanguage = key;
 | |
|         } else {
 | |
|             if (hasModule) {
 | |
|                 req = require('./lang/' + key);
 | |
|                 moment.lang(key, req);
 | |
|             }
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     // set default language
 | |
|     moment.lang('en', {
 | |
|         months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
 | |
|         monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
 | |
|         weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
 | |
|         weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
 | |
|         longDateFormat : {
 | |
|             LT : "h:mm A",
 | |
|             L : "MM/DD/YYYY",
 | |
|             LL : "MMMM D YYYY",
 | |
|             LLL : "MMMM D YYYY LT",
 | |
|             LLLL : "dddd, MMMM D YYYY LT"
 | |
|         },
 | |
|         meridiem : false,
 | |
|         calendar : {
 | |
|             sameDay : '[Today at] LT',
 | |
|             nextDay : '[Tomorrow at] LT',
 | |
|             nextWeek : 'dddd [at] LT',
 | |
|             lastDay : '[Yesterday at] LT',
 | |
|             lastWeek : '[last] dddd [at] LT',
 | |
|             sameElse : 'L'
 | |
|         },
 | |
|         relativeTime : {
 | |
|             future : "in %s",
 | |
|             past : "%s ago",
 | |
|             s : "a few seconds",
 | |
|             m : "a minute",
 | |
|             mm : "%d minutes",
 | |
|             h : "an hour",
 | |
|             hh : "%d hours",
 | |
|             d : "a day",
 | |
|             dd : "%d days",
 | |
|             M : "a month",
 | |
|             MM : "%d months",
 | |
|             y : "a year",
 | |
|             yy : "%d years"
 | |
|         },
 | |
|         ordinal : function (number) {
 | |
|             var b = number % 10;
 | |
|             return (~~ (number % 100 / 10) === 1) ? 'th' :
 | |
|                 (b === 1) ? 'st' :
 | |
|                 (b === 2) ? 'nd' :
 | |
|                 (b === 3) ? 'rd' : 'th';
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     // compare moment object
 | |
|     moment.isMoment = function (obj) {
 | |
|         return obj instanceof Moment;
 | |
|     };
 | |
| 
 | |
|     // for typechecking Duration objects
 | |
|     moment.isDuration = function (obj) {
 | |
|         return obj instanceof Duration;
 | |
|     };
 | |
| 
 | |
|     // shortcut for prototype
 | |
|     moment.fn = Moment.prototype = {
 | |
| 
 | |
|         clone : function () {
 | |
|             return moment(this);
 | |
|         },
 | |
| 
 | |
|         valueOf : function () {
 | |
|             return +this._d;
 | |
|         },
 | |
| 
 | |
|         unix : function () {
 | |
|             return Math.floor(+this._d / 1000);
 | |
|         },
 | |
| 
 | |
|         toString : function () {
 | |
|             return this._d.toString();
 | |
|         },
 | |
| 
 | |
|         toDate : function () {
 | |
|             return this._d;
 | |
|         },
 | |
| 
 | |
|         utc : function () {
 | |
|             this._isUTC = true;
 | |
|             return this;
 | |
|         },
 | |
| 
 | |
|         local : function () {
 | |
|             this._isUTC = false;
 | |
|             return this;
 | |
|         },
 | |
| 
 | |
|         format : function (inputString) {
 | |
|             return formatMoment(this, inputString ? inputString : moment.defaultFormat);
 | |
|         },
 | |
| 
 | |
|         add : function (input, val) {
 | |
|             var dur = val ? moment.duration(+val, input) : moment.duration(input);
 | |
|             addOrSubtractDurationFromMoment(this, dur, 1);
 | |
|             return this;
 | |
|         },
 | |
| 
 | |
|         subtract : function (input, val) {
 | |
|             var dur = val ? moment.duration(+val, input) : moment.duration(input);
 | |
|             addOrSubtractDurationFromMoment(this, dur, -1);
 | |
|             return this;
 | |
|         },
 | |
| 
 | |
|         diff : function (input, val, asFloat) {
 | |
|             var inputMoment = this._isUTC ? moment(input).utc() : moment(input).local(),
 | |
|                 zoneDiff = (this.zone() - inputMoment.zone()) * 6e4,
 | |
|                 diff = this._d - inputMoment._d - zoneDiff,
 | |
|                 year = this.year() - inputMoment.year(),
 | |
|                 month = this.month() - inputMoment.month(),
 | |
|                 date = this.date() - inputMoment.date(),
 | |
|                 output;
 | |
|             if (val === 'months') {
 | |
|                 output = year * 12 + month + date / 30;
 | |
|             } else if (val === 'years') {
 | |
|                 output = year + (month + date / 30) / 12;
 | |
|             } else {
 | |
|                 output = val === 'seconds' ? diff / 1e3 : // 1000
 | |
|                     val === 'minutes' ? diff / 6e4 : // 1000 * 60
 | |
|                     val === 'hours' ? diff / 36e5 : // 1000 * 60 * 60
 | |
|                     val === 'days' ? diff / 864e5 : // 1000 * 60 * 60 * 24
 | |
|                     val === 'weeks' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
 | |
|                     diff;
 | |
|             }
 | |
|             return asFloat ? output : round(output);
 | |
|         },
 | |
| 
 | |
|         from : function (time, withoutSuffix) {
 | |
|             return moment.duration(this.diff(time)).humanize(!withoutSuffix);
 | |
|         },
 | |
| 
 | |
|         fromNow : function (withoutSuffix) {
 | |
|             return this.from(moment(), withoutSuffix);
 | |
|         },
 | |
| 
 | |
|         calendar : function () {
 | |
|             var diff = this.diff(moment().sod(), 'days', true),
 | |
|                 calendar = moment.calendar,
 | |
|                 allElse = calendar.sameElse,
 | |
|                 format = diff < -6 ? allElse :
 | |
|                 diff < -1 ? calendar.lastWeek :
 | |
|                 diff < 0 ? calendar.lastDay :
 | |
|                 diff < 1 ? calendar.sameDay :
 | |
|                 diff < 2 ? calendar.nextDay :
 | |
|                 diff < 7 ? calendar.nextWeek : allElse;
 | |
|             return this.format(typeof format === 'function' ? format.apply(this) : format);
 | |
|         },
 | |
| 
 | |
|         isLeapYear : function () {
 | |
|             var year = this.year();
 | |
|             return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
 | |
|         },
 | |
| 
 | |
|         isDST : function () {
 | |
|             return (this.zone() < moment([this.year()]).zone() || 
 | |
|                 this.zone() < moment([this.year(), 5]).zone());
 | |
|         },
 | |
| 
 | |
|         day : function (input) {
 | |
|             var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
 | |
|             return input == null ? day :
 | |
|                 this.add({ d : input - day });
 | |
|         },
 | |
| 
 | |
|         sod: function () {
 | |
|             return moment(this)
 | |
|                 .hours(0)
 | |
|                 .minutes(0)
 | |
|                 .seconds(0)
 | |
|                 .milliseconds(0);
 | |
|         },
 | |
| 
 | |
|         eod: function () {
 | |
|             // end of day = start of day plus 1 day, minus 1 millisecond
 | |
|             return this.sod().add({
 | |
|                 d : 1,
 | |
|                 ms : -1
 | |
|             });
 | |
|         },
 | |
| 
 | |
|         zone : function () {
 | |
|             return this._isUTC ? 0 : this._d.getTimezoneOffset();
 | |
|         },
 | |
| 
 | |
|         daysInMonth : function () {
 | |
|             return moment(this).month(this.month() + 1).date(0).date();
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     // helper for adding shortcuts
 | |
|     function makeGetterAndSetter(name, key) {
 | |
|         moment.fn[name] = function (input) {
 | |
|             var utc = this._isUTC ? 'UTC' : '';
 | |
|             if (input != null) {
 | |
|                 this._d['set' + utc + key](input);
 | |
|                 return this;
 | |
|             } else {
 | |
|                 return this._d['get' + utc + key]();
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
 | |
|     for (i = 0; i < proxyGettersAndSetters.length; i ++) {
 | |
|         makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase(), proxyGettersAndSetters[i]);
 | |
|     }
 | |
| 
 | |
|     // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
 | |
|     makeGetterAndSetter('year', 'FullYear');
 | |
| 
 | |
|     moment.duration.fn = Duration.prototype = {
 | |
|         weeks : function () {
 | |
|             return absRound(this.days() / 7);
 | |
|         },
 | |
| 
 | |
|         valueOf : function () {
 | |
|             return this._milliseconds +
 | |
|               this._days * 864e5 +
 | |
|               this._months * 2592e6;
 | |
|         },
 | |
| 
 | |
|         humanize : function (withSuffix) {
 | |
|             var difference = +this,
 | |
|                 rel = moment.relativeTime,
 | |
|                 output = relativeTime(difference, !withSuffix);
 | |
| 
 | |
|             if (withSuffix) {
 | |
|                 output = (difference <= 0 ? rel.past : rel.future).replace(/%s/i, output);
 | |
|             }
 | |
| 
 | |
|             return output;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     function makeDurationGetter(name) {
 | |
|         moment.duration.fn[name] = function () {
 | |
|             return this._data[name];
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     function makeDurationAsGetter(name, factor) {
 | |
|         moment.duration.fn['as' + name] = function () {
 | |
|             return +this / factor;
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     for (i in unitMillisecondFactors) {
 | |
|         if (unitMillisecondFactors.hasOwnProperty(i)) {
 | |
|             makeDurationAsGetter(i, unitMillisecondFactors[i]);
 | |
|             makeDurationGetter(i.toLowerCase());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     makeDurationAsGetter('Weeks', 6048e5);
 | |
| 
 | |
|     // CommonJS module is defined
 | |
|     if (hasModule) {
 | |
|         module.exports = moment;
 | |
|     }
 | |
|     /*global ender:false */
 | |
|     if (typeof window !== 'undefined' && typeof ender === 'undefined') {
 | |
|         window.moment = moment;
 | |
|     }
 | |
|     /*global define:false */
 | |
|     if (typeof define === "function" && define.amd) {
 | |
|         define("moment", [], function () {
 | |
|             return moment;
 | |
|         });
 | |
|     }
 | |
| })(Date);
 |