batman-rails 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ (function() {
2
+ var date_re, numericKeys,
3
+ __hasProp = {}.hasOwnProperty,
4
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
+
6
+ numericKeys = [1, 2, 3, 4, 5, 6, 7, 10, 11];
7
+
8
+ date_re = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
9
+
10
+ Batman.mixin(Batman.Encoders, {
11
+ railsDate: {
12
+ defaultTimezoneOffset: (new Date()).getTimezoneOffset(),
13
+ encode: function(value) {
14
+ return value;
15
+ },
16
+ decode: function(value) {
17
+ var key, minutesOffset, obj, _i, _len;
18
+ if (value != null) {
19
+ if ((obj = date_re.exec(value))) {
20
+ for (_i = 0, _len = numericKeys.length; _i < _len; _i++) {
21
+ key = numericKeys[_i];
22
+ obj[key] = +obj[key] || 0;
23
+ }
24
+ obj[2] = (+obj[2] || 1) - 1;
25
+ obj[3] = +obj[3] || 1;
26
+ if (obj[8] !== "Z" && obj[9] !== void 0) {
27
+ minutesOffset = obj[10] * 60 + obj[11];
28
+ if (obj[9] === "+") {
29
+ minutesOffset = 0 - minutesOffset;
30
+ }
31
+ } else {
32
+ minutesOffset = Batman.Encoders.railsDate.defaultTimezoneOffset;
33
+ }
34
+ return new Date(Date.UTC(obj[1], obj[2], obj[3], obj[4], obj[5] + minutesOffset, obj[6], obj[7]));
35
+ } else {
36
+ Batman.developer.warn("Unrecognized rails date " + value + "!");
37
+ return Date.parse(value);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ });
43
+
44
+ Batman.RailsStorage = (function(_super) {
45
+
46
+ __extends(RailsStorage, _super);
47
+
48
+ function RailsStorage() {
49
+ return RailsStorage.__super__.constructor.apply(this, arguments);
50
+ }
51
+
52
+ RailsStorage.prototype.urlForRecord = function() {
53
+ return this._addJsonExtension(RailsStorage.__super__.urlForRecord.apply(this, arguments));
54
+ };
55
+
56
+ RailsStorage.prototype.urlForCollection = function() {
57
+ return this._addJsonExtension(RailsStorage.__super__.urlForCollection.apply(this, arguments));
58
+ };
59
+
60
+ RailsStorage.prototype._addJsonExtension = function(url) {
61
+ if (url.indexOf('?') !== -1 || url.substr(-5, 5) === '.json') {
62
+ return url;
63
+ }
64
+ return url + '.json';
65
+ };
66
+
67
+ RailsStorage.prototype._errorsFrom422Response = function(response) {
68
+ return JSON.parse(response);
69
+ };
70
+
71
+ RailsStorage.prototype.after('update', 'create', function(env, next) {
72
+ var error, errorsArray, key, record, response, validationError, validationErrors, _i, _len, _ref;
73
+ record = env.subject;
74
+ error = env.error, response = env.response;
75
+ if (error) {
76
+ if (((_ref = error.request) != null ? _ref.get('status') : void 0) === 422) {
77
+ try {
78
+ validationErrors = this._errorsFrom422Response(response);
79
+ } catch (extractionError) {
80
+ env.error = extractionError;
81
+ return next();
82
+ }
83
+ for (key in validationErrors) {
84
+ errorsArray = validationErrors[key];
85
+ for (_i = 0, _len = errorsArray.length; _i < _len; _i++) {
86
+ validationError = errorsArray[_i];
87
+ record.get('errors').add(key, validationError);
88
+ }
89
+ }
90
+ env.result = record;
91
+ env.error = record.get('errors');
92
+ return next();
93
+ }
94
+ }
95
+ return next();
96
+ });
97
+
98
+ return RailsStorage;
99
+
100
+ })(Batman.RestStorage);
101
+
102
+ }).call(this);
@@ -1,11 +1,5 @@
1
- #
2
- # batman.solo.coffee
3
- # batman.js
4
- #
5
- # Created by Nick Small
6
- # Copyright 2011, Shopify
7
- #
8
- `
1
+ (function() {
2
+
9
3
  /*!
10
4
  * Reqwest! A general purpose XHR connection manager
11
5
  * (c) Dustin Diaz 2011
@@ -382,115 +376,129 @@
382
376
  return reqwest
383
377
  })
384
378
 
385
- `
386
- (exports ? this).reqwest = if window? then window.reqwest else reqwest
387
-
388
- # `param` and `buildParams` stolen from jQuery
389
- #
390
- # jQuery JavaScript Library v1.6.1
391
- # http://jquery.com/
392
- #
393
- # Copyright 2011, John Resig
394
- # Dual licensed under the MIT or GPL Version 2 licenses.
395
- # http://jquery.org/license
396
- rbracket = /\[\]$/
397
- r20 = /%20/g
398
- param = (a) ->
399
- return a if typeof a is 'string'
400
- s = []
401
- add = (key, value) ->
402
- value = value() if typeof value is 'function'
403
- value = '' unless value?
404
- s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value)
405
-
406
- if Batman.typeOf(a) is 'Array'
407
- for value, name of a
408
- add name, value
409
- else
410
- for own k, v of a
411
- buildParams k, v, add
412
- s.join("&").replace r20, "+"
413
-
414
- buildParams = (prefix, obj, add) ->
415
- if Batman.typeOf(obj) is 'Array'
416
- for v, i in obj
417
- if rbracket.test(prefix)
418
- add prefix, v
419
- else
420
- buildParams prefix + "[" + (if typeof v == "object" or Batman.typeOf(v) is 'Array' then i else "") + "]", v, add
421
- else if obj? and typeof obj == "object"
422
- for name of obj
423
- buildParams prefix + "[" + name + "]", obj[name], add
424
- else
425
- add prefix, obj
426
-
427
- Batman.Request::send = (data) ->
428
- data ?= @get('data')
429
- @fire 'loading'
430
-
431
- options =
432
- url: @get 'url'
433
- method: @get 'method'
434
- type: @get 'type'
435
- headers: @get 'headers'
436
-
437
- success: (response) =>
438
- @set 'response', response
439
- @set 'status', (xhr?.status or 200)
440
- @fire 'success', response
441
-
442
- error: (xhr) =>
443
- @set 'response', xhr.responseText || xhr.content
444
- @set 'status', xhr.status
445
- xhr.request = @
446
- @fire 'error', xhr
447
-
448
- complete: =>
449
- @fire 'loaded'
450
-
451
- if options.method in ['PUT', 'POST']
452
- if @hasFileUploads()
453
- options.data = @constructor.objectToFormData(data)
454
- else
455
- options.contentType = @get('contentType')
456
- options.data = param(data)
457
-
458
- else
459
- options.data = data
460
-
461
- # Fires the request. Grab a reference to the xhr object so we can get the status code elsewhere.
462
- xhr = (reqwest options).request
463
-
464
- prefixes = ['Webkit', 'Moz', 'O', 'ms', '']
465
- Batman.mixins.animation =
466
- initialize: ->
467
- for prefix in prefixes
468
- @style["#{prefix}Transform"] = 'scale(0, 0)'
469
- @style.opacity = 0
470
-
471
- @style["#{prefix}TransitionProperty"] = "#{if prefix then '-' + prefix.toLowerCase() + '-' else ''}transform, opacity"
472
- @style["#{prefix}TransitionDuration"] = "0.8s, 0.55s"
473
- @style["#{prefix}TransformOrigin"] = "left top"
474
- @
475
- show: (addToParent) ->
476
- show = =>
477
- @style.opacity = 1
478
- for prefix in prefixes
479
- @style["#{prefix}Transform"] = 'scale(1, 1)'
480
- @
481
-
482
- if addToParent
483
- addToParent.append?.appendChild @
484
- addToParent.before?.parentNode.insertBefore @, addToParent.before
485
-
486
- setTimeout show, 0
487
- else
488
- show()
489
- @
490
- hide: (shouldRemove) ->
491
- @style.opacity = 0
492
- for prefix in prefixes
493
- @style["#{prefix}Transform"] = 'scale(0, 0)'
494
-
495
- setTimeout((=> @parentNode?.removeChild @), 600) if shouldRemove
496
- @
379
+ ;
380
+
381
+ var prefixes;
382
+
383
+ (typeof exports !== "undefined" && exports !== null ? exports : this).reqwest = typeof window !== "undefined" && window !== null ? window.reqwest : reqwest;
384
+
385
+ Batman.Request.prototype._parseResponseHeaders = function(xhr) {
386
+ var headers;
387
+ return headers = xhr.getAllResponseHeaders().split('\n').reduce(function(acc, header) {
388
+ var key, matches, value;
389
+ if (matches = header.match(/([^:]*):\s*(.*)/)) {
390
+ key = matches[1];
391
+ value = matches[2];
392
+ acc[key] = value;
393
+ }
394
+ return acc;
395
+ }, {});
396
+ };
397
+
398
+ Batman.Request.prototype.send = function(data) {
399
+ var options, xhr, _ref,
400
+ _this = this;
401
+ if (data == null) {
402
+ data = this.get('data');
403
+ }
404
+ this.fire('loading');
405
+ options = {
406
+ url: this.get('url'),
407
+ method: this.get('method'),
408
+ type: this.get('type'),
409
+ headers: this.get('headers'),
410
+ success: function(response) {
411
+ _this.mixin({
412
+ xhr: xhr,
413
+ response: response,
414
+ status: typeof xhr !== "undefined" && xhr !== null ? xhr.status : void 0,
415
+ responseHeaders: _this._parseResponseHeaders(xhr)
416
+ });
417
+ return _this.fire('success', response);
418
+ },
419
+ error: function(xhr) {
420
+ _this.mixin({
421
+ xhr: xhr,
422
+ response: xhr.responseText || xhr.content,
423
+ status: xhr.status,
424
+ responseHeaders: _this._parseResponseHeaders(xhr)
425
+ });
426
+ xhr.request = _this;
427
+ return _this.fire('error', xhr);
428
+ },
429
+ complete: function() {
430
+ return _this.fire('loaded');
431
+ }
432
+ };
433
+ if ((_ref = options.method) === 'PUT' || _ref === 'POST') {
434
+ if (this.hasFileUploads()) {
435
+ options.data = this.constructor.objectToFormData(data);
436
+ } else {
437
+ options.contentType = this.get('contentType');
438
+ options.data = Batman.URI.queryFromParams(data);
439
+ }
440
+ } else {
441
+ options.data = data;
442
+ }
443
+ return xhr = (reqwest(options)).request;
444
+ };
445
+
446
+ prefixes = ['Webkit', 'Moz', 'O', 'ms', ''];
447
+
448
+ Batman.mixins.animation = {
449
+ initialize: function() {
450
+ var prefix, _i, _len;
451
+ for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
452
+ prefix = prefixes[_i];
453
+ this.style["" + prefix + "Transform"] = 'scale(0, 0)';
454
+ this.style.opacity = 0;
455
+ this.style["" + prefix + "TransitionProperty"] = "" + (prefix ? '-' + prefix.toLowerCase() + '-' : '') + "transform, opacity";
456
+ this.style["" + prefix + "TransitionDuration"] = "0.8s, 0.55s";
457
+ this.style["" + prefix + "TransformOrigin"] = "left top";
458
+ }
459
+ return this;
460
+ },
461
+ show: function(addToParent) {
462
+ var show, _ref, _ref1,
463
+ _this = this;
464
+ show = function() {
465
+ var prefix, _i, _len;
466
+ _this.style.opacity = 1;
467
+ for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
468
+ prefix = prefixes[_i];
469
+ _this.style["" + prefix + "Transform"] = 'scale(1, 1)';
470
+ }
471
+ return _this;
472
+ };
473
+ if (addToParent) {
474
+ if ((_ref = addToParent.append) != null) {
475
+ _ref.appendChild(this);
476
+ }
477
+ if ((_ref1 = addToParent.before) != null) {
478
+ _ref1.parentNode.insertBefore(this, addToParent.before);
479
+ }
480
+ setTimeout(show, 0);
481
+ } else {
482
+ show();
483
+ }
484
+ return this;
485
+ },
486
+ hide: function(shouldRemove) {
487
+ var prefix, _i, _len,
488
+ _this = this;
489
+ this.style.opacity = 0;
490
+ for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
491
+ prefix = prefixes[_i];
492
+ this.style["" + prefix + "Transform"] = 'scale(0, 0)';
493
+ }
494
+ if (shouldRemove) {
495
+ setTimeout((function() {
496
+ var _ref;
497
+ return (_ref = _this.parentNode) != null ? _ref.removeChild(_this) : void 0;
498
+ }), 600);
499
+ }
500
+ return this;
501
+ }
502
+ };
503
+
504
+ }).call(this);
@@ -0,0 +1,1021 @@
1
+ // vim: ts=4 sts=4 sw=4 expandtab
2
+ // -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License
3
+ // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
4
+ // -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA
5
+ // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
6
+ // -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License
7
+ // -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License
8
+ // -- kossnocorp Sasha Koss XXX TODO License or CLA
9
+ // -- bryanforbes Bryan Forbes XXX TODO License or CLA
10
+ // -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence
11
+ // -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License
12
+ // -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License
13
+ // -- bbqsrc Brendan Molloy XXX TODO License or CLA
14
+ // -- iwyg XXX TODO License or CLA
15
+ // -- DomenicDenicola Domenic Denicola XXX TODO License or CLA
16
+ // -- xavierm02 Montillet Xavier XXX TODO License or CLA
17
+ // -- Raynos Raynos XXX TODO License or CLA
18
+ // -- samsonjs Sami Samhuri XXX TODO License or CLA
19
+ // -- rwldrn Rick Waldron Copyright (C) 2011 MIT License
20
+ // -- lexer Alexey Zakharov XXX TODO License or CLA
21
+
22
+ /*!
23
+ Copyright (c) 2009, 280 North Inc. http://280north.com/
24
+ MIT License. http://github.com/280north/narwhal/blob/master/README.md
25
+ */
26
+
27
+ // Module systems magic dance
28
+ (function (definition) {
29
+ // RequireJS
30
+ if (typeof define == "function") {
31
+ define(definition);
32
+ // CommonJS and <script>
33
+ } else {
34
+ definition();
35
+ }
36
+ })(function () {
37
+
38
+ /**
39
+ * Brings an environment as close to ECMAScript 5 compliance
40
+ * as is possible with the facilities of erstwhile engines.
41
+ *
42
+ * ES5 Draft
43
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-050.pdf
44
+ *
45
+ * NOTE: this is a draft, and as such, the URL is subject to change. If the
46
+ * link is broken, check in the parent directory for the latest TC39 PDF.
47
+ * http://www.ecma-international.org/publications/files/drafts/
48
+ *
49
+ * Previous ES5 Draft
50
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
51
+ * This is a broken link to the previous draft of ES5 on which most of the
52
+ * numbered specification references and quotes herein were taken. Updating
53
+ * these references and quotes to reflect the new document would be a welcome
54
+ * volunteer project.
55
+ *
56
+ * @module
57
+ */
58
+
59
+ /*whatsupdoc*/
60
+
61
+ //
62
+ // Function
63
+ // ========
64
+ //
65
+
66
+ // ES-5 15.3.4.5
67
+ // http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
68
+
69
+ if (!Function.prototype.bind) {
70
+ Function.prototype.bind = function bind(that) { // .length is 1
71
+ // 1. Let Target be the this value.
72
+ var target = this;
73
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
74
+ if (typeof target != "function")
75
+ throw new TypeError(); // TODO message
76
+ // 3. Let A be a new (possibly empty) internal list of all of the
77
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
78
+ // XXX slicedArgs will stand in for "A" if used
79
+ var args = slice.call(arguments, 1); // for normal call
80
+ // 4. Let F be a new native ECMAScript object.
81
+ // 9. Set the [[Prototype]] internal property of F to the standard
82
+ // built-in Function prototype object as specified in 15.3.3.1.
83
+ // 10. Set the [[Call]] internal property of F as described in
84
+ // 15.3.4.5.1.
85
+ // 11. Set the [[Construct]] internal property of F as described in
86
+ // 15.3.4.5.2.
87
+ // 12. Set the [[HasInstance]] internal property of F as described in
88
+ // 15.3.4.5.3.
89
+ // 13. The [[Scope]] internal property of F is unused and need not
90
+ // exist.
91
+ var bound = function () {
92
+
93
+ if (this instanceof bound) {
94
+ // 15.3.4.5.2 [[Construct]]
95
+ // When the [[Construct]] internal method of a function object,
96
+ // F that was created using the bind function is called with a
97
+ // list of arguments ExtraArgs the following steps are taken:
98
+ // 1. Let target be the value of F's [[TargetFunction]]
99
+ // internal property.
100
+ // 2. If target has no [[Construct]] internal method, a
101
+ // TypeError exception is thrown.
102
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
103
+ // property.
104
+ // 4. Let args be a new list containing the same values as the
105
+ // list boundArgs in the same order followed by the same
106
+ // values as the list ExtraArgs in the same order.
107
+
108
+ var F = function(){};
109
+ F.prototype = target.prototype;
110
+ var self = new F;
111
+
112
+ var result = target.apply(
113
+ self,
114
+ args.concat(slice.call(arguments))
115
+ );
116
+ if (result !== null && Object(result) === result)
117
+ return result;
118
+ return self;
119
+
120
+ } else {
121
+ // 15.3.4.5.1 [[Call]]
122
+ // When the [[Call]] internal method of a function object, F,
123
+ // which was created using the bind function is called with a
124
+ // this value and a list of arguments ExtraArgs the following
125
+ // steps are taken:
126
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
127
+ // property.
128
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
129
+ // property.
130
+ // 3. Let target be the value of F's [[TargetFunction]] internal
131
+ // property.
132
+ // 4. Let args be a new list containing the same values as the list
133
+ // boundArgs in the same order followed by the same values as
134
+ // the list ExtraArgs in the same order. 5. Return the
135
+ // result of calling the [[Call]] internal method of target
136
+ // providing boundThis as the this value and providing args
137
+ // as the arguments.
138
+
139
+ // equiv: target.call(this, ...boundArgs, ...args)
140
+ return target.apply(
141
+ that,
142
+ args.concat(slice.call(arguments))
143
+ );
144
+
145
+ }
146
+
147
+ };
148
+ // XXX bound.length is never writable, so don't even try
149
+ //
150
+ // 16. The length own property of F is given attributes as specified in
151
+ // 15.3.5.1.
152
+ // TODO
153
+ // 17. Set the [[Extensible]] internal property of F to true.
154
+ // TODO
155
+ // 18. Call the [[DefineOwnProperty]] internal method of F with
156
+ // arguments "caller", PropertyDescriptor {[[Value]]: null,
157
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
158
+ // false}, and false.
159
+ // TODO
160
+ // 19. Call the [[DefineOwnProperty]] internal method of F with
161
+ // arguments "arguments", PropertyDescriptor {[[Value]]: null,
162
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
163
+ // false}, and false.
164
+ // TODO
165
+ // NOTE Function objects created using Function.prototype.bind do not
166
+ // have a prototype property.
167
+ // XXX can't delete it in pure-js.
168
+ return bound;
169
+ };
170
+ }
171
+
172
+ // Shortcut to an often accessed properties, in order to avoid multiple
173
+ // dereference that costs universally.
174
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
175
+ // us it in defining shortcuts.
176
+ var call = Function.prototype.call;
177
+ var prototypeOfArray = Array.prototype;
178
+ var prototypeOfObject = Object.prototype;
179
+ var slice = prototypeOfArray.slice;
180
+ var toString = call.bind(prototypeOfObject.toString);
181
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
182
+
183
+ // If JS engine supports accessors creating shortcuts.
184
+ var defineGetter;
185
+ var defineSetter;
186
+ var lookupGetter;
187
+ var lookupSetter;
188
+ var supportsAccessors;
189
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
190
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
191
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
192
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
193
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
194
+ }
195
+
196
+ //
197
+ // Array
198
+ // =====
199
+ //
200
+
201
+ // ES5 15.4.3.2
202
+ if (!Array.isArray) {
203
+ Array.isArray = function isArray(obj) {
204
+ return toString(obj) == "[object Array]";
205
+ };
206
+ }
207
+
208
+ // The IsCallable() check in the Array functions
209
+ // has been replaced with a strict check on the
210
+ // internal class of the object to trap cases where
211
+ // the provided function was actually a regular
212
+ // expression literal, which in V8 and
213
+ // JavaScriptCore is a typeof "function". Only in
214
+ // V8 are regular expression literals permitted as
215
+ // reduce parameters, so it is desirable in the
216
+ // general case for the shim to match the more
217
+ // strict and common behavior of rejecting regular
218
+ // expressions.
219
+
220
+ // ES5 15.4.4.18
221
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
222
+ if (!Array.prototype.forEach) {
223
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
224
+ var self = toObject(this),
225
+ thisp = arguments[1],
226
+ i = 0,
227
+ length = self.length >>> 0;
228
+
229
+ // If no callback function or if callback is not a callable function
230
+ if (toString(fun) != "[object Function]") {
231
+ throw new TypeError(); // TODO message
232
+ }
233
+
234
+ while (i < length) {
235
+ if (i in self) {
236
+ // Invoke the callback function with call, passing arguments:
237
+ // context, property value, property key, thisArg object context
238
+ fun.call(thisp, self[i], i, self);
239
+ }
240
+ i++;
241
+ }
242
+ };
243
+ }
244
+
245
+ // ES5 15.4.4.19
246
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
247
+ if (!Array.prototype.map) {
248
+ Array.prototype.map = function map(fun /*, thisp*/) {
249
+ var self = toObject(this),
250
+ length = self.length >>> 0,
251
+ result = Array(length),
252
+ thisp = arguments[1];
253
+
254
+ // If no callback function or if callback is not a callable function
255
+ if (toString(fun) != "[object Function]") {
256
+ throw new TypeError(); // TODO message
257
+ }
258
+
259
+ for (var i = 0; i < length; i++) {
260
+ if (i in self)
261
+ result[i] = fun.call(thisp, self[i], i, self);
262
+ }
263
+ return result;
264
+ };
265
+ }
266
+
267
+ // ES5 15.4.4.20
268
+ if (!Array.prototype.filter) {
269
+ Array.prototype.filter = function filter(fun /*, thisp */) {
270
+ var self = toObject(this),
271
+ length = self.length >>> 0,
272
+ result = [],
273
+ thisp = arguments[1];
274
+
275
+ // If no callback function or if callback is not a callable function
276
+ if (toString(fun) != "[object Function]") {
277
+ throw new TypeError(); // TODO message
278
+ }
279
+
280
+ for (var i = 0; i < length; i++) {
281
+ if (i in self && fun.call(thisp, self[i], i, self))
282
+ result.push(self[i]);
283
+ }
284
+ return result;
285
+ };
286
+ }
287
+
288
+ // ES5 15.4.4.16
289
+ if (!Array.prototype.every) {
290
+ Array.prototype.every = function every(fun /*, thisp */) {
291
+ var self = toObject(this),
292
+ length = self.length >>> 0,
293
+ thisp = arguments[1];
294
+
295
+ // If no callback function or if callback is not a callable function
296
+ if (toString(fun) != "[object Function]") {
297
+ throw new TypeError(); // TODO message
298
+ }
299
+
300
+ for (var i = 0; i < length; i++) {
301
+ if (i in self && !fun.call(thisp, self[i], i, self))
302
+ return false;
303
+ }
304
+ return true;
305
+ };
306
+ }
307
+
308
+ // ES5 15.4.4.17
309
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
310
+ if (!Array.prototype.some) {
311
+ Array.prototype.some = function some(fun /*, thisp */) {
312
+ var self = toObject(this),
313
+ length = self.length >>> 0,
314
+ thisp = arguments[1];
315
+
316
+ // If no callback function or if callback is not a callable function
317
+ if (toString(fun) != "[object Function]") {
318
+ throw new TypeError(); // TODO message
319
+ }
320
+
321
+ for (var i = 0; i < length; i++) {
322
+ if (i in self && fun.call(thisp, self[i], i, self))
323
+ return true;
324
+ }
325
+ return false;
326
+ };
327
+ }
328
+
329
+ // ES5 15.4.4.21
330
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
331
+ if (!Array.prototype.reduce) {
332
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
333
+ var self = toObject(this),
334
+ length = self.length >>> 0;
335
+
336
+ // If no callback function or if callback is not a callable function
337
+ if (toString(fun) != "[object Function]") {
338
+ throw new TypeError(); // TODO message
339
+ }
340
+
341
+ // no value to return if no initial value and an empty array
342
+ if (!length && arguments.length == 1)
343
+ throw new TypeError(); // TODO message
344
+
345
+ var i = 0;
346
+ var result;
347
+ if (arguments.length >= 2) {
348
+ result = arguments[1];
349
+ } else {
350
+ do {
351
+ if (i in self) {
352
+ result = self[i++];
353
+ break;
354
+ }
355
+
356
+ // if array contains no values, no initial value to return
357
+ if (++i >= length)
358
+ throw new TypeError(); // TODO message
359
+ } while (true);
360
+ }
361
+
362
+ for (; i < length; i++) {
363
+ if (i in self)
364
+ result = fun.call(void 0, result, self[i], i, self);
365
+ }
366
+
367
+ return result;
368
+ };
369
+ }
370
+
371
+ // ES5 15.4.4.22
372
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
373
+ if (!Array.prototype.reduceRight) {
374
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
375
+ var self = toObject(this),
376
+ length = self.length >>> 0;
377
+
378
+ // If no callback function or if callback is not a callable function
379
+ if (toString(fun) != "[object Function]") {
380
+ throw new TypeError(); // TODO message
381
+ }
382
+
383
+ // no value to return if no initial value, empty array
384
+ if (!length && arguments.length == 1)
385
+ throw new TypeError(); // TODO message
386
+
387
+ var result, i = length - 1;
388
+ if (arguments.length >= 2) {
389
+ result = arguments[1];
390
+ } else {
391
+ do {
392
+ if (i in self) {
393
+ result = self[i--];
394
+ break;
395
+ }
396
+
397
+ // if array contains no values, no initial value to return
398
+ if (--i < 0)
399
+ throw new TypeError(); // TODO message
400
+ } while (true);
401
+ }
402
+
403
+ do {
404
+ if (i in this)
405
+ result = fun.call(void 0, result, self[i], i, self);
406
+ } while (i--);
407
+
408
+ return result;
409
+ };
410
+ }
411
+
412
+ // ES5 15.4.4.14
413
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
414
+ if (!Array.prototype.indexOf) {
415
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
416
+ var self = toObject(this),
417
+ length = self.length >>> 0;
418
+
419
+ if (!length)
420
+ return -1;
421
+
422
+ var i = 0;
423
+ if (arguments.length > 1)
424
+ i = toInteger(arguments[1]);
425
+
426
+ // handle negative indices
427
+ i = i >= 0 ? i : length - Math.abs(i);
428
+ for (; i < length; i++) {
429
+ if (i in self && self[i] === sought) {
430
+ return i;
431
+ }
432
+ }
433
+ return -1;
434
+ };
435
+ }
436
+
437
+ // ES5 15.4.4.15
438
+ if (!Array.prototype.lastIndexOf) {
439
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
440
+ var self = toObject(this),
441
+ length = self.length >>> 0;
442
+
443
+ if (!length)
444
+ return -1;
445
+ var i = length - 1;
446
+ if (arguments.length > 1)
447
+ i = toInteger(arguments[1]);
448
+ // handle negative indices
449
+ i = i >= 0 ? i : length - Math.abs(i);
450
+ for (; i >= 0; i--) {
451
+ if (i in self && sought === self[i])
452
+ return i;
453
+ }
454
+ return -1;
455
+ };
456
+ }
457
+
458
+ //
459
+ // Object
460
+ // ======
461
+ //
462
+
463
+ // ES5 15.2.3.2
464
+ if (!Object.getPrototypeOf) {
465
+ // https://github.com/kriskowal/es5-shim/issues#issue/2
466
+ // http://ejohn.org/blog/objectgetprototypeof/
467
+ // recommended by fschaefer on github
468
+ Object.getPrototypeOf = function getPrototypeOf(object) {
469
+ return object.__proto__ || (
470
+ object.constructor ?
471
+ object.constructor.prototype :
472
+ prototypeOfObject
473
+ );
474
+ };
475
+ }
476
+
477
+ // ES5 15.2.3.3
478
+ if (!Object.getOwnPropertyDescriptor) {
479
+ var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
480
+ "non-object: ";
481
+ Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
482
+ if ((typeof object != "object" && typeof object != "function") || object === null)
483
+ throw new TypeError(ERR_NON_OBJECT + object);
484
+ // If object does not owns property return undefined immediately.
485
+ if (!owns(object, property))
486
+ return;
487
+
488
+ var descriptor, getter, setter;
489
+
490
+ // If object has a property then it's for sure both `enumerable` and
491
+ // `configurable`.
492
+ descriptor = { enumerable: true, configurable: true };
493
+
494
+ // If JS engine supports accessor properties then property may be a
495
+ // getter or setter.
496
+ if (supportsAccessors) {
497
+ // Unfortunately `__lookupGetter__` will return a getter even
498
+ // if object has own non getter property along with a same named
499
+ // inherited getter. To avoid misbehavior we temporary remove
500
+ // `__proto__` so that `__lookupGetter__` will return getter only
501
+ // if it's owned by an object.
502
+ var prototype = object.__proto__;
503
+ object.__proto__ = prototypeOfObject;
504
+
505
+ var getter = lookupGetter(object, property);
506
+ var setter = lookupSetter(object, property);
507
+
508
+ // Once we have getter and setter we can put values back.
509
+ object.__proto__ = prototype;
510
+
511
+ if (getter || setter) {
512
+ if (getter) descriptor.get = getter;
513
+ if (setter) descriptor.set = setter;
514
+
515
+ // If it was accessor property we're done and return here
516
+ // in order to avoid adding `value` to the descriptor.
517
+ return descriptor;
518
+ }
519
+ }
520
+
521
+ // If we got this far we know that object has an own property that is
522
+ // not an accessor so we set it as a value and return descriptor.
523
+ descriptor.value = object[property];
524
+ return descriptor;
525
+ };
526
+ }
527
+
528
+ // ES5 15.2.3.4
529
+ if (!Object.getOwnPropertyNames) {
530
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
531
+ return Object.keys(object);
532
+ };
533
+ }
534
+
535
+ // ES5 15.2.3.5
536
+ if (!Object.create) {
537
+ Object.create = function create(prototype, properties) {
538
+ var object;
539
+ if (prototype === null) {
540
+ object = { "__proto__": null };
541
+ } else {
542
+ if (typeof prototype != "object")
543
+ throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
544
+ var Type = function () {};
545
+ Type.prototype = prototype;
546
+ object = new Type();
547
+ // IE has no built-in implementation of `Object.getPrototypeOf`
548
+ // neither `__proto__`, but this manually setting `__proto__` will
549
+ // guarantee that `Object.getPrototypeOf` will work as expected with
550
+ // objects created using `Object.create`
551
+ object.__proto__ = prototype;
552
+ }
553
+ if (properties !== void 0)
554
+ Object.defineProperties(object, properties);
555
+ return object;
556
+ };
557
+ }
558
+
559
+ // ES5 15.2.3.6
560
+
561
+ // Patch for WebKit and IE8 standard mode
562
+ // Designed by hax <hax.github.com>
563
+ // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
564
+ // IE8 Reference:
565
+ // http://msdn.microsoft.com/en-us/library/dd282900.aspx
566
+ // http://msdn.microsoft.com/en-us/library/dd229916.aspx
567
+ // WebKit Bugs:
568
+ // https://bugs.webkit.org/show_bug.cgi?id=36423
569
+
570
+ function doesDefinePropertyWork(object) {
571
+ try {
572
+ Object.defineProperty(object, "sentinel", {});
573
+ return "sentinel" in object;
574
+ } catch (exception) {
575
+ // returns falsy
576
+ }
577
+ }
578
+
579
+ // check whether defineProperty works if it's given. Otherwise,
580
+ // shim partially.
581
+ if (Object.defineProperty) {
582
+ var definePropertyWorksOnObject = doesDefinePropertyWork({});
583
+ var definePropertyWorksOnDom = typeof document == "undefined" ||
584
+ doesDefinePropertyWork(document.createElement("div"));
585
+ if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
586
+ var definePropertyFallback = Object.defineProperty;
587
+ }
588
+ }
589
+
590
+ if (!Object.defineProperty || definePropertyFallback) {
591
+ var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
592
+ var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
593
+ var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
594
+ "on this javascript engine";
595
+
596
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
597
+ if ((typeof object != "object" && typeof object != "function") || object === null)
598
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
599
+ if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
600
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
601
+
602
+ // make a valiant attempt to use the real defineProperty
603
+ // for I8's DOM elements.
604
+ if (definePropertyFallback) {
605
+ try {
606
+ return definePropertyFallback.call(Object, object, property, descriptor);
607
+ } catch (exception) {
608
+ // try the shim if the real one doesn't work
609
+ }
610
+ }
611
+
612
+ // If it's a data property.
613
+ if (owns(descriptor, "value")) {
614
+ // fail silently if "writable", "enumerable", or "configurable"
615
+ // are requested but not supported
616
+ /*
617
+ // alternate approach:
618
+ if ( // can't implement these features; allow false but not true
619
+ !(owns(descriptor, "writable") ? descriptor.writable : true) ||
620
+ !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
621
+ !(owns(descriptor, "configurable") ? descriptor.configurable : true)
622
+ )
623
+ throw new RangeError(
624
+ "This implementation of Object.defineProperty does not " +
625
+ "support configurable, enumerable, or writable."
626
+ );
627
+ */
628
+
629
+ if (supportsAccessors && (lookupGetter(object, property) ||
630
+ lookupSetter(object, property)))
631
+ {
632
+ // As accessors are supported only on engines implementing
633
+ // `__proto__` we can safely override `__proto__` while defining
634
+ // a property to make sure that we don't hit an inherited
635
+ // accessor.
636
+ var prototype = object.__proto__;
637
+ object.__proto__ = prototypeOfObject;
638
+ // Deleting a property anyway since getter / setter may be
639
+ // defined on object itself.
640
+ delete object[property];
641
+ object[property] = descriptor.value;
642
+ // Setting original `__proto__` back now.
643
+ object.__proto__ = prototype;
644
+ } else {
645
+ object[property] = descriptor.value;
646
+ }
647
+ } else {
648
+ if (!supportsAccessors)
649
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
650
+ // If we got that far then getters and setters can be defined !!
651
+ if (owns(descriptor, "get"))
652
+ defineGetter(object, property, descriptor.get);
653
+ if (owns(descriptor, "set"))
654
+ defineSetter(object, property, descriptor.set);
655
+ }
656
+
657
+ return object;
658
+ };
659
+ }
660
+
661
+ // ES5 15.2.3.7
662
+ if (!Object.defineProperties) {
663
+ Object.defineProperties = function defineProperties(object, properties) {
664
+ for (var property in properties) {
665
+ if (owns(properties, property))
666
+ Object.defineProperty(object, property, properties[property]);
667
+ }
668
+ return object;
669
+ };
670
+ }
671
+
672
+ // ES5 15.2.3.8
673
+ if (!Object.seal) {
674
+ Object.seal = function seal(object) {
675
+ // this is misleading and breaks feature-detection, but
676
+ // allows "securable" code to "gracefully" degrade to working
677
+ // but insecure code.
678
+ return object;
679
+ };
680
+ }
681
+
682
+ // ES5 15.2.3.9
683
+ if (!Object.freeze) {
684
+ Object.freeze = function freeze(object) {
685
+ // this is misleading and breaks feature-detection, but
686
+ // allows "securable" code to "gracefully" degrade to working
687
+ // but insecure code.
688
+ return object;
689
+ };
690
+ }
691
+
692
+ // detect a Rhino bug and patch it
693
+ try {
694
+ Object.freeze(function () {});
695
+ } catch (exception) {
696
+ Object.freeze = (function freeze(freezeObject) {
697
+ return function freeze(object) {
698
+ if (typeof object == "function") {
699
+ return object;
700
+ } else {
701
+ return freezeObject(object);
702
+ }
703
+ };
704
+ })(Object.freeze);
705
+ }
706
+
707
+ // ES5 15.2.3.10
708
+ if (!Object.preventExtensions) {
709
+ Object.preventExtensions = function preventExtensions(object) {
710
+ // this is misleading and breaks feature-detection, but
711
+ // allows "securable" code to "gracefully" degrade to working
712
+ // but insecure code.
713
+ return object;
714
+ };
715
+ }
716
+
717
+ // ES5 15.2.3.11
718
+ if (!Object.isSealed) {
719
+ Object.isSealed = function isSealed(object) {
720
+ return false;
721
+ };
722
+ }
723
+
724
+ // ES5 15.2.3.12
725
+ if (!Object.isFrozen) {
726
+ Object.isFrozen = function isFrozen(object) {
727
+ return false;
728
+ };
729
+ }
730
+
731
+ // ES5 15.2.3.13
732
+ if (!Object.isExtensible) {
733
+ Object.isExtensible = function isExtensible(object) {
734
+ // 1. If Type(O) is not Object throw a TypeError exception.
735
+ if (Object(object) === object) {
736
+ throw new TypeError(); // TODO message
737
+ }
738
+ // 2. Return the Boolean value of the [[Extensible]] internal property of O.
739
+ var name = '';
740
+ while (owns(object, name)) {
741
+ name += '?';
742
+ }
743
+ object[name] = true;
744
+ var returnValue = owns(object, name);
745
+ delete object[name];
746
+ return returnValue;
747
+ };
748
+ }
749
+
750
+ // ES5 15.2.3.14
751
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
752
+ if (!Object.keys) {
753
+
754
+ var hasDontEnumBug = true,
755
+ dontEnums = [
756
+ "toString",
757
+ "toLocaleString",
758
+ "valueOf",
759
+ "hasOwnProperty",
760
+ "isPrototypeOf",
761
+ "propertyIsEnumerable",
762
+ "constructor"
763
+ ],
764
+ dontEnumsLength = dontEnums.length;
765
+
766
+ for (var key in {"toString": null})
767
+ hasDontEnumBug = false;
768
+
769
+ Object.keys = function keys(object) {
770
+
771
+ if ((typeof object != "object" && typeof object != "function") || object === null)
772
+ throw new TypeError("Object.keys called on a non-object");
773
+
774
+ var keys = [];
775
+ for (var name in object) {
776
+ if (owns(object, name)) {
777
+ keys.push(name);
778
+ }
779
+ }
780
+
781
+ if (hasDontEnumBug) {
782
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
783
+ var dontEnum = dontEnums[i];
784
+ if (owns(object, dontEnum)) {
785
+ keys.push(dontEnum);
786
+ }
787
+ }
788
+ }
789
+
790
+ return keys;
791
+ };
792
+
793
+ }
794
+
795
+ //
796
+ // Date
797
+ // ====
798
+ //
799
+
800
+ // ES5 15.9.5.43
801
+ // Format a Date object as a string according to a simplified subset of the ISO 8601
802
+ // standard as defined in 15.9.1.15.
803
+ if (!Date.prototype.toISOString) {
804
+ Date.prototype.toISOString = function toISOString() {
805
+ var result, length, value;
806
+ if (!isFinite(this))
807
+ throw new RangeError;
808
+
809
+ // the date time string format is specified in 15.9.1.15.
810
+ result = [this.getUTCFullYear(), this.getUTCMonth() + 1, this.getUTCDate(),
811
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
812
+
813
+ length = result.length;
814
+ while (length--) {
815
+ value = result[length];
816
+ // pad months, days, hours, minutes, and seconds to have two digits.
817
+ if (value < 10)
818
+ result[length] = "0" + value;
819
+ }
820
+ // pad milliseconds to have three digits.
821
+ return result.slice(0, 3).join("-") + "T" + result.slice(3).join(":") + "." +
822
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
823
+ }
824
+ }
825
+
826
+ // ES5 15.9.4.4
827
+ if (!Date.now) {
828
+ Date.now = function now() {
829
+ return new Date().getTime();
830
+ };
831
+ }
832
+
833
+ // ES5 15.9.5.44
834
+ if (!Date.prototype.toJSON) {
835
+ Date.prototype.toJSON = function toJSON(key) {
836
+ // This function provides a String representation of a Date object for
837
+ // use by JSON.stringify (15.12.3). When the toJSON method is called
838
+ // with argument key, the following steps are taken:
839
+
840
+ // 1. Let O be the result of calling ToObject, giving it the this
841
+ // value as its argument.
842
+ // 2. Let tv be ToPrimitive(O, hint Number).
843
+ // 3. If tv is a Number and is not finite, return null.
844
+ // XXX
845
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
846
+ // O with argument "toISOString".
847
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
848
+ if (typeof this.toISOString != "function")
849
+ throw new TypeError(); // TODO message
850
+ // 6. Return the result of calling the [[Call]] internal method of
851
+ // toISO with O as the this value and an empty argument list.
852
+ return this.toISOString();
853
+
854
+ // NOTE 1 The argument is ignored.
855
+
856
+ // NOTE 2 The toJSON function is intentionally generic; it does not
857
+ // require that its this value be a Date object. Therefore, it can be
858
+ // transferred to other kinds of objects for use as a method. However,
859
+ // it does require that any such object have a toISOString method. An
860
+ // object is free to use the argument key to filter its
861
+ // stringification.
862
+ };
863
+ }
864
+
865
+ // 15.9.4.2 Date.parse (string)
866
+ // 15.9.1.15 Date Time String Format
867
+ // Date.parse
868
+ // based on work shared by Daniel Friesen (dantman)
869
+ // http://gist.github.com/303249
870
+ if (isNaN(Date.parse("2011-06-15T21:40:05+06:00"))) {
871
+ // XXX global assignment won't work in embeddings that use
872
+ // an alternate object for the context.
873
+ Date = (function(NativeDate) {
874
+
875
+ // Date.length === 7
876
+ var Date = function Date(Y, M, D, h, m, s, ms) {
877
+ var length = arguments.length;
878
+ if (this instanceof NativeDate) {
879
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
880
+ // We explicitly pass it through parse:
881
+ new NativeDate(Date.parse(Y)) :
882
+ // We have to manually make calls depending on argument
883
+ // length here
884
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
885
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
886
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
887
+ length >= 4 ? new NativeDate(Y, M, D, h) :
888
+ length >= 3 ? new NativeDate(Y, M, D) :
889
+ length >= 2 ? new NativeDate(Y, M) :
890
+ length >= 1 ? new NativeDate(Y) :
891
+ new NativeDate();
892
+ // Prevent mixups with unfixed Date object
893
+ date.constructor = Date;
894
+ return date;
895
+ }
896
+ return NativeDate.apply(this, arguments);
897
+ };
898
+
899
+ // 15.9.1.15 Date Time String Format. This pattern does not implement
900
+ // extended years (15.9.1.15.1), as `Date.UTC` cannot parse them.
901
+ var isoDateExpression = new RegExp("^" +
902
+ "(\\d{4})" + // four-digit year capture
903
+ "(?:-(\\d{2})" + // optional month capture
904
+ "(?:-(\\d{2})" + // optional day capture
905
+ "(?:" + // capture hours:minutes:seconds.milliseconds
906
+ "T(\\d{2})" + // hours capture
907
+ ":(\\d{2})" + // minutes capture
908
+ "(?:" + // optional :seconds.milliseconds
909
+ ":(\\d{2})" + // seconds capture
910
+ "(?:\\.(\\d{3}))?" + // milliseconds capture
911
+ ")?" +
912
+ "(?:" + // capture UTC offset component
913
+ "Z|" + // UTC capture
914
+ "(?:" + // offset specifier +/-hours:minutes
915
+ "([-+])" + // sign capture
916
+ "(\\d{2})" + // hours offset capture
917
+ ":(\\d{2})" + // minutes offset capture
918
+ ")" +
919
+ ")?)?)?)?" +
920
+ "$");
921
+
922
+ // Copy any custom methods a 3rd party library may have added
923
+ for (var key in NativeDate)
924
+ Date[key] = NativeDate[key];
925
+
926
+ // Copy "native" methods explicitly; they may be non-enumerable
927
+ Date.now = NativeDate.now;
928
+ Date.UTC = NativeDate.UTC;
929
+ Date.prototype = NativeDate.prototype;
930
+ Date.prototype.constructor = Date;
931
+
932
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
933
+ Date.parse = function parse(string) {
934
+ var match = isoDateExpression.exec(string);
935
+ if (match) {
936
+ match.shift(); // kill match[0], the full match
937
+ // parse months, days, hours, minutes, seconds, and milliseconds
938
+ for (var i = 1; i < 7; i++) {
939
+ // provide default values if necessary
940
+ match[i] = +(match[i] || (i < 3 ? 1 : 0));
941
+ // match[1] is the month. Months are 0-11 in JavaScript
942
+ // `Date` objects, but 1-12 in ISO notation, so we
943
+ // decrement.
944
+ if (i == 1)
945
+ match[i]--;
946
+ }
947
+
948
+ // parse the UTC offset component
949
+ var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
950
+
951
+ // compute the explicit time zone offset if specified
952
+ var offset = 0;
953
+ if (sign) {
954
+ // detect invalid offsets and return early
955
+ if (hourOffset > 23 || minuteOffset > 59)
956
+ return NaN;
957
+
958
+ // express the provided time zone offset in minutes. The offset is
959
+ // negative for time zones west of UTC; positive otherwise.
960
+ offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
961
+ }
962
+
963
+ // compute a new UTC date value, accounting for the optional offset
964
+ return NativeDate.UTC.apply(this, match) + offset;
965
+ }
966
+ return NativeDate.parse.apply(this, arguments);
967
+ };
968
+
969
+ return Date;
970
+ })(Date);
971
+ }
972
+
973
+ //
974
+ // String
975
+ // ======
976
+ //
977
+
978
+ // ES5 15.5.4.20
979
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
980
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
981
+ "\u2029\uFEFF";
982
+ if (!String.prototype.trim || ws.trim()) {
983
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
984
+ // http://perfectionkills.com/whitespace-deviations/
985
+ ws = "[" + ws + "]";
986
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
987
+ trimEndRegexp = new RegExp(ws + ws + "*$");
988
+ String.prototype.trim = function trim() {
989
+ return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
990
+ };
991
+ }
992
+
993
+ //
994
+ // Util
995
+ // ======
996
+ //
997
+
998
+ // http://jsperf.com/to-integer
999
+ var toInteger = function (n) {
1000
+ n = +n;
1001
+ if (n !== n) // isNaN
1002
+ n = -1;
1003
+ else if (n !== 0 && n !== (1/0) && n !== -(1/0))
1004
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1005
+ return n;
1006
+ };
1007
+
1008
+ var prepareString = "a"[0] != "a",
1009
+ // ES5 9.9
1010
+ toObject = function (o) {
1011
+ if (o == null) { // this matches both null and undefined
1012
+ throw new TypeError(); // TODO message
1013
+ }
1014
+ // If the implementation doesn't support by-index access of
1015
+ // string characters (ex. IE < 7), split the string
1016
+ if (prepareString && typeof o == "string" && o) {
1017
+ return o.split("");
1018
+ }
1019
+ return Object(o);
1020
+ };
1021
+ });