├── loading.gif
├── readme.md
├── config.xml
├── index.html
└── lib
├── gadgetlib.js
└── moment.js
/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kyleladd/OU-inactive-users-gadget/master/loading.gif
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## Installation
2 | - Upload Gadget directory to web server
3 | - Setup->Gadgets->New
4 |
5 |
6 | #### Demo
7 | - https://youtu.be/726NMYvZR5g
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Inactive Users
6 |
7 |
8 | http://commons.omniupdate.com/favicon.ico
9 |
10 |
11 | Gets the list of users who have contributed the least over the last month
12 |
13 |
14 | http://fakeimg.pl/96/
15 |
16 |
18 | dashboard, sidebar
19 |
20 |
22 | message
23 |
24 |
25 |
26 |
27 |
29 | 1
30 |
31 |
32 | 290
33 |
34 |
37 | 14px
38 |
39 |
40 | 5
41 |
42 |
43 |
44 |
45 |
54 |
55 |
56 |
68 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Inactive Users
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
190 |
191 |
192 |
193 | Loading.

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