Update es5-shim to v4.5.8
[lhc/web/wiklou.git] / resources / lib / es5-shim / es5-shim.js
1 /*!
2 * https://github.com/es-shims/es5-shim
3 * @license es5-shim Copyright 2009-2015 by contributors, MIT License
4 * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
5 */
6
7 // vim: ts=4 sts=4 sw=4 expandtab
8
9 // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
10 ;
11
12 // UMD (Universal Module Definition)
13 // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
14 (function (root, factory) {
15 'use strict';
16
17 /* global define, exports, module */
18 if (typeof define === 'function' && define.amd) {
19 // AMD. Register as an anonymous module.
20 define(factory);
21 } else if (typeof exports === 'object') {
22 // Node. Does not work with strict CommonJS, but
23 // only CommonJS-like enviroments that support module.exports,
24 // like Node.
25 module.exports = factory();
26 } else {
27 // Browser globals (root is window)
28 root.returnExports = factory();
29 }
30 }(this, function () {
31
32 /**
33 * Brings an environment as close to ECMAScript 5 compliance
34 * as is possible with the facilities of erstwhile engines.
35 *
36 * Annotated ES5: http://es5.github.com/ (specific links below)
37 * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
38 * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
39 */
40
41 // Shortcut to an often accessed properties, in order to avoid multiple
42 // dereference that costs universally. This also holds a reference to known-good
43 // functions.
44 var $Array = Array;
45 var ArrayPrototype = $Array.prototype;
46 var $Object = Object;
47 var ObjectPrototype = $Object.prototype;
48 var $Function = Function;
49 var FunctionPrototype = $Function.prototype;
50 var $String = String;
51 var StringPrototype = $String.prototype;
52 var $Number = Number;
53 var NumberPrototype = $Number.prototype;
54 var array_slice = ArrayPrototype.slice;
55 var array_splice = ArrayPrototype.splice;
56 var array_push = ArrayPrototype.push;
57 var array_unshift = ArrayPrototype.unshift;
58 var array_concat = ArrayPrototype.concat;
59 var array_join = ArrayPrototype.join;
60 var call = FunctionPrototype.call;
61 var apply = FunctionPrototype.apply;
62 var max = Math.max;
63 var min = Math.min;
64
65 // Having a toString local variable name breaks in Opera so use to_string.
66 var to_string = ObjectPrototype.toString;
67
68 /* global Symbol */
69 /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
70 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
71 var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
72
73 var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
74 var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
75 /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
76
77 /* inlined from http://npmjs.com/define-properties */
78 var supportsDescriptors = $Object.defineProperty && (function () {
79 try {
80 var obj = {};
81 $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
82 for (var _ in obj) { return false; }
83 return obj.x === obj;
84 } catch (e) { /* this is ES3 */
85 return false;
86 }
87 }());
88 var defineProperties = (function (has) {
89 // Define configurable, writable, and non-enumerable props
90 // if they don't exist.
91 var defineProperty;
92 if (supportsDescriptors) {
93 defineProperty = function (object, name, method, forceAssign) {
94 if (!forceAssign && (name in object)) { return; }
95 $Object.defineProperty(object, name, {
96 configurable: true,
97 enumerable: false,
98 writable: true,
99 value: method
100 });
101 };
102 } else {
103 defineProperty = function (object, name, method, forceAssign) {
104 if (!forceAssign && (name in object)) { return; }
105 object[name] = method;
106 };
107 }
108 return function defineProperties(object, map, forceAssign) {
109 for (var name in map) {
110 if (has.call(map, name)) {
111 defineProperty(object, name, map[name], forceAssign);
112 }
113 }
114 };
115 }(ObjectPrototype.hasOwnProperty));
116
117 //
118 // Util
119 // ======
120 //
121
122 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
123 var isPrimitive = function isPrimitive(input) {
124 var type = typeof input;
125 return input === null || (type !== 'object' && type !== 'function');
126 };
127
128 var isActualNaN = $Number.isNaN || function (x) { return x !== x; };
129
130 var ES = {
131 // ES5 9.4
132 // http://es5.github.com/#x9.4
133 // http://jsperf.com/to-integer
134 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
135 ToInteger: function ToInteger(num) {
136 var n = +num;
137 if (isActualNaN(n)) {
138 n = 0;
139 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
140 n = (n > 0 || -1) * Math.floor(Math.abs(n));
141 }
142 return n;
143 },
144
145 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
146 ToPrimitive: function ToPrimitive(input) {
147 var val, valueOf, toStr;
148 if (isPrimitive(input)) {
149 return input;
150 }
151 valueOf = input.valueOf;
152 if (isCallable(valueOf)) {
153 val = valueOf.call(input);
154 if (isPrimitive(val)) {
155 return val;
156 }
157 }
158 toStr = input.toString;
159 if (isCallable(toStr)) {
160 val = toStr.call(input);
161 if (isPrimitive(val)) {
162 return val;
163 }
164 }
165 throw new TypeError();
166 },
167
168 // ES5 9.9
169 // http://es5.github.com/#x9.9
170 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
171 ToObject: function (o) {
172 if (o == null) { // this matches both null and undefined
173 throw new TypeError("can't convert " + o + ' to object');
174 }
175 return $Object(o);
176 },
177
178 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
179 ToUint32: function ToUint32(x) {
180 return x >>> 0;
181 }
182 };
183
184 //
185 // Function
186 // ========
187 //
188
189 // ES-5 15.3.4.5
190 // http://es5.github.com/#x15.3.4.5
191
192 var Empty = function Empty() {};
193
194 defineProperties(FunctionPrototype, {
195 bind: function bind(that) { // .length is 1
196 // 1. Let Target be the this value.
197 var target = this;
198 // 2. If IsCallable(Target) is false, throw a TypeError exception.
199 if (!isCallable(target)) {
200 throw new TypeError('Function.prototype.bind called on incompatible ' + target);
201 }
202 // 3. Let A be a new (possibly empty) internal list of all of the
203 // argument values provided after thisArg (arg1, arg2 etc), in order.
204 // XXX slicedArgs will stand in for "A" if used
205 var args = array_slice.call(arguments, 1); // for normal call
206 // 4. Let F be a new native ECMAScript object.
207 // 11. Set the [[Prototype]] internal property of F to the standard
208 // built-in Function prototype object as specified in 15.3.3.1.
209 // 12. Set the [[Call]] internal property of F as described in
210 // 15.3.4.5.1.
211 // 13. Set the [[Construct]] internal property of F as described in
212 // 15.3.4.5.2.
213 // 14. Set the [[HasInstance]] internal property of F as described in
214 // 15.3.4.5.3.
215 var bound;
216 var binder = function () {
217
218 if (this instanceof bound) {
219 // 15.3.4.5.2 [[Construct]]
220 // When the [[Construct]] internal method of a function object,
221 // F that was created using the bind function is called with a
222 // list of arguments ExtraArgs, the following steps are taken:
223 // 1. Let target be the value of F's [[TargetFunction]]
224 // internal property.
225 // 2. If target has no [[Construct]] internal method, a
226 // TypeError exception is thrown.
227 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
228 // property.
229 // 4. Let args be a new list containing the same values as the
230 // list boundArgs in the same order followed by the same
231 // values as the list ExtraArgs in the same order.
232 // 5. Return the result of calling the [[Construct]] internal
233 // method of target providing args as the arguments.
234
235 var result = apply.call(
236 target,
237 this,
238 array_concat.call(args, array_slice.call(arguments))
239 );
240 if ($Object(result) === result) {
241 return result;
242 }
243 return this;
244
245 } else {
246 // 15.3.4.5.1 [[Call]]
247 // When the [[Call]] internal method of a function object, F,
248 // which was created using the bind function is called with a
249 // this value and a list of arguments ExtraArgs, the following
250 // steps are taken:
251 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
252 // property.
253 // 2. Let boundThis be the value of F's [[BoundThis]] internal
254 // property.
255 // 3. Let target be the value of F's [[TargetFunction]] internal
256 // property.
257 // 4. Let args be a new list containing the same values as the
258 // list boundArgs in the same order followed by the same
259 // values as the list ExtraArgs in the same order.
260 // 5. Return the result of calling the [[Call]] internal method
261 // of target providing boundThis as the this value and
262 // providing args as the arguments.
263
264 // equiv: target.call(this, ...boundArgs, ...args)
265 return apply.call(
266 target,
267 that,
268 array_concat.call(args, array_slice.call(arguments))
269 );
270
271 }
272
273 };
274
275 // 15. If the [[Class]] internal property of Target is "Function", then
276 // a. Let L be the length property of Target minus the length of A.
277 // b. Set the length own property of F to either 0 or L, whichever is
278 // larger.
279 // 16. Else set the length own property of F to 0.
280
281 var boundLength = max(0, target.length - args.length);
282
283 // 17. Set the attributes of the length own property of F to the values
284 // specified in 15.3.5.1.
285 var boundArgs = [];
286 for (var i = 0; i < boundLength; i++) {
287 array_push.call(boundArgs, '$' + i);
288 }
289
290 // XXX Build a dynamic function with desired amount of arguments is the only
291 // way to set the length property of a function.
292 // In environments where Content Security Policies enabled (Chrome extensions,
293 // for ex.) all use of eval or Function costructor throws an exception.
294 // However in all of these environments Function.prototype.bind exists
295 // and so this code will never be executed.
296 bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
297
298 if (target.prototype) {
299 Empty.prototype = target.prototype;
300 bound.prototype = new Empty();
301 // Clean up dangling references.
302 Empty.prototype = null;
303 }
304
305 // TODO
306 // 18. Set the [[Extensible]] internal property of F to true.
307
308 // TODO
309 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
310 // 20. Call the [[DefineOwnProperty]] internal method of F with
311 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
312 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
313 // false.
314 // 21. Call the [[DefineOwnProperty]] internal method of F with
315 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
316 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
317 // and false.
318
319 // TODO
320 // NOTE Function objects created using Function.prototype.bind do not
321 // have a prototype property or the [[Code]], [[FormalParameters]], and
322 // [[Scope]] internal properties.
323 // XXX can't delete prototype in pure-js.
324
325 // 22. Return F.
326 return bound;
327 }
328 });
329
330 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
331 // use it in defining shortcuts.
332 var owns = call.bind(ObjectPrototype.hasOwnProperty);
333 var toStr = call.bind(ObjectPrototype.toString);
334 var arraySlice = call.bind(array_slice);
335 var arraySliceApply = apply.bind(array_slice);
336 var strSlice = call.bind(StringPrototype.slice);
337 var strSplit = call.bind(StringPrototype.split);
338 var strIndexOf = call.bind(StringPrototype.indexOf);
339 var pushCall = call.bind(array_push);
340 var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
341 var arraySort = call.bind(ArrayPrototype.sort);
342
343 //
344 // Array
345 // =====
346 //
347
348 var isArray = $Array.isArray || function isArray(obj) {
349 return toStr(obj) === '[object Array]';
350 };
351
352 // ES5 15.4.4.12
353 // http://es5.github.com/#x15.4.4.13
354 // Return len+argCount.
355 // [bugfix, ielt8]
356 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
357 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
358 defineProperties(ArrayPrototype, {
359 unshift: function () {
360 array_unshift.apply(this, arguments);
361 return this.length;
362 }
363 }, hasUnshiftReturnValueBug);
364
365 // ES5 15.4.3.2
366 // http://es5.github.com/#x15.4.3.2
367 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
368 defineProperties($Array, { isArray: isArray });
369
370 // The IsCallable() check in the Array functions
371 // has been replaced with a strict check on the
372 // internal class of the object to trap cases where
373 // the provided function was actually a regular
374 // expression literal, which in V8 and
375 // JavaScriptCore is a typeof "function". Only in
376 // V8 are regular expression literals permitted as
377 // reduce parameters, so it is desirable in the
378 // general case for the shim to match the more
379 // strict and common behavior of rejecting regular
380 // expressions.
381
382 // ES5 15.4.4.18
383 // http://es5.github.com/#x15.4.4.18
384 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
385
386 // Check failure of by-index access of string characters (IE < 9)
387 // and failure of `0 in boxedString` (Rhino)
388 var boxedString = $Object('a');
389 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
390
391 var properlyBoxesContext = function properlyBoxed(method) {
392 // Check node 0.6.21 bug where third parameter is not boxed
393 var properlyBoxesNonStrict = true;
394 var properlyBoxesStrict = true;
395 var threwException = false;
396 if (method) {
397 try {
398 method.call('foo', function (_, __, context) {
399 if (typeof context !== 'object') {
400 properlyBoxesNonStrict = false;
401 }
402 });
403
404 method.call([1], function () {
405 'use strict';
406
407 properlyBoxesStrict = typeof this === 'string';
408 }, 'x');
409 } catch (e) {
410 threwException = true;
411 }
412 }
413 return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
414 };
415
416 defineProperties(ArrayPrototype, {
417 forEach: function forEach(callbackfn/*, thisArg*/) {
418 var object = ES.ToObject(this);
419 var self = splitString && isString(this) ? strSplit(this, '') : object;
420 var i = -1;
421 var length = ES.ToUint32(self.length);
422 var T;
423 if (arguments.length > 1) {
424 T = arguments[1];
425 }
426
427 // If no callback function or if callback is not a callable function
428 if (!isCallable(callbackfn)) {
429 throw new TypeError('Array.prototype.forEach callback must be a function');
430 }
431
432 while (++i < length) {
433 if (i in self) {
434 // Invoke the callback function with call, passing arguments:
435 // context, property value, property key, thisArg object
436 if (typeof T === 'undefined') {
437 callbackfn(self[i], i, object);
438 } else {
439 callbackfn.call(T, self[i], i, object);
440 }
441 }
442 }
443 }
444 }, !properlyBoxesContext(ArrayPrototype.forEach));
445
446 // ES5 15.4.4.19
447 // http://es5.github.com/#x15.4.4.19
448 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
449 defineProperties(ArrayPrototype, {
450 map: function map(callbackfn/*, thisArg*/) {
451 var object = ES.ToObject(this);
452 var self = splitString && isString(this) ? strSplit(this, '') : object;
453 var length = ES.ToUint32(self.length);
454 var result = $Array(length);
455 var T;
456 if (arguments.length > 1) {
457 T = arguments[1];
458 }
459
460 // If no callback function or if callback is not a callable function
461 if (!isCallable(callbackfn)) {
462 throw new TypeError('Array.prototype.map callback must be a function');
463 }
464
465 for (var i = 0; i < length; i++) {
466 if (i in self) {
467 if (typeof T === 'undefined') {
468 result[i] = callbackfn(self[i], i, object);
469 } else {
470 result[i] = callbackfn.call(T, self[i], i, object);
471 }
472 }
473 }
474 return result;
475 }
476 }, !properlyBoxesContext(ArrayPrototype.map));
477
478 // ES5 15.4.4.20
479 // http://es5.github.com/#x15.4.4.20
480 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
481 defineProperties(ArrayPrototype, {
482 filter: function filter(callbackfn/*, thisArg*/) {
483 var object = ES.ToObject(this);
484 var self = splitString && isString(this) ? strSplit(this, '') : object;
485 var length = ES.ToUint32(self.length);
486 var result = [];
487 var value;
488 var T;
489 if (arguments.length > 1) {
490 T = arguments[1];
491 }
492
493 // If no callback function or if callback is not a callable function
494 if (!isCallable(callbackfn)) {
495 throw new TypeError('Array.prototype.filter callback must be a function');
496 }
497
498 for (var i = 0; i < length; i++) {
499 if (i in self) {
500 value = self[i];
501 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
502 pushCall(result, value);
503 }
504 }
505 }
506 return result;
507 }
508 }, !properlyBoxesContext(ArrayPrototype.filter));
509
510 // ES5 15.4.4.16
511 // http://es5.github.com/#x15.4.4.16
512 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
513 defineProperties(ArrayPrototype, {
514 every: function every(callbackfn/*, thisArg*/) {
515 var object = ES.ToObject(this);
516 var self = splitString && isString(this) ? strSplit(this, '') : object;
517 var length = ES.ToUint32(self.length);
518 var T;
519 if (arguments.length > 1) {
520 T = arguments[1];
521 }
522
523 // If no callback function or if callback is not a callable function
524 if (!isCallable(callbackfn)) {
525 throw new TypeError('Array.prototype.every callback must be a function');
526 }
527
528 for (var i = 0; i < length; i++) {
529 if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
530 return false;
531 }
532 }
533 return true;
534 }
535 }, !properlyBoxesContext(ArrayPrototype.every));
536
537 // ES5 15.4.4.17
538 // http://es5.github.com/#x15.4.4.17
539 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
540 defineProperties(ArrayPrototype, {
541 some: function some(callbackfn/*, thisArg */) {
542 var object = ES.ToObject(this);
543 var self = splitString && isString(this) ? strSplit(this, '') : object;
544 var length = ES.ToUint32(self.length);
545 var T;
546 if (arguments.length > 1) {
547 T = arguments[1];
548 }
549
550 // If no callback function or if callback is not a callable function
551 if (!isCallable(callbackfn)) {
552 throw new TypeError('Array.prototype.some callback must be a function');
553 }
554
555 for (var i = 0; i < length; i++) {
556 if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
557 return true;
558 }
559 }
560 return false;
561 }
562 }, !properlyBoxesContext(ArrayPrototype.some));
563
564 // ES5 15.4.4.21
565 // http://es5.github.com/#x15.4.4.21
566 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
567 var reduceCoercesToObject = false;
568 if (ArrayPrototype.reduce) {
569 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
570 return list;
571 }) === 'object';
572 }
573 defineProperties(ArrayPrototype, {
574 reduce: function reduce(callbackfn/*, initialValue*/) {
575 var object = ES.ToObject(this);
576 var self = splitString && isString(this) ? strSplit(this, '') : object;
577 var length = ES.ToUint32(self.length);
578
579 // If no callback function or if callback is not a callable function
580 if (!isCallable(callbackfn)) {
581 throw new TypeError('Array.prototype.reduce callback must be a function');
582 }
583
584 // no value to return if no initial value and an empty array
585 if (length === 0 && arguments.length === 1) {
586 throw new TypeError('reduce of empty array with no initial value');
587 }
588
589 var i = 0;
590 var result;
591 if (arguments.length >= 2) {
592 result = arguments[1];
593 } else {
594 do {
595 if (i in self) {
596 result = self[i++];
597 break;
598 }
599
600 // if array contains no values, no initial value to return
601 if (++i >= length) {
602 throw new TypeError('reduce of empty array with no initial value');
603 }
604 } while (true);
605 }
606
607 for (; i < length; i++) {
608 if (i in self) {
609 result = callbackfn(result, self[i], i, object);
610 }
611 }
612
613 return result;
614 }
615 }, !reduceCoercesToObject);
616
617 // ES5 15.4.4.22
618 // http://es5.github.com/#x15.4.4.22
619 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
620 var reduceRightCoercesToObject = false;
621 if (ArrayPrototype.reduceRight) {
622 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
623 return list;
624 }) === 'object';
625 }
626 defineProperties(ArrayPrototype, {
627 reduceRight: function reduceRight(callbackfn/*, initial*/) {
628 var object = ES.ToObject(this);
629 var self = splitString && isString(this) ? strSplit(this, '') : object;
630 var length = ES.ToUint32(self.length);
631
632 // If no callback function or if callback is not a callable function
633 if (!isCallable(callbackfn)) {
634 throw new TypeError('Array.prototype.reduceRight callback must be a function');
635 }
636
637 // no value to return if no initial value, empty array
638 if (length === 0 && arguments.length === 1) {
639 throw new TypeError('reduceRight of empty array with no initial value');
640 }
641
642 var result;
643 var i = length - 1;
644 if (arguments.length >= 2) {
645 result = arguments[1];
646 } else {
647 do {
648 if (i in self) {
649 result = self[i--];
650 break;
651 }
652
653 // if array contains no values, no initial value to return
654 if (--i < 0) {
655 throw new TypeError('reduceRight of empty array with no initial value');
656 }
657 } while (true);
658 }
659
660 if (i < 0) {
661 return result;
662 }
663
664 do {
665 if (i in self) {
666 result = callbackfn(result, self[i], i, object);
667 }
668 } while (i--);
669
670 return result;
671 }
672 }, !reduceRightCoercesToObject);
673
674 // ES5 15.4.4.14
675 // http://es5.github.com/#x15.4.4.14
676 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
677 var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
678 defineProperties(ArrayPrototype, {
679 indexOf: function indexOf(searchElement/*, fromIndex */) {
680 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
681 var length = ES.ToUint32(self.length);
682
683 if (length === 0) {
684 return -1;
685 }
686
687 var i = 0;
688 if (arguments.length > 1) {
689 i = ES.ToInteger(arguments[1]);
690 }
691
692 // handle negative indices
693 i = i >= 0 ? i : max(0, length + i);
694 for (; i < length; i++) {
695 if (i in self && self[i] === searchElement) {
696 return i;
697 }
698 }
699 return -1;
700 }
701 }, hasFirefox2IndexOfBug);
702
703 // ES5 15.4.4.15
704 // http://es5.github.com/#x15.4.4.15
705 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
706 var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
707 defineProperties(ArrayPrototype, {
708 lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
709 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
710 var length = ES.ToUint32(self.length);
711
712 if (length === 0) {
713 return -1;
714 }
715 var i = length - 1;
716 if (arguments.length > 1) {
717 i = min(i, ES.ToInteger(arguments[1]));
718 }
719 // handle negative indices
720 i = i >= 0 ? i : length - Math.abs(i);
721 for (; i >= 0; i--) {
722 if (i in self && searchElement === self[i]) {
723 return i;
724 }
725 }
726 return -1;
727 }
728 }, hasFirefox2LastIndexOfBug);
729
730 // ES5 15.4.4.12
731 // http://es5.github.com/#x15.4.4.12
732 var spliceNoopReturnsEmptyArray = (function () {
733 var a = [1, 2];
734 var result = a.splice();
735 return a.length === 2 && isArray(result) && result.length === 0;
736 }());
737 defineProperties(ArrayPrototype, {
738 // Safari 5.0 bug where .splice() returns undefined
739 splice: function splice(start, deleteCount) {
740 if (arguments.length === 0) {
741 return [];
742 } else {
743 return array_splice.apply(this, arguments);
744 }
745 }
746 }, !spliceNoopReturnsEmptyArray);
747
748 var spliceWorksWithEmptyObject = (function () {
749 var obj = {};
750 ArrayPrototype.splice.call(obj, 0, 0, 1);
751 return obj.length === 1;
752 }());
753 defineProperties(ArrayPrototype, {
754 splice: function splice(start, deleteCount) {
755 if (arguments.length === 0) { return []; }
756 var args = arguments;
757 this.length = max(ES.ToInteger(this.length), 0);
758 if (arguments.length > 0 && typeof deleteCount !== 'number') {
759 args = arraySlice(arguments);
760 if (args.length < 2) {
761 pushCall(args, this.length - start);
762 } else {
763 args[1] = ES.ToInteger(deleteCount);
764 }
765 }
766 return array_splice.apply(this, args);
767 }
768 }, !spliceWorksWithEmptyObject);
769 var spliceWorksWithLargeSparseArrays = (function () {
770 // Per https://github.com/es-shims/es5-shim/issues/295
771 // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
772 var arr = new $Array(1e5);
773 // note: the index MUST be 8 or larger or the test will false pass
774 arr[8] = 'x';
775 arr.splice(1, 1);
776 // note: this test must be defined *after* the indexOf shim
777 // per https://github.com/es-shims/es5-shim/issues/313
778 return arr.indexOf('x') === 7;
779 }());
780 var spliceWorksWithSmallSparseArrays = (function () {
781 // Per https://github.com/es-shims/es5-shim/issues/295
782 // Opera 12.15 breaks on this, no idea why.
783 var n = 256;
784 var arr = [];
785 arr[n] = 'a';
786 arr.splice(n + 1, 0, 'b');
787 return arr[n] === 'a';
788 }());
789 defineProperties(ArrayPrototype, {
790 splice: function splice(start, deleteCount) {
791 var O = ES.ToObject(this);
792 var A = [];
793 var len = ES.ToUint32(O.length);
794 var relativeStart = ES.ToInteger(start);
795 var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
796 var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
797
798 var k = 0;
799 var from;
800 while (k < actualDeleteCount) {
801 from = $String(actualStart + k);
802 if (owns(O, from)) {
803 A[k] = O[from];
804 }
805 k += 1;
806 }
807
808 var items = arraySlice(arguments, 2);
809 var itemCount = items.length;
810 var to;
811 if (itemCount < actualDeleteCount) {
812 k = actualStart;
813 var maxK = len - actualDeleteCount;
814 while (k < maxK) {
815 from = $String(k + actualDeleteCount);
816 to = $String(k + itemCount);
817 if (owns(O, from)) {
818 O[to] = O[from];
819 } else {
820 delete O[to];
821 }
822 k += 1;
823 }
824 k = len;
825 var minK = len - actualDeleteCount + itemCount;
826 while (k > minK) {
827 delete O[k - 1];
828 k -= 1;
829 }
830 } else if (itemCount > actualDeleteCount) {
831 k = len - actualDeleteCount;
832 while (k > actualStart) {
833 from = $String(k + actualDeleteCount - 1);
834 to = $String(k + itemCount - 1);
835 if (owns(O, from)) {
836 O[to] = O[from];
837 } else {
838 delete O[to];
839 }
840 k -= 1;
841 }
842 }
843 k = actualStart;
844 for (var i = 0; i < items.length; ++i) {
845 O[k] = items[i];
846 k += 1;
847 }
848 O.length = len - actualDeleteCount + itemCount;
849
850 return A;
851 }
852 }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
853
854 var originalJoin = ArrayPrototype.join;
855 var hasStringJoinBug;
856 try {
857 hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
858 } catch (e) {
859 hasStringJoinBug = true;
860 }
861 if (hasStringJoinBug) {
862 defineProperties(ArrayPrototype, {
863 join: function join(separator) {
864 var sep = typeof separator === 'undefined' ? ',' : separator;
865 return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
866 }
867 }, hasStringJoinBug);
868 }
869
870 var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
871 if (hasJoinUndefinedBug) {
872 defineProperties(ArrayPrototype, {
873 join: function join(separator) {
874 var sep = typeof separator === 'undefined' ? ',' : separator;
875 return originalJoin.call(this, sep);
876 }
877 }, hasJoinUndefinedBug);
878 }
879
880 var pushShim = function push(item) {
881 var O = ES.ToObject(this);
882 var n = ES.ToUint32(O.length);
883 var i = 0;
884 while (i < arguments.length) {
885 O[n + i] = arguments[i];
886 i += 1;
887 }
888 O.length = n + i;
889 return n + i;
890 };
891
892 var pushIsNotGeneric = (function () {
893 var obj = {};
894 var result = Array.prototype.push.call(obj, undefined);
895 return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
896 }());
897 defineProperties(ArrayPrototype, {
898 push: function push(item) {
899 if (isArray(this)) {
900 return array_push.apply(this, arguments);
901 }
902 return pushShim.apply(this, arguments);
903 }
904 }, pushIsNotGeneric);
905
906 // This fixes a very weird bug in Opera 10.6 when pushing `undefined
907 var pushUndefinedIsWeird = (function () {
908 var arr = [];
909 var result = arr.push(undefined);
910 return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
911 }());
912 defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
913
914 // ES5 15.2.3.14
915 // http://es5.github.io/#x15.4.4.10
916 // Fix boxed string bug
917 defineProperties(ArrayPrototype, {
918 slice: function (start, end) {
919 var arr = isString(this) ? strSplit(this, '') : this;
920 return arraySliceApply(arr, arguments);
921 }
922 }, splitString);
923
924 var sortIgnoresNonFunctions = (function () {
925 try {
926 [1, 2].sort(null);
927 [1, 2].sort({});
928 return true;
929 } catch (e) { /**/ }
930 return false;
931 }());
932 var sortThrowsOnRegex = (function () {
933 // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
934 try {
935 [1, 2].sort(/a/);
936 return false;
937 } catch (e) { /**/ }
938 return true;
939 }());
940 var sortIgnoresUndefined = (function () {
941 // applies in IE 8, for one.
942 try {
943 [1, 2].sort(undefined);
944 return true;
945 } catch (e) { /**/ }
946 return false;
947 }());
948 defineProperties(ArrayPrototype, {
949 sort: function sort(compareFn) {
950 if (typeof compareFn === 'undefined') {
951 return arraySort(this);
952 }
953 if (!isCallable(compareFn)) {
954 throw new TypeError('Array.prototype.sort callback must be a function');
955 }
956 return arraySort(this, compareFn);
957 }
958 }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
959
960 //
961 // Object
962 // ======
963 //
964
965 // ES5 15.2.3.14
966 // http://es5.github.com/#x15.2.3.14
967
968 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
969 var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
970 var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
971 var hasStringEnumBug = !owns('x', '0');
972 var equalsConstructorPrototype = function (o) {
973 var ctor = o.constructor;
974 return ctor && ctor.prototype === o;
975 };
976 var blacklistedKeys = {
977 $window: true,
978 $console: true,
979 $parent: true,
980 $self: true,
981 $frame: true,
982 $frames: true,
983 $frameElement: true,
984 $webkitIndexedDB: true,
985 $webkitStorageInfo: true,
986 $external: true
987 };
988 var hasAutomationEqualityBug = (function () {
989 /* globals window */
990 if (typeof window === 'undefined') { return false; }
991 for (var k in window) {
992 try {
993 if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
994 equalsConstructorPrototype(window[k]);
995 }
996 } catch (e) {
997 return true;
998 }
999 }
1000 return false;
1001 }());
1002 var equalsConstructorPrototypeIfNotBuggy = function (object) {
1003 if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); }
1004 try {
1005 return equalsConstructorPrototype(object);
1006 } catch (e) {
1007 return false;
1008 }
1009 };
1010 var dontEnums = [
1011 'toString',
1012 'toLocaleString',
1013 'valueOf',
1014 'hasOwnProperty',
1015 'isPrototypeOf',
1016 'propertyIsEnumerable',
1017 'constructor'
1018 ];
1019 var dontEnumsLength = dontEnums.length;
1020
1021 // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
1022 // can be replaced with require('is-arguments') if we ever use a build process instead
1023 var isStandardArguments = function isArguments(value) {
1024 return toStr(value) === '[object Arguments]';
1025 };
1026 var isLegacyArguments = function isArguments(value) {
1027 return value !== null &&
1028 typeof value === 'object' &&
1029 typeof value.length === 'number' &&
1030 value.length >= 0 &&
1031 !isArray(value) &&
1032 isCallable(value.callee);
1033 };
1034 var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
1035
1036 defineProperties($Object, {
1037 keys: function keys(object) {
1038 var isFn = isCallable(object);
1039 var isArgs = isArguments(object);
1040 var isObject = object !== null && typeof object === 'object';
1041 var isStr = isObject && isString(object);
1042
1043 if (!isObject && !isFn && !isArgs) {
1044 throw new TypeError('Object.keys called on a non-object');
1045 }
1046
1047 var theKeys = [];
1048 var skipProto = hasProtoEnumBug && isFn;
1049 if ((isStr && hasStringEnumBug) || isArgs) {
1050 for (var i = 0; i < object.length; ++i) {
1051 pushCall(theKeys, $String(i));
1052 }
1053 }
1054
1055 if (!isArgs) {
1056 for (var name in object) {
1057 if (!(skipProto && name === 'prototype') && owns(object, name)) {
1058 pushCall(theKeys, $String(name));
1059 }
1060 }
1061 }
1062
1063 if (hasDontEnumBug) {
1064 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
1065 for (var j = 0; j < dontEnumsLength; j++) {
1066 var dontEnum = dontEnums[j];
1067 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
1068 pushCall(theKeys, dontEnum);
1069 }
1070 }
1071 }
1072 return theKeys;
1073 }
1074 });
1075
1076 var keysWorksWithArguments = $Object.keys && (function () {
1077 // Safari 5.0 bug
1078 return $Object.keys(arguments).length === 2;
1079 }(1, 2));
1080 var keysHasArgumentsLengthBug = $Object.keys && (function () {
1081 var argKeys = $Object.keys(arguments);
1082 return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
1083 }(1));
1084 var originalKeys = $Object.keys;
1085 defineProperties($Object, {
1086 keys: function keys(object) {
1087 if (isArguments(object)) {
1088 return originalKeys(arraySlice(object));
1089 } else {
1090 return originalKeys(object);
1091 }
1092 }
1093 }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
1094
1095 //
1096 // Date
1097 // ====
1098 //
1099
1100 var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
1101 var aNegativeTestDate = new Date(-1509842289600292);
1102 var aPositiveTestDate = new Date(1449662400000);
1103 var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
1104 var hasToDateStringFormatBug;
1105 var hasToStringFormatBug;
1106 var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
1107 if (timeZoneOffset < -720) {
1108 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
1109 hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
1110 } else {
1111 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
1112 hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
1113 }
1114
1115 var originalGetFullYear = call.bind(Date.prototype.getFullYear);
1116 var originalGetMonth = call.bind(Date.prototype.getMonth);
1117 var originalGetDate = call.bind(Date.prototype.getDate);
1118 var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
1119 var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
1120 var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
1121 var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
1122 var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
1123 var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
1124 var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
1125 var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
1126 var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
1127 var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1128 var daysInMonth = function daysInMonth(month, year) {
1129 return originalGetDate(new Date(year, month, 0));
1130 };
1131
1132 defineProperties(Date.prototype, {
1133 getFullYear: function getFullYear() {
1134 if (!this || !(this instanceof Date)) {
1135 throw new TypeError('this is not a Date object.');
1136 }
1137 var year = originalGetFullYear(this);
1138 if (year < 0 && originalGetMonth(this) > 11) {
1139 return year + 1;
1140 }
1141 return year;
1142 },
1143 getMonth: function getMonth() {
1144 if (!this || !(this instanceof Date)) {
1145 throw new TypeError('this is not a Date object.');
1146 }
1147 var year = originalGetFullYear(this);
1148 var month = originalGetMonth(this);
1149 if (year < 0 && month > 11) {
1150 return 0;
1151 }
1152 return month;
1153 },
1154 getDate: function getDate() {
1155 if (!this || !(this instanceof Date)) {
1156 throw new TypeError('this is not a Date object.');
1157 }
1158 var year = originalGetFullYear(this);
1159 var month = originalGetMonth(this);
1160 var date = originalGetDate(this);
1161 if (year < 0 && month > 11) {
1162 if (month === 12) {
1163 return date;
1164 }
1165 var days = daysInMonth(0, year + 1);
1166 return (days - date) + 1;
1167 }
1168 return date;
1169 },
1170 getUTCFullYear: function getUTCFullYear() {
1171 if (!this || !(this instanceof Date)) {
1172 throw new TypeError('this is not a Date object.');
1173 }
1174 var year = originalGetUTCFullYear(this);
1175 if (year < 0 && originalGetUTCMonth(this) > 11) {
1176 return year + 1;
1177 }
1178 return year;
1179 },
1180 getUTCMonth: function getUTCMonth() {
1181 if (!this || !(this instanceof Date)) {
1182 throw new TypeError('this is not a Date object.');
1183 }
1184 var year = originalGetUTCFullYear(this);
1185 var month = originalGetUTCMonth(this);
1186 if (year < 0 && month > 11) {
1187 return 0;
1188 }
1189 return month;
1190 },
1191 getUTCDate: function getUTCDate() {
1192 if (!this || !(this instanceof Date)) {
1193 throw new TypeError('this is not a Date object.');
1194 }
1195 var year = originalGetUTCFullYear(this);
1196 var month = originalGetUTCMonth(this);
1197 var date = originalGetUTCDate(this);
1198 if (year < 0 && month > 11) {
1199 if (month === 12) {
1200 return date;
1201 }
1202 var days = daysInMonth(0, year + 1);
1203 return (days - date) + 1;
1204 }
1205 return date;
1206 }
1207 }, hasNegativeMonthYearBug);
1208
1209 defineProperties(Date.prototype, {
1210 toUTCString: function toUTCString() {
1211 if (!this || !(this instanceof Date)) {
1212 throw new TypeError('this is not a Date object.');
1213 }
1214 var day = originalGetUTCDay(this);
1215 var date = originalGetUTCDate(this);
1216 var month = originalGetUTCMonth(this);
1217 var year = originalGetUTCFullYear(this);
1218 var hour = originalGetUTCHours(this);
1219 var minute = originalGetUTCMinutes(this);
1220 var second = originalGetUTCSeconds(this);
1221 return dayName[day] + ', ' +
1222 (date < 10 ? '0' + date : date) + ' ' +
1223 monthName[month] + ' ' +
1224 year + ' ' +
1225 (hour < 10 ? '0' + hour : hour) + ':' +
1226 (minute < 10 ? '0' + minute : minute) + ':' +
1227 (second < 10 ? '0' + second : second) + ' GMT';
1228 }
1229 }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
1230
1231 // Opera 12 has `,`
1232 defineProperties(Date.prototype, {
1233 toDateString: function toDateString() {
1234 if (!this || !(this instanceof Date)) {
1235 throw new TypeError('this is not a Date object.');
1236 }
1237 var day = this.getDay();
1238 var date = this.getDate();
1239 var month = this.getMonth();
1240 var year = this.getFullYear();
1241 return dayName[day] + ' ' +
1242 monthName[month] + ' ' +
1243 (date < 10 ? '0' + date : date) + ' ' +
1244 year;
1245 }
1246 }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
1247
1248 // can't use defineProperties here because of toString enumeration issue in IE <= 8
1249 if (hasNegativeMonthYearBug || hasToStringFormatBug) {
1250 Date.prototype.toString = function toString() {
1251 if (!this || !(this instanceof Date)) {
1252 throw new TypeError('this is not a Date object.');
1253 }
1254 var day = this.getDay();
1255 var date = this.getDate();
1256 var month = this.getMonth();
1257 var year = this.getFullYear();
1258 var hour = this.getHours();
1259 var minute = this.getMinutes();
1260 var second = this.getSeconds();
1261 var timezoneOffset = this.getTimezoneOffset();
1262 var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
1263 var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
1264 return dayName[day] + ' ' +
1265 monthName[month] + ' ' +
1266 (date < 10 ? '0' + date : date) + ' ' +
1267 year + ' ' +
1268 (hour < 10 ? '0' + hour : hour) + ':' +
1269 (minute < 10 ? '0' + minute : minute) + ':' +
1270 (second < 10 ? '0' + second : second) + ' GMT' +
1271 (timezoneOffset > 0 ? '-' : '+') +
1272 (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
1273 (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
1274 };
1275 if (supportsDescriptors) {
1276 $Object.defineProperty(Date.prototype, 'toString', {
1277 configurable: true,
1278 enumerable: false,
1279 writable: true
1280 });
1281 }
1282 }
1283
1284 // ES5 15.9.5.43
1285 // http://es5.github.com/#x15.9.5.43
1286 // This function returns a String value represent the instance in time
1287 // represented by this Date object. The format of the String is the Date Time
1288 // string format defined in 15.9.1.15. All fields are present in the String.
1289 // The time zone is always UTC, denoted by the suffix Z. If the time value of
1290 // this object is not a finite Number a RangeError exception is thrown.
1291 var negativeDate = -62198755200000;
1292 var negativeYearString = '-000001';
1293 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
1294 var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
1295
1296 var getTime = call.bind(Date.prototype.getTime);
1297
1298 defineProperties(Date.prototype, {
1299 toISOString: function toISOString() {
1300 if (!isFinite(this) || !isFinite(getTime(this))) {
1301 // Adope Photoshop requires the second check.
1302 throw new RangeError('Date.prototype.toISOString called on non-finite value.');
1303 }
1304
1305 var year = originalGetUTCFullYear(this);
1306
1307 var month = originalGetUTCMonth(this);
1308 // see https://github.com/es-shims/es5-shim/issues/111
1309 year += Math.floor(month / 12);
1310 month = (month % 12 + 12) % 12;
1311
1312 // the date time string format is specified in 15.9.1.15.
1313 var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
1314 year = (
1315 (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
1316 strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
1317 );
1318
1319 for (var i = 0; i < result.length; ++i) {
1320 // pad months, days, hours, minutes, and seconds to have two digits.
1321 result[i] = strSlice('00' + result[i], -2);
1322 }
1323 // pad milliseconds to have three digits.
1324 return (
1325 year + '-' + arraySlice(result, 0, 2).join('-') +
1326 'T' + arraySlice(result, 2).join(':') + '.' +
1327 strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
1328 );
1329 }
1330 }, hasNegativeDateBug || hasSafari51DateBug);
1331
1332 // ES5 15.9.5.44
1333 // http://es5.github.com/#x15.9.5.44
1334 // This function provides a String representation of a Date object for use by
1335 // JSON.stringify (15.12.3).
1336 var dateToJSONIsSupported = (function () {
1337 try {
1338 return Date.prototype.toJSON &&
1339 new Date(NaN).toJSON() === null &&
1340 new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
1341 Date.prototype.toJSON.call({ // generic
1342 toISOString: function () { return true; }
1343 });
1344 } catch (e) {
1345 return false;
1346 }
1347 }());
1348 if (!dateToJSONIsSupported) {
1349 Date.prototype.toJSON = function toJSON(key) {
1350 // When the toJSON method is called with argument key, the following
1351 // steps are taken:
1352
1353 // 1. Let O be the result of calling ToObject, giving it the this
1354 // value as its argument.
1355 // 2. Let tv be ES.ToPrimitive(O, hint Number).
1356 var O = $Object(this);
1357 var tv = ES.ToPrimitive(O);
1358 // 3. If tv is a Number and is not finite, return null.
1359 if (typeof tv === 'number' && !isFinite(tv)) {
1360 return null;
1361 }
1362 // 4. Let toISO be the result of calling the [[Get]] internal method of
1363 // O with argument "toISOString".
1364 var toISO = O.toISOString;
1365 // 5. If IsCallable(toISO) is false, throw a TypeError exception.
1366 if (!isCallable(toISO)) {
1367 throw new TypeError('toISOString property is not callable');
1368 }
1369 // 6. Return the result of calling the [[Call]] internal method of
1370 // toISO with O as the this value and an empty argument list.
1371 return toISO.call(O);
1372
1373 // NOTE 1 The argument is ignored.
1374
1375 // NOTE 2 The toJSON function is intentionally generic; it does not
1376 // require that its this value be a Date object. Therefore, it can be
1377 // transferred to other kinds of objects for use as a method. However,
1378 // it does require that any such object have a toISOString method. An
1379 // object is free to use the argument key to filter its
1380 // stringification.
1381 };
1382 }
1383
1384 // ES5 15.9.4.2
1385 // http://es5.github.com/#x15.9.4.2
1386 // based on work shared by Daniel Friesen (dantman)
1387 // http://gist.github.com/303249
1388 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
1389 var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
1390 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
1391 if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
1392 // XXX global assignment won't work in embeddings that use
1393 // an alternate object for the context.
1394 /* global Date: true */
1395 /* eslint-disable no-undef */
1396 var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
1397 var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
1398 /* eslint-disable no-implicit-globals */
1399 Date = (function (NativeDate) {
1400 /* eslint-enable no-implicit-globals */
1401 /* eslint-enable no-undef */
1402 // Date.length === 7
1403 var DateShim = function Date(Y, M, D, h, m, s, ms) {
1404 var length = arguments.length;
1405 var date;
1406 if (this instanceof NativeDate) {
1407 var seconds = s;
1408 var millis = ms;
1409 if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
1410 // work around a Safari 8/9 bug where it treats the seconds as signed
1411 var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1412 var sToShift = Math.floor(msToShift / 1e3);
1413 seconds += sToShift;
1414 millis -= sToShift * 1e3;
1415 }
1416 date = length === 1 && $String(Y) === Y ? // isString(Y)
1417 // We explicitly pass it through parse:
1418 new NativeDate(DateShim.parse(Y)) :
1419 // We have to manually make calls depending on argument
1420 // length here
1421 length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
1422 length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
1423 length >= 5 ? new NativeDate(Y, M, D, h, m) :
1424 length >= 4 ? new NativeDate(Y, M, D, h) :
1425 length >= 3 ? new NativeDate(Y, M, D) :
1426 length >= 2 ? new NativeDate(Y, M) :
1427 length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
1428 new NativeDate();
1429 } else {
1430 date = NativeDate.apply(this, arguments);
1431 }
1432 if (!isPrimitive(date)) {
1433 // Prevent mixups with unfixed Date object
1434 defineProperties(date, { constructor: DateShim }, true);
1435 }
1436 return date;
1437 };
1438
1439 // 15.9.1.15 Date Time String Format.
1440 var isoDateExpression = new RegExp('^' +
1441 '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
1442 // 6-digit extended year
1443 '(?:-(\\d{2})' + // optional month capture
1444 '(?:-(\\d{2})' + // optional day capture
1445 '(?:' + // capture hours:minutes:seconds.milliseconds
1446 'T(\\d{2})' + // hours capture
1447 ':(\\d{2})' + // minutes capture
1448 '(?:' + // optional :seconds.milliseconds
1449 ':(\\d{2})' + // seconds capture
1450 '(?:(\\.\\d{1,}))?' + // milliseconds capture
1451 ')?' +
1452 '(' + // capture UTC offset component
1453 'Z|' + // UTC capture
1454 '(?:' + // offset specifier +/-hours:minutes
1455 '([-+])' + // sign capture
1456 '(\\d{2})' + // hours offset capture
1457 ':(\\d{2})' + // minutes offset capture
1458 ')' +
1459 ')?)?)?)?' +
1460 '$');
1461
1462 var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
1463
1464 var dayFromMonth = function dayFromMonth(year, month) {
1465 var t = month > 1 ? 1 : 0;
1466 return (
1467 months[month] +
1468 Math.floor((year - 1969 + t) / 4) -
1469 Math.floor((year - 1901 + t) / 100) +
1470 Math.floor((year - 1601 + t) / 400) +
1471 365 * (year - 1970)
1472 );
1473 };
1474
1475 var toUTC = function toUTC(t) {
1476 var s = 0;
1477 var ms = t;
1478 if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
1479 // work around a Safari 8/9 bug where it treats the seconds as signed
1480 var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1481 var sToShift = Math.floor(msToShift / 1e3);
1482 s += sToShift;
1483 ms -= sToShift * 1e3;
1484 }
1485 return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
1486 };
1487
1488 // Copy any custom methods a 3rd party library may have added
1489 for (var key in NativeDate) {
1490 if (owns(NativeDate, key)) {
1491 DateShim[key] = NativeDate[key];
1492 }
1493 }
1494
1495 // Copy "native" methods explicitly; they may be non-enumerable
1496 defineProperties(DateShim, {
1497 now: NativeDate.now,
1498 UTC: NativeDate.UTC
1499 }, true);
1500 DateShim.prototype = NativeDate.prototype;
1501 defineProperties(DateShim.prototype, {
1502 constructor: DateShim
1503 }, true);
1504
1505 // Upgrade Date.parse to handle simplified ISO 8601 strings
1506 var parseShim = function parse(string) {
1507 var match = isoDateExpression.exec(string);
1508 if (match) {
1509 // parse months, days, hours, minutes, seconds, and milliseconds
1510 // provide default values if necessary
1511 // parse the UTC offset component
1512 var year = $Number(match[1]),
1513 month = $Number(match[2] || 1) - 1,
1514 day = $Number(match[3] || 1) - 1,
1515 hour = $Number(match[4] || 0),
1516 minute = $Number(match[5] || 0),
1517 second = $Number(match[6] || 0),
1518 millisecond = Math.floor($Number(match[7] || 0) * 1000),
1519 // When time zone is missed, local offset should be used
1520 // (ES 5.1 bug)
1521 // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1522 isLocalTime = Boolean(match[4] && !match[8]),
1523 signOffset = match[9] === '-' ? 1 : -1,
1524 hourOffset = $Number(match[10] || 0),
1525 minuteOffset = $Number(match[11] || 0),
1526 result;
1527 var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
1528 if (
1529 hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
1530 minute < 60 && second < 60 && millisecond < 1000 &&
1531 month > -1 && month < 12 && hourOffset < 24 &&
1532 minuteOffset < 60 && // detect invalid offsets
1533 day > -1 &&
1534 day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
1535 ) {
1536 result = (
1537 (dayFromMonth(year, month) + day) * 24 +
1538 hour +
1539 hourOffset * signOffset
1540 ) * 60;
1541 result = (
1542 (result + minute + minuteOffset * signOffset) * 60 +
1543 second
1544 ) * 1000 + millisecond;
1545 if (isLocalTime) {
1546 result = toUTC(result);
1547 }
1548 if (-8.64e15 <= result && result <= 8.64e15) {
1549 return result;
1550 }
1551 }
1552 return NaN;
1553 }
1554 return NativeDate.parse.apply(this, arguments);
1555 };
1556 defineProperties(DateShim, { parse: parseShim });
1557
1558 return DateShim;
1559 }(Date));
1560 /* global Date: false */
1561 }
1562
1563 // ES5 15.9.4.4
1564 // http://es5.github.com/#x15.9.4.4
1565 if (!Date.now) {
1566 Date.now = function now() {
1567 return new Date().getTime();
1568 };
1569 }
1570
1571 //
1572 // Number
1573 // ======
1574 //
1575
1576 // ES5.1 15.7.4.5
1577 // http://es5.github.com/#x15.7.4.5
1578 var hasToFixedBugs = NumberPrototype.toFixed && (
1579 (0.00008).toFixed(3) !== '0.000' ||
1580 (0.9).toFixed(0) !== '1' ||
1581 (1.255).toFixed(2) !== '1.25' ||
1582 (1000000000000000128).toFixed(0) !== '1000000000000000128'
1583 );
1584
1585 var toFixedHelpers = {
1586 base: 1e7,
1587 size: 6,
1588 data: [0, 0, 0, 0, 0, 0],
1589 multiply: function multiply(n, c) {
1590 var i = -1;
1591 var c2 = c;
1592 while (++i < toFixedHelpers.size) {
1593 c2 += n * toFixedHelpers.data[i];
1594 toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1595 c2 = Math.floor(c2 / toFixedHelpers.base);
1596 }
1597 },
1598 divide: function divide(n) {
1599 var i = toFixedHelpers.size;
1600 var c = 0;
1601 while (--i >= 0) {
1602 c += toFixedHelpers.data[i];
1603 toFixedHelpers.data[i] = Math.floor(c / n);
1604 c = (c % n) * toFixedHelpers.base;
1605 }
1606 },
1607 numToString: function numToString() {
1608 var i = toFixedHelpers.size;
1609 var s = '';
1610 while (--i >= 0) {
1611 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1612 var t = $String(toFixedHelpers.data[i]);
1613 if (s === '') {
1614 s = t;
1615 } else {
1616 s += strSlice('0000000', 0, 7 - t.length) + t;
1617 }
1618 }
1619 }
1620 return s;
1621 },
1622 pow: function pow(x, n, acc) {
1623 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1624 },
1625 log: function log(x) {
1626 var n = 0;
1627 var x2 = x;
1628 while (x2 >= 4096) {
1629 n += 12;
1630 x2 /= 4096;
1631 }
1632 while (x2 >= 2) {
1633 n += 1;
1634 x2 /= 2;
1635 }
1636 return n;
1637 }
1638 };
1639
1640 var toFixedShim = function toFixed(fractionDigits) {
1641 var f, x, s, m, e, z, j, k;
1642
1643 // Test for NaN and round fractionDigits down
1644 f = $Number(fractionDigits);
1645 f = isActualNaN(f) ? 0 : Math.floor(f);
1646
1647 if (f < 0 || f > 20) {
1648 throw new RangeError('Number.toFixed called with invalid number of decimals');
1649 }
1650
1651 x = $Number(this);
1652
1653 if (isActualNaN(x)) {
1654 return 'NaN';
1655 }
1656
1657 // If it is too big or small, return the string value of the number
1658 if (x <= -1e21 || x >= 1e21) {
1659 return $String(x);
1660 }
1661
1662 s = '';
1663
1664 if (x < 0) {
1665 s = '-';
1666 x = -x;
1667 }
1668
1669 m = '0';
1670
1671 if (x > 1e-21) {
1672 // 1e-21 < x < 1e21
1673 // -70 < log2(x) < 70
1674 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1675 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1676 z *= 0x10000000000000; // Math.pow(2, 52);
1677 e = 52 - e;
1678
1679 // -18 < e < 122
1680 // x = z / 2 ^ e
1681 if (e > 0) {
1682 toFixedHelpers.multiply(0, z);
1683 j = f;
1684
1685 while (j >= 7) {
1686 toFixedHelpers.multiply(1e7, 0);
1687 j -= 7;
1688 }
1689
1690 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1691 j = e - 1;
1692
1693 while (j >= 23) {
1694 toFixedHelpers.divide(1 << 23);
1695 j -= 23;
1696 }
1697
1698 toFixedHelpers.divide(1 << j);
1699 toFixedHelpers.multiply(1, 1);
1700 toFixedHelpers.divide(2);
1701 m = toFixedHelpers.numToString();
1702 } else {
1703 toFixedHelpers.multiply(0, z);
1704 toFixedHelpers.multiply(1 << (-e), 0);
1705 m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
1706 }
1707 }
1708
1709 if (f > 0) {
1710 k = m.length;
1711
1712 if (k <= f) {
1713 m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
1714 } else {
1715 m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
1716 }
1717 } else {
1718 m = s + m;
1719 }
1720
1721 return m;
1722 };
1723 defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
1724
1725 var hasToPrecisionUndefinedBug = (function () {
1726 try {
1727 return 1.0.toPrecision(undefined) === '1';
1728 } catch (e) {
1729 return true;
1730 }
1731 }());
1732 var originalToPrecision = NumberPrototype.toPrecision;
1733 defineProperties(NumberPrototype, {
1734 toPrecision: function toPrecision(precision) {
1735 return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
1736 }
1737 }, hasToPrecisionUndefinedBug);
1738
1739 //
1740 // String
1741 // ======
1742 //
1743
1744 // ES5 15.5.4.14
1745 // http://es5.github.com/#x15.5.4.14
1746
1747 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1748 // Many browsers do not split properly with regular expressions or they
1749 // do not perform the split correctly under obscure conditions.
1750 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1751 // I've tested in many browsers and this seems to cover the deviant ones:
1752 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1753 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1754 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1755 // [undefined, "t", undefined, "e", ...]
1756 // ''.split(/.?/) should be [], not [""]
1757 // '.'.split(/()()/) should be ["."], not ["", "", "."]
1758
1759 if (
1760 'ab'.split(/(?:ab)*/).length !== 2 ||
1761 '.'.split(/(.?)(.?)/).length !== 4 ||
1762 'tesst'.split(/(s)*/)[1] === 't' ||
1763 'test'.split(/(?:)/, -1).length !== 4 ||
1764 ''.split(/.?/).length ||
1765 '.'.split(/()()/).length > 1
1766 ) {
1767 (function () {
1768 var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1769 var maxSafe32BitInt = Math.pow(2, 32) - 1;
1770
1771 StringPrototype.split = function (separator, limit) {
1772 var string = String(this);
1773 if (typeof separator === 'undefined' && limit === 0) {
1774 return [];
1775 }
1776
1777 // If `separator` is not a regex, use native split
1778 if (!isRegex(separator)) {
1779 return strSplit(this, separator, limit);
1780 }
1781
1782 var output = [];
1783 var flags = (separator.ignoreCase ? 'i' : '') +
1784 (separator.multiline ? 'm' : '') +
1785 (separator.unicode ? 'u' : '') + // in ES6
1786 (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
1787 lastLastIndex = 0,
1788 // Make `global` and avoid `lastIndex` issues by working with a copy
1789 separator2, match, lastIndex, lastLength;
1790 var separatorCopy = new RegExp(separator.source, flags + 'g');
1791 if (!compliantExecNpcg) {
1792 // Doesn't need flags gy, but they don't hurt
1793 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
1794 }
1795 /* Values for `limit`, per the spec:
1796 * If undefined: 4294967295 // maxSafe32BitInt
1797 * If 0, Infinity, or NaN: 0
1798 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1799 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1800 * If other: Type-convert, then use the above rules
1801 */
1802 var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
1803 match = separatorCopy.exec(string);
1804 while (match) {
1805 // `separatorCopy.lastIndex` is not reliable cross-browser
1806 lastIndex = match.index + match[0].length;
1807 if (lastIndex > lastLastIndex) {
1808 pushCall(output, strSlice(string, lastLastIndex, match.index));
1809 // Fix browsers whose `exec` methods don't consistently return `undefined` for
1810 // nonparticipating capturing groups
1811 if (!compliantExecNpcg && match.length > 1) {
1812 /* eslint-disable no-loop-func */
1813 match[0].replace(separator2, function () {
1814 for (var i = 1; i < arguments.length - 2; i++) {
1815 if (typeof arguments[i] === 'undefined') {
1816 match[i] = void 0;
1817 }
1818 }
1819 });
1820 /* eslint-enable no-loop-func */
1821 }
1822 if (match.length > 1 && match.index < string.length) {
1823 array_push.apply(output, arraySlice(match, 1));
1824 }
1825 lastLength = match[0].length;
1826 lastLastIndex = lastIndex;
1827 if (output.length >= splitLimit) {
1828 break;
1829 }
1830 }
1831 if (separatorCopy.lastIndex === match.index) {
1832 separatorCopy.lastIndex++; // Avoid an infinite loop
1833 }
1834 match = separatorCopy.exec(string);
1835 }
1836 if (lastLastIndex === string.length) {
1837 if (lastLength || !separatorCopy.test('')) {
1838 pushCall(output, '');
1839 }
1840 } else {
1841 pushCall(output, strSlice(string, lastLastIndex));
1842 }
1843 return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
1844 };
1845 }());
1846
1847 // [bugfix, chrome]
1848 // If separator is undefined, then the result array contains just one String,
1849 // which is the this value (converted to a String). If limit is not undefined,
1850 // then the output array is truncated so that it contains no more than limit
1851 // elements.
1852 // "0".split(undefined, 0) -> []
1853 } else if ('0'.split(void 0, 0).length) {
1854 StringPrototype.split = function split(separator, limit) {
1855 if (typeof separator === 'undefined' && limit === 0) { return []; }
1856 return strSplit(this, separator, limit);
1857 };
1858 }
1859
1860 var str_replace = StringPrototype.replace;
1861 var replaceReportsGroupsCorrectly = (function () {
1862 var groups = [];
1863 'x'.replace(/x(.)?/g, function (match, group) {
1864 pushCall(groups, group);
1865 });
1866 return groups.length === 1 && typeof groups[0] === 'undefined';
1867 }());
1868
1869 if (!replaceReportsGroupsCorrectly) {
1870 StringPrototype.replace = function replace(searchValue, replaceValue) {
1871 var isFn = isCallable(replaceValue);
1872 var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
1873 if (!isFn || !hasCapturingGroups) {
1874 return str_replace.call(this, searchValue, replaceValue);
1875 } else {
1876 var wrappedReplaceValue = function (match) {
1877 var length = arguments.length;
1878 var originalLastIndex = searchValue.lastIndex;
1879 searchValue.lastIndex = 0;
1880 var args = searchValue.exec(match) || [];
1881 searchValue.lastIndex = originalLastIndex;
1882 pushCall(args, arguments[length - 2], arguments[length - 1]);
1883 return replaceValue.apply(this, args);
1884 };
1885 return str_replace.call(this, searchValue, wrappedReplaceValue);
1886 }
1887 };
1888 }
1889
1890 // ECMA-262, 3rd B.2.3
1891 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1892 // non-normative section suggesting uniform semantics and it should be
1893 // normalized across all browsers
1894 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1895 var string_substr = StringPrototype.substr;
1896 var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1897 defineProperties(StringPrototype, {
1898 substr: function substr(start, length) {
1899 var normalizedStart = start;
1900 if (start < 0) {
1901 normalizedStart = max(this.length + start, 0);
1902 }
1903 return string_substr.call(this, normalizedStart, length);
1904 }
1905 }, hasNegativeSubstrBug);
1906
1907 // ES5 15.5.4.20
1908 // whitespace from: http://es5.github.io/#x15.5.4.20
1909 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
1910 '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
1911 '\u2029\uFEFF';
1912 var zeroWidth = '\u200b';
1913 var wsRegexChars = '[' + ws + ']';
1914 var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
1915 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
1916 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
1917 defineProperties(StringPrototype, {
1918 // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1919 // http://perfectionkills.com/whitespace-deviations/
1920 trim: function trim() {
1921 if (typeof this === 'undefined' || this === null) {
1922 throw new TypeError("can't convert " + this + ' to object');
1923 }
1924 return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
1925 }
1926 }, hasTrimWhitespaceBug);
1927 var trim = call.bind(String.prototype.trim);
1928
1929 var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
1930 defineProperties(StringPrototype, {
1931 lastIndexOf: function lastIndexOf(searchString) {
1932 if (typeof this === 'undefined' || this === null) {
1933 throw new TypeError("can't convert " + this + ' to object');
1934 }
1935 var S = $String(this);
1936 var searchStr = $String(searchString);
1937 var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
1938 var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
1939 var start = min(max(pos, 0), S.length);
1940 var searchLen = searchStr.length;
1941 var k = start + searchLen;
1942 while (k > 0) {
1943 k = max(0, k - searchLen);
1944 var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
1945 if (index !== -1) {
1946 return k + index;
1947 }
1948 }
1949 return -1;
1950 }
1951 }, hasLastIndexBug);
1952
1953 var originalLastIndexOf = StringPrototype.lastIndexOf;
1954 defineProperties(StringPrototype, {
1955 lastIndexOf: function lastIndexOf(searchString) {
1956 return originalLastIndexOf.apply(this, arguments);
1957 }
1958 }, StringPrototype.lastIndexOf.length !== 1);
1959
1960 // ES-5 15.1.2.2
1961 /* eslint-disable radix */
1962 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
1963 /* eslint-enable radix */
1964 /* global parseInt: true */
1965 parseInt = (function (origParseInt) {
1966 var hexRegex = /^[\-+]?0[xX]/;
1967 return function parseInt(str, radix) {
1968 var string = trim(str);
1969 var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
1970 return origParseInt(string, defaultedRadix);
1971 };
1972 }(parseInt));
1973 }
1974
1975 // https://es5.github.io/#x15.1.2.3
1976 if (1 / parseFloat('-0') !== -Infinity) {
1977 /* global parseFloat: true */
1978 parseFloat = (function (origParseFloat) {
1979 return function parseFloat(string) {
1980 var inputString = trim(string);
1981 var result = origParseFloat(inputString);
1982 return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
1983 };
1984 }(parseFloat));
1985 }
1986
1987 if (String(new RangeError('test')) !== 'RangeError: test') {
1988 var errorToStringShim = function toString() {
1989 if (typeof this === 'undefined' || this === null) {
1990 throw new TypeError("can't convert " + this + ' to object');
1991 }
1992 var name = this.name;
1993 if (typeof name === 'undefined') {
1994 name = 'Error';
1995 } else if (typeof name !== 'string') {
1996 name = $String(name);
1997 }
1998 var msg = this.message;
1999 if (typeof msg === 'undefined') {
2000 msg = '';
2001 } else if (typeof msg !== 'string') {
2002 msg = $String(msg);
2003 }
2004 if (!name) {
2005 return msg;
2006 }
2007 if (!msg) {
2008 return name;
2009 }
2010 return name + ': ' + msg;
2011 };
2012 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2013 Error.prototype.toString = errorToStringShim;
2014 }
2015
2016 if (supportsDescriptors) {
2017 var ensureNonEnumerable = function (obj, prop) {
2018 if (isEnum(obj, prop)) {
2019 var desc = Object.getOwnPropertyDescriptor(obj, prop);
2020 if (desc.configurable) {
2021 desc.enumerable = false;
2022 Object.defineProperty(obj, prop, desc);
2023 }
2024 }
2025 };
2026 ensureNonEnumerable(Error.prototype, 'message');
2027 if (Error.prototype.message !== '') {
2028 Error.prototype.message = '';
2029 }
2030 ensureNonEnumerable(Error.prototype, 'name');
2031 }
2032
2033 if (String(/a/mig) !== '/a/gim') {
2034 var regexToString = function toString() {
2035 var str = '/' + this.source + '/';
2036 if (this.global) {
2037 str += 'g';
2038 }
2039 if (this.ignoreCase) {
2040 str += 'i';
2041 }
2042 if (this.multiline) {
2043 str += 'm';
2044 }
2045 return str;
2046 };
2047 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2048 RegExp.prototype.toString = regexToString;
2049 }
2050
2051 }));