Merge "Made ReplicatedBagOStuff wrapping the SQL class the default stash"
[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/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.
43 var ArrayPrototype = Array.prototype;
44 var ObjectPrototype = Object.prototype;
45 var FunctionPrototype = Function.prototype;
46 var StringPrototype = String.prototype;
47 var NumberPrototype = Number.prototype;
48 var array_slice = ArrayPrototype.slice;
49 var array_splice = ArrayPrototype.splice;
50 var array_push = ArrayPrototype.push;
51 var array_unshift = ArrayPrototype.unshift;
52 var array_concat = ArrayPrototype.concat;
53 var call = FunctionPrototype.call;
54
55 // Having a toString local variable name breaks in Opera so use to_string.
56 var to_string = ObjectPrototype.toString;
57
58 var isArray = Array.isArray || function isArray(obj) {
59 return to_string.call(obj) === '[object Array]';
60 };
61
62 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
63 var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
64 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; };
65 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; };
66
67 var isArguments = function isArguments(value) {
68 var str = to_string.call(value);
69 var isArgs = str === '[object Arguments]';
70 if (!isArgs) {
71 isArgs = !isArray(value) &&
72 value !== null &&
73 typeof value === 'object' &&
74 typeof value.length === 'number' &&
75 value.length >= 0 &&
76 isCallable(value.callee);
77 }
78 return isArgs;
79 };
80
81 /* inlined from http://npmjs.com/define-properties */
82 var defineProperties = (function (has) {
83 var supportsDescriptors = Object.defineProperty && (function () {
84 try {
85 var obj = {};
86 Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
87 for (var _ in obj) { return false; }
88 return obj.x === obj;
89 } catch (e) { /* this is ES3 */
90 return false;
91 }
92 }());
93
94 // Define configurable, writable and non-enumerable props
95 // if they don't exist.
96 var defineProperty;
97 if (supportsDescriptors) {
98 defineProperty = function (object, name, method, forceAssign) {
99 if (!forceAssign && (name in object)) { return; }
100 Object.defineProperty(object, name, {
101 configurable: true,
102 enumerable: false,
103 writable: true,
104 value: method
105 });
106 };
107 } else {
108 defineProperty = function (object, name, method, forceAssign) {
109 if (!forceAssign && (name in object)) { return; }
110 object[name] = method;
111 };
112 }
113 return function defineProperties(object, map, forceAssign) {
114 for (var name in map) {
115 if (has.call(map, name)) {
116 defineProperty(object, name, map[name], forceAssign);
117 }
118 }
119 };
120 }(ObjectPrototype.hasOwnProperty));
121
122 //
123 // Util
124 // ======
125 //
126
127 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
128 var isPrimitive = function isPrimitive(input) {
129 var type = typeof input;
130 return input === null || (type !== 'object' && type !== 'function');
131 };
132
133 var ES = {
134 // ES5 9.4
135 // http://es5.github.com/#x9.4
136 // http://jsperf.com/to-integer
137 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
138 ToInteger: function ToInteger(num) {
139 var n = +num;
140 if (n !== n) { // isNaN
141 n = 0;
142 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
143 n = (n > 0 || -1) * Math.floor(Math.abs(n));
144 }
145 return n;
146 },
147
148 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
149 ToPrimitive: function ToPrimitive(input) {
150 var val, valueOf, toStr;
151 if (isPrimitive(input)) {
152 return input;
153 }
154 valueOf = input.valueOf;
155 if (isCallable(valueOf)) {
156 val = valueOf.call(input);
157 if (isPrimitive(val)) {
158 return val;
159 }
160 }
161 toStr = input.toString;
162 if (isCallable(toStr)) {
163 val = toStr.call(input);
164 if (isPrimitive(val)) {
165 return val;
166 }
167 }
168 throw new TypeError();
169 },
170
171 // ES5 9.9
172 // http://es5.github.com/#x9.9
173 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
174 ToObject: function (o) {
175 /*jshint eqnull: true */
176 if (o == null) { // this matches both null and undefined
177 throw new TypeError("can't convert " + o + ' to object');
178 }
179 return Object(o);
180 },
181
182 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
183 ToUint32: function ToUint32(x) {
184 return x >>> 0;
185 }
186 };
187
188 //
189 // Function
190 // ========
191 //
192
193 // ES-5 15.3.4.5
194 // http://es5.github.com/#x15.3.4.5
195
196 var Empty = function Empty() {};
197
198 defineProperties(FunctionPrototype, {
199 bind: function bind(that) { // .length is 1
200 // 1. Let Target be the this value.
201 var target = this;
202 // 2. If IsCallable(Target) is false, throw a TypeError exception.
203 if (!isCallable(target)) {
204 throw new TypeError('Function.prototype.bind called on incompatible ' + target);
205 }
206 // 3. Let A be a new (possibly empty) internal list of all of the
207 // argument values provided after thisArg (arg1, arg2 etc), in order.
208 // XXX slicedArgs will stand in for "A" if used
209 var args = array_slice.call(arguments, 1); // for normal call
210 // 4. Let F be a new native ECMAScript object.
211 // 11. Set the [[Prototype]] internal property of F to the standard
212 // built-in Function prototype object as specified in 15.3.3.1.
213 // 12. Set the [[Call]] internal property of F as described in
214 // 15.3.4.5.1.
215 // 13. Set the [[Construct]] internal property of F as described in
216 // 15.3.4.5.2.
217 // 14. Set the [[HasInstance]] internal property of F as described in
218 // 15.3.4.5.3.
219 var bound;
220 var binder = function () {
221
222 if (this instanceof bound) {
223 // 15.3.4.5.2 [[Construct]]
224 // When the [[Construct]] internal method of a function object,
225 // F that was created using the bind function is called with a
226 // list of arguments ExtraArgs, the following steps are taken:
227 // 1. Let target be the value of F's [[TargetFunction]]
228 // internal property.
229 // 2. If target has no [[Construct]] internal method, a
230 // TypeError exception is thrown.
231 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
232 // property.
233 // 4. Let args be a new list containing the same values as the
234 // list boundArgs in the same order followed by the same
235 // values as the list ExtraArgs in the same order.
236 // 5. Return the result of calling the [[Construct]] internal
237 // method of target providing args as the arguments.
238
239 var result = target.apply(
240 this,
241 array_concat.call(args, array_slice.call(arguments))
242 );
243 if (Object(result) === result) {
244 return result;
245 }
246 return this;
247
248 } else {
249 // 15.3.4.5.1 [[Call]]
250 // When the [[Call]] internal method of a function object, F,
251 // which was created using the bind function is called with a
252 // this value and a list of arguments ExtraArgs, the following
253 // steps are taken:
254 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
255 // property.
256 // 2. Let boundThis be the value of F's [[BoundThis]] internal
257 // property.
258 // 3. Let target be the value of F's [[TargetFunction]] internal
259 // property.
260 // 4. Let args be a new list containing the same values as the
261 // list boundArgs in the same order followed by the same
262 // values as the list ExtraArgs in the same order.
263 // 5. Return the result of calling the [[Call]] internal method
264 // of target providing boundThis as the this value and
265 // providing args as the arguments.
266
267 // equiv: target.call(this, ...boundArgs, ...args)
268 return target.apply(
269 that,
270 array_concat.call(args, array_slice.call(arguments))
271 );
272
273 }
274
275 };
276
277 // 15. If the [[Class]] internal property of Target is "Function", then
278 // a. Let L be the length property of Target minus the length of A.
279 // b. Set the length own property of F to either 0 or L, whichever is
280 // larger.
281 // 16. Else set the length own property of F to 0.
282
283 var boundLength = Math.max(0, target.length - args.length);
284
285 // 17. Set the attributes of the length own property of F to the values
286 // specified in 15.3.5.1.
287 var boundArgs = [];
288 for (var i = 0; i < boundLength; i++) {
289 boundArgs.push('$' + i);
290 }
291
292 // XXX Build a dynamic function with desired amount of arguments is the only
293 // way to set the length property of a function.
294 // In environments where Content Security Policies enabled (Chrome extensions,
295 // for ex.) all use of eval or Function costructor throws an exception.
296 // However in all of these environments Function.prototype.bind exists
297 // and so this code will never be executed.
298 bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
299
300 if (target.prototype) {
301 Empty.prototype = target.prototype;
302 bound.prototype = new Empty();
303 // Clean up dangling references.
304 Empty.prototype = null;
305 }
306
307 // TODO
308 // 18. Set the [[Extensible]] internal property of F to true.
309
310 // TODO
311 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
312 // 20. Call the [[DefineOwnProperty]] internal method of F with
313 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
314 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
315 // false.
316 // 21. Call the [[DefineOwnProperty]] internal method of F with
317 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
318 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
319 // and false.
320
321 // TODO
322 // NOTE Function objects created using Function.prototype.bind do not
323 // have a prototype property or the [[Code]], [[FormalParameters]], and
324 // [[Scope]] internal properties.
325 // XXX can't delete prototype in pure-js.
326
327 // 22. Return F.
328 return bound;
329 }
330 });
331
332 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
333 // us it in defining shortcuts.
334 var owns = call.bind(ObjectPrototype.hasOwnProperty);
335
336 //
337 // Array
338 // =====
339 //
340
341 // ES5 15.4.4.12
342 // http://es5.github.com/#x15.4.4.12
343 var spliceNoopReturnsEmptyArray = (function () {
344 var a = [1, 2];
345 var result = a.splice();
346 return a.length === 2 && isArray(result) && result.length === 0;
347 }());
348 defineProperties(ArrayPrototype, {
349 // Safari 5.0 bug where .splice() returns undefined
350 splice: function splice(start, deleteCount) {
351 if (arguments.length === 0) {
352 return [];
353 } else {
354 return array_splice.apply(this, arguments);
355 }
356 }
357 }, !spliceNoopReturnsEmptyArray);
358
359 var spliceWorksWithEmptyObject = (function () {
360 var obj = {};
361 ArrayPrototype.splice.call(obj, 0, 0, 1);
362 return obj.length === 1;
363 }());
364 defineProperties(ArrayPrototype, {
365 splice: function splice(start, deleteCount) {
366 if (arguments.length === 0) { return []; }
367 var args = arguments;
368 this.length = Math.max(ES.ToInteger(this.length), 0);
369 if (arguments.length > 0 && typeof deleteCount !== 'number') {
370 args = array_slice.call(arguments);
371 if (args.length < 2) {
372 args.push(this.length - start);
373 } else {
374 args[1] = ES.ToInteger(deleteCount);
375 }
376 }
377 return array_splice.apply(this, args);
378 }
379 }, !spliceWorksWithEmptyObject);
380
381 // ES5 15.4.4.12
382 // http://es5.github.com/#x15.4.4.13
383 // Return len+argCount.
384 // [bugfix, ielt8]
385 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
386 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
387 defineProperties(ArrayPrototype, {
388 unshift: function () {
389 array_unshift.apply(this, arguments);
390 return this.length;
391 }
392 }, hasUnshiftReturnValueBug);
393
394 // ES5 15.4.3.2
395 // http://es5.github.com/#x15.4.3.2
396 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
397 defineProperties(Array, { isArray: isArray });
398
399 // The IsCallable() check in the Array functions
400 // has been replaced with a strict check on the
401 // internal class of the object to trap cases where
402 // the provided function was actually a regular
403 // expression literal, which in V8 and
404 // JavaScriptCore is a typeof "function". Only in
405 // V8 are regular expression literals permitted as
406 // reduce parameters, so it is desirable in the
407 // general case for the shim to match the more
408 // strict and common behavior of rejecting regular
409 // expressions.
410
411 // ES5 15.4.4.18
412 // http://es5.github.com/#x15.4.4.18
413 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
414
415 // Check failure of by-index access of string characters (IE < 9)
416 // and failure of `0 in boxedString` (Rhino)
417 var boxedString = Object('a');
418 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
419
420 var properlyBoxesContext = function properlyBoxed(method) {
421 // Check node 0.6.21 bug where third parameter is not boxed
422 var properlyBoxesNonStrict = true;
423 var properlyBoxesStrict = true;
424 if (method) {
425 method.call('foo', function (_, __, context) {
426 if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
427 });
428
429 method.call([1], function () {
430 'use strict';
431
432 properlyBoxesStrict = typeof this === 'string';
433 }, 'x');
434 }
435 return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
436 };
437
438 defineProperties(ArrayPrototype, {
439 forEach: function forEach(callbackfn /*, thisArg*/) {
440 var object = ES.ToObject(this);
441 var self = splitString && isString(this) ? this.split('') : object;
442 var i = -1;
443 var length = self.length >>> 0;
444 var T;
445 if (arguments.length > 1) {
446 T = arguments[1];
447 }
448
449 // If no callback function or if callback is not a callable function
450 if (!isCallable(callbackfn)) {
451 throw new TypeError('Array.prototype.forEach callback must be a function');
452 }
453
454 while (++i < length) {
455 if (i in self) {
456 // Invoke the callback function with call, passing arguments:
457 // context, property value, property key, thisArg object
458 if (typeof T !== 'undefined') {
459 callbackfn.call(T, self[i], i, object);
460 } else {
461 callbackfn(self[i], i, object);
462 }
463 }
464 }
465 }
466 }, !properlyBoxesContext(ArrayPrototype.forEach));
467
468 // ES5 15.4.4.19
469 // http://es5.github.com/#x15.4.4.19
470 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
471 defineProperties(ArrayPrototype, {
472 map: function map(callbackfn/*, thisArg*/) {
473 var object = ES.ToObject(this);
474 var self = splitString && isString(this) ? this.split('') : object;
475 var length = self.length >>> 0;
476 var result = Array(length);
477 var T;
478 if (arguments.length > 1) {
479 T = arguments[1];
480 }
481
482 // If no callback function or if callback is not a callable function
483 if (!isCallable(callbackfn)) {
484 throw new TypeError('Array.prototype.map callback must be a function');
485 }
486
487 for (var i = 0; i < length; i++) {
488 if (i in self) {
489 if (typeof T !== 'undefined') {
490 result[i] = callbackfn.call(T, self[i], i, object);
491 } else {
492 result[i] = callbackfn(self[i], i, object);
493 }
494 }
495 }
496 return result;
497 }
498 }, !properlyBoxesContext(ArrayPrototype.map));
499
500 // ES5 15.4.4.20
501 // http://es5.github.com/#x15.4.4.20
502 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
503 defineProperties(ArrayPrototype, {
504 filter: function filter(callbackfn /*, thisArg*/) {
505 var object = ES.ToObject(this);
506 var self = splitString && isString(this) ? this.split('') : object;
507 var length = self.length >>> 0;
508 var result = [];
509 var value;
510 var T;
511 if (arguments.length > 1) {
512 T = arguments[1];
513 }
514
515 // If no callback function or if callback is not a callable function
516 if (!isCallable(callbackfn)) {
517 throw new TypeError('Array.prototype.filter callback must be a function');
518 }
519
520 for (var i = 0; i < length; i++) {
521 if (i in self) {
522 value = self[i];
523 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
524 result.push(value);
525 }
526 }
527 }
528 return result;
529 }
530 }, !properlyBoxesContext(ArrayPrototype.filter));
531
532 // ES5 15.4.4.16
533 // http://es5.github.com/#x15.4.4.16
534 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
535 defineProperties(ArrayPrototype, {
536 every: function every(callbackfn /*, thisArg*/) {
537 var object = ES.ToObject(this);
538 var self = splitString && isString(this) ? this.split('') : object;
539 var length = self.length >>> 0;
540 var T;
541 if (arguments.length > 1) {
542 T = arguments[1];
543 }
544
545 // If no callback function or if callback is not a callable function
546 if (!isCallable(callbackfn)) {
547 throw new TypeError('Array.prototype.every callback must be a function');
548 }
549
550 for (var i = 0; i < length; i++) {
551 if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
552 return false;
553 }
554 }
555 return true;
556 }
557 }, !properlyBoxesContext(ArrayPrototype.every));
558
559 // ES5 15.4.4.17
560 // http://es5.github.com/#x15.4.4.17
561 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
562 defineProperties(ArrayPrototype, {
563 some: function some(callbackfn/*, thisArg */) {
564 var object = ES.ToObject(this);
565 var self = splitString && isString(this) ? this.split('') : object;
566 var length = self.length >>> 0;
567 var T;
568 if (arguments.length > 1) {
569 T = arguments[1];
570 }
571
572 // If no callback function or if callback is not a callable function
573 if (!isCallable(callbackfn)) {
574 throw new TypeError('Array.prototype.some callback must be a function');
575 }
576
577 for (var i = 0; i < length; i++) {
578 if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
579 return true;
580 }
581 }
582 return false;
583 }
584 }, !properlyBoxesContext(ArrayPrototype.some));
585
586 // ES5 15.4.4.21
587 // http://es5.github.com/#x15.4.4.21
588 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
589 var reduceCoercesToObject = false;
590 if (ArrayPrototype.reduce) {
591 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
592 }
593 defineProperties(ArrayPrototype, {
594 reduce: function reduce(callbackfn /*, initialValue*/) {
595 var object = ES.ToObject(this);
596 var self = splitString && isString(this) ? this.split('') : object;
597 var length = self.length >>> 0;
598
599 // If no callback function or if callback is not a callable function
600 if (!isCallable(callbackfn)) {
601 throw new TypeError('Array.prototype.reduce callback must be a function');
602 }
603
604 // no value to return if no initial value and an empty array
605 if (length === 0 && arguments.length === 1) {
606 throw new TypeError('reduce of empty array with no initial value');
607 }
608
609 var i = 0;
610 var result;
611 if (arguments.length >= 2) {
612 result = arguments[1];
613 } else {
614 do {
615 if (i in self) {
616 result = self[i++];
617 break;
618 }
619
620 // if array contains no values, no initial value to return
621 if (++i >= length) {
622 throw new TypeError('reduce of empty array with no initial value');
623 }
624 } while (true);
625 }
626
627 for (; i < length; i++) {
628 if (i in self) {
629 result = callbackfn(result, self[i], i, object);
630 }
631 }
632
633 return result;
634 }
635 }, !reduceCoercesToObject);
636
637 // ES5 15.4.4.22
638 // http://es5.github.com/#x15.4.4.22
639 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
640 var reduceRightCoercesToObject = false;
641 if (ArrayPrototype.reduceRight) {
642 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
643 }
644 defineProperties(ArrayPrototype, {
645 reduceRight: function reduceRight(callbackfn/*, initial*/) {
646 var object = ES.ToObject(this);
647 var self = splitString && isString(this) ? this.split('') : object;
648 var length = self.length >>> 0;
649
650 // If no callback function or if callback is not a callable function
651 if (!isCallable(callbackfn)) {
652 throw new TypeError('Array.prototype.reduceRight callback must be a function');
653 }
654
655 // no value to return if no initial value, empty array
656 if (length === 0 && arguments.length === 1) {
657 throw new TypeError('reduceRight of empty array with no initial value');
658 }
659
660 var result;
661 var i = length - 1;
662 if (arguments.length >= 2) {
663 result = arguments[1];
664 } else {
665 do {
666 if (i in self) {
667 result = self[i--];
668 break;
669 }
670
671 // if array contains no values, no initial value to return
672 if (--i < 0) {
673 throw new TypeError('reduceRight of empty array with no initial value');
674 }
675 } while (true);
676 }
677
678 if (i < 0) {
679 return result;
680 }
681
682 do {
683 if (i in self) {
684 result = callbackfn(result, self[i], i, object);
685 }
686 } while (i--);
687
688 return result;
689 }
690 }, !reduceRightCoercesToObject);
691
692 // ES5 15.4.4.14
693 // http://es5.github.com/#x15.4.4.14
694 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
695 var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
696 defineProperties(ArrayPrototype, {
697 indexOf: function indexOf(searchElement /*, fromIndex */) {
698 var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
699 var length = self.length >>> 0;
700
701 if (length === 0) {
702 return -1;
703 }
704
705 var i = 0;
706 if (arguments.length > 1) {
707 i = ES.ToInteger(arguments[1]);
708 }
709
710 // handle negative indices
711 i = i >= 0 ? i : Math.max(0, length + i);
712 for (; i < length; i++) {
713 if (i in self && self[i] === searchElement) {
714 return i;
715 }
716 }
717 return -1;
718 }
719 }, hasFirefox2IndexOfBug);
720
721 // ES5 15.4.4.15
722 // http://es5.github.com/#x15.4.4.15
723 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
724 var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
725 defineProperties(ArrayPrototype, {
726 lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
727 var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
728 var length = self.length >>> 0;
729
730 if (length === 0) {
731 return -1;
732 }
733 var i = length - 1;
734 if (arguments.length > 1) {
735 i = Math.min(i, ES.ToInteger(arguments[1]));
736 }
737 // handle negative indices
738 i = i >= 0 ? i : length - Math.abs(i);
739 for (; i >= 0; i--) {
740 if (i in self && searchElement === self[i]) {
741 return i;
742 }
743 }
744 return -1;
745 }
746 }, hasFirefox2LastIndexOfBug);
747
748 //
749 // Object
750 // ======
751 //
752
753 // ES5 15.2.3.14
754 // http://es5.github.com/#x15.2.3.14
755
756 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
757 var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString'),
758 hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'),
759 hasStringEnumBug = !owns('x', '0'),
760 dontEnums = [
761 'toString',
762 'toLocaleString',
763 'valueOf',
764 'hasOwnProperty',
765 'isPrototypeOf',
766 'propertyIsEnumerable',
767 'constructor'
768 ],
769 dontEnumsLength = dontEnums.length;
770
771 defineProperties(Object, {
772 keys: function keys(object) {
773 var isFn = isCallable(object),
774 isArgs = isArguments(object),
775 isObject = object !== null && typeof object === 'object',
776 isStr = isObject && isString(object);
777
778 if (!isObject && !isFn && !isArgs) {
779 throw new TypeError('Object.keys called on a non-object');
780 }
781
782 var theKeys = [];
783 var skipProto = hasProtoEnumBug && isFn;
784 if ((isStr && hasStringEnumBug) || isArgs) {
785 for (var i = 0; i < object.length; ++i) {
786 theKeys.push(String(i));
787 }
788 }
789
790 if (!isArgs) {
791 for (var name in object) {
792 if (!(skipProto && name === 'prototype') && owns(object, name)) {
793 theKeys.push(String(name));
794 }
795 }
796 }
797
798 if (hasDontEnumBug) {
799 var ctor = object.constructor,
800 skipConstructor = ctor && ctor.prototype === object;
801 for (var j = 0; j < dontEnumsLength; j++) {
802 var dontEnum = dontEnums[j];
803 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
804 theKeys.push(dontEnum);
805 }
806 }
807 }
808 return theKeys;
809 }
810 });
811
812 var keysWorksWithArguments = Object.keys && (function () {
813 // Safari 5.0 bug
814 return Object.keys(arguments).length === 2;
815 }(1, 2));
816 var originalKeys = Object.keys;
817 defineProperties(Object, {
818 keys: function keys(object) {
819 if (isArguments(object)) {
820 return originalKeys(ArrayPrototype.slice.call(object));
821 } else {
822 return originalKeys(object);
823 }
824 }
825 }, !keysWorksWithArguments);
826
827 //
828 // Date
829 // ====
830 //
831
832 // ES5 15.9.5.43
833 // http://es5.github.com/#x15.9.5.43
834 // This function returns a String value represent the instance in time
835 // represented by this Date object. The format of the String is the Date Time
836 // string format defined in 15.9.1.15. All fields are present in the String.
837 // The time zone is always UTC, denoted by the suffix Z. If the time value of
838 // this object is not a finite Number a RangeError exception is thrown.
839 var negativeDate = -62198755200000;
840 var negativeYearString = '-000001';
841 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
842
843 defineProperties(Date.prototype, {
844 toISOString: function toISOString() {
845 var result, length, value, year, month;
846 if (!isFinite(this)) {
847 throw new RangeError('Date.prototype.toISOString called on non-finite value.');
848 }
849
850 year = this.getUTCFullYear();
851
852 month = this.getUTCMonth();
853 // see https://github.com/es-shims/es5-shim/issues/111
854 year += Math.floor(month / 12);
855 month = (month % 12 + 12) % 12;
856
857 // the date time string format is specified in 15.9.1.15.
858 result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
859 year = (
860 (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
861 ('00000' + Math.abs(year)).slice((0 <= year && year <= 9999) ? -4 : -6)
862 );
863
864 length = result.length;
865 while (length--) {
866 value = result[length];
867 // pad months, days, hours, minutes, and seconds to have two
868 // digits.
869 if (value < 10) {
870 result[length] = '0' + value;
871 }
872 }
873 // pad milliseconds to have three digits.
874 return (
875 year + '-' + result.slice(0, 2).join('-') +
876 'T' + result.slice(2).join(':') + '.' +
877 ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'
878 );
879 }
880 }, hasNegativeDateBug);
881
882 // ES5 15.9.5.44
883 // http://es5.github.com/#x15.9.5.44
884 // This function provides a String representation of a Date object for use by
885 // JSON.stringify (15.12.3).
886 var dateToJSONIsSupported = (function () {
887 try {
888 return Date.prototype.toJSON &&
889 new Date(NaN).toJSON() === null &&
890 new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
891 Date.prototype.toJSON.call({ // generic
892 toISOString: function () { return true; }
893 });
894 } catch (e) {
895 return false;
896 }
897 }());
898 if (!dateToJSONIsSupported) {
899 Date.prototype.toJSON = function toJSON(key) {
900 // When the toJSON method is called with argument key, the following
901 // steps are taken:
902
903 // 1. Let O be the result of calling ToObject, giving it the this
904 // value as its argument.
905 // 2. Let tv be ES.ToPrimitive(O, hint Number).
906 var O = Object(this);
907 var tv = ES.ToPrimitive(O);
908 // 3. If tv is a Number and is not finite, return null.
909 if (typeof tv === 'number' && !isFinite(tv)) {
910 return null;
911 }
912 // 4. Let toISO be the result of calling the [[Get]] internal method of
913 // O with argument "toISOString".
914 var toISO = O.toISOString;
915 // 5. If IsCallable(toISO) is false, throw a TypeError exception.
916 if (!isCallable(toISO)) {
917 throw new TypeError('toISOString property is not callable');
918 }
919 // 6. Return the result of calling the [[Call]] internal method of
920 // toISO with O as the this value and an empty argument list.
921 return toISO.call(O);
922
923 // NOTE 1 The argument is ignored.
924
925 // NOTE 2 The toJSON function is intentionally generic; it does not
926 // require that its this value be a Date object. Therefore, it can be
927 // transferred to other kinds of objects for use as a method. However,
928 // it does require that any such object have a toISOString method. An
929 // object is free to use the argument key to filter its
930 // stringification.
931 };
932 }
933
934 // ES5 15.9.4.2
935 // http://es5.github.com/#x15.9.4.2
936 // based on work shared by Daniel Friesen (dantman)
937 // http://gist.github.com/303249
938 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
939 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'));
940 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
941 if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
942 // XXX global assignment won't work in embeddings that use
943 // an alternate object for the context.
944 /*global Date: true */
945 /*eslint-disable no-undef*/
946 Date = (function (NativeDate) {
947 /*eslint-enable no-undef*/
948 // Date.length === 7
949 var DateShim = function Date(Y, M, D, h, m, s, ms) {
950 var length = arguments.length;
951 var date;
952 if (this instanceof NativeDate) {
953 date = length === 1 && String(Y) === Y ? // isString(Y)
954 // We explicitly pass it through parse:
955 new NativeDate(DateShim.parse(Y)) :
956 // We have to manually make calls depending on argument
957 // length here
958 length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
959 length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
960 length >= 5 ? new NativeDate(Y, M, D, h, m) :
961 length >= 4 ? new NativeDate(Y, M, D, h) :
962 length >= 3 ? new NativeDate(Y, M, D) :
963 length >= 2 ? new NativeDate(Y, M) :
964 length >= 1 ? new NativeDate(Y) :
965 new NativeDate();
966 } else {
967 date = NativeDate.apply(this, arguments);
968 }
969 // Prevent mixups with unfixed Date object
970 defineProperties(date, { constructor: DateShim }, true);
971 return date;
972 };
973
974 // 15.9.1.15 Date Time String Format.
975 var isoDateExpression = new RegExp('^' +
976 '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
977 // 6-digit extended year
978 '(?:-(\\d{2})' + // optional month capture
979 '(?:-(\\d{2})' + // optional day capture
980 '(?:' + // capture hours:minutes:seconds.milliseconds
981 'T(\\d{2})' + // hours capture
982 ':(\\d{2})' + // minutes capture
983 '(?:' + // optional :seconds.milliseconds
984 ':(\\d{2})' + // seconds capture
985 '(?:(\\.\\d{1,}))?' + // milliseconds capture
986 ')?' +
987 '(' + // capture UTC offset component
988 'Z|' + // UTC capture
989 '(?:' + // offset specifier +/-hours:minutes
990 '([-+])' + // sign capture
991 '(\\d{2})' + // hours offset capture
992 ':(\\d{2})' + // minutes offset capture
993 ')' +
994 ')?)?)?)?' +
995 '$');
996
997 var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
998
999 var dayFromMonth = function dayFromMonth(year, month) {
1000 var t = month > 1 ? 1 : 0;
1001 return (
1002 months[month] +
1003 Math.floor((year - 1969 + t) / 4) -
1004 Math.floor((year - 1901 + t) / 100) +
1005 Math.floor((year - 1601 + t) / 400) +
1006 365 * (year - 1970)
1007 );
1008 };
1009
1010 var toUTC = function toUTC(t) {
1011 return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
1012 };
1013
1014 // Copy any custom methods a 3rd party library may have added
1015 for (var key in NativeDate) {
1016 if (owns(NativeDate, key)) {
1017 DateShim[key] = NativeDate[key];
1018 }
1019 }
1020
1021 // Copy "native" methods explicitly; they may be non-enumerable
1022 defineProperties(DateShim, {
1023 now: NativeDate.now,
1024 UTC: NativeDate.UTC
1025 }, true);
1026 DateShim.prototype = NativeDate.prototype;
1027 defineProperties(DateShim.prototype, {
1028 constructor: DateShim
1029 }, true);
1030
1031 // Upgrade Date.parse to handle simplified ISO 8601 strings
1032 DateShim.parse = function parse(string) {
1033 var match = isoDateExpression.exec(string);
1034 if (match) {
1035 // parse months, days, hours, minutes, seconds, and milliseconds
1036 // provide default values if necessary
1037 // parse the UTC offset component
1038 var year = Number(match[1]),
1039 month = Number(match[2] || 1) - 1,
1040 day = Number(match[3] || 1) - 1,
1041 hour = Number(match[4] || 0),
1042 minute = Number(match[5] || 0),
1043 second = Number(match[6] || 0),
1044 millisecond = Math.floor(Number(match[7] || 0) * 1000),
1045 // When time zone is missed, local offset should be used
1046 // (ES 5.1 bug)
1047 // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1048 isLocalTime = Boolean(match[4] && !match[8]),
1049 signOffset = match[9] === '-' ? 1 : -1,
1050 hourOffset = Number(match[10] || 0),
1051 minuteOffset = Number(match[11] || 0),
1052 result;
1053 if (
1054 hour < (
1055 minute > 0 || second > 0 || millisecond > 0 ?
1056 24 : 25
1057 ) &&
1058 minute < 60 && second < 60 && millisecond < 1000 &&
1059 month > -1 && month < 12 && hourOffset < 24 &&
1060 minuteOffset < 60 && // detect invalid offsets
1061 day > -1 &&
1062 day < (
1063 dayFromMonth(year, month + 1) -
1064 dayFromMonth(year, month)
1065 )
1066 ) {
1067 result = (
1068 (dayFromMonth(year, month) + day) * 24 +
1069 hour +
1070 hourOffset * signOffset
1071 ) * 60;
1072 result = (
1073 (result + minute + minuteOffset * signOffset) * 60 +
1074 second
1075 ) * 1000 + millisecond;
1076 if (isLocalTime) {
1077 result = toUTC(result);
1078 }
1079 if (-8.64e15 <= result && result <= 8.64e15) {
1080 return result;
1081 }
1082 }
1083 return NaN;
1084 }
1085 return NativeDate.parse.apply(this, arguments);
1086 };
1087
1088 return DateShim;
1089 }(Date));
1090 /*global Date: false */
1091 }
1092
1093 // ES5 15.9.4.4
1094 // http://es5.github.com/#x15.9.4.4
1095 if (!Date.now) {
1096 Date.now = function now() {
1097 return new Date().getTime();
1098 };
1099 }
1100
1101 //
1102 // Number
1103 // ======
1104 //
1105
1106 // ES5.1 15.7.4.5
1107 // http://es5.github.com/#x15.7.4.5
1108 var hasToFixedBugs = NumberPrototype.toFixed && (
1109 (0.00008).toFixed(3) !== '0.000' ||
1110 (0.9).toFixed(0) !== '1' ||
1111 (1.255).toFixed(2) !== '1.25' ||
1112 (1000000000000000128).toFixed(0) !== '1000000000000000128'
1113 );
1114
1115 var toFixedHelpers = {
1116 base: 1e7,
1117 size: 6,
1118 data: [0, 0, 0, 0, 0, 0],
1119 multiply: function multiply(n, c) {
1120 var i = -1;
1121 var c2 = c;
1122 while (++i < toFixedHelpers.size) {
1123 c2 += n * toFixedHelpers.data[i];
1124 toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1125 c2 = Math.floor(c2 / toFixedHelpers.base);
1126 }
1127 },
1128 divide: function divide(n) {
1129 var i = toFixedHelpers.size, c = 0;
1130 while (--i >= 0) {
1131 c += toFixedHelpers.data[i];
1132 toFixedHelpers.data[i] = Math.floor(c / n);
1133 c = (c % n) * toFixedHelpers.base;
1134 }
1135 },
1136 numToString: function numToString() {
1137 var i = toFixedHelpers.size;
1138 var s = '';
1139 while (--i >= 0) {
1140 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1141 var t = String(toFixedHelpers.data[i]);
1142 if (s === '') {
1143 s = t;
1144 } else {
1145 s += '0000000'.slice(0, 7 - t.length) + t;
1146 }
1147 }
1148 }
1149 return s;
1150 },
1151 pow: function pow(x, n, acc) {
1152 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1153 },
1154 log: function log(x) {
1155 var n = 0;
1156 var x2 = x;
1157 while (x2 >= 4096) {
1158 n += 12;
1159 x2 /= 4096;
1160 }
1161 while (x2 >= 2) {
1162 n += 1;
1163 x2 /= 2;
1164 }
1165 return n;
1166 }
1167 };
1168
1169 defineProperties(NumberPrototype, {
1170 toFixed: function toFixed(fractionDigits) {
1171 var f, x, s, m, e, z, j, k;
1172
1173 // Test for NaN and round fractionDigits down
1174 f = Number(fractionDigits);
1175 f = f !== f ? 0 : Math.floor(f);
1176
1177 if (f < 0 || f > 20) {
1178 throw new RangeError('Number.toFixed called with invalid number of decimals');
1179 }
1180
1181 x = Number(this);
1182
1183 // Test for NaN
1184 if (x !== x) {
1185 return 'NaN';
1186 }
1187
1188 // If it is too big or small, return the string value of the number
1189 if (x <= -1e21 || x >= 1e21) {
1190 return String(x);
1191 }
1192
1193 s = '';
1194
1195 if (x < 0) {
1196 s = '-';
1197 x = -x;
1198 }
1199
1200 m = '0';
1201
1202 if (x > 1e-21) {
1203 // 1e-21 < x < 1e21
1204 // -70 < log2(x) < 70
1205 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1206 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1207 z *= 0x10000000000000; // Math.pow(2, 52);
1208 e = 52 - e;
1209
1210 // -18 < e < 122
1211 // x = z / 2 ^ e
1212 if (e > 0) {
1213 toFixedHelpers.multiply(0, z);
1214 j = f;
1215
1216 while (j >= 7) {
1217 toFixedHelpers.multiply(1e7, 0);
1218 j -= 7;
1219 }
1220
1221 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1222 j = e - 1;
1223
1224 while (j >= 23) {
1225 toFixedHelpers.divide(1 << 23);
1226 j -= 23;
1227 }
1228
1229 toFixedHelpers.divide(1 << j);
1230 toFixedHelpers.multiply(1, 1);
1231 toFixedHelpers.divide(2);
1232 m = toFixedHelpers.numToString();
1233 } else {
1234 toFixedHelpers.multiply(0, z);
1235 toFixedHelpers.multiply(1 << (-e), 0);
1236 m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
1237 }
1238 }
1239
1240 if (f > 0) {
1241 k = m.length;
1242
1243 if (k <= f) {
1244 m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1245 } else {
1246 m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1247 }
1248 } else {
1249 m = s + m;
1250 }
1251
1252 return m;
1253 }
1254 }, hasToFixedBugs);
1255
1256 //
1257 // String
1258 // ======
1259 //
1260
1261 // ES5 15.5.4.14
1262 // http://es5.github.com/#x15.5.4.14
1263
1264 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1265 // Many browsers do not split properly with regular expressions or they
1266 // do not perform the split correctly under obscure conditions.
1267 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1268 // I've tested in many browsers and this seems to cover the deviant ones:
1269 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1270 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1271 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1272 // [undefined, "t", undefined, "e", ...]
1273 // ''.split(/.?/) should be [], not [""]
1274 // '.'.split(/()()/) should be ["."], not ["", "", "."]
1275
1276 var string_split = StringPrototype.split;
1277 if (
1278 'ab'.split(/(?:ab)*/).length !== 2 ||
1279 '.'.split(/(.?)(.?)/).length !== 4 ||
1280 'tesst'.split(/(s)*/)[1] === 't' ||
1281 'test'.split(/(?:)/, -1).length !== 4 ||
1282 ''.split(/.?/).length ||
1283 '.'.split(/()()/).length > 1
1284 ) {
1285 (function () {
1286 var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1287
1288 StringPrototype.split = function (separator, limit) {
1289 var string = this;
1290 if (typeof separator === 'undefined' && limit === 0) {
1291 return [];
1292 }
1293
1294 // If `separator` is not a regex, use native split
1295 if (!isRegex(separator)) {
1296 return string_split.call(this, separator, limit);
1297 }
1298
1299 var output = [];
1300 var flags = (separator.ignoreCase ? 'i' : '') +
1301 (separator.multiline ? 'm' : '') +
1302 (separator.extended ? 'x' : '') + // Proposed for ES6
1303 (separator.sticky ? 'y' : ''), // Firefox 3+
1304 lastLastIndex = 0,
1305 // Make `global` and avoid `lastIndex` issues by working with a copy
1306 separator2, match, lastIndex, lastLength;
1307 var separatorCopy = new RegExp(separator.source, flags + 'g');
1308 string += ''; // Type-convert
1309 if (!compliantExecNpcg) {
1310 // Doesn't need flags gy, but they don't hurt
1311 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
1312 }
1313 /* Values for `limit`, per the spec:
1314 * If undefined: 4294967295 // Math.pow(2, 32) - 1
1315 * If 0, Infinity, or NaN: 0
1316 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1317 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1318 * If other: Type-convert, then use the above rules
1319 */
1320 var splitLimit = typeof limit === 'undefined' ?
1321 -1 >>> 0 : // Math.pow(2, 32) - 1
1322 ES.ToUint32(limit);
1323 match = separatorCopy.exec(string);
1324 while (match) {
1325 // `separatorCopy.lastIndex` is not reliable cross-browser
1326 lastIndex = match.index + match[0].length;
1327 if (lastIndex > lastLastIndex) {
1328 output.push(string.slice(lastLastIndex, match.index));
1329 // Fix browsers whose `exec` methods don't consistently return `undefined` for
1330 // nonparticipating capturing groups
1331 if (!compliantExecNpcg && match.length > 1) {
1332 /*eslint-disable no-loop-func */
1333 match[0].replace(separator2, function () {
1334 for (var i = 1; i < arguments.length - 2; i++) {
1335 if (typeof arguments[i] === 'undefined') {
1336 match[i] = void 0;
1337 }
1338 }
1339 });
1340 /*eslint-enable no-loop-func */
1341 }
1342 if (match.length > 1 && match.index < string.length) {
1343 array_push.apply(output, match.slice(1));
1344 }
1345 lastLength = match[0].length;
1346 lastLastIndex = lastIndex;
1347 if (output.length >= splitLimit) {
1348 break;
1349 }
1350 }
1351 if (separatorCopy.lastIndex === match.index) {
1352 separatorCopy.lastIndex++; // Avoid an infinite loop
1353 }
1354 match = separatorCopy.exec(string);
1355 }
1356 if (lastLastIndex === string.length) {
1357 if (lastLength || !separatorCopy.test('')) {
1358 output.push('');
1359 }
1360 } else {
1361 output.push(string.slice(lastLastIndex));
1362 }
1363 return output.length > splitLimit ? output.slice(0, splitLimit) : output;
1364 };
1365 }());
1366
1367 // [bugfix, chrome]
1368 // If separator is undefined, then the result array contains just one String,
1369 // which is the this value (converted to a String). If limit is not undefined,
1370 // then the output array is truncated so that it contains no more than limit
1371 // elements.
1372 // "0".split(undefined, 0) -> []
1373 } else if ('0'.split(void 0, 0).length) {
1374 StringPrototype.split = function split(separator, limit) {
1375 if (typeof separator === 'undefined' && limit === 0) { return []; }
1376 return string_split.call(this, separator, limit);
1377 };
1378 }
1379
1380 var str_replace = StringPrototype.replace;
1381 var replaceReportsGroupsCorrectly = (function () {
1382 var groups = [];
1383 'x'.replace(/x(.)?/g, function (match, group) {
1384 groups.push(group);
1385 });
1386 return groups.length === 1 && typeof groups[0] === 'undefined';
1387 }());
1388
1389 if (!replaceReportsGroupsCorrectly) {
1390 StringPrototype.replace = function replace(searchValue, replaceValue) {
1391 var isFn = isCallable(replaceValue);
1392 var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
1393 if (!isFn || !hasCapturingGroups) {
1394 return str_replace.call(this, searchValue, replaceValue);
1395 } else {
1396 var wrappedReplaceValue = function (match) {
1397 var length = arguments.length;
1398 var originalLastIndex = searchValue.lastIndex;
1399 searchValue.lastIndex = 0;
1400 var args = searchValue.exec(match) || [];
1401 searchValue.lastIndex = originalLastIndex;
1402 args.push(arguments[length - 2], arguments[length - 1]);
1403 return replaceValue.apply(this, args);
1404 };
1405 return str_replace.call(this, searchValue, wrappedReplaceValue);
1406 }
1407 };
1408 }
1409
1410 // ECMA-262, 3rd B.2.3
1411 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1412 // non-normative section suggesting uniform semantics and it should be
1413 // normalized across all browsers
1414 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1415 var string_substr = StringPrototype.substr;
1416 var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1417 defineProperties(StringPrototype, {
1418 substr: function substr(start, length) {
1419 var normalizedStart = start;
1420 if (start < 0) {
1421 normalizedStart = Math.max(this.length + start, 0);
1422 }
1423 return string_substr.call(this, normalizedStart, length);
1424 }
1425 }, hasNegativeSubstrBug);
1426
1427 // ES5 15.5.4.20
1428 // whitespace from: http://es5.github.io/#x15.5.4.20
1429 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
1430 '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
1431 '\u2029\uFEFF';
1432 var zeroWidth = '\u200b';
1433 var wsRegexChars = '[' + ws + ']';
1434 var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
1435 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
1436 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
1437 defineProperties(StringPrototype, {
1438 // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1439 // http://perfectionkills.com/whitespace-deviations/
1440 trim: function trim() {
1441 if (typeof this === 'undefined' || this === null) {
1442 throw new TypeError("can't convert " + this + ' to object');
1443 }
1444 return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
1445 }
1446 }, hasTrimWhitespaceBug);
1447
1448 // ES-5 15.1.2.2
1449 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
1450 /*global parseInt: true */
1451 parseInt = (function (origParseInt) {
1452 var hexRegex = /^0[xX]/;
1453 return function parseInt(str, radix) {
1454 var string = String(str).trim();
1455 var defaultedRadix = Number(radix) || (hexRegex.test(string) ? 16 : 10);
1456 return origParseInt(string, defaultedRadix);
1457 };
1458 }(parseInt));
1459 }
1460
1461 }));