DYEBench should use TodoMVC to test FlightJS for consistency
[WebKit-https.git] / PerformanceTests / DoYouEvenBench / resources / todomvc / dependency-examples / flight / bower_components / es5-shim / es5-shim.js
1 // Copyright 2009-2012 by contributors, MIT License
2 // vim: ts=4 sts=4 sw=4 expandtab
3
4 // Module systems magic dance
5 (function (definition) {
6     // RequireJS
7     if (typeof define == "function") {
8         define(definition);
9     // YUI3
10     } else if (typeof YUI == "function") {
11         YUI.add("es5", definition);
12     // CommonJS and <script>
13     } else {
14         definition();
15     }
16 })(function () {
17
18 /**
19  * Brings an environment as close to ECMAScript 5 compliance
20  * as is possible with the facilities of erstwhile engines.
21  *
22  * Annotated ES5: http://es5.github.com/ (specific links below)
23  * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
24  * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
25  */
26
27 //
28 // Function
29 // ========
30 //
31
32 // ES-5 15.3.4.5
33 // http://es5.github.com/#x15.3.4.5
34
35 if (!Function.prototype.bind) {
36     Function.prototype.bind = function bind(that) { // .length is 1
37         // 1. Let Target be the this value.
38         var target = this;
39         // 2. If IsCallable(Target) is false, throw a TypeError exception.
40         if (typeof target != "function") {
41             throw new TypeError("Function.prototype.bind called on incompatible " + target);
42         }
43         // 3. Let A be a new (possibly empty) internal list of all of the
44         //   argument values provided after thisArg (arg1, arg2 etc), in order.
45         // XXX slicedArgs will stand in for "A" if used
46         var args = slice.call(arguments, 1); // for normal call
47         // 4. Let F be a new native ECMAScript object.
48         // 11. Set the [[Prototype]] internal property of F to the standard
49         //   built-in Function prototype object as specified in 15.3.3.1.
50         // 12. Set the [[Call]] internal property of F as described in
51         //   15.3.4.5.1.
52         // 13. Set the [[Construct]] internal property of F as described in
53         //   15.3.4.5.2.
54         // 14. Set the [[HasInstance]] internal property of F as described in
55         //   15.3.4.5.3.
56         var bound = function () {
57
58             if (this instanceof bound) {
59                 // 15.3.4.5.2 [[Construct]]
60                 // When the [[Construct]] internal method of a function object,
61                 // F that was created using the bind function is called with a
62                 // list of arguments ExtraArgs, the following steps are taken:
63                 // 1. Let target be the value of F's [[TargetFunction]]
64                 //   internal property.
65                 // 2. If target has no [[Construct]] internal method, a
66                 //   TypeError exception is thrown.
67                 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
68                 //   property.
69                 // 4. Let args be a new list containing the same values as the
70                 //   list boundArgs in the same order followed by the same
71                 //   values as the list ExtraArgs in the same order.
72                 // 5. Return the result of calling the [[Construct]] internal
73                 //   method of target providing args as the arguments.
74
75                 var F = function(){};
76                 F.prototype = target.prototype;
77                 var self = new F;
78
79                 var result = target.apply(
80                     self,
81                     args.concat(slice.call(arguments))
82                 );
83                 if (Object(result) === result) {
84                     return result;
85                 }
86                 return self;
87
88             } else {
89                 // 15.3.4.5.1 [[Call]]
90                 // When the [[Call]] internal method of a function object, F,
91                 // which was created using the bind function is called with a
92                 // this value and a list of arguments ExtraArgs, the following
93                 // steps are taken:
94                 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
95                 //   property.
96                 // 2. Let boundThis be the value of F's [[BoundThis]] internal
97                 //   property.
98                 // 3. Let target be the value of F's [[TargetFunction]] internal
99                 //   property.
100                 // 4. Let args be a new list containing the same values as the
101                 //   list boundArgs in the same order followed by the same
102                 //   values as the list ExtraArgs in the same order.
103                 // 5. Return the result of calling the [[Call]] internal method
104                 //   of target providing boundThis as the this value and
105                 //   providing args as the arguments.
106
107                 // equiv: target.call(this, ...boundArgs, ...args)
108                 return target.apply(
109                     that,
110                     args.concat(slice.call(arguments))
111                 );
112
113             }
114
115         };
116         // XXX bound.length is never writable, so don't even try
117         //
118         // 15. If the [[Class]] internal property of Target is "Function", then
119         //     a. Let L be the length property of Target minus the length of A.
120         //     b. Set the length own property of F to either 0 or L, whichever is
121         //       larger.
122         // 16. Else set the length own property of F to 0.
123         // 17. Set the attributes of the length own property of F to the values
124         //   specified in 15.3.5.1.
125
126         // TODO
127         // 18. Set the [[Extensible]] internal property of F to true.
128
129         // TODO
130         // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
131         // 20. Call the [[DefineOwnProperty]] internal method of F with
132         //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
133         //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
134         //   false.
135         // 21. Call the [[DefineOwnProperty]] internal method of F with
136         //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
137         //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
138         //   and false.
139
140         // TODO
141         // NOTE Function objects created using Function.prototype.bind do not
142         // have a prototype property or the [[Code]], [[FormalParameters]], and
143         // [[Scope]] internal properties.
144         // XXX can't delete prototype in pure-js.
145
146         // 22. Return F.
147         return bound;
148     };
149 }
150
151 // Shortcut to an often accessed properties, in order to avoid multiple
152 // dereference that costs universally.
153 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
154 // us it in defining shortcuts.
155 var call = Function.prototype.call;
156 var prototypeOfArray = Array.prototype;
157 var prototypeOfObject = Object.prototype;
158 var slice = prototypeOfArray.slice;
159 // Having a toString local variable name breaks in Opera so use _toString.
160 var _toString = call.bind(prototypeOfObject.toString);
161 var owns = call.bind(prototypeOfObject.hasOwnProperty);
162
163 // If JS engine supports accessors creating shortcuts.
164 var defineGetter;
165 var defineSetter;
166 var lookupGetter;
167 var lookupSetter;
168 var supportsAccessors;
169 if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
170     defineGetter = call.bind(prototypeOfObject.__defineGetter__);
171     defineSetter = call.bind(prototypeOfObject.__defineSetter__);
172     lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
173     lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
174 }
175
176 //
177 // Array
178 // =====
179 //
180
181 // ES5 15.4.3.2
182 // http://es5.github.com/#x15.4.3.2
183 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
184 if (!Array.isArray) {
185     Array.isArray = function isArray(obj) {
186         return _toString(obj) == "[object Array]";
187     };
188 }
189
190 // The IsCallable() check in the Array functions
191 // has been replaced with a strict check on the
192 // internal class of the object to trap cases where
193 // the provided function was actually a regular
194 // expression literal, which in V8 and
195 // JavaScriptCore is a typeof "function".  Only in
196 // V8 are regular expression literals permitted as
197 // reduce parameters, so it is desirable in the
198 // general case for the shim to match the more
199 // strict and common behavior of rejecting regular
200 // expressions.
201
202 // ES5 15.4.4.18
203 // http://es5.github.com/#x15.4.4.18
204 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
205 if (!Array.prototype.forEach) {
206     Array.prototype.forEach = function forEach(fun /*, thisp*/) {
207         var self = toObject(this),
208             thisp = arguments[1],
209             i = -1,
210             length = self.length >>> 0;
211
212         // If no callback function or if callback is not a callable function
213         if (_toString(fun) != "[object Function]") {
214             throw new TypeError(); // TODO message
215         }
216
217         while (++i < length) {
218             if (i in self) {
219                 // Invoke the callback function with call, passing arguments:
220                 // context, property value, property key, thisArg object context
221                 fun.call(thisp, self[i], i, self);
222             }
223         }
224     };
225 }
226
227 // ES5 15.4.4.19
228 // http://es5.github.com/#x15.4.4.19
229 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
230 if (!Array.prototype.map) {
231     Array.prototype.map = function map(fun /*, thisp*/) {
232         var self = toObject(this),
233             length = self.length >>> 0,
234             result = Array(length),
235             thisp = arguments[1];
236
237         // If no callback function or if callback is not a callable function
238         if (_toString(fun) != "[object Function]") {
239             throw new TypeError(fun + " is not a function");
240         }
241
242         for (var i = 0; i < length; i++) {
243             if (i in self)
244                 result[i] = fun.call(thisp, self[i], i, self);
245         }
246         return result;
247     };
248 }
249
250 // ES5 15.4.4.20
251 // http://es5.github.com/#x15.4.4.20
252 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
253 if (!Array.prototype.filter) {
254     Array.prototype.filter = function filter(fun /*, thisp */) {
255         var self = toObject(this),
256             length = self.length >>> 0,
257             result = [],
258             value,
259             thisp = arguments[1];
260
261         // If no callback function or if callback is not a callable function
262         if (_toString(fun) != "[object Function]") {
263             throw new TypeError(fun + " is not a function");
264         }
265
266         for (var i = 0; i < length; i++) {
267             if (i in self) {
268                 value = self[i];
269                 if (fun.call(thisp, value, i, self)) {
270                     result.push(value);
271                 }
272             }
273         }
274         return result;
275     };
276 }
277
278 // ES5 15.4.4.16
279 // http://es5.github.com/#x15.4.4.16
280 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
281 if (!Array.prototype.every) {
282     Array.prototype.every = function every(fun /*, thisp */) {
283         var self = toObject(this),
284             length = self.length >>> 0,
285             thisp = arguments[1];
286
287         // If no callback function or if callback is not a callable function
288         if (_toString(fun) != "[object Function]") {
289             throw new TypeError(fun + " is not a function");
290         }
291
292         for (var i = 0; i < length; i++) {
293             if (i in self && !fun.call(thisp, self[i], i, self)) {
294                 return false;
295             }
296         }
297         return true;
298     };
299 }
300
301 // ES5 15.4.4.17
302 // http://es5.github.com/#x15.4.4.17
303 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
304 if (!Array.prototype.some) {
305     Array.prototype.some = function some(fun /*, thisp */) {
306         var self = toObject(this),
307             length = self.length >>> 0,
308             thisp = arguments[1];
309
310         // If no callback function or if callback is not a callable function
311         if (_toString(fun) != "[object Function]") {
312             throw new TypeError(fun + " is not a function");
313         }
314
315         for (var i = 0; i < length; i++) {
316             if (i in self && fun.call(thisp, self[i], i, self)) {
317                 return true;
318             }
319         }
320         return false;
321     };
322 }
323
324 // ES5 15.4.4.21
325 // http://es5.github.com/#x15.4.4.21
326 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
327 if (!Array.prototype.reduce) {
328     Array.prototype.reduce = function reduce(fun /*, initial*/) {
329         var self = toObject(this),
330             length = self.length >>> 0;
331
332         // If no callback function or if callback is not a callable function
333         if (_toString(fun) != "[object Function]") {
334             throw new TypeError(fun + " is not a function");
335         }
336
337         // no value to return if no initial value and an empty array
338         if (!length && arguments.length == 1) {
339             throw new TypeError('reduce of empty array with no initial value');
340         }
341
342         var i = 0;
343         var result;
344         if (arguments.length >= 2) {
345             result = arguments[1];
346         } else {
347             do {
348                 if (i in self) {
349                     result = self[i++];
350                     break;
351                 }
352
353                 // if array contains no values, no initial value to return
354                 if (++i >= length) {
355                     throw new TypeError('reduce of empty array with no initial value');
356                 }
357             } while (true);
358         }
359
360         for (; i < length; i++) {
361             if (i in self) {
362                 result = fun.call(void 0, result, self[i], i, self);
363             }
364         }
365
366         return result;
367     };
368 }
369
370 // ES5 15.4.4.22
371 // http://es5.github.com/#x15.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(fun + " is not a function");
381         }
382
383         // no value to return if no initial value, empty array
384         if (!length && arguments.length == 1) {
385             throw new TypeError('reduceRight of empty array with no initial value');
386         }
387
388         var result, i = length - 1;
389         if (arguments.length >= 2) {
390             result = arguments[1];
391         } else {
392             do {
393                 if (i in self) {
394                     result = self[i--];
395                     break;
396                 }
397
398                 // if array contains no values, no initial value to return
399                 if (--i < 0) {
400                     throw new TypeError('reduceRight of empty array with no initial value');
401                 }
402             } while (true);
403         }
404
405         do {
406             if (i in this) {
407                 result = fun.call(void 0, result, self[i], i, self);
408             }
409         } while (i--);
410
411         return result;
412     };
413 }
414
415 // ES5 15.4.4.14
416 // http://es5.github.com/#x15.4.4.14
417 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
418 if (!Array.prototype.indexOf) {
419     Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
420         var self = toObject(this),
421             length = self.length >>> 0;
422
423         if (!length) {
424             return -1;
425         }
426
427         var i = 0;
428         if (arguments.length > 1) {
429             i = toInteger(arguments[1]);
430         }
431
432         // handle negative indices
433         i = i >= 0 ? i : Math.max(0, length + i);
434         for (; i < length; i++) {
435             if (i in self && self[i] === sought) {
436                 return i;
437             }
438         }
439         return -1;
440     };
441 }
442
443 // ES5 15.4.4.15
444 // http://es5.github.com/#x15.4.4.15
445 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
446 if (!Array.prototype.lastIndexOf) {
447     Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
448         var self = toObject(this),
449             length = self.length >>> 0;
450
451         if (!length) {
452             return -1;
453         }
454         var i = length - 1;
455         if (arguments.length > 1) {
456             i = Math.min(i, toInteger(arguments[1]));
457         }
458         // handle negative indices
459         i = i >= 0 ? i : length - Math.abs(i);
460         for (; i >= 0; i--) {
461             if (i in self && sought === self[i]) {
462                 return i;
463             }
464         }
465         return -1;
466     };
467 }
468
469 //
470 // Object
471 // ======
472 //
473
474 // ES5 15.2.3.14
475 // http://es5.github.com/#x15.2.3.14
476 if (!Object.keys) {
477     // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
478     var hasDontEnumBug = true,
479         dontEnums = [
480             "toString",
481             "toLocaleString",
482             "valueOf",
483             "hasOwnProperty",
484             "isPrototypeOf",
485             "propertyIsEnumerable",
486             "constructor"
487         ],
488         dontEnumsLength = dontEnums.length;
489
490     for (var key in {"toString": null}) {
491         hasDontEnumBug = false;
492     }
493
494     Object.keys = function keys(object) {
495
496         if ((typeof object != "object" && typeof object != "function") || object === null) {
497             throw new TypeError("Object.keys called on a non-object");
498         }
499
500         var keys = [];
501         for (var name in object) {
502             if (owns(object, name)) {
503                 keys.push(name);
504             }
505         }
506
507         if (hasDontEnumBug) {
508             for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
509                 var dontEnum = dontEnums[i];
510                 if (owns(object, dontEnum)) {
511                     keys.push(dontEnum);
512                 }
513             }
514         }
515         return keys;
516     };
517
518 }
519
520 //
521 // Date
522 // ====
523 //
524
525 // ES5 15.9.5.43
526 // http://es5.github.com/#x15.9.5.43
527 // This function returns a String value represent the instance in time
528 // represented by this Date object. The format of the String is the Date Time
529 // string format defined in 15.9.1.15. All fields are present in the String.
530 // The time zone is always UTC, denoted by the suffix Z. If the time value of
531 // this object is not a finite Number a RangeError exception is thrown.
532 if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) {
533     Date.prototype.toISOString = function toISOString() {
534         var result, length, value, year;
535         if (!isFinite(this)) {
536             throw new RangeError("Date.prototype.toISOString called on non-finite value.");
537         }
538
539         // the date time string format is specified in 15.9.1.15.
540         result = [this.getUTCMonth() + 1, this.getUTCDate(),
541             this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
542         year = this.getUTCFullYear();
543         year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6);
544
545         length = result.length;
546         while (length--) {
547             value = result[length];
548             // pad months, days, hours, minutes, and seconds to have two digits.
549             if (value < 10) {
550                 result[length] = "0" + value;
551             }
552         }
553         // pad milliseconds to have three digits.
554         return year + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." +
555             ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
556     }
557 }
558
559 // ES5 15.9.4.4
560 // http://es5.github.com/#x15.9.4.4
561 if (!Date.now) {
562     Date.now = function now() {
563         return new Date().getTime();
564     };
565 }
566
567 // ES5 15.9.5.44
568 // http://es5.github.com/#x15.9.5.44
569 // This function provides a String representation of a Date object for use by
570 // JSON.stringify (15.12.3).
571 if (!Date.prototype.toJSON) {
572     Date.prototype.toJSON = function toJSON(key) {
573         // When the toJSON method is called with argument key, the following
574         // steps are taken:
575
576         // 1.  Let O be the result of calling ToObject, giving it the this
577         // value as its argument.
578         // 2. Let tv be ToPrimitive(O, hint Number).
579         // 3. If tv is a Number and is not finite, return null.
580         // XXX
581         // 4. Let toISO be the result of calling the [[Get]] internal method of
582         // O with argument "toISOString".
583         // 5. If IsCallable(toISO) is false, throw a TypeError exception.
584         if (typeof this.toISOString != "function") {
585             throw new TypeError('toISOString property is not callable');
586         }
587         // 6. Return the result of calling the [[Call]] internal method of
588         //  toISO with O as the this value and an empty argument list.
589         return this.toISOString();
590
591         // NOTE 1 The argument is ignored.
592
593         // NOTE 2 The toJSON function is intentionally generic; it does not
594         // require that its this value be a Date object. Therefore, it can be
595         // transferred to other kinds of objects for use as a method. However,
596         // it does require that any such object have a toISOString method. An
597         // object is free to use the argument key to filter its
598         // stringification.
599     };
600 }
601
602 // ES5 15.9.4.2
603 // http://es5.github.com/#x15.9.4.2
604 // based on work shared by Daniel Friesen (dantman)
605 // http://gist.github.com/303249
606 if (!Date.parse || Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) {
607     // XXX global assignment won't work in embeddings that use
608     // an alternate object for the context.
609     Date = (function(NativeDate) {
610
611         // Date.length === 7
612         var Date = function Date(Y, M, D, h, m, s, ms) {
613             var length = arguments.length;
614             if (this instanceof NativeDate) {
615                 var date = length == 1 && String(Y) === Y ? // isString(Y)
616                     // We explicitly pass it through parse:
617                     new NativeDate(Date.parse(Y)) :
618                     // We have to manually make calls depending on argument
619                     // length here
620                     length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
621                     length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
622                     length >= 5 ? new NativeDate(Y, M, D, h, m) :
623                     length >= 4 ? new NativeDate(Y, M, D, h) :
624                     length >= 3 ? new NativeDate(Y, M, D) :
625                     length >= 2 ? new NativeDate(Y, M) :
626                     length >= 1 ? new NativeDate(Y) :
627                                   new NativeDate();
628                 // Prevent mixups with unfixed Date object
629                 date.constructor = Date;
630                 return date;
631             }
632             return NativeDate.apply(this, arguments);
633         };
634
635         // 15.9.1.15 Date Time String Format.
636         var isoDateExpression = new RegExp("^" +
637             "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 6-digit extended year
638             "(?:-(\\d{2})" + // optional month capture
639             "(?:-(\\d{2})" + // optional day capture
640             "(?:" + // capture hours:minutes:seconds.milliseconds
641                 "T(\\d{2})" + // hours capture
642                 ":(\\d{2})" + // minutes capture
643                 "(?:" + // optional :seconds.milliseconds
644                     ":(\\d{2})" + // seconds capture
645                     "(?:\\.(\\d{3}))?" + // milliseconds capture
646                 ")?" +
647             "(?:" + // capture UTC offset component
648                 "Z|" + // UTC capture
649                 "(?:" + // offset specifier +/-hours:minutes
650                     "([-+])" + // sign capture
651                     "(\\d{2})" + // hours offset capture
652                     ":(\\d{2})" + // minutes offset capture
653                 ")" +
654             ")?)?)?)?" +
655         "$");
656
657         // Copy any custom methods a 3rd party library may have added
658         for (var key in NativeDate) {
659             Date[key] = NativeDate[key];
660         }
661
662         // Copy "native" methods explicitly; they may be non-enumerable
663         Date.now = NativeDate.now;
664         Date.UTC = NativeDate.UTC;
665         Date.prototype = NativeDate.prototype;
666         Date.prototype.constructor = Date;
667
668         // Upgrade Date.parse to handle simplified ISO 8601 strings
669         Date.parse = function parse(string) {
670             var match = isoDateExpression.exec(string);
671             if (match) {
672                 match.shift(); // kill match[0], the full match
673                 // parse months, days, hours, minutes, seconds, and milliseconds
674                 for (var i = 1; i < 7; i++) {
675                     // provide default values if necessary
676                     match[i] = +(match[i] || (i < 3 ? 1 : 0));
677                     // match[1] is the month. Months are 0-11 in JavaScript
678                     // `Date` objects, but 1-12 in ISO notation, so we
679                     // decrement.
680                     if (i == 1) {
681                         match[i]--;
682                     }
683                 }
684
685                 // parse the UTC offset component
686                 var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
687
688                 // compute the explicit time zone offset if specified
689                 var offset = 0;
690                 if (sign) {
691                     // detect invalid offsets and return early
692                     if (hourOffset > 23 || minuteOffset > 59) {
693                         return NaN;
694                     }
695
696                     // express the provided time zone offset in minutes. The offset is
697                     // negative for time zones west of UTC; positive otherwise.
698                     offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
699                 }
700
701                 // Date.UTC for years between 0 and 99 converts year to 1900 + year
702                 // The Gregorian calendar has a 400-year cycle, so
703                 // to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...),
704                 // where 12622780800000 - number of milliseconds in Gregorian calendar 400 years
705                 var year = +match[0];
706                 if (0 <= year && year <= 99) {
707                     match[0] = year + 400;
708                     return NativeDate.UTC.apply(this, match) + offset - 12622780800000;
709                 }
710
711                 // compute a new UTC date value, accounting for the optional offset
712                 return NativeDate.UTC.apply(this, match) + offset;
713             }
714             return NativeDate.parse.apply(this, arguments);
715         };
716
717         return Date;
718     })(Date);
719 }
720
721 //
722 // String
723 // ======
724 //
725
726 // ES5 15.5.4.20
727 // http://es5.github.com/#x15.5.4.20
728 var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
729     "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
730     "\u2029\uFEFF";
731 if (!String.prototype.trim || ws.trim()) {
732     // http://blog.stevenlevithan.com/archives/faster-trim-javascript
733     // http://perfectionkills.com/whitespace-deviations/
734     ws = "[" + ws + "]";
735     var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
736         trimEndRegexp = new RegExp(ws + ws + "*$");
737     String.prototype.trim = function trim() {
738         if (this === undefined || this === null) {
739             throw new TypeError("can't convert "+this+" to object");
740         }
741         return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
742     };
743 }
744
745 //
746 // Util
747 // ======
748 //
749
750 // ES5 9.4
751 // http://es5.github.com/#x9.4
752 // http://jsperf.com/to-integer
753 var toInteger = function (n) {
754     n = +n;
755     if (n !== n) { // isNaN
756         n = 0;
757     } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
758         n = (n > 0 || -1) * Math.floor(Math.abs(n));
759     }
760     return n;
761 };
762
763 var prepareString = "a"[0] != "a";
764     // ES5 9.9
765     // http://es5.github.com/#x9.9
766 var toObject = function (o) {
767     if (o == null) { // this matches both null and undefined
768         throw new TypeError("can't convert "+o+" to object");
769     }
770     // If the implementation doesn't support by-index access of
771     // string characters (ex. IE < 9), split the string
772     if (prepareString && typeof o == "string" && o) {
773         return o.split("");
774     }
775     return Object(o);
776 };
777
778 });