UNPKG

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