PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.1.5
HTML Forms – Simple WordPress Forms Plugin v1.1.5
1.7.0 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.3.0 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 All 67 releases
html-forms / assets / js / public.js

public.js in HTML Forms – Simple WordPress Forms Plugin 1.1.5, at assets/js/public.js

2,910 lines 112.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () { var require = undefined; var module = undefined; var exports = undefined; var define = undefined;(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
2 'use strict';
3
4 Object.defineProperty(exports, "__esModule", {
5 value: true
6 });
7 function getFieldValues(form, fieldName) {
8 var values = [];
9 var inputs = form.querySelectorAll('input[name="' + fieldName + '"], select[name="' + fieldName + '"], textarea[name="' + fieldName + '"]');
10
11 for (var i = 0; i < inputs.length; i++) {
12 var input = inputs[i];
13 var type = input.getAttribute("type");
14
15 if ((type === "radio" || type === "checkbox") && !input.checked) {
16 continue;
17 }
18
19 values.push(input.value);
20 }
21
22 return values;
23 }
24
25 function findForm(element) {
26 var bubbleElement = element;
27
28 while (bubbleElement.parentElement) {
29 bubbleElement = bubbleElement.parentElement;
30
31 if (bubbleElement.tagName === 'FORM') {
32 return bubbleElement;
33 }
34 }
35
36 return null;
37 }
38
39 function toggleElement(el) {
40 var show = !!el.getAttribute('data-show-if');
41 var conditions = show ? el.getAttribute('data-show-if').split(':') : el.getAttribute('data-hide-if').split(':');
42 var fieldName = conditions[0];
43 var expectedValues = (conditions.length > 1 ? conditions[1] : "*").split('|');
44 var form = findForm(el);
45 var values = getFieldValues(form, fieldName);
46
47 // determine whether condition is met
48 var conditionMet = false;
49 for (var i = 0; i < values.length; i++) {
50 var value = values[i];
51
52 // condition is met when value is in array of expected values OR expected values contains a wildcard and value is not empty
53 conditionMet = expectedValues.indexOf(value) > -1 || expectedValues.indexOf('*') > -1 && value.length > 0;
54
55 if (conditionMet) {
56 break;
57 }
58 }
59
60 // toggle element display
61 if (show) {
62 el.style.display = conditionMet ? '' : 'none';
63 } else {
64 el.style.display = conditionMet ? 'none' : '';
65 }
66
67 // find all inputs inside this element and toggle [required] attr (to prevent HTML5 validation on hidden elements)
68 var inputs = el.querySelectorAll('input, select, textarea');
69 [].forEach.call(inputs, function (el) {
70 if ((conditionMet || show) && el.getAttribute('data-was-required')) {
71 el.required = true;
72 el.removeAttribute('data-was-required');
73 }
74
75 if ((!conditionMet || !show) && el.required) {
76 el.setAttribute('data-was-required', "true");
77 el.required = false;
78 }
79 });
80 }
81
82 // evaluate conditional elements globally
83 function evaluate() {
84 var elements = document.querySelectorAll('.hf-form [data-show-if], .hf-form [data-hide-if]');
85 [].forEach.call(elements, toggleElement);
86 }
87
88 // re-evaluate conditional elements for change events on forms
89 function handleInputEvent(evt) {
90 if (!evt.target || !evt.target.form || evt.target.form.className.indexOf('hf-form') < 0) {
91 return;
92 }
93
94 var form = evt.target.form;
95 var elements = form.querySelectorAll('[data-show-if], [data-hide-if]');
96 [].forEach.call(elements, toggleElement);
97 }
98
99 exports.default = {
100 'init': function init() {
101 document.addEventListener('keyup', handleInputEvent, true);
102 document.addEventListener('change', handleInputEvent, true);
103 document.addEventListener('hf-refresh', evaluate, true);
104 window.addEventListener('load', evaluate);
105 evaluate();
106 }
107 };
108
109 },{}],2:[function(require,module,exports){
110 'use strict';
111
112 function getButtonText(button) {
113 return button.innerHTML ? button.innerHTML : button.value;
114 }
115
116 function setButtonText(button, text) {
117 button.innerHTML ? button.innerHTML = text : button.value = text;
118 }
119
120 function Loader(formElement) {
121 this.form = formElement;
122 this.button = formElement.querySelector('input[type="submit"], button[type="submit"]');
123 this.loadingInterval = 0;
124 this.character = '\xB7';
125
126 if (this.button) {
127 this.originalButton = this.button.cloneNode(true);
128 }
129 }
130
131 Loader.prototype.setCharacter = function (c) {
132 this.character = c;
133 };
134
135 Loader.prototype.start = function () {
136 if (this.button) {
137 // loading text
138 var loadingText = this.button.getAttribute('data-loading-text');
139 if (loadingText) {
140 setButtonText(this.button, loadingText);
141 return;
142 }
143
144 // Show AJAX loader
145 var styles = window.getComputedStyle(this.button);
146 this.button.style.width = styles.width;
147 setButtonText(this.button, this.character);
148 this.loadingInterval = window.setInterval(this.tick.bind(this), 500);
149 } else {
150 this.form.style.opacity = '0.5';
151 }
152 };
153
154 Loader.prototype.tick = function () {
155 // count chars, start over at 5
156 var text = getButtonText(this.button);
157 var loadingChar = this.character;
158 setButtonText(this.button, text.length >= 5 ? loadingChar : text + " " + loadingChar);
159 };
160
161 Loader.prototype.stop = function () {
162 if (this.button) {
163 this.button.style.width = this.originalButton.style.width;
164 var text = getButtonText(this.originalButton);
165 setButtonText(this.button, text);
166 window.clearInterval(this.loadingInterval);
167 } else {
168 this.form.style.opacity = '';
169 }
170 };
171
172 module.exports = Loader;
173
174 },{}],3:[function(require,module,exports){
175 "use strict";
176
177 /* window.CustomEvent polyfill for IE */
178 (function () {
179 if (typeof window.CustomEvent === "function") return false;
180
181 function CustomEvent(event, params) {
182 params = params || { bubbles: false, cancelable: false, detail: undefined };
183 var evt = document.createEvent('CustomEvent');
184 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
185 return evt;
186 }
187
188 CustomEvent.prototype = window.Event.prototype;
189
190 window.CustomEvent = CustomEvent;
191 })();
192
193 },{}],4:[function(require,module,exports){
194 "use strict";
195
196 var _conditionalElements = require('./conditional-elements.js');
197
198 var _conditionalElements2 = _interopRequireDefault(_conditionalElements);
199
200 require('./polyfills/custom-event.js');
201
202 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
203
204 var shim = require('es5-shim');
205 var Loader = require('./form-loading-indicator.js');
206 var vars = window.hf_js_vars || { ajax_url: window.location.href };
207 var EventEmitter = require('wolfy87-eventemitter');
208 var events = new EventEmitter();
209
210 function cleanFormMessages(formEl) {
211 var messageElements = formEl.querySelectorAll('.hf-message');
212 [].forEach.call(messageElements, function (el) {
213 el.parentNode.removeChild(el);
214 });
215 }
216
217 function addFormMessage(formEl, message) {
218 var txtElement = document.createElement('p');
219 txtElement.className = 'hf-message hf-message-' + message.type;
220 txtElement.innerHTML = message.text;
221 formEl.insertBefore(txtElement, formEl.lastElementChild.nextElementSibling);
222 }
223
224 function handleSubmitEvents(e) {
225 var formEl = e.target;
226
227 // only act on html-forms
228 if (formEl.className.indexOf('hf-form') < 0) {
229 return;
230 }
231
232 e.preventDefault();
233 submitForm(formEl);
234 }
235
236 function submitForm(formEl) {
237 cleanFormMessages(formEl);
238 emitEvent('submit', formEl);
239
240 var formData = new FormData(formEl);
241 [].forEach.call(formEl.querySelectorAll('[data-was-required=true]'), function (el) {
242 formData.append('was_required[]', el.getAttribute('name'));
243 });
244
245 var request = new XMLHttpRequest();
246 request.onreadystatechange = createRequestHandler(formEl);
247 request.open('POST', vars.ajax_url, true);
248 request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
249 request.send(formData);
250 request = null;
251 }
252
253 function emitEvent(eventName, element) {
254 // browser event API: formElement.on('hf-success', ..)
255 element.dispatchEvent(new CustomEvent("hf-" + eventName));
256
257 // custom events API: html_forms.on('success', ..)
258 events.emit(eventName, [element]);
259 }
260
261 function createRequestHandler(formEl) {
262 var loader = new Loader(formEl);
263 loader.start();
264
265 return function () {
266 // are we done?
267 if (this.readyState === 4) {
268 var response = void 0;
269 loader.stop();
270
271 if (this.status >= 200 && this.status < 400) {
272 try {
273 response = JSON.parse(this.responseText);
274 } catch (error) {
275 console.log('HTML Forms: failed to parse AJAX response.\n\nError: "' + error + '"');
276 return;
277 }
278
279 emitEvent('submitted', formEl);
280
281 if (response.error) {
282 emitEvent('error', formEl);
283 } else {
284 emitEvent('success', formEl);
285 }
286
287 // Show form message
288 if (response.message) {
289 addFormMessage(formEl, response.message);
290 }
291
292 // Should we hide form?
293 if (response.hide_form) {
294 formEl.querySelector('.hf-fields-wrap').style.display = 'none';
295 }
296
297 // Should we redirect?
298 if (response.redirect_url) {
299 window.location = response.redirect_url;
300 }
301
302 // clear form
303 if (!response.error) {
304 formEl.reset();
305 }
306 } else {
307 // Server error :(
308 console.log(this.responseText);
309 }
310 }
311 };
312 }
313
314 document.addEventListener('submit', handleSubmitEvents, true);
315 _conditionalElements2.default.init();
316
317 window.html_forms = {
318 'on': events.on.bind(events)
319 };
320
321 },{"./conditional-elements.js":1,"./form-loading-indicator.js":2,"./polyfills/custom-event.js":3,"es5-shim":5,"wolfy87-eventemitter":6}],5:[function(require,module,exports){
322 /*!
323 * https://github.com/es-shims/es5-shim
324 * @license es5-shim Copyright 2009-2015 by contributors, MIT License
325 * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
326 */
327
328 // vim: ts=4 sts=4 sw=4 expandtab
329
330 // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
331 ;
332
333 // UMD (Universal Module Definition)
334 // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
335 (function (root, factory) {
336 'use strict';
337
338 /* global define, exports, module */
339 if (typeof define === 'function' && define.amd) {
340 // AMD. Register as an anonymous module.
341 define(factory);
342 } else if (typeof exports === 'object') {
343 // Node. Does not work with strict CommonJS, but
344 // only CommonJS-like enviroments that support module.exports,
345 // like Node.
346 module.exports = factory();
347 } else {
348 // Browser globals (root is window)
349 root.returnExports = factory();
350 }
351 }(this, function () {
352 /**
353 * Brings an environment as close to ECMAScript 5 compliance
354 * as is possible with the facilities of erstwhile engines.
355 *
356 * Annotated ES5: http://es5.github.com/ (specific links below)
357 * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
358 * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
359 */
360
361 // Shortcut to an often accessed properties, in order to avoid multiple
362 // dereference that costs universally. This also holds a reference to known-good
363 // functions.
364 var $Array = Array;
365 var ArrayPrototype = $Array.prototype;
366 var $Object = Object;
367 var ObjectPrototype = $Object.prototype;
368 var $Function = Function;
369 var FunctionPrototype = $Function.prototype;
370 var $String = String;
371 var StringPrototype = $String.prototype;
372 var $Number = Number;
373 var NumberPrototype = $Number.prototype;
374 var array_slice = ArrayPrototype.slice;
375 var array_splice = ArrayPrototype.splice;
376 var array_push = ArrayPrototype.push;
377 var array_unshift = ArrayPrototype.unshift;
378 var array_concat = ArrayPrototype.concat;
379 var array_join = ArrayPrototype.join;
380 var call = FunctionPrototype.call;
381 var apply = FunctionPrototype.apply;
382 var max = Math.max;
383 var min = Math.min;
384
385 // Having a toString local variable name breaks in Opera so use to_string.
386 var to_string = ObjectPrototype.toString;
387
388 /* global Symbol */
389 /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
390 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
391 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; };
392
393 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; };
394 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; };
395 /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
396
397 /* inlined from http://npmjs.com/define-properties */
398 var supportsDescriptors = $Object.defineProperty && (function () {
399 try {
400 var obj = {};
401 $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
402 for (var _ in obj) { // jscs:ignore disallowUnusedVariables
403 return false;
404 }
405 return obj.x === obj;
406 } catch (e) { /* this is ES3 */
407 return false;
408 }
409 }());
410 var defineProperties = (function (has) {
411 // Define configurable, writable, and non-enumerable props
412 // if they don't exist.
413 var defineProperty;
414 if (supportsDescriptors) {
415 defineProperty = function (object, name, method, forceAssign) {
416 if (!forceAssign && (name in object)) {
417 return;
418 }
419 $Object.defineProperty(object, name, {
420 configurable: true,
421 enumerable: false,
422 writable: true,
423 value: method
424 });
425 };
426 } else {
427 defineProperty = function (object, name, method, forceAssign) {
428 if (!forceAssign && (name in object)) {
429 return;
430 }
431 object[name] = method;
432 };
433 }
434 return function defineProperties(object, map, forceAssign) {
435 for (var name in map) {
436 if (has.call(map, name)) {
437 defineProperty(object, name, map[name], forceAssign);
438 }
439 }
440 };
441 }(ObjectPrototype.hasOwnProperty));
442
443 //
444 // Util
445 // ======
446 //
447
448 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
449 var isPrimitive = function isPrimitive(input) {
450 var type = typeof input;
451 return input === null || (type !== 'object' && type !== 'function');
452 };
453
454 var isActualNaN = $Number.isNaN || function isActualNaN(x) {
455 return x !== x;
456 };
457
458 var ES = {
459 // ES5 9.4
460 // http://es5.github.com/#x9.4
461 // http://jsperf.com/to-integer
462 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
463 ToInteger: function ToInteger(num) {
464 var n = +num;
465 if (isActualNaN(n)) {
466 n = 0;
467 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
468 n = (n > 0 || -1) * Math.floor(Math.abs(n));
469 }
470 return n;
471 },
472
473 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
474 ToPrimitive: function ToPrimitive(input) {
475 var val, valueOf, toStr;
476 if (isPrimitive(input)) {
477 return input;
478 }
479 valueOf = input.valueOf;
480 if (isCallable(valueOf)) {
481 val = valueOf.call(input);
482 if (isPrimitive(val)) {
483 return val;
484 }
485 }
486 toStr = input.toString;
487 if (isCallable(toStr)) {
488 val = toStr.call(input);
489 if (isPrimitive(val)) {
490 return val;
491 }
492 }
493 throw new TypeError();
494 },
495
496 // ES5 9.9
497 // http://es5.github.com/#x9.9
498 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
499 ToObject: function (o) {
500 if (o == null) { // this matches both null and undefined
501 throw new TypeError("can't convert " + o + ' to object');
502 }
503 return $Object(o);
504 },
505
506 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
507 ToUint32: function ToUint32(x) {
508 return x >>> 0;
509 }
510 };
511
512 //
513 // Function
514 // ========
515 //
516
517 // ES-5 15.3.4.5
518 // http://es5.github.com/#x15.3.4.5
519
520 var Empty = function Empty() {};
521
522 defineProperties(FunctionPrototype, {
523 bind: function bind(that) { // .length is 1
524 // 1. Let Target be the this value.
525 var target = this;
526 // 2. If IsCallable(Target) is false, throw a TypeError exception.
527 if (!isCallable(target)) {
528 throw new TypeError('Function.prototype.bind called on incompatible ' + target);
529 }
530 // 3. Let A be a new (possibly empty) internal list of all of the
531 // argument values provided after thisArg (arg1, arg2 etc), in order.
532 // XXX slicedArgs will stand in for "A" if used
533 var args = array_slice.call(arguments, 1); // for normal call
534 // 4. Let F be a new native ECMAScript object.
535 // 11. Set the [[Prototype]] internal property of F to the standard
536 // built-in Function prototype object as specified in 15.3.3.1.
537 // 12. Set the [[Call]] internal property of F as described in
538 // 15.3.4.5.1.
539 // 13. Set the [[Construct]] internal property of F as described in
540 // 15.3.4.5.2.
541 // 14. Set the [[HasInstance]] internal property of F as described in
542 // 15.3.4.5.3.
543 var bound;
544 var binder = function () {
545
546 if (this instanceof bound) {
547 // 15.3.4.5.2 [[Construct]]
548 // When the [[Construct]] internal method of a function object,
549 // F that was created using the bind function is called with a
550 // list of arguments ExtraArgs, the following steps are taken:
551 // 1. Let target be the value of F's [[TargetFunction]]
552 // internal property.
553 // 2. If target has no [[Construct]] internal method, a
554 // TypeError exception is thrown.
555 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
556 // property.
557 // 4. Let args be a new list containing the same values as the
558 // list boundArgs in the same order followed by the same
559 // values as the list ExtraArgs in the same order.
560 // 5. Return the result of calling the [[Construct]] internal
561 // method of target providing args as the arguments.
562
563 var result = apply.call(
564 target,
565 this,
566 array_concat.call(args, array_slice.call(arguments))
567 );
568 if ($Object(result) === result) {
569 return result;
570 }
571 return this;
572
573 } else {
574 // 15.3.4.5.1 [[Call]]
575 // When the [[Call]] internal method of a function object, F,
576 // which was created using the bind function is called with a
577 // this value and a list of arguments ExtraArgs, the following
578 // steps are taken:
579 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
580 // property.
581 // 2. Let boundThis be the value of F's [[BoundThis]] internal
582 // property.
583 // 3. Let target be the value of F's [[TargetFunction]] internal
584 // property.
585 // 4. Let args be a new list containing the same values as the
586 // list boundArgs in the same order followed by the same
587 // values as the list ExtraArgs in the same order.
588 // 5. Return the result of calling the [[Call]] internal method
589 // of target providing boundThis as the this value and
590 // providing args as the arguments.
591
592 // equiv: target.call(this, ...boundArgs, ...args)
593 return apply.call(
594 target,
595 that,
596 array_concat.call(args, array_slice.call(arguments))
597 );
598
599 }
600
601 };
602
603 // 15. If the [[Class]] internal property of Target is "Function", then
604 // a. Let L be the length property of Target minus the length of A.
605 // b. Set the length own property of F to either 0 or L, whichever is
606 // larger.
607 // 16. Else set the length own property of F to 0.
608
609 var boundLength = max(0, target.length - args.length);
610
611 // 17. Set the attributes of the length own property of F to the values
612 // specified in 15.3.5.1.
613 var boundArgs = [];
614 for (var i = 0; i < boundLength; i++) {
615 array_push.call(boundArgs, '$' + i);
616 }
617
618 // XXX Build a dynamic function with desired amount of arguments is the only
619 // way to set the length property of a function.
620 // In environments where Content Security Policies enabled (Chrome extensions,
621 // for ex.) all use of eval or Function costructor throws an exception.
622 // However in all of these environments Function.prototype.bind exists
623 // and so this code will never be executed.
624 bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
625
626 if (target.prototype) {
627 Empty.prototype = target.prototype;
628 bound.prototype = new Empty();
629 // Clean up dangling references.
630 Empty.prototype = null;
631 }
632
633 // TODO
634 // 18. Set the [[Extensible]] internal property of F to true.
635
636 // TODO
637 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
638 // 20. Call the [[DefineOwnProperty]] internal method of F with
639 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
640 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
641 // false.
642 // 21. Call the [[DefineOwnProperty]] internal method of F with
643 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
644 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
645 // and false.
646
647 // TODO
648 // NOTE Function objects created using Function.prototype.bind do not
649 // have a prototype property or the [[Code]], [[FormalParameters]], and
650 // [[Scope]] internal properties.
651 // XXX can't delete prototype in pure-js.
652
653 // 22. Return F.
654 return bound;
655 }
656 });
657
658 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
659 // use it in defining shortcuts.
660 var owns = call.bind(ObjectPrototype.hasOwnProperty);
661 var toStr = call.bind(ObjectPrototype.toString);
662 var arraySlice = call.bind(array_slice);
663 var arraySliceApply = apply.bind(array_slice);
664 /* globals document */
665 if (typeof document === 'object' && document && document.documentElement) {
666 try {
667 arraySlice(document.documentElement.childNodes);
668 } catch (e) {
669 var origArraySlice = arraySlice;
670 var origArraySliceApply = arraySliceApply;
671 arraySlice = function arraySliceIE(arr) {
672 var r = [];
673 var i = arr.length;
674 while (i-- > 0) {
675 r[i] = arr[i];
676 }
677 return origArraySliceApply(r, origArraySlice(arguments, 1));
678 };
679 arraySliceApply = function arraySliceApplyIE(arr, args) {
680 return origArraySliceApply(arraySlice(arr), args);
681 };
682 }
683 }
684 var strSlice = call.bind(StringPrototype.slice);
685 var strSplit = call.bind(StringPrototype.split);
686 var strIndexOf = call.bind(StringPrototype.indexOf);
687 var pushCall = call.bind(array_push);
688 var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
689 var arraySort = call.bind(ArrayPrototype.sort);
690
691 //
692 // Array
693 // =====
694 //
695
696 var isArray = $Array.isArray || function isArray(obj) {
697 return toStr(obj) === '[object Array]';
698 };
699
700 // ES5 15.4.4.12
701 // http://es5.github.com/#x15.4.4.13
702 // Return len+argCount.
703 // [bugfix, ielt8]
704 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
705 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
706 defineProperties(ArrayPrototype, {
707 unshift: function () {
708 array_unshift.apply(this, arguments);
709 return this.length;
710 }
711 }, hasUnshiftReturnValueBug);
712
713 // ES5 15.4.3.2
714 // http://es5.github.com/#x15.4.3.2
715 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
716 defineProperties($Array, { isArray: isArray });
717
718 // The IsCallable() check in the Array functions
719 // has been replaced with a strict check on the
720 // internal class of the object to trap cases where
721 // the provided function was actually a regular
722 // expression literal, which in V8 and
723 // JavaScriptCore is a typeof "function". Only in
724 // V8 are regular expression literals permitted as
725 // reduce parameters, so it is desirable in the
726 // general case for the shim to match the more
727 // strict and common behavior of rejecting regular
728 // expressions.
729
730 // ES5 15.4.4.18
731 // http://es5.github.com/#x15.4.4.18
732 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
733
734 // Check failure of by-index access of string characters (IE < 9)
735 // and failure of `0 in boxedString` (Rhino)
736 var boxedString = $Object('a');
737 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
738
739 var properlyBoxesContext = function properlyBoxed(method) {
740 // Check node 0.6.21 bug where third parameter is not boxed
741 var properlyBoxesNonStrict = true;
742 var properlyBoxesStrict = true;
743 var threwException = false;
744 if (method) {
745 try {
746 method.call('foo', function (_, __, context) {
747 if (typeof context !== 'object') {
748 properlyBoxesNonStrict = false;
749 }
750 });
751
752 method.call([1], function () {
753 'use strict';
754
755 properlyBoxesStrict = typeof this === 'string';
756 }, 'x');
757 } catch (e) {
758 threwException = true;
759 }
760 }
761 return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
762 };
763
764 defineProperties(ArrayPrototype, {
765 forEach: function forEach(callbackfn/*, thisArg*/) {
766 var object = ES.ToObject(this);
767 var self = splitString && isString(this) ? strSplit(this, '') : object;
768 var i = -1;
769 var length = ES.ToUint32(self.length);
770 var T;
771 if (arguments.length > 1) {
772 T = arguments[1];
773 }
774
775 // If no callback function or if callback is not a callable function
776 if (!isCallable(callbackfn)) {
777 throw new TypeError('Array.prototype.forEach callback must be a function');
778 }
779
780 while (++i < length) {
781 if (i in self) {
782 // Invoke the callback function with call, passing arguments:
783 // context, property value, property key, thisArg object
784 if (typeof T === 'undefined') {
785 callbackfn(self[i], i, object);
786 } else {
787 callbackfn.call(T, self[i], i, object);
788 }
789 }
790 }
791 }
792 }, !properlyBoxesContext(ArrayPrototype.forEach));
793
794 // ES5 15.4.4.19
795 // http://es5.github.com/#x15.4.4.19
796 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
797 defineProperties(ArrayPrototype, {
798 map: function map(callbackfn/*, thisArg*/) {
799 var object = ES.ToObject(this);
800 var self = splitString && isString(this) ? strSplit(this, '') : object;
801 var length = ES.ToUint32(self.length);
802 var result = $Array(length);
803 var T;
804 if (arguments.length > 1) {
805 T = arguments[1];
806 }
807
808 // If no callback function or if callback is not a callable function
809 if (!isCallable(callbackfn)) {
810 throw new TypeError('Array.prototype.map callback must be a function');
811 }
812
813 for (var i = 0; i < length; i++) {
814 if (i in self) {
815 if (typeof T === 'undefined') {
816 result[i] = callbackfn(self[i], i, object);
817 } else {
818 result[i] = callbackfn.call(T, self[i], i, object);
819 }
820 }
821 }
822 return result;
823 }
824 }, !properlyBoxesContext(ArrayPrototype.map));
825
826 // ES5 15.4.4.20
827 // http://es5.github.com/#x15.4.4.20
828 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
829 defineProperties(ArrayPrototype, {
830 filter: function filter(callbackfn/*, thisArg*/) {
831 var object = ES.ToObject(this);
832 var self = splitString && isString(this) ? strSplit(this, '') : object;
833 var length = ES.ToUint32(self.length);
834 var result = [];
835 var value;
836 var T;
837 if (arguments.length > 1) {
838 T = arguments[1];
839 }
840
841 // If no callback function or if callback is not a callable function
842 if (!isCallable(callbackfn)) {
843 throw new TypeError('Array.prototype.filter callback must be a function');
844 }
845
846 for (var i = 0; i < length; i++) {
847 if (i in self) {
848 value = self[i];
849 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
850 pushCall(result, value);
851 }
852 }
853 }
854 return result;
855 }
856 }, !properlyBoxesContext(ArrayPrototype.filter));
857
858 // ES5 15.4.4.16
859 // http://es5.github.com/#x15.4.4.16
860 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
861 defineProperties(ArrayPrototype, {
862 every: function every(callbackfn/*, thisArg*/) {
863 var object = ES.ToObject(this);
864 var self = splitString && isString(this) ? strSplit(this, '') : object;
865 var length = ES.ToUint32(self.length);
866 var T;
867 if (arguments.length > 1) {
868 T = arguments[1];
869 }
870
871 // If no callback function or if callback is not a callable function
872 if (!isCallable(callbackfn)) {
873 throw new TypeError('Array.prototype.every callback must be a function');
874 }
875
876 for (var i = 0; i < length; i++) {
877 if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
878 return false;
879 }
880 }
881 return true;
882 }
883 }, !properlyBoxesContext(ArrayPrototype.every));
884
885 // ES5 15.4.4.17
886 // http://es5.github.com/#x15.4.4.17
887 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
888 defineProperties(ArrayPrototype, {
889 some: function some(callbackfn/*, thisArg */) {
890 var object = ES.ToObject(this);
891 var self = splitString && isString(this) ? strSplit(this, '') : object;
892 var length = ES.ToUint32(self.length);
893 var T;
894 if (arguments.length > 1) {
895 T = arguments[1];
896 }
897
898 // If no callback function or if callback is not a callable function
899 if (!isCallable(callbackfn)) {
900 throw new TypeError('Array.prototype.some callback must be a function');
901 }
902
903 for (var i = 0; i < length; i++) {
904 if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
905 return true;
906 }
907 }
908 return false;
909 }
910 }, !properlyBoxesContext(ArrayPrototype.some));
911
912 // ES5 15.4.4.21
913 // http://es5.github.com/#x15.4.4.21
914 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
915 var reduceCoercesToObject = false;
916 if (ArrayPrototype.reduce) {
917 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
918 return list;
919 }) === 'object';
920 }
921 defineProperties(ArrayPrototype, {
922 reduce: function reduce(callbackfn/*, initialValue*/) {
923 var object = ES.ToObject(this);
924 var self = splitString && isString(this) ? strSplit(this, '') : object;
925 var length = ES.ToUint32(self.length);
926
927 // If no callback function or if callback is not a callable function
928 if (!isCallable(callbackfn)) {
929 throw new TypeError('Array.prototype.reduce callback must be a function');
930 }
931
932 // no value to return if no initial value and an empty array
933 if (length === 0 && arguments.length === 1) {
934 throw new TypeError('reduce of empty array with no initial value');
935 }
936
937 var i = 0;
938 var result;
939 if (arguments.length >= 2) {
940 result = arguments[1];
941 } else {
942 do {
943 if (i in self) {
944 result = self[i++];
945 break;
946 }
947
948 // if array contains no values, no initial value to return
949 if (++i >= length) {
950 throw new TypeError('reduce of empty array with no initial value');
951 }
952 } while (true);
953 }
954
955 for (; i < length; i++) {
956 if (i in self) {
957 result = callbackfn(result, self[i], i, object);
958 }
959 }
960
961 return result;
962 }
963 }, !reduceCoercesToObject);
964
965 // ES5 15.4.4.22
966 // http://es5.github.com/#x15.4.4.22
967 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
968 var reduceRightCoercesToObject = false;
969 if (ArrayPrototype.reduceRight) {
970 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
971 return list;
972 }) === 'object';
973 }
974 defineProperties(ArrayPrototype, {
975 reduceRight: function reduceRight(callbackfn/*, initial*/) {
976 var object = ES.ToObject(this);
977 var self = splitString && isString(this) ? strSplit(this, '') : object;
978 var length = ES.ToUint32(self.length);
979
980 // If no callback function or if callback is not a callable function
981 if (!isCallable(callbackfn)) {
982 throw new TypeError('Array.prototype.reduceRight callback must be a function');
983 }
984
985 // no value to return if no initial value, empty array
986 if (length === 0 && arguments.length === 1) {
987 throw new TypeError('reduceRight of empty array with no initial value');
988 }
989
990 var result;
991 var i = length - 1;
992 if (arguments.length >= 2) {
993 result = arguments[1];
994 } else {
995 do {
996 if (i in self) {
997 result = self[i--];
998 break;
999 }
1000
1001 // if array contains no values, no initial value to return
1002 if (--i < 0) {
1003 throw new TypeError('reduceRight of empty array with no initial value');
1004 }
1005 } while (true);
1006 }
1007
1008 if (i < 0) {
1009 return result;
1010 }
1011
1012 do {
1013 if (i in self) {
1014 result = callbackfn(result, self[i], i, object);
1015 }
1016 } while (i--);
1017
1018 return result;
1019 }
1020 }, !reduceRightCoercesToObject);
1021
1022 // ES5 15.4.4.14
1023 // http://es5.github.com/#x15.4.4.14
1024 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
1025 var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
1026 defineProperties(ArrayPrototype, {
1027 indexOf: function indexOf(searchElement/*, fromIndex */) {
1028 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
1029 var length = ES.ToUint32(self.length);
1030
1031 if (length === 0) {
1032 return -1;
1033 }
1034
1035 var i = 0;
1036 if (arguments.length > 1) {
1037 i = ES.ToInteger(arguments[1]);
1038 }
1039
1040 // handle negative indices
1041 i = i >= 0 ? i : max(0, length + i);
1042 for (; i < length; i++) {
1043 if (i in self && self[i] === searchElement) {
1044 return i;
1045 }
1046 }
1047 return -1;
1048 }
1049 }, hasFirefox2IndexOfBug);
1050
1051 // ES5 15.4.4.15
1052 // http://es5.github.com/#x15.4.4.15
1053 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
1054 var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
1055 defineProperties(ArrayPrototype, {
1056 lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
1057 var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
1058 var length = ES.ToUint32(self.length);
1059
1060 if (length === 0) {
1061 return -1;
1062 }
1063 var i = length - 1;
1064 if (arguments.length > 1) {
1065 i = min(i, ES.ToInteger(arguments[1]));
1066 }
1067 // handle negative indices
1068 i = i >= 0 ? i : length - Math.abs(i);
1069 for (; i >= 0; i--) {
1070 if (i in self && searchElement === self[i]) {
1071 return i;
1072 }
1073 }
1074 return -1;
1075 }
1076 }, hasFirefox2LastIndexOfBug);
1077
1078 // ES5 15.4.4.12
1079 // http://es5.github.com/#x15.4.4.12
1080 var spliceNoopReturnsEmptyArray = (function () {
1081 var a = [1, 2];
1082 var result = a.splice();
1083 return a.length === 2 && isArray(result) && result.length === 0;
1084 }());
1085 defineProperties(ArrayPrototype, {
1086 // Safari 5.0 bug where .splice() returns undefined
1087 splice: function splice(start, deleteCount) {
1088 if (arguments.length === 0) {
1089 return [];
1090 } else {
1091 return array_splice.apply(this, arguments);
1092 }
1093 }
1094 }, !spliceNoopReturnsEmptyArray);
1095
1096 var spliceWorksWithEmptyObject = (function () {
1097 var obj = {};
1098 ArrayPrototype.splice.call(obj, 0, 0, 1);
1099 return obj.length === 1;
1100 }());
1101 defineProperties(ArrayPrototype, {
1102 splice: function splice(start, deleteCount) {
1103 if (arguments.length === 0) {
1104 return [];
1105 }
1106 var args = arguments;
1107 this.length = max(ES.ToInteger(this.length), 0);
1108 if (arguments.length > 0 && typeof deleteCount !== 'number') {
1109 args = arraySlice(arguments);
1110 if (args.length < 2) {
1111 pushCall(args, this.length - start);
1112 } else {
1113 args[1] = ES.ToInteger(deleteCount);
1114 }
1115 }
1116 return array_splice.apply(this, args);
1117 }
1118 }, !spliceWorksWithEmptyObject);
1119 var spliceWorksWithLargeSparseArrays = (function () {
1120 // Per https://github.com/es-shims/es5-shim/issues/295
1121 // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
1122 var arr = new $Array(1e5);
1123 // note: the index MUST be 8 or larger or the test will false pass
1124 arr[8] = 'x';
1125 arr.splice(1, 1);
1126 // note: this test must be defined *after* the indexOf shim
1127 // per https://github.com/es-shims/es5-shim/issues/313
1128 return arr.indexOf('x') === 7;
1129 }());
1130 var spliceWorksWithSmallSparseArrays = (function () {
1131 // Per https://github.com/es-shims/es5-shim/issues/295
1132 // Opera 12.15 breaks on this, no idea why.
1133 var n = 256;
1134 var arr = [];
1135 arr[n] = 'a';
1136 arr.splice(n + 1, 0, 'b');
1137 return arr[n] === 'a';
1138 }());
1139 defineProperties(ArrayPrototype, {
1140 splice: function splice(start, deleteCount) {
1141 var O = ES.ToObject(this);
1142 var A = [];
1143 var len = ES.ToUint32(O.length);
1144 var relativeStart = ES.ToInteger(start);
1145 var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
1146 var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
1147
1148 var k = 0;
1149 var from;
1150 while (k < actualDeleteCount) {
1151 from = $String(actualStart + k);
1152 if (owns(O, from)) {
1153 A[k] = O[from];
1154 }
1155 k += 1;
1156 }
1157
1158 var items = arraySlice(arguments, 2);
1159 var itemCount = items.length;
1160 var to;
1161 if (itemCount < actualDeleteCount) {
1162 k = actualStart;
1163 var maxK = len - actualDeleteCount;
1164 while (k < maxK) {
1165 from = $String(k + actualDeleteCount);
1166 to = $String(k + itemCount);
1167 if (owns(O, from)) {
1168 O[to] = O[from];
1169 } else {
1170 delete O[to];
1171 }
1172 k += 1;
1173 }
1174 k = len;
1175 var minK = len - actualDeleteCount + itemCount;
1176 while (k > minK) {
1177 delete O[k - 1];
1178 k -= 1;
1179 }
1180 } else if (itemCount > actualDeleteCount) {
1181 k = len - actualDeleteCount;
1182 while (k > actualStart) {
1183 from = $String(k + actualDeleteCount - 1);
1184 to = $String(k + itemCount - 1);
1185 if (owns(O, from)) {
1186 O[to] = O[from];
1187 } else {
1188 delete O[to];
1189 }
1190 k -= 1;
1191 }
1192 }
1193 k = actualStart;
1194 for (var i = 0; i < items.length; ++i) {
1195 O[k] = items[i];
1196 k += 1;
1197 }
1198 O.length = len - actualDeleteCount + itemCount;
1199
1200 return A;
1201 }
1202 }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
1203
1204 var originalJoin = ArrayPrototype.join;
1205 var hasStringJoinBug;
1206 try {
1207 hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
1208 } catch (e) {
1209 hasStringJoinBug = true;
1210 }
1211 if (hasStringJoinBug) {
1212 defineProperties(ArrayPrototype, {
1213 join: function join(separator) {
1214 var sep = typeof separator === 'undefined' ? ',' : separator;
1215 return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
1216 }
1217 }, hasStringJoinBug);
1218 }
1219
1220 var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
1221 if (hasJoinUndefinedBug) {
1222 defineProperties(ArrayPrototype, {
1223 join: function join(separator) {
1224 var sep = typeof separator === 'undefined' ? ',' : separator;
1225 return originalJoin.call(this, sep);
1226 }
1227 }, hasJoinUndefinedBug);
1228 }
1229
1230 var pushShim = function push(item) {
1231 var O = ES.ToObject(this);
1232 var n = ES.ToUint32(O.length);
1233 var i = 0;
1234 while (i < arguments.length) {
1235 O[n + i] = arguments[i];
1236 i += 1;
1237 }
1238 O.length = n + i;
1239 return n + i;
1240 };
1241
1242 var pushIsNotGeneric = (function () {
1243 var obj = {};
1244 var result = Array.prototype.push.call(obj, undefined);
1245 return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
1246 }());
1247 defineProperties(ArrayPrototype, {
1248 push: function push(item) {
1249 if (isArray(this)) {
1250 return array_push.apply(this, arguments);
1251 }
1252 return pushShim.apply(this, arguments);
1253 }
1254 }, pushIsNotGeneric);
1255
1256 // This fixes a very weird bug in Opera 10.6 when pushing `undefined
1257 var pushUndefinedIsWeird = (function () {
1258 var arr = [];
1259 var result = arr.push(undefined);
1260 return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
1261 }());
1262 defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
1263
1264 // ES5 15.2.3.14
1265 // http://es5.github.io/#x15.4.4.10
1266 // Fix boxed string bug
1267 defineProperties(ArrayPrototype, {
1268 slice: function (start, end) {
1269 var arr = isString(this) ? strSplit(this, '') : this;
1270 return arraySliceApply(arr, arguments);
1271 }
1272 }, splitString);
1273
1274 var sortIgnoresNonFunctions = (function () {
1275 try {
1276 [1, 2].sort(null);
1277 } catch (e) {
1278 try {
1279 [1, 2].sort({});
1280 } catch (e2) {
1281 return false;
1282 }
1283 }
1284 return true;
1285 }());
1286 var sortThrowsOnRegex = (function () {
1287 // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
1288 try {
1289 [1, 2].sort(/a/);
1290 return false;
1291 } catch (e) {}
1292 return true;
1293 }());
1294 var sortIgnoresUndefined = (function () {
1295 // applies in IE 8, for one.
1296 try {
1297 [1, 2].sort(undefined);
1298 return true;
1299 } catch (e) {}
1300 return false;
1301 }());
1302 defineProperties(ArrayPrototype, {
1303 sort: function sort(compareFn) {
1304 if (typeof compareFn === 'undefined') {
1305 return arraySort(this);
1306 }
1307 if (!isCallable(compareFn)) {
1308 throw new TypeError('Array.prototype.sort callback must be a function');
1309 }
1310 return arraySort(this, compareFn);
1311 }
1312 }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
1313
1314 //
1315 // Object
1316 // ======
1317 //
1318
1319 // ES5 15.2.3.14
1320 // http://es5.github.com/#x15.2.3.14
1321
1322 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
1323 var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString'); // jscs:ignore disallowQuotedKeysInObjects
1324 var hasProtoEnumBug = isEnum(function () {}, 'prototype');
1325 var hasStringEnumBug = !owns('x', '0');
1326 var equalsConstructorPrototype = function (o) {
1327 var ctor = o.constructor;
1328 return ctor && ctor.prototype === o;
1329 };
1330 var excludedKeys = {
1331 $window: true,
1332 $console: true,
1333 $parent: true,
1334 $self: true,
1335 $frame: true,
1336 $frames: true,
1337 $frameElement: true,
1338 $webkitIndexedDB: true,
1339 $webkitStorageInfo: true,
1340 $external: true,
1341 $width: true,
1342 $height: true,
1343 $top: true,
1344 $localStorage: true
1345 };
1346 var hasAutomationEqualityBug = (function () {
1347 /* globals window */
1348 if (typeof window === 'undefined') {
1349 return false;
1350 }
1351 for (var k in window) {
1352 try {
1353 if (!excludedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
1354 equalsConstructorPrototype(window[k]);
1355 }
1356 } catch (e) {
1357 return true;
1358 }
1359 }
1360 return false;
1361 }());
1362 var equalsConstructorPrototypeIfNotBuggy = function (object) {
1363 if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
1364 return equalsConstructorPrototype(object);
1365 }
1366 try {
1367 return equalsConstructorPrototype(object);
1368 } catch (e) {
1369 return false;
1370 }
1371 };
1372 var dontEnums = [
1373 'toString',
1374 'toLocaleString',
1375 'valueOf',
1376 'hasOwnProperty',
1377 'isPrototypeOf',
1378 'propertyIsEnumerable',
1379 'constructor'
1380 ];
1381 var dontEnumsLength = dontEnums.length;
1382
1383 // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
1384 // can be replaced with require('is-arguments') if we ever use a build process instead
1385 var isStandardArguments = function isArguments(value) {
1386 return toStr(value) === '[object Arguments]';
1387 };
1388 var isLegacyArguments = function isArguments(value) {
1389 return value !== null
1390 && typeof value === 'object'
1391 && typeof value.length === 'number'
1392 && value.length >= 0
1393 && !isArray(value)
1394 && isCallable(value.callee);
1395 };
1396 var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
1397
1398 defineProperties($Object, {
1399 keys: function keys(object) {
1400 var isFn = isCallable(object);
1401 var isArgs = isArguments(object);
1402 var isObject = object !== null && typeof object === 'object';
1403 var isStr = isObject && isString(object);
1404
1405 if (!isObject && !isFn && !isArgs) {
1406 throw new TypeError('Object.keys called on a non-object');
1407 }
1408
1409 var theKeys = [];
1410 var skipProto = hasProtoEnumBug && isFn;
1411 if ((isStr && hasStringEnumBug) || isArgs) {
1412 for (var i = 0; i < object.length; ++i) {
1413 pushCall(theKeys, $String(i));
1414 }
1415 }
1416
1417 if (!isArgs) {
1418 for (var name in object) {
1419 if (!(skipProto && name === 'prototype') && owns(object, name)) {
1420 pushCall(theKeys, $String(name));
1421 }
1422 }
1423 }
1424
1425 if (hasDontEnumBug) {
1426 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
1427 for (var j = 0; j < dontEnumsLength; j++) {
1428 var dontEnum = dontEnums[j];
1429 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
1430 pushCall(theKeys, dontEnum);
1431 }
1432 }
1433 }
1434 return theKeys;
1435 }
1436 });
1437
1438 var keysWorksWithArguments = $Object.keys && (function () {
1439 // Safari 5.0 bug
1440 return $Object.keys(arguments).length === 2;
1441 }(1, 2));
1442 var keysHasArgumentsLengthBug = $Object.keys && (function () {
1443 var argKeys = $Object.keys(arguments);
1444 return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
1445 }(1));
1446 var originalKeys = $Object.keys;
1447 defineProperties($Object, {
1448 keys: function keys(object) {
1449 if (isArguments(object)) {
1450 return originalKeys(arraySlice(object));
1451 } else {
1452 return originalKeys(object);
1453 }
1454 }
1455 }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
1456
1457 //
1458 // Date
1459 // ====
1460 //
1461
1462 var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
1463 var aNegativeTestDate = new Date(-1509842289600292);
1464 var aPositiveTestDate = new Date(1449662400000);
1465 var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
1466 var hasToDateStringFormatBug;
1467 var hasToStringFormatBug;
1468 var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
1469 if (timeZoneOffset < -720) {
1470 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
1471 hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-+]\d\d\d\d(?: |$)/).test(String(aPositiveTestDate));
1472 } else {
1473 hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
1474 hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-+]\d\d\d\d(?: |$)/).test(String(aPositiveTestDate));
1475 }
1476
1477 var originalGetFullYear = call.bind(Date.prototype.getFullYear);
1478 var originalGetMonth = call.bind(Date.prototype.getMonth);
1479 var originalGetDate = call.bind(Date.prototype.getDate);
1480 var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
1481 var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
1482 var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
1483 var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
1484 var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
1485 var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
1486 var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
1487 var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
1488 var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
1489 var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1490 var daysInMonth = function daysInMonth(month, year) {
1491 return originalGetDate(new Date(year, month, 0));
1492 };
1493
1494 defineProperties(Date.prototype, {
1495 getFullYear: function getFullYear() {
1496 if (!this || !(this instanceof Date)) {
1497 throw new TypeError('this is not a Date object.');
1498 }
1499 var year = originalGetFullYear(this);
1500 if (year < 0 && originalGetMonth(this) > 11) {
1501 return year + 1;
1502 }
1503 return year;
1504 },
1505 getMonth: function getMonth() {
1506 if (!this || !(this instanceof Date)) {
1507 throw new TypeError('this is not a Date object.');
1508 }
1509 var year = originalGetFullYear(this);
1510 var month = originalGetMonth(this);
1511 if (year < 0 && month > 11) {
1512 return 0;
1513 }
1514 return month;
1515 },
1516 getDate: function getDate() {
1517 if (!this || !(this instanceof Date)) {
1518 throw new TypeError('this is not a Date object.');
1519 }
1520 var year = originalGetFullYear(this);
1521 var month = originalGetMonth(this);
1522 var date = originalGetDate(this);
1523 if (year < 0 && month > 11) {
1524 if (month === 12) {
1525 return date;
1526 }
1527 var days = daysInMonth(0, year + 1);
1528 return (days - date) + 1;
1529 }
1530 return date;
1531 },
1532 getUTCFullYear: function getUTCFullYear() {
1533 if (!this || !(this instanceof Date)) {
1534 throw new TypeError('this is not a Date object.');
1535 }
1536 var year = originalGetUTCFullYear(this);
1537 if (year < 0 && originalGetUTCMonth(this) > 11) {
1538 return year + 1;
1539 }
1540 return year;
1541 },
1542 getUTCMonth: function getUTCMonth() {
1543 if (!this || !(this instanceof Date)) {
1544 throw new TypeError('this is not a Date object.');
1545 }
1546 var year = originalGetUTCFullYear(this);
1547 var month = originalGetUTCMonth(this);
1548 if (year < 0 && month > 11) {
1549 return 0;
1550 }
1551 return month;
1552 },
1553 getUTCDate: function getUTCDate() {
1554 if (!this || !(this instanceof Date)) {
1555 throw new TypeError('this is not a Date object.');
1556 }
1557 var year = originalGetUTCFullYear(this);
1558 var month = originalGetUTCMonth(this);
1559 var date = originalGetUTCDate(this);
1560 if (year < 0 && month > 11) {
1561 if (month === 12) {
1562 return date;
1563 }
1564 var days = daysInMonth(0, year + 1);
1565 return (days - date) + 1;
1566 }
1567 return date;
1568 }
1569 }, hasNegativeMonthYearBug);
1570
1571 defineProperties(Date.prototype, {
1572 toUTCString: function toUTCString() {
1573 if (!this || !(this instanceof Date)) {
1574 throw new TypeError('this is not a Date object.');
1575 }
1576 var day = originalGetUTCDay(this);
1577 var date = originalGetUTCDate(this);
1578 var month = originalGetUTCMonth(this);
1579 var year = originalGetUTCFullYear(this);
1580 var hour = originalGetUTCHours(this);
1581 var minute = originalGetUTCMinutes(this);
1582 var second = originalGetUTCSeconds(this);
1583 return dayName[day] + ', '
1584 + (date < 10 ? '0' + date : date) + ' '
1585 + monthName[month] + ' '
1586 + year + ' '
1587 + (hour < 10 ? '0' + hour : hour) + ':'
1588 + (minute < 10 ? '0' + minute : minute) + ':'
1589 + (second < 10 ? '0' + second : second) + ' GMT';
1590 }
1591 }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
1592
1593 // Opera 12 has `,`
1594 defineProperties(Date.prototype, {
1595 toDateString: function toDateString() {
1596 if (!this || !(this instanceof Date)) {
1597 throw new TypeError('this is not a Date object.');
1598 }
1599 var day = this.getDay();
1600 var date = this.getDate();
1601 var month = this.getMonth();
1602 var year = this.getFullYear();
1603 return dayName[day] + ' '
1604 + monthName[month] + ' '
1605 + (date < 10 ? '0' + date : date) + ' '
1606 + year;
1607 }
1608 }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
1609
1610 // can't use defineProperties here because of toString enumeration issue in IE <= 8
1611 if (hasNegativeMonthYearBug || hasToStringFormatBug) {
1612 Date.prototype.toString = function toString() {
1613 if (!this || !(this instanceof Date)) {
1614 throw new TypeError('this is not a Date object.');
1615 }
1616 var day = this.getDay();
1617 var date = this.getDate();
1618 var month = this.getMonth();
1619 var year = this.getFullYear();
1620 var hour = this.getHours();
1621 var minute = this.getMinutes();
1622 var second = this.getSeconds();
1623 var timezoneOffset = this.getTimezoneOffset();
1624 var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
1625 var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
1626 return dayName[day] + ' '
1627 + monthName[month] + ' '
1628 + (date < 10 ? '0' + date : date) + ' '
1629 + year + ' '
1630 + (hour < 10 ? '0' + hour : hour) + ':'
1631 + (minute < 10 ? '0' + minute : minute) + ':'
1632 + (second < 10 ? '0' + second : second) + ' GMT'
1633 + (timezoneOffset > 0 ? '-' : '+')
1634 + (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset)
1635 + (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
1636 };
1637 if (supportsDescriptors) {
1638 $Object.defineProperty(Date.prototype, 'toString', {
1639 configurable: true,
1640 enumerable: false,
1641 writable: true
1642 });
1643 }
1644 }
1645
1646 // ES5 15.9.5.43
1647 // http://es5.github.com/#x15.9.5.43
1648 // This function returns a String value represent the instance in time
1649 // represented by this Date object. The format of the String is the Date Time
1650 // string format defined in 15.9.1.15. All fields are present in the String.
1651 // The time zone is always UTC, denoted by the suffix Z. If the time value of
1652 // this object is not a finite Number a RangeError exception is thrown.
1653 var negativeDate = -62198755200000;
1654 var negativeYearString = '-000001';
1655 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; // eslint-disable-line max-len
1656 var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
1657
1658 var getTime = call.bind(Date.prototype.getTime);
1659
1660 defineProperties(Date.prototype, {
1661 toISOString: function toISOString() {
1662 if (!isFinite(this) || !isFinite(getTime(this))) {
1663 // Adope Photoshop requires the second check.
1664 throw new RangeError('Date.prototype.toISOString called on non-finite value.');
1665 }
1666
1667 var year = originalGetUTCFullYear(this);
1668
1669 var month = originalGetUTCMonth(this);
1670 // see https://github.com/es-shims/es5-shim/issues/111
1671 year += Math.floor(month / 12);
1672 month = ((month % 12) + 12) % 12;
1673
1674 // the date time string format is specified in 15.9.1.15.
1675 var result = [
1676 month + 1,
1677 originalGetUTCDate(this),
1678 originalGetUTCHours(this),
1679 originalGetUTCMinutes(this),
1680 originalGetUTCSeconds(this)
1681 ];
1682 year = (
1683 (year < 0 ? '-' : (year > 9999 ? '+' : ''))
1684 + strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
1685 );
1686
1687 for (var i = 0; i < result.length; ++i) {
1688 // pad months, days, hours, minutes, and seconds to have two digits.
1689 result[i] = strSlice('00' + result[i], -2);
1690 }
1691 // pad milliseconds to have three digits.
1692 return (
1693 year + '-' + arraySlice(result, 0, 2).join('-')
1694 + 'T' + arraySlice(result, 2).join(':') + '.'
1695 + strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
1696 );
1697 }
1698 }, hasNegativeDateBug || hasSafari51DateBug);
1699
1700 // ES5 15.9.5.44
1701 // http://es5.github.com/#x15.9.5.44
1702 // This function provides a String representation of a Date object for use by
1703 // JSON.stringify (15.12.3).
1704 var dateToJSONIsSupported = (function () {
1705 try {
1706 return Date.prototype.toJSON
1707 && new Date(NaN).toJSON() === null
1708 && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1
1709 && Date.prototype.toJSON.call({ // generic
1710 toISOString: function () { return true; }
1711 });
1712 } catch (e) {
1713 return false;
1714 }
1715 }());
1716 if (!dateToJSONIsSupported) {
1717 Date.prototype.toJSON = function toJSON(key) {
1718 // When the toJSON method is called with argument key, the following
1719 // steps are taken:
1720
1721 // 1. Let O be the result of calling ToObject, giving it the this
1722 // value as its argument.
1723 // 2. Let tv be ES.ToPrimitive(O, hint Number).
1724 var O = $Object(this);
1725 var tv = ES.ToPrimitive(O);
1726 // 3. If tv is a Number and is not finite, return null.
1727 if (typeof tv === 'number' && !isFinite(tv)) {
1728 return null;
1729 }
1730 // 4. Let toISO be the result of calling the [[Get]] internal method of
1731 // O with argument "toISOString".
1732 var toISO = O.toISOString;
1733 // 5. If IsCallable(toISO) is false, throw a TypeError exception.
1734 if (!isCallable(toISO)) {
1735 throw new TypeError('toISOString property is not callable');
1736 }
1737 // 6. Return the result of calling the [[Call]] internal method of
1738 // toISO with O as the this value and an empty argument list.
1739 return toISO.call(O);
1740
1741 // NOTE 1 The argument is ignored.
1742
1743 // NOTE 2 The toJSON function is intentionally generic; it does not
1744 // require that its this value be a Date object. Therefore, it can be
1745 // transferred to other kinds of objects for use as a method. However,
1746 // it does require that any such object have a toISOString method. An
1747 // object is free to use the argument key to filter its
1748 // stringification.
1749 };
1750 }
1751
1752 // ES5 15.9.4.2
1753 // http://es5.github.com/#x15.9.4.2
1754 // based on work shared by Daniel Friesen (dantman)
1755 // http://gist.github.com/303249
1756 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
1757 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'));
1758 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
1759 if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
1760 // XXX global assignment won't work in embeddings that use
1761 // an alternate object for the context.
1762 /* global Date: true */
1763 var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
1764 var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
1765 // eslint-disable-next-line no-implicit-globals, no-global-assign
1766 Date = (function (NativeDate) {
1767 // Date.length === 7
1768 var DateShim = function Date(Y, M, D, h, m, s, ms) {
1769 var length = arguments.length;
1770 var date;
1771 if (this instanceof NativeDate) {
1772 var seconds = s;
1773 var millis = ms;
1774 if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
1775 // work around a Safari 8/9 bug where it treats the seconds as signed
1776 var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1777 var sToShift = Math.floor(msToShift / 1e3);
1778 seconds += sToShift;
1779 millis -= sToShift * 1e3;
1780 }
1781 date = length === 1 && $String(Y) === Y // isString(Y)
1782 // We explicitly pass it through parse:
1783 ? new NativeDate(DateShim.parse(Y))
1784 // We have to manually make calls depending on argument
1785 // length here
1786 : length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis)
1787 : length >= 6 ? new NativeDate(Y, M, D, h, m, seconds)
1788 : length >= 5 ? new NativeDate(Y, M, D, h, m)
1789 : length >= 4 ? new NativeDate(Y, M, D, h)
1790 : length >= 3 ? new NativeDate(Y, M, D)
1791 : length >= 2 ? new NativeDate(Y, M)
1792 : length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y)
1793 : new NativeDate();
1794 } else {
1795 date = NativeDate.apply(this, arguments);
1796 }
1797 if (!isPrimitive(date)) {
1798 // Prevent mixups with unfixed Date object
1799 defineProperties(date, { constructor: DateShim }, true);
1800 }
1801 return date;
1802 };
1803
1804 // 15.9.1.15 Date Time String Format.
1805 var isoDateExpression = new RegExp('^'
1806 + '(\\d{4}|[+-]\\d{6})' // four-digit year capture or sign + 6-digit extended year
1807 + '(?:-(\\d{2})' // optional month capture
1808 + '(?:-(\\d{2})' // optional day capture
1809 + '(?:' // capture hours:minutes:seconds.milliseconds
1810 + 'T(\\d{2})' // hours capture
1811 + ':(\\d{2})' // minutes capture
1812 + '(?:' // optional :seconds.milliseconds
1813 + ':(\\d{2})' // seconds capture
1814 + '(?:(\\.\\d{1,}))?' // milliseconds capture
1815 + ')?'
1816 + '(' // capture UTC offset component
1817 + 'Z|' // UTC capture
1818 + '(?:' // offset specifier +/-hours:minutes
1819 + '([-+])' // sign capture
1820 + '(\\d{2})' // hours offset capture
1821 + ':(\\d{2})' // minutes offset capture
1822 + ')'
1823 + ')?)?)?)?'
1824 + '$');
1825
1826 var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
1827
1828 var dayFromMonth = function dayFromMonth(year, month) {
1829 var t = month > 1 ? 1 : 0;
1830 return (
1831 months[month]
1832 + Math.floor((year - 1969 + t) / 4)
1833 - Math.floor((year - 1901 + t) / 100)
1834 + Math.floor((year - 1601 + t) / 400)
1835 + (365 * (year - 1970))
1836 );
1837 };
1838
1839 var toUTC = function toUTC(t) {
1840 var s = 0;
1841 var ms = t;
1842 if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
1843 // work around a Safari 8/9 bug where it treats the seconds as signed
1844 var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
1845 var sToShift = Math.floor(msToShift / 1e3);
1846 s += sToShift;
1847 ms -= sToShift * 1e3;
1848 }
1849 return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
1850 };
1851
1852 // Copy any custom methods a 3rd party library may have added
1853 for (var key in NativeDate) {
1854 if (owns(NativeDate, key)) {
1855 DateShim[key] = NativeDate[key];
1856 }
1857 }
1858
1859 // Copy "native" methods explicitly; they may be non-enumerable
1860 defineProperties(DateShim, {
1861 now: NativeDate.now,
1862 UTC: NativeDate.UTC
1863 }, true);
1864 DateShim.prototype = NativeDate.prototype;
1865 defineProperties(DateShim.prototype, { constructor: DateShim }, true);
1866
1867 // Upgrade Date.parse to handle simplified ISO 8601 strings
1868 var parseShim = function parse(string) {
1869 var match = isoDateExpression.exec(string);
1870 if (match) {
1871 // parse months, days, hours, minutes, seconds, and milliseconds
1872 // provide default values if necessary
1873 // parse the UTC offset component
1874 var year = $Number(match[1]),
1875 month = $Number(match[2] || 1) - 1,
1876 day = $Number(match[3] || 1) - 1,
1877 hour = $Number(match[4] || 0),
1878 minute = $Number(match[5] || 0),
1879 second = $Number(match[6] || 0),
1880 millisecond = Math.floor($Number(match[7] || 0) * 1000),
1881 // When time zone is missed, local offset should be used
1882 // (ES 5.1 bug)
1883 // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1884 isLocalTime = Boolean(match[4] && !match[8]),
1885 signOffset = match[9] === '-' ? 1 : -1,
1886 hourOffset = $Number(match[10] || 0),
1887 minuteOffset = $Number(match[11] || 0),
1888 result;
1889 var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
1890 if (
1891 hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25)
1892 && minute < 60 && second < 60 && millisecond < 1000
1893 && month > -1 && month < 12 && hourOffset < 24
1894 && minuteOffset < 60 // detect invalid offsets
1895 && day > -1
1896 && day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
1897 ) {
1898 result = (
1899 ((dayFromMonth(year, month) + day) * 24)
1900 + hour
1901 + (hourOffset * signOffset)
1902 ) * 60;
1903 result = ((
1904 ((result + minute + (minuteOffset * signOffset)) * 60)
1905 + second
1906 ) * 1000) + millisecond;
1907 if (isLocalTime) {
1908 result = toUTC(result);
1909 }
1910 if (-8.64e15 <= result && result <= 8.64e15) {
1911 return result;
1912 }
1913 }
1914 return NaN;
1915 }
1916 return NativeDate.parse.apply(this, arguments);
1917 };
1918 defineProperties(DateShim, { parse: parseShim });
1919
1920 return DateShim;
1921 }(Date));
1922 /* global Date: false */
1923 }
1924
1925 // ES5 15.9.4.4
1926 // http://es5.github.com/#x15.9.4.4
1927 if (!Date.now) {
1928 Date.now = function now() {
1929 return new Date().getTime();
1930 };
1931 }
1932
1933 //
1934 // Number
1935 // ======
1936 //
1937
1938 // ES5.1 15.7.4.5
1939 // http://es5.github.com/#x15.7.4.5
1940 var hasToFixedBugs = NumberPrototype.toFixed && (
1941 (0.00008).toFixed(3) !== '0.000'
1942 || (0.9).toFixed(0) !== '1'
1943 || (1.255).toFixed(2) !== '1.25'
1944 || (1000000000000000128).toFixed(0) !== '1000000000000000128'
1945 );
1946
1947 var toFixedHelpers = {
1948 base: 1e7,
1949 size: 6,
1950 data: [0, 0, 0, 0, 0, 0],
1951 multiply: function multiply(n, c) {
1952 var i = -1;
1953 var c2 = c;
1954 while (++i < toFixedHelpers.size) {
1955 c2 += n * toFixedHelpers.data[i];
1956 toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1957 c2 = Math.floor(c2 / toFixedHelpers.base);
1958 }
1959 },
1960 divide: function divide(n) {
1961 var i = toFixedHelpers.size;
1962 var c = 0;
1963 while (--i >= 0) {
1964 c += toFixedHelpers.data[i];
1965 toFixedHelpers.data[i] = Math.floor(c / n);
1966 c = (c % n) * toFixedHelpers.base;
1967 }
1968 },
1969 numToString: function numToString() {
1970 var i = toFixedHelpers.size;
1971 var s = '';
1972 while (--i >= 0) {
1973 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1974 var t = $String(toFixedHelpers.data[i]);
1975 if (s === '') {
1976 s = t;
1977 } else {
1978 s += strSlice('0000000', 0, 7 - t.length) + t;
1979 }
1980 }
1981 }
1982 return s;
1983 },
1984 pow: function pow(x, n, acc) {
1985 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1986 },
1987 log: function log(x) {
1988 var n = 0;
1989 var x2 = x;
1990 while (x2 >= 4096) {
1991 n += 12;
1992 x2 /= 4096;
1993 }
1994 while (x2 >= 2) {
1995 n += 1;
1996 x2 /= 2;
1997 }
1998 return n;
1999 }
2000 };
2001
2002 var toFixedShim = function toFixed(fractionDigits) {
2003 var f, x, s, m, e, z, j, k;
2004
2005 // Test for NaN and round fractionDigits down
2006 f = $Number(fractionDigits);
2007 f = isActualNaN(f) ? 0 : Math.floor(f);
2008
2009 if (f < 0 || f > 20) {
2010 throw new RangeError('Number.toFixed called with invalid number of decimals');
2011 }
2012
2013 x = $Number(this);
2014
2015 if (isActualNaN(x)) {
2016 return 'NaN';
2017 }
2018
2019 // If it is too big or small, return the string value of the number
2020 if (x <= -1e21 || x >= 1e21) {
2021 return $String(x);
2022 }
2023
2024 s = '';
2025
2026 if (x < 0) {
2027 s = '-';
2028 x = -x;
2029 }
2030
2031 m = '0';
2032
2033 if (x > 1e-21) {
2034 // 1e-21 < x < 1e21
2035 // -70 < log2(x) < 70
2036 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
2037 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
2038 z *= 0x10000000000000; // Math.pow(2, 52);
2039 e = 52 - e;
2040
2041 // -18 < e < 122
2042 // x = z / 2 ^ e
2043 if (e > 0) {
2044 toFixedHelpers.multiply(0, z);
2045 j = f;
2046
2047 while (j >= 7) {
2048 toFixedHelpers.multiply(1e7, 0);
2049 j -= 7;
2050 }
2051
2052 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
2053 j = e - 1;
2054
2055 while (j >= 23) {
2056 toFixedHelpers.divide(1 << 23);
2057 j -= 23;
2058 }
2059
2060 toFixedHelpers.divide(1 << j);
2061 toFixedHelpers.multiply(1, 1);
2062 toFixedHelpers.divide(2);
2063 m = toFixedHelpers.numToString();
2064 } else {
2065 toFixedHelpers.multiply(0, z);
2066 toFixedHelpers.multiply(1 << (-e), 0);
2067 m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
2068 }
2069 }
2070
2071 if (f > 0) {
2072 k = m.length;
2073
2074 if (k <= f) {
2075 m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
2076 } else {
2077 m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
2078 }
2079 } else {
2080 m = s + m;
2081 }
2082
2083 return m;
2084 };
2085 defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
2086
2087 var hasToPrecisionUndefinedBug = (function () {
2088 try {
2089 return 1.0.toPrecision(undefined) === '1';
2090 } catch (e) {
2091 return true;
2092 }
2093 }());
2094 var originalToPrecision = NumberPrototype.toPrecision;
2095 defineProperties(NumberPrototype, {
2096 toPrecision: function toPrecision(precision) {
2097 return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
2098 }
2099 }, hasToPrecisionUndefinedBug);
2100
2101 //
2102 // String
2103 // ======
2104 //
2105
2106 // ES5 15.5.4.14
2107 // http://es5.github.com/#x15.5.4.14
2108
2109 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
2110 // Many browsers do not split properly with regular expressions or they
2111 // do not perform the split correctly under obscure conditions.
2112 // See http://blog.stevenlevithan.com/archives/cross-browser-split
2113 // I've tested in many browsers and this seems to cover the deviant ones:
2114 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
2115 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
2116 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
2117 // [undefined, "t", undefined, "e", ...]
2118 // ''.split(/.?/) should be [], not [""]
2119 // '.'.split(/()()/) should be ["."], not ["", "", "."]
2120
2121 if (
2122 'ab'.split(/(?:ab)*/).length !== 2
2123 || '.'.split(/(.?)(.?)/).length !== 4
2124 || 'tesst'.split(/(s)*/)[1] === 't'
2125 || 'test'.split(/(?:)/, -1).length !== 4
2126 || ''.split(/.?/).length
2127 || '.'.split(/()()/).length > 1
2128 ) {
2129 (function () {
2130 var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
2131 var maxSafe32BitInt = Math.pow(2, 32) - 1;
2132
2133 StringPrototype.split = function (separator, limit) {
2134 var string = String(this);
2135 if (typeof separator === 'undefined' && limit === 0) {
2136 return [];
2137 }
2138
2139 // If `separator` is not a regex, use native split
2140 if (!isRegex(separator)) {
2141 return strSplit(this, separator, limit);
2142 }
2143
2144 var output = [];
2145 var flags = (separator.ignoreCase ? 'i' : '')
2146 + (separator.multiline ? 'm' : '')
2147 + (separator.unicode ? 'u' : '') // in ES6
2148 + (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
2149 lastLastIndex = 0,
2150 // Make `global` and avoid `lastIndex` issues by working with a copy
2151 separator2, match, lastIndex, lastLength;
2152 var separatorCopy = new RegExp(separator.source, flags + 'g');
2153 if (!compliantExecNpcg) {
2154 // Doesn't need flags gy, but they don't hurt
2155 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
2156 }
2157 /* Values for `limit`, per the spec:
2158 * If undefined: 4294967295 // maxSafe32BitInt
2159 * If 0, Infinity, or NaN: 0
2160 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
2161 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
2162 * If other: Type-convert, then use the above rules
2163 */
2164 var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
2165 match = separatorCopy.exec(string);
2166 while (match) {
2167 // `separatorCopy.lastIndex` is not reliable cross-browser
2168 lastIndex = match.index + match[0].length;
2169 if (lastIndex > lastLastIndex) {
2170 pushCall(output, strSlice(string, lastLastIndex, match.index));
2171 // Fix browsers whose `exec` methods don't consistently return `undefined` for
2172 // nonparticipating capturing groups
2173 if (!compliantExecNpcg && match.length > 1) {
2174 /* eslint-disable no-loop-func */
2175 match[0].replace(separator2, function () {
2176 for (var i = 1; i < arguments.length - 2; i++) {
2177 if (typeof arguments[i] === 'undefined') {
2178 match[i] = void 0;
2179 }
2180 }
2181 });
2182 /* eslint-enable no-loop-func */
2183 }
2184 if (match.length > 1 && match.index < string.length) {
2185 array_push.apply(output, arraySlice(match, 1));
2186 }
2187 lastLength = match[0].length;
2188 lastLastIndex = lastIndex;
2189 if (output.length >= splitLimit) {
2190 break;
2191 }
2192 }
2193 if (separatorCopy.lastIndex === match.index) {
2194 separatorCopy.lastIndex++; // Avoid an infinite loop
2195 }
2196 match = separatorCopy.exec(string);
2197 }
2198 if (lastLastIndex === string.length) {
2199 if (lastLength || !separatorCopy.test('')) {
2200 pushCall(output, '');
2201 }
2202 } else {
2203 pushCall(output, strSlice(string, lastLastIndex));
2204 }
2205 return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
2206 };
2207 }());
2208
2209 // [bugfix, chrome]
2210 // If separator is undefined, then the result array contains just one String,
2211 // which is the this value (converted to a String). If limit is not undefined,
2212 // then the output array is truncated so that it contains no more than limit
2213 // elements.
2214 // "0".split(undefined, 0) -> []
2215 } else if ('0'.split(void 0, 0).length) {
2216 StringPrototype.split = function split(separator, limit) {
2217 if (typeof separator === 'undefined' && limit === 0) {
2218 return [];
2219 }
2220 return strSplit(this, separator, limit);
2221 };
2222 }
2223
2224 var str_replace = StringPrototype.replace;
2225 var replaceReportsGroupsCorrectly = (function () {
2226 var groups = [];
2227 'x'.replace(/x(.)?/g, function (match, group) {
2228 pushCall(groups, group);
2229 });
2230 return groups.length === 1 && typeof groups[0] === 'undefined';
2231 }());
2232
2233 if (!replaceReportsGroupsCorrectly) {
2234 StringPrototype.replace = function replace(searchValue, replaceValue) {
2235 var isFn = isCallable(replaceValue);
2236 var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
2237 if (!isFn || !hasCapturingGroups) {
2238 return str_replace.call(this, searchValue, replaceValue);
2239 } else {
2240 var wrappedReplaceValue = function (match) {
2241 var length = arguments.length;
2242 var originalLastIndex = searchValue.lastIndex;
2243 searchValue.lastIndex = 0;
2244 var args = searchValue.exec(match) || [];
2245 searchValue.lastIndex = originalLastIndex;
2246 pushCall(args, arguments[length - 2], arguments[length - 1]);
2247 return replaceValue.apply(this, args);
2248 };
2249 return str_replace.call(this, searchValue, wrappedReplaceValue);
2250 }
2251 };
2252 }
2253
2254 // ECMA-262, 3rd B.2.3
2255 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
2256 // non-normative section suggesting uniform semantics and it should be
2257 // normalized across all browsers
2258 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
2259 var string_substr = StringPrototype.substr;
2260 var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
2261 defineProperties(StringPrototype, {
2262 substr: function substr(start, length) {
2263 var normalizedStart = start;
2264 if (start < 0) {
2265 normalizedStart = max(this.length + start, 0);
2266 }
2267 return string_substr.call(this, normalizedStart, length);
2268 }
2269 }, hasNegativeSubstrBug);
2270
2271 // ES5 15.5.4.20
2272 // whitespace from: http://es5.github.io/#x15.5.4.20
2273 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003'
2274 + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028'
2275 + '\u2029\uFEFF';
2276 var zeroWidth = '\u200b';
2277 var wsRegexChars = '[' + ws + ']';
2278 var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
2279 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
2280 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
2281 defineProperties(StringPrototype, {
2282 // http://blog.stevenlevithan.com/archives/faster-trim-javascript
2283 // http://perfectionkills.com/whitespace-deviations/
2284 trim: function trim() {
2285 if (typeof this === 'undefined' || this === null) {
2286 throw new TypeError("can't convert " + this + ' to object');
2287 }
2288 return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
2289 }
2290 }, hasTrimWhitespaceBug);
2291 var trim = call.bind(String.prototype.trim);
2292
2293 var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
2294 defineProperties(StringPrototype, {
2295 lastIndexOf: function lastIndexOf(searchString) {
2296 if (typeof this === 'undefined' || this === null) {
2297 throw new TypeError("can't convert " + this + ' to object');
2298 }
2299 var S = $String(this);
2300 var searchStr = $String(searchString);
2301 var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
2302 var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
2303 var start = min(max(pos, 0), S.length);
2304 var searchLen = searchStr.length;
2305 var k = start + searchLen;
2306 while (k > 0) {
2307 k = max(0, k - searchLen);
2308 var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
2309 if (index !== -1) {
2310 return k + index;
2311 }
2312 }
2313 return -1;
2314 }
2315 }, hasLastIndexBug);
2316
2317 var originalLastIndexOf = StringPrototype.lastIndexOf;
2318 defineProperties(StringPrototype, {
2319 lastIndexOf: function lastIndexOf(searchString) {
2320 return originalLastIndexOf.apply(this, arguments);
2321 }
2322 }, StringPrototype.lastIndexOf.length !== 1);
2323
2324 // ES-5 15.1.2.2
2325 // eslint-disable-next-line radix
2326 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
2327 /* global parseInt: true */
2328 parseInt = (function (origParseInt) {
2329 var hexRegex = /^[-+]?0[xX]/;
2330 return function parseInt(str, radix) {
2331 if (typeof str === 'symbol') {
2332 // handle Symbols in node 8.3/8.4
2333 // eslint-disable-next-line no-implicit-coercion, no-unused-expressions
2334 '' + str; // jscs:ignore disallowImplicitTypeConversion
2335 }
2336
2337 var string = trim(String(str));
2338 var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
2339 return origParseInt(string, defaultedRadix);
2340 };
2341 }(parseInt));
2342 }
2343
2344 // https://es5.github.io/#x15.1.2.3
2345 if (1 / parseFloat('-0') !== -Infinity) {
2346 /* global parseFloat: true */
2347 parseFloat = (function (origParseFloat) {
2348 return function parseFloat(string) {
2349 var inputString = trim(String(string));
2350 var result = origParseFloat(inputString);
2351 return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
2352 };
2353 }(parseFloat));
2354 }
2355
2356 if (String(new RangeError('test')) !== 'RangeError: test') {
2357 var errorToStringShim = function toString() {
2358 if (typeof this === 'undefined' || this === null) {
2359 throw new TypeError("can't convert " + this + ' to object');
2360 }
2361 var name = this.name;
2362 if (typeof name === 'undefined') {
2363 name = 'Error';
2364 } else if (typeof name !== 'string') {
2365 name = $String(name);
2366 }
2367 var msg = this.message;
2368 if (typeof msg === 'undefined') {
2369 msg = '';
2370 } else if (typeof msg !== 'string') {
2371 msg = $String(msg);
2372 }
2373 if (!name) {
2374 return msg;
2375 }
2376 if (!msg) {
2377 return name;
2378 }
2379 return name + ': ' + msg;
2380 };
2381 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2382 Error.prototype.toString = errorToStringShim;
2383 }
2384
2385 if (supportsDescriptors) {
2386 var ensureNonEnumerable = function (obj, prop) {
2387 if (isEnum(obj, prop)) {
2388 var desc = Object.getOwnPropertyDescriptor(obj, prop);
2389 if (desc.configurable) {
2390 desc.enumerable = false;
2391 Object.defineProperty(obj, prop, desc);
2392 }
2393 }
2394 };
2395 ensureNonEnumerable(Error.prototype, 'message');
2396 if (Error.prototype.message !== '') {
2397 Error.prototype.message = '';
2398 }
2399 ensureNonEnumerable(Error.prototype, 'name');
2400 }
2401
2402 if (String(/a/mig) !== '/a/gim') {
2403 var regexToString = function toString() {
2404 var str = '/' + this.source + '/';
2405 if (this.global) {
2406 str += 'g';
2407 }
2408 if (this.ignoreCase) {
2409 str += 'i';
2410 }
2411 if (this.multiline) {
2412 str += 'm';
2413 }
2414 return str;
2415 };
2416 // can't use defineProperties here because of toString enumeration issue in IE <= 8
2417 RegExp.prototype.toString = regexToString;
2418 }
2419 }));
2420
2421 },{}],6:[function(require,module,exports){
2422 /*!
2423 * EventEmitter v5.2.4 - git.io/ee
2424 * Unlicense - http://unlicense.org/
2425 * Oliver Caldwell - http://oli.me.uk/
2426 * @preserve
2427 */
2428
2429 ;(function (exports) {
2430 'use strict';
2431
2432 /**
2433 * Class for managing events.
2434 * Can be extended to provide event functionality in other classes.
2435 *
2436 * @class EventEmitter Manages event registering and emitting.
2437 */
2438 function EventEmitter() {}
2439
2440 // Shortcuts to improve speed and size
2441 var proto = EventEmitter.prototype;
2442 var originalGlobalValue = exports.EventEmitter;
2443
2444 /**
2445 * Finds the index of the listener for the event in its storage array.
2446 *
2447 * @param {Function[]} listeners Array of listeners to search through.
2448 * @param {Function} listener Method to look for.
2449 * @return {Number} Index of the specified listener, -1 if not found
2450 * @api private
2451 */
2452 function indexOfListener(listeners, listener) {
2453 var i = listeners.length;
2454 while (i--) {
2455 if (listeners[i].listener === listener) {
2456 return i;
2457 }
2458 }
2459
2460 return -1;
2461 }
2462
2463 /**
2464 * Alias a method while keeping the context correct, to allow for overwriting of target method.
2465 *
2466 * @param {String} name The name of the target method.
2467 * @return {Function} The aliased method
2468 * @api private
2469 */
2470 function alias(name) {
2471 return function aliasClosure() {
2472 return this[name].apply(this, arguments);
2473 };
2474 }
2475
2476 /**
2477 * Returns the listener array for the specified event.
2478 * Will initialise the event object and listener arrays if required.
2479 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
2480 * Each property in the object response is an array of listener functions.
2481 *
2482 * @param {String|RegExp} evt Name of the event to return the listeners from.
2483 * @return {Function[]|Object} All listener functions for the event.
2484 */
2485 proto.getListeners = function getListeners(evt) {
2486 var events = this._getEvents();
2487 var response;
2488 var key;
2489
2490 // Return a concatenated array of all matching events if
2491 // the selector is a regular expression.
2492 if (evt instanceof RegExp) {
2493 response = {};
2494 for (key in events) {
2495 if (events.hasOwnProperty(key) && evt.test(key)) {
2496 response[key] = events[key];
2497 }
2498 }
2499 }
2500 else {
2501 response = events[evt] || (events[evt] = []);
2502 }
2503
2504 return response;
2505 };
2506
2507 /**
2508 * Takes a list of listener objects and flattens it into a list of listener functions.
2509 *
2510 * @param {Object[]} listeners Raw listener objects.
2511 * @return {Function[]} Just the listener functions.
2512 */
2513 proto.flattenListeners = function flattenListeners(listeners) {
2514 var flatListeners = [];
2515 var i;
2516
2517 for (i = 0; i < listeners.length; i += 1) {
2518 flatListeners.push(listeners[i].listener);
2519 }
2520
2521 return flatListeners;
2522 };
2523
2524 /**
2525 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
2526 *
2527 * @param {String|RegExp} evt Name of the event to return the listeners from.
2528 * @return {Object} All listener functions for an event in an object.
2529 */
2530 proto.getListenersAsObject = function getListenersAsObject(evt) {
2531 var listeners = this.getListeners(evt);
2532 var response;
2533
2534 if (listeners instanceof Array) {
2535 response = {};
2536 response[evt] = listeners;
2537 }
2538
2539 return response || listeners;
2540 };
2541
2542 function isValidListener (listener) {
2543 if (typeof listener === 'function' || listener instanceof RegExp) {
2544 return true
2545 } else if (listener && typeof listener === 'object') {
2546 return isValidListener(listener.listener)
2547 } else {
2548 return false
2549 }
2550 }
2551
2552 /**
2553 * Adds a listener function to the specified event.
2554 * The listener will not be added if it is a duplicate.
2555 * If the listener returns true then it will be removed after it is called.
2556 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
2557 *
2558 * @param {String|RegExp} evt Name of the event to attach the listener to.
2559 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
2560 * @return {Object} Current instance of EventEmitter for chaining.
2561 */
2562 proto.addListener = function addListener(evt, listener) {
2563 if (!isValidListener(listener)) {
2564 throw new TypeError('listener must be a function');
2565 }
2566
2567 var listeners = this.getListenersAsObject(evt);
2568 var listenerIsWrapped = typeof listener === 'object';
2569 var key;
2570
2571 for (key in listeners) {
2572 if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
2573 listeners[key].push(listenerIsWrapped ? listener : {
2574 listener: listener,
2575 once: false
2576 });
2577 }
2578 }
2579
2580 return this;
2581 };
2582
2583 /**
2584 * Alias of addListener
2585 */
2586 proto.on = alias('addListener');
2587
2588 /**
2589 * Semi-alias of addListener. It will add a listener that will be
2590 * automatically removed after its first execution.
2591 *
2592 * @param {String|RegExp} evt Name of the event to attach the listener to.
2593 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
2594 * @return {Object} Current instance of EventEmitter for chaining.
2595 */
2596 proto.addOnceListener = function addOnceListener(evt, listener) {
2597 return this.addListener(evt, {
2598 listener: listener,
2599 once: true
2600 });
2601 };
2602
2603 /**
2604 * Alias of addOnceListener.
2605 */
2606 proto.once = alias('addOnceListener');
2607
2608 /**
2609 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
2610 * You need to tell it what event names should be matched by a regex.
2611 *
2612 * @param {String} evt Name of the event to create.
2613 * @return {Object} Current instance of EventEmitter for chaining.
2614 */
2615 proto.defineEvent = function defineEvent(evt) {
2616 this.getListeners(evt);
2617 return this;
2618 };
2619
2620 /**
2621 * Uses defineEvent to define multiple events.
2622 *
2623 * @param {String[]} evts An array of event names to define.
2624 * @return {Object} Current instance of EventEmitter for chaining.
2625 */
2626 proto.defineEvents = function defineEvents(evts) {
2627 for (var i = 0; i < evts.length; i += 1) {
2628 this.defineEvent(evts[i]);
2629 }
2630 return this;
2631 };
2632
2633 /**
2634 * Removes a listener function from the specified event.
2635 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
2636 *
2637 * @param {String|RegExp} evt Name of the event to remove the listener from.
2638 * @param {Function} listener Method to remove from the event.
2639 * @return {Object} Current instance of EventEmitter for chaining.
2640 */
2641 proto.removeListener = function removeListener(evt, listener) {
2642 var listeners = this.getListenersAsObject(evt);
2643 var index;
2644 var key;
2645
2646 for (key in listeners) {
2647 if (listeners.hasOwnProperty(key)) {
2648 index = indexOfListener(listeners[key], listener);
2649
2650 if (index !== -1) {
2651 listeners[key].splice(index, 1);
2652 }
2653 }
2654 }
2655
2656 return this;
2657 };
2658
2659 /**
2660 * Alias of removeListener
2661 */
2662 proto.off = alias('removeListener');
2663
2664 /**
2665 * Adds listeners in bulk using the manipulateListeners method.
2666 * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
2667 * You can also pass it a regular expression to add the array of listeners to all events that match it.
2668 * Yeah, this function does quite a bit. That's probably a bad thing.
2669 *
2670 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
2671 * @param {Function[]} [listeners] An optional array of listener functions to add.
2672 * @return {Object} Current instance of EventEmitter for chaining.
2673 */
2674 proto.addListeners = function addListeners(evt, listeners) {
2675 // Pass through to manipulateListeners
2676 return this.manipulateListeners(false, evt, listeners);
2677 };
2678
2679 /**
2680 * Removes listeners in bulk using the manipulateListeners method.
2681 * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
2682 * You can also pass it an event name and an array of listeners to be removed.
2683 * You can also pass it a regular expression to remove the listeners from all events that match it.
2684 *
2685 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
2686 * @param {Function[]} [listeners] An optional array of listener functions to remove.
2687 * @return {Object} Current instance of EventEmitter for chaining.
2688 */
2689 proto.removeListeners = function removeListeners(evt, listeners) {
2690 // Pass through to manipulateListeners
2691 return this.manipulateListeners(true, evt, listeners);
2692 };
2693
2694 /**
2695 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
2696 * The first argument will determine if the listeners are removed (true) or added (false).
2697 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
2698 * You can also pass it an event name and an array of listeners to be added/removed.
2699 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
2700 *
2701 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
2702 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
2703 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
2704 * @return {Object} Current instance of EventEmitter for chaining.
2705 */
2706 proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
2707 var i;
2708 var value;
2709 var single = remove ? this.removeListener : this.addListener;
2710 var multiple = remove ? this.removeListeners : this.addListeners;
2711
2712 // If evt is an object then pass each of its properties to this method
2713 if (typeof evt === 'object' && !(evt instanceof RegExp)) {
2714 for (i in evt) {
2715 if (evt.hasOwnProperty(i) && (value = evt[i])) {
2716 // Pass the single listener straight through to the singular method
2717 if (typeof value === 'function') {
2718 single.call(this, i, value);
2719 }
2720 else {
2721 // Otherwise pass back to the multiple function
2722 multiple.call(this, i, value);
2723 }
2724 }
2725 }
2726 }
2727 else {
2728 // So evt must be a string
2729 // And listeners must be an array of listeners
2730 // Loop over it and pass each one to the multiple method
2731 i = listeners.length;
2732 while (i--) {
2733 single.call(this, evt, listeners[i]);
2734 }
2735 }
2736
2737 return this;
2738 };
2739
2740 /**
2741 * Removes all listeners from a specified event.
2742 * If you do not specify an event then all listeners will be removed.
2743 * That means every event will be emptied.
2744 * You can also pass a regex to remove all events that match it.
2745 *
2746 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
2747 * @return {Object} Current instance of EventEmitter for chaining.
2748 */
2749 proto.removeEvent = function removeEvent(evt) {
2750 var type = typeof evt;
2751 var events = this._getEvents();
2752 var key;
2753
2754 // Remove different things depending on the state of evt
2755 if (type === 'string') {
2756 // Remove all listeners for the specified event
2757 delete events[evt];
2758 }
2759 else if (evt instanceof RegExp) {
2760 // Remove all events matching the regex.
2761 for (key in events) {
2762 if (events.hasOwnProperty(key) && evt.test(key)) {
2763 delete events[key];
2764 }
2765 }
2766 }
2767 else {
2768 // Remove all listeners in all events
2769 delete this._events;
2770 }
2771
2772 return this;
2773 };
2774
2775 /**
2776 * Alias of removeEvent.
2777 *
2778 * Added to mirror the node API.
2779 */
2780 proto.removeAllListeners = alias('removeEvent');
2781
2782 /**
2783 * Emits an event of your choice.
2784 * When emitted, every listener attached to that event will be executed.
2785 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
2786 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
2787 * So they will not arrive within the array on the other side, they will be separate.
2788 * You can also pass a regular expression to emit to all events that match it.
2789 *
2790 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
2791 * @param {Array} [args] Optional array of arguments to be passed to each listener.
2792 * @return {Object} Current instance of EventEmitter for chaining.
2793 */
2794 proto.emitEvent = function emitEvent(evt, args) {
2795 var listenersMap = this.getListenersAsObject(evt);
2796 var listeners;
2797 var listener;
2798 var i;
2799 var key;
2800 var response;
2801
2802 for (key in listenersMap) {
2803 if (listenersMap.hasOwnProperty(key)) {
2804 listeners = listenersMap[key].slice(0);
2805
2806 for (i = 0; i < listeners.length; i++) {
2807 // If the listener returns true then it shall be removed from the event
2808 // The function is executed either with a basic call or an apply if there is an args array
2809 listener = listeners[i];
2810
2811 if (listener.once === true) {
2812 this.removeListener(evt, listener.listener);
2813 }
2814
2815 response = listener.listener.apply(this, args || []);
2816
2817 if (response === this._getOnceReturnValue()) {
2818 this.removeListener(evt, listener.listener);
2819 }
2820 }
2821 }
2822 }
2823
2824 return this;
2825 };
2826
2827 /**
2828 * Alias of emitEvent
2829 */
2830 proto.trigger = alias('emitEvent');
2831
2832 /**
2833 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
2834 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
2835 *
2836 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
2837 * @param {...*} Optional additional arguments to be passed to each listener.
2838 * @return {Object} Current instance of EventEmitter for chaining.
2839 */
2840 proto.emit = function emit(evt) {
2841 var args = Array.prototype.slice.call(arguments, 1);
2842 return this.emitEvent(evt, args);
2843 };
2844
2845 /**
2846 * Sets the current value to check against when executing listeners. If a
2847 * listeners return value matches the one set here then it will be removed
2848 * after execution. This value defaults to true.
2849 *
2850 * @param {*} value The new value to check for when executing listeners.
2851 * @return {Object} Current instance of EventEmitter for chaining.
2852 */
2853 proto.setOnceReturnValue = function setOnceReturnValue(value) {
2854 this._onceReturnValue = value;
2855 return this;
2856 };
2857
2858 /**
2859 * Fetches the current value to check against when executing listeners. If
2860 * the listeners return value matches this one then it should be removed
2861 * automatically. It will return true by default.
2862 *
2863 * @return {*|Boolean} The current value to check for or the default, true.
2864 * @api private
2865 */
2866 proto._getOnceReturnValue = function _getOnceReturnValue() {
2867 if (this.hasOwnProperty('_onceReturnValue')) {
2868 return this._onceReturnValue;
2869 }
2870 else {
2871 return true;
2872 }
2873 };
2874
2875 /**
2876 * Fetches the events object and creates one if required.
2877 *
2878 * @return {Object} The events storage object.
2879 * @api private
2880 */
2881 proto._getEvents = function _getEvents() {
2882 return this._events || (this._events = {});
2883 };
2884
2885 /**
2886 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
2887 *
2888 * @return {Function} Non conflicting EventEmitter class.
2889 */
2890 EventEmitter.noConflict = function noConflict() {
2891 exports.EventEmitter = originalGlobalValue;
2892 return EventEmitter;
2893 };
2894
2895 // Expose the class either via AMD, CommonJS or the global object
2896 if (typeof define === 'function' && define.amd) {
2897 define(function () {
2898 return EventEmitter;
2899 });
2900 }
2901 else if (typeof module === 'object' && module.exports){
2902 module.exports = EventEmitter;
2903 }
2904 else {
2905 exports.EventEmitter = EventEmitter;
2906 }
2907 }(this || {}));
2908
2909 },{}]},{},[4]);
2910 ; })();