提交 ef57b34b 编写于 作者: B Brian 提交者: Mr.doob

Benchmarks Suite Added (#8999)

* Upgrading BenchmarkJS to major version 2

* Added Benchmarks page

* Updated old Vector3Components Benchmark

* Real order

* Float32 Array Benchs Added

* Vector 3 Length Bench Added

* Vector 3 Storage Bench Added

* Deleted old benchmark pages

* Added some functionality

* Added Doc
上级 7e0a836e
# THREEJS Benchmark Suite
### Example: Adding a New Suite
For adding a new Tests we need two things
- Adding the Test File
- Linking it on the benchmark.html page
Some example could be like this
```javascript
(function() {
// We want to make sure THREE.JS is loaded for this Benchmark
var THREE
if (Bench.isTHREELoaded()) {
THREE = Bench.THREE;
} else {
Bench.warning("Test Example Benchmark not loaded because THREEJS was not loaded");
return;
}
var s = Bench.newSuite("Example Benchmark Distance Calculation");
var v2a = new THREE.Vector2(3.0, 3.0);
var v2b = new THREE.Vector2(9.0, -3.0);
var v3a = new THREE.Vector3(3.0, 3.0, 0.0);
var v3b = new THREE.Vector3(9.0, -3.0, 0.0);
s.add("Vector3", function() {
v3a.distanceTo(v3b);
})
s.add("Vector2", function() {
v2a.distanceTo(v2b);
})
})();
```
Remember that THREEJS library is only accesible via `Bench.THREE`
/*!
* Benchmark.js v1.0.0 <http://benchmarkjs.com/>
* Copyright 2010-2012 Mathias Bynens <http://mths.be/>
* Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
* Modified by John-David Dalton <http://allyoucanleet.com/>
* Available under MIT license <http://mths.be/mit>
*/
;(function(window, undefined) {
'use strict';
/** Used to assign each benchmark an incrimented id */
var counter = 0;
/** Detect DOM document object */
var doc = isHostType(window, 'document') && document;
/** Detect free variable `define` */
var freeDefine = typeof define == 'function' &&
typeof define.amd == 'object' && define.amd && define;
/** Detect free variable `exports` */
var freeExports = typeof exports == 'object' && exports &&
(typeof global == 'object' && global && global == global.global && (window = global), exports);
/** Detect free variable `require` */
var freeRequire = typeof require == 'function' && require;
/** Used to crawl all properties regardless of enumerability */
var getAllKeys = Object.getOwnPropertyNames;
/** Used to get property descriptors */
var getDescriptor = Object.getOwnPropertyDescriptor;
/** Used in case an object doesn't have its own method */
var hasOwnProperty = {}.hasOwnProperty;
/** Used to check if an object is extensible */
var isExtensible = Object.isExtensible || function() { return true; };
/** Used to access Wade Simmons' Node microtime module */
var microtimeObject = req('microtime');
/** Used to access the browser's high resolution timer */
var perfObject = isHostType(window, 'performance') && performance;
/** Used to call the browser's high resolution timer */
var perfName = perfObject && (
perfObject.now && 'now' ||
perfObject.webkitNow && 'webkitNow'
);
/** Used to access Node's high resolution timer */
var processObject = isHostType(window, 'process') && process;
/** Used to check if an own property is enumerable */
var propertyIsEnumerable = {}.propertyIsEnumerable;
/** Used to set property descriptors */
var setDescriptor = Object.defineProperty;
/** Used to resolve a value's internal [[Class]] */
var toString = {}.toString;
/** Used to prevent a `removeChild` memory leak in IE < 9 */
var trash = doc && doc.createElement('div');
/** Used to integrity check compiled tests */
var uid = 'uid' + (+new Date);
/** Used to avoid infinite recursion when methods call each other */
var calledBy = {};
/** Used to avoid hz of Infinity */
var divisors = {
'1': 4096,
'2': 512,
'3': 64,
'4': 8,
'5': 0
};
/**
* T-Distribution two-tailed critical values for 95% confidence
* http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
*/
var tTable = {
'1': 12.706,'2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447,
'7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179,
'13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101,
'19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064,
'25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042,
'infinity': 1.96
};
/**
* Critical Mann-Whitney U-values for 95% confidence
* http://www.saburchill.com/IBbiology/stats/003.html
*/
var uTable = {
'5': [0, 1, 2],
'6': [1, 2, 3, 5],
'7': [1, 3, 5, 6, 8],
'8': [2, 4, 6, 8, 10, 13],
'9': [2, 4, 7, 10, 12, 15, 17],
'10': [3, 5, 8, 11, 14, 17, 20, 23],
'11': [3, 6, 9, 13, 16, 19, 23, 26, 30],
'12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37],
'13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45],
'14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55],
'15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64],
'16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75],
'17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87],
'18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99],
'19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113],
'20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127],
'21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142],
'22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158],
'23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175],
'24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192],
'25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211],
'26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230],
'27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250],
'28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272],
'29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294],
'30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317]
};
/**
* An object used to flag environments/features.
*
* @static
* @memberOf Benchmark
* @type Object
*/
var support = {};
(function() {
/**
* Detect Adobe AIR.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.air = isClassOf(window.runtime, 'ScriptBridgingProxyObject');
/**
* Detect if `arguments` objects have the correct internal [[Class]] value.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.argumentsClass = isClassOf(arguments, 'Arguments');
/**
* Detect if in a browser environment.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.browser = doc && isHostType(window, 'navigator');
/**
* Detect if strings support accessing characters by index.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.charByIndex =
// IE 8 supports indexes on string literals but not string objects
('x'[0] + Object('x')[0]) == 'xx';
/**
* Detect if strings have indexes as own properties.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.charByOwnIndex =
// Narwhal, Rhino, RingoJS, IE 8, and Opera < 10.52 support indexes on
// strings but don't detect them as own properties
support.charByIndex && hasKey('x', '0');
/**
* Detect if Java is enabled/exposed.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.java = isClassOf(window.java, 'JavaPackage');
/**
* Detect if the Timers API exists.
*
* @memberOf Benchmark.support
* @type Boolean
*/
support.timeout = isHostType(window, 'setTimeout') && isHostType(window, 'clearTimeout');
/**
* Detect if functions support decompilation.
*
* @name decompilation
* @memberOf Benchmark.support
* @type Boolean
*/
try {
// Safari 2.x removes commas in object literals
// from Function#toString results
// http://webk.it/11609
// Firefox 3.6 and Opera 9.25 strip grouping
// parentheses from Function#toString results
// http://bugzil.la/559438
support.decompilation = Function(
'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')'
)()(0).x === '1';
} catch(e) {
support.decompilation = false;
}
/**
* Detect ES5+ property descriptor API.
*
* @name descriptors
* @memberOf Benchmark.support
* @type Boolean
*/
try {
var o = {};
support.descriptors = (setDescriptor(o, o, o), 'value' in getDescriptor(o, o));
} catch(e) {
support.descriptors = false;
}
/**
* Detect ES5+ Object.getOwnPropertyNames().
*
* @name getAllKeys
* @memberOf Benchmark.support
* @type Boolean
*/
try {
support.getAllKeys = /\bvalueOf\b/.test(getAllKeys(Object.prototype));
} catch(e) {
support.getAllKeys = false;
}
/**
* Detect if own properties are iterated before inherited properties (all but IE < 9).
*
* @name iteratesOwnLast
* @memberOf Benchmark.support
* @type Boolean
*/
support.iteratesOwnFirst = (function() {
var props = [];
function ctor() { this.x = 1; }
ctor.prototype = { 'y': 1 };
for (var prop in new ctor) { props.push(prop); }
return props[0] == 'x';
}());
/**
* Detect if a node's [[Class]] is resolvable (all but IE < 9)
* and that the JS engine errors when attempting to coerce an object to a
* string without a `toString` property value of `typeof` "function".
*
* @name nodeClass
* @memberOf Benchmark.support
* @type Boolean
*/
try {
support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]');
} catch(e) {
support.nodeClass = true;
}
}());
/**
* Timer object used by `clock()` and `Deferred#resolve`.
*
* @private
* @type Object
*/
var timer = {
/**
* The timer namespace object or constructor.
*
* @private
* @memberOf timer
* @type Function|Object
*/
'ns': Date,
/**
* Starts the deferred timer.
*
* @private
* @memberOf timer
* @param {Object} deferred The deferred instance.
*/
'start': null, // lazy defined in `clock()`
/**
* Stops the deferred timer.
*
* @private
* @memberOf timer
* @param {Object} deferred The deferred instance.
*/
'stop': null // lazy defined in `clock()`
};
/** Shortcut for inverse results */
var noArgumentsClass = !support.argumentsClass,
noCharByIndex = !support.charByIndex,
noCharByOwnIndex = !support.charByOwnIndex;
/** Math shortcuts */
var abs = Math.abs,
floor = Math.floor,
max = Math.max,
min = Math.min,
pow = Math.pow,
sqrt = Math.sqrt;
/*--------------------------------------------------------------------------*/
/**
* The Benchmark constructor.
*
* @constructor
* @param {String} name A name to identify the benchmark.
* @param {Function|String} fn The test to benchmark.
* @param {Object} [options={}] Options object.
* @example
*
* // basic usage (the `new` operator is optional)
* var bench = new Benchmark(fn);
*
* // or using a name first
* var bench = new Benchmark('foo', fn);
*
* // or with options
* var bench = new Benchmark('foo', fn, {
*
* // displayed by Benchmark#toString if `name` is not available
* 'id': 'xyz',
*
* // called when the benchmark starts running
* 'onStart': onStart,
*
* // called after each run cycle
* 'onCycle': onCycle,
*
* // called when aborted
* 'onAbort': onAbort,
*
* // called when a test errors
* 'onError': onError,
*
* // called when reset
* 'onReset': onReset,
*
* // called when the benchmark completes running
* 'onComplete': onComplete,
*
* // compiled/called before the test loop
* 'setup': setup,
*
* // compiled/called after the test loop
* 'teardown': teardown
* });
*
* // or name and options
* var bench = new Benchmark('foo', {
*
* // a flag to indicate the benchmark is deferred
* 'defer': true,
*
* // benchmark test function
* 'fn': function(deferred) {
* // call resolve() when the deferred test is finished
* deferred.resolve();
* }
* });
*
* // or options only
* var bench = new Benchmark({
*
* // benchmark name
* 'name': 'foo',
*
* // benchmark test as a string
* 'fn': '[1,2,3,4].sort()'
* });
*
* // a test's `this` binding is set to the benchmark instance
* var bench = new Benchmark('foo', function() {
* 'My name is '.concat(this.name); // My name is foo
* });
*/
function Benchmark(name, fn, options) {
var me = this;
// allow instance creation without the `new` operator
if (me == null || me.constructor != Benchmark) {
return new Benchmark(name, fn, options);
}
// juggle arguments
if (isClassOf(name, 'Object')) {
// 1 argument (options)
options = name;
}
else if (isClassOf(name, 'Function')) {
// 2 arguments (fn, options)
options = fn;
fn = name;
}
else if (isClassOf(fn, 'Object')) {
// 2 arguments (name, options)
options = fn;
fn = null;
me.name = name;
}
else {
// 3 arguments (name, fn [, options])
me.name = name;
}
setOptions(me, options);
me.id || (me.id = ++counter);
me.fn == null && (me.fn = fn);
me.stats = deepClone(me.stats);
me.times = deepClone(me.times);
}
/**
* The Deferred constructor.
*
* @constructor
* @memberOf Benchmark
* @param {Object} clone The cloned benchmark instance.
*/
function Deferred(clone) {
var me = this;
if (me == null || me.constructor != Deferred) {
return new Deferred(clone);
}
me.benchmark = clone;
clock(me);
}
/**
* The Event constructor.
*
* @constructor
* @memberOf Benchmark
* @param {String|Object} type The event type.
*/
function Event(type) {
var me = this;
return (me == null || me.constructor != Event)
? new Event(type)
: (type instanceof Event)
? type
: extend(me, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type);
}
/**
* The Suite constructor.
*
* @constructor
* @memberOf Benchmark
* @param {String} name A name to identify the suite.
* @param {Object} [options={}] Options object.
* @example
*
* // basic usage (the `new` operator is optional)
* var suite = new Benchmark.Suite;
*
* // or using a name first
* var suite = new Benchmark.Suite('foo');
*
* // or with options
* var suite = new Benchmark.Suite('foo', {
*
* // called when the suite starts running
* 'onStart': onStart,
*
* // called between running benchmarks
* 'onCycle': onCycle,
*
* // called when aborted
* 'onAbort': onAbort,
*
* // called when a test errors
* 'onError': onError,
*
* // called when reset
* 'onReset': onReset,
*
* // called when the suite completes running
* 'onComplete': onComplete
* });
*/
function Suite(name, options) {
var me = this;
// allow instance creation without the `new` operator
if (me == null || me.constructor != Suite) {
return new Suite(name, options);
}
// juggle arguments
if (isClassOf(name, 'Object')) {
// 1 argument (options)
options = name;
} else {
// 2 arguments (name [, options])
me.name = name;
}
setOptions(me, options);
}
/*--------------------------------------------------------------------------*/
/**
* Note: Some array methods have been implemented in plain JavaScript to avoid
* bugs in IE, Opera, Rhino, and Mobile Safari.
*
* IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()`
* functions that fail to remove the last element, `object[0]`, of
* array-like-objects even though the `length` property is set to `0`.
* The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
* is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
*
* In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()`
* generically to augment the `arguments` object will pave the value at index 0
* without incrimenting the other values's indexes.
* https://github.com/documentcloud/underscore/issues/9
*
* Rhino and environments it powers, like Narwhal and RingoJS, may have
* buggy Array `concat()`, `reverse()`, `shift()`, `slice()`, `splice()` and
* `unshift()` functions that make sparse arrays non-sparse by assigning the
* undefined indexes a value of undefined.
* https://github.com/mozilla/rhino/commit/702abfed3f8ca043b2636efd31c14ba7552603dd
*/
/**
* Creates an array containing the elements of the host array followed by the
* elements of each argument in order.
*
* @memberOf Benchmark.Suite
* @returns {Array} The new array.
*/
function concat() {
var value,
j = -1,
length = arguments.length,
result = slice.call(this),
index = result.length;
while (++j < length) {
value = arguments[j];
if (isClassOf(value, 'Array')) {
for (var k = 0, l = value.length; k < l; k++, index++) {
if (k in value) {
result[index] = value[k];
}
}
} else {
result[index++] = value;
}
}
return result;
}
/**
* Utility function used by `shift()`, `splice()`, and `unshift()`.
*
* @private
* @param {Number} start The index to start inserting elements.
* @param {Number} deleteCount The number of elements to delete from the insert point.
* @param {Array} elements The elements to insert.
* @returns {Array} An array of deleted elements.
*/
function insert(start, deleteCount, elements) {
// `result` should have its length set to the `deleteCount`
// see https://bugs.ecmascript.org/show_bug.cgi?id=332
var deleteEnd = start + deleteCount,
elementCount = elements ? elements.length : 0,
index = start - 1,
length = start + elementCount,
object = this,
result = Array(deleteCount),
tail = slice.call(object, deleteEnd);
// delete elements from the array
while (++index < deleteEnd) {
if (index in object) {
result[index - start] = object[index];
delete object[index];
}
}
// insert elements
index = start - 1;
while (++index < length) {
object[index] = elements[index - start];
}
// append tail elements
start = index--;
length = max(0, (object.length >>> 0) - deleteCount + elementCount);
while (++index < length) {
if ((index - start) in tail) {
object[index] = tail[index - start];
} else if (index in object) {
delete object[index];
}
}
// delete excess elements
deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0;
while (deleteCount--) {
index = length + deleteCount;
if (index in object) {
delete object[index];
}
}
object.length = length;
return result;
}
/**
* Rearrange the host array's elements in reverse order.
*
* @memberOf Benchmark.Suite
* @returns {Array} The reversed array.
*/
function reverse() {
var upperIndex,
value,
index = -1,
object = Object(this),
length = object.length >>> 0,
middle = floor(length / 2);
if (length > 1) {
while (++index < middle) {
upperIndex = length - index - 1;
value = upperIndex in object ? object[upperIndex] : uid;
if (index in object) {
object[upperIndex] = object[index];
} else {
delete object[upperIndex];
}
if (value != uid) {
object[index] = value;
} else {
delete object[index];
}
}
}
return object;
}
/**
* Removes the first element of the host array and returns it.
*
* @memberOf Benchmark.Suite
* @returns {Mixed} The first element of the array.
*/
function shift() {
return insert.call(this, 0, 1)[0];
}
/**
* Creates an array of the host array's elements from the start index up to,
* but not including, the end index.
*
* @memberOf Benchmark.Suite
* @param {Number} start The starting index.
* @param {Number} end The end index.
* @returns {Array} The new array.
*/
function slice(start, end) {
var index = -1,
object = Object(this),
length = object.length >>> 0,
result = [];
start = toInteger(start);
start = start < 0 ? max(length + start, 0) : min(start, length);
start--;
end = end == null ? length : toInteger(end);
end = end < 0 ? max(length + end, 0) : min(end, length);
while ((++index, ++start) < end) {
if (start in object) {
result[index] = object[start];
}
}
return result;
}
/**
* Allows removing a range of elements and/or inserting elements into the
* host array.
*
* @memberOf Benchmark.Suite
* @param {Number} start The start index.
* @param {Number} deleteCount The number of elements to delete.
* @param {Mixed} [val1, val2, ...] values to insert at the `start` index.
* @returns {Array} An array of removed elements.
*/
function splice(start, deleteCount) {
var object = Object(this),
length = object.length >>> 0;
start = toInteger(start);
start = start < 0 ? max(length + start, 0) : min(start, length);
// support the de-facto SpiderMonkey extension
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice#Parameters
// https://bugs.ecmascript.org/show_bug.cgi?id=429
deleteCount = arguments.length == 1
? length - start
: min(max(toInteger(deleteCount), 0), length - start);
return insert.call(object, start, deleteCount, slice.call(arguments, 2));
}
/**
* Converts the specified `value` to an integer.
*
* @private
* @param {Mixed} value The value to convert.
* @returns {Number} The resulting integer.
*/
function toInteger(value) {
value = +value;
return value === 0 || !isFinite(value) ? value || 0 : value - (value % 1);
}
/**
* Appends arguments to the host array.
*
* @memberOf Benchmark.Suite
* @returns {Number} The new length.
*/
function unshift() {
var object = Object(this);
insert.call(object, 0, 0, arguments);
return object.length;
}
/*--------------------------------------------------------------------------*/
/**
* A generic `Function#bind` like method.
*
* @private
* @param {Function} fn The function to be bound to `thisArg`.
* @param {Mixed} thisArg The `this` binding for the given function.
* @returns {Function} The bound function.
*/
function bind(fn, thisArg) {
return function() { fn.apply(thisArg, arguments); };
}
/**
* Creates a function from the given arguments string and body.
*
* @private
* @param {String} args The comma separated function arguments.
* @param {String} body The function body.
* @returns {Function} The new function.
*/
function createFunction() {
// lazy define
createFunction = function(args, body) {
var result,
anchor = freeDefine ? define.amd : Benchmark,
prop = uid + 'createFunction';
runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}');
result = anchor[prop];
delete anchor[prop];
return result;
};
// fix JaegerMonkey bug
// http://bugzil.la/639720
createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || noop)() == uid ? createFunction : Function;
return createFunction.apply(null, arguments);
}
/**
* Delay the execution of a function based on the benchmark's `delay` property.
*
* @private
* @param {Object} bench The benchmark instance.
* @param {Object} fn The function to execute.
*/
function delay(bench, fn) {
bench._timerId = setTimeout(fn, bench.delay * 1e3);
}
/**
* Destroys the given element.
*
* @private
* @param {Element} element The element to destroy.
*/
function destroyElement(element) {
trash.appendChild(element);
trash.innerHTML = '';
}
/**
* Iterates over an object's properties, executing the `callback` for each.
* Callbacks may terminate the loop by explicitly returning `false`.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback The function executed per own property.
* @param {Object} options The options object.
* @returns {Object} Returns the object iterated over.
*/
function forProps() {
var forShadowed,
skipSeen,
forArgs = true,
shadowed = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
(function(enumFlag, key) {
// must use a non-native constructor to catch the Safari 2 issue
function Klass() { this.valueOf = 0; };
Klass.prototype.valueOf = 0;
// check various for-in bugs
for (key in new Klass) {
enumFlag += key == 'valueOf' ? 1 : 0;
}
// check if `arguments` objects have non-enumerable indexes
for (key in arguments) {
key == '0' && (forArgs = false);
}
// Safari 2 iterates over shadowed properties twice
// http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/
skipSeen = enumFlag == 2;
// IE < 9 incorrectly makes an object's properties non-enumerable if they have
// the same name as other non-enumerable properties in its prototype chain.
forShadowed = !enumFlag;
}(0));
// lazy define
forProps = function(object, callback, options) {
options || (options = {});
var result = object;
object = Object(object);
var ctor,
key,
keys,
skipCtor,
done = !result,
which = options.which,
allFlag = which == 'all',
index = -1,
iteratee = object,
length = object.length,
ownFlag = allFlag || which == 'own',
seen = {},
skipProto = isClassOf(object, 'Function'),
thisArg = options.bind;
if (thisArg !== undefined) {
callback = bind(callback, thisArg);
}
// iterate all properties
if (allFlag && support.getAllKeys) {
for (index = 0, keys = getAllKeys(object), length = keys.length; index < length; index++) {
key = keys[index];
if (callback(object[key], key, object) === false) {
break;
}
}
}
// else iterate only enumerable properties
else {
for (key in object) {
// Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
// (if the prototype or a property on the prototype has been set)
// incorrectly set a function's `prototype` property [[Enumerable]] value
// to `true`. Because of this we standardize on skipping the `prototype`
// property of functions regardless of their [[Enumerable]] value.
if ((done =
!(skipProto && key == 'prototype') &&
!(skipSeen && (hasKey(seen, key) || !(seen[key] = true))) &&
(!ownFlag || ownFlag && hasKey(object, key)) &&
callback(object[key], key, object) === false)) {
break;
}
}
// in IE < 9 strings don't support accessing characters by index
if (!done && (forArgs && isArguments(object) ||
((noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String') &&
(iteratee = noCharByIndex ? object.split('') : object)))) {
while (++index < length) {
if ((done =
callback(iteratee[index], String(index), object) === false)) {
break;
}
}
}
if (!done && forShadowed) {
// Because IE < 9 can't set the `[[Enumerable]]` attribute of an existing
// property and the `constructor` property of a prototype defaults to
// non-enumerable, we manually skip the `constructor` property when we
// think we are iterating over a `prototype` object.
ctor = object.constructor;
skipCtor = ctor && ctor.prototype && ctor.prototype.constructor === ctor;
for (index = 0; index < 7; index++) {
key = shadowed[index];
if (!(skipCtor && key == 'constructor') &&
hasKey(object, key) &&
callback(object[key], key, object) === false) {
break;
}
}
}
}
return result;
};
return forProps.apply(null, arguments);
}
/**
* Gets the name of the first argument from a function's source.
*
* @private
* @param {Function} fn The function.
* @returns {String} The argument name.
*/
function getFirstArgument(fn) {
return (!hasKey(fn, 'toString') &&
(/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || '';
}
/**
* Computes the arithmetic mean of a sample.
*
* @private
* @param {Array} sample The sample.
* @returns {Number} The mean.
*/
function getMean(sample) {
return reduce(sample, function(sum, x) {
return sum + x;
}) / sample.length || 0;
}
/**
* Gets the source code of a function.
*
* @private
* @param {Function} fn The function.
* @param {String} altSource A string used when a function's source code is unretrievable.
* @returns {String} The function's source code.
*/
function getSource(fn, altSource) {
var result = altSource;
if (isStringable(fn)) {
result = String(fn);
} else if (support.decompilation) {
// escape the `{` for Firefox 1
result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
}
// trim string
result = (result || '').replace(/^\s+|\s+$/g, '');
// detect strings containing only the "use strict" directive
return /^(?:\/\*+[\w|\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result)
? ''
: result;
}
/**
* Checks if a value is an `arguments` object.
*
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the value is an `arguments` object, else `false`.
*/
function isArguments() {
// lazy define
isArguments = function(value) {
return toString.call(value) == '[object Arguments]';
};
if (noArgumentsClass) {
isArguments = function(value) {
return hasKey(value, 'callee') &&
!(propertyIsEnumerable && propertyIsEnumerable.call(value, 'callee'));
};
}
return isArguments(arguments[0]);
}
/**
* Checks if an object is of the specified class.
*
* @private
* @param {Mixed} value The value to check.
* @param {String} name The name of the class.
* @returns {Boolean} Returns `true` if the value is of the specified class, else `false`.
*/
function isClassOf(value, name) {
return value != null && toString.call(value) == '[object ' + name + ']';
}
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of object, function, or unknown.
*
* @private
* @param {Mixed} object The owner of the property.
* @param {String} property The property to check.
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
(type == 'object' ? !!object[property] : true);
}
/**
* Checks if a given `value` is an object created by the `Object` constructor
* assuming objects created by the `Object` constructor have no inherited
* enumerable properties and that there are no `Object.prototype` extensions.
*
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`.
*/
function isPlainObject(value) {
// avoid non-objects and false positives for `arguments` objects in IE < 9
var result = false;
if (!(value && typeof value == 'object') || isArguments(value)) {
return result;
}
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
// methods that are `typeof` "string" and still can coerce nodes to strings.
// Also check that the constructor is `Object` (i.e. `Object instanceof Object`)
var ctor = value.constructor;
if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&
(!isClassOf(ctor, 'Function') || ctor instanceof ctor)) {
// In most environments an object's own properties are iterated before
// its inherited properties. If the last iterated property is an object's
// own property then there are no inherited enumerable properties.
if (support.iteratesOwnFirst) {
forProps(value, function(subValue, subKey) {
result = subKey;
});
return result === false || hasKey(value, result);
}
// IE < 9 iterates inherited properties before own properties. If the first
// iterated property is an object's own property then there are no inherited
// enumerable properties.
forProps(value, function(subValue, subKey) {
result = !hasKey(value, subKey);
return false;
});
return result === false;
}
return result;
}
/**
* Checks if a value can be safely coerced to a string.
*
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if the value can be coerced, else `false`.
*/
function isStringable(value) {
return hasKey(value, 'toString') || isClassOf(value, 'String');
}
/**
* Wraps a function and passes `this` to the original function as the
* first argument.
*
* @private
* @param {Function} fn The function to be wrapped.
* @returns {Function} The new function.
*/
function methodize(fn) {
return function() {
var args = [this];
args.push.apply(args, arguments);
return fn.apply(null, args);
};
}
/**
* A no-operation function.
*
* @private
*/
function noop() {
// no operation performed
}
/**
* A wrapper around require() to suppress `module missing` errors.
*
* @private
* @param {String} id The module id.
* @returns {Mixed} The exported module or `null`.
*/
function req(id) {
try {
var result = freeExports && freeRequire(id);
} catch(e) { }
return result || null;
}
/**
* Runs a snippet of JavaScript via script injection.
*
* @private
* @param {String} code The code to run.
*/
function runScript(code) {
var anchor = freeDefine ? define.amd : Benchmark,
script = doc.createElement('script'),
sibling = doc.getElementsByTagName('script')[0],
parent = sibling.parentNode,
prop = uid + 'runScript',
prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();';
// Firefox 2.0.0.2 cannot use script injection as intended because it executes
// asynchronously, but that's OK because script injection is only used to avoid
// the previously commented JaegerMonkey bug.
try {
// remove the inserted script *before* running the code to avoid differences
// in the expected script element count/order of the document.
script.appendChild(doc.createTextNode(prefix + code));
anchor[prop] = function() { destroyElement(script); };
} catch(e) {
parent = parent.cloneNode(false);
sibling = null;
script.text = code;
}
parent.insertBefore(script, sibling);
delete anchor[prop];
}
/**
* A helper function for setting options/event handlers.
*
* @private
* @param {Object} bench The benchmark instance.
* @param {Object} [options={}] Options object.
*/
function setOptions(bench, options) {
options = extend({}, bench.constructor.options, options);
bench.options = forOwn(options, function(value, key) {
if (value != null) {
// add event listeners
if (/^on[A-Z]/.test(key)) {
forEach(key.split(' '), function(key) {
bench.on(key.slice(2).toLowerCase(), value);
});
} else if (!hasKey(bench, key)) {
bench[key] = deepClone(value);
}
}
});
}
/*--------------------------------------------------------------------------*/
/**
* Handles cycling/completing the deferred benchmark.
*
* @memberOf Benchmark.Deferred
*/
function resolve() {
var me = this,
clone = me.benchmark,
bench = clone._original;
if (bench.aborted) {
// cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete
me.teardown();
clone.running = false;
cycle(me);
}
else if (++me.cycles < clone.count) {
// continue the test loop
if (support.timeout) {
// use setTimeout to avoid a call stack overflow if called recursively
setTimeout(function() { clone.compiled.call(me, timer); }, 0);
} else {
clone.compiled.call(me, timer);
}
}
else {
timer.stop(me);
me.teardown();
delay(clone, function() { cycle(me); });
}
}
/*--------------------------------------------------------------------------*/
/**
* A deep clone utility.
*
* @static
* @memberOf Benchmark
* @param {Mixed} value The value to clone.
* @returns {Mixed} The cloned value.
*/
function deepClone(value) {
var accessor,
circular,
clone,
ctor,
descriptor,
extensible,
key,
length,
markerKey,
parent,
result,
source,
subIndex,
data = { 'value': value },
index = 0,
marked = [],
queue = { 'length': 0 },
unmarked = [];
/**
* An easily detectable decorator for cloned values.
*/
function Marker(object) {
this.raw = object;
}
/**
* The callback used by `forProps()`.
*/
function forPropsCallback(subValue, subKey) {
// exit early to avoid cloning the marker
if (subValue && subValue.constructor == Marker) {
return;
}
// add objects to the queue
if (subValue === Object(subValue)) {
queue[queue.length++] = { 'key': subKey, 'parent': clone, 'source': value };
}
// assign non-objects
else {
try {
// will throw an error in strict mode if the property is read-only
clone[subKey] = subValue;
} catch(e) { }
}
}
/**
* Gets an available marker key for the given object.
*/
function getMarkerKey(object) {
// avoid collisions with existing keys
var result = uid;
while (object[result] && object[result].constructor != Marker) {
result += 1;
}
return result;
}
do {
key = data.key;
parent = data.parent;
source = data.source;
clone = value = source ? source[key] : data.value;
accessor = circular = descriptor = false;
// create a basic clone to filter out functions, DOM elements, and
// other non `Object` objects
if (value === Object(value)) {
// use custom deep clone function if available
if (isClassOf(value.deepClone, 'Function')) {
clone = value.deepClone();
} else {
ctor = value.constructor;
switch (toString.call(value)) {
case '[object Array]':
clone = new ctor(value.length);
break;
case '[object Boolean]':
clone = new ctor(value == true);
break;
case '[object Date]':
clone = new ctor(+value);
break;
case '[object Object]':
isPlainObject(value) && (clone = {});
break;
case '[object Number]':
case '[object String]':
clone = new ctor(value);
break;
case '[object RegExp]':
clone = ctor(value.source,
(value.global ? 'g' : '') +
(value.ignoreCase ? 'i' : '') +
(value.multiline ? 'm' : ''));
}
}
// continue clone if `value` doesn't have an accessor descriptor
// http://es5.github.com/#x8.10.1
if (clone && clone != value &&
!(descriptor = source && support.descriptors && getDescriptor(source, key),
accessor = descriptor && (descriptor.get || descriptor.set))) {
// use an existing clone (circular reference)
if ((extensible = isExtensible(value))) {
markerKey = getMarkerKey(value);
if (value[markerKey]) {
circular = clone = value[markerKey].raw;
}
} else {
// for frozen/sealed objects
for (subIndex = 0, length = unmarked.length; subIndex < length; subIndex++) {
data = unmarked[subIndex];
if (data.object === value) {
circular = clone = data.clone;
break;
}
}
}
if (!circular) {
// mark object to allow quickly detecting circular references and tie it to its clone
if (extensible) {
value[markerKey] = new Marker(clone);
marked.push({ 'key': markerKey, 'object': value });
} else {
// for frozen/sealed objects
unmarked.push({ 'clone': clone, 'object': value });
}
// iterate over object properties
forProps(value, forPropsCallback, { 'which': 'all' });
}
}
}
if (parent) {
// for custom property descriptors
if (accessor || (descriptor && !(descriptor.configurable && descriptor.enumerable && descriptor.writable))) {
if ('value' in descriptor) {
descriptor.value = clone;
}
setDescriptor(parent, key, descriptor);
}
// for default property descriptors
else {
parent[key] = clone;
}
} else {
result = clone;
}
} while ((data = queue[index++]));
// remove markers
for (index = 0, length = marked.length; index < length; index++) {
data = marked[index];
delete data.object[data.key];
}
return result;
}
/**
* An iteration utility for arrays and objects.
* Callbacks may terminate the loop by explicitly returning `false`.
*
* @static
* @memberOf Benchmark
* @param {Array|Object} object The object to iterate over.
* @param {Function} callback The function called per iteration.
* @param {Mixed} thisArg The `this` binding for the callback.
* @returns {Array|Object} Returns the object iterated over.
*/
function each(object, callback, thisArg) {
var result = object;
object = Object(object);
var fn = callback,
index = -1,
length = object.length,
isSnapshot = !!(object.snapshotItem && (length = object.snapshotLength)),
isSplittable = (noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String'),
isConvertable = isSnapshot || isSplittable || 'item' in object,
origObject = object;
// in Opera < 10.5 `hasKey(object, 'length')` returns `false` for NodeLists
if (length === length >>> 0) {
if (isConvertable) {
// the third argument of the callback is the original non-array object
callback = function(value, index) {
return fn.call(this, value, index, origObject);
};
// in IE < 9 strings don't support accessing characters by index
if (isSplittable) {
object = object.split('');
} else {
object = [];
while (++index < length) {
// in Safari 2 `index in object` is always `false` for NodeLists
object[index] = isSnapshot ? result.snapshotItem(index) : result[index];
}
}
}
forEach(object, callback, thisArg);
} else {
forOwn(object, callback, thisArg);
}
return result;
}
/**
* Copies enumerable properties from the source(s) object to the destination object.
*
* @static
* @memberOf Benchmark
* @param {Object} destination The destination object.
* @param {Object} [source={}] The source object.
* @returns {Object} The destination object.
*/
function extend(destination, source) {
// Chrome < 14 incorrectly sets `destination` to `undefined` when we `delete arguments[0]`
// http://code.google.com/p/v8/issues/detail?id=839
var result = destination;
delete arguments[0];
forEach(arguments, function(source) {
forProps(source, function(value, key) {
result[key] = value;
});
});
return result;
}
/**
* A generic `Array#filter` like method.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {Function|String} callback The function/alias called per iteration.
* @param {Mixed} thisArg The `this` binding for the callback.
* @returns {Array} A new array of values that passed callback filter.
* @example
*
* // get odd numbers
* Benchmark.filter([1, 2, 3, 4, 5], function(n) {
* return n % 2;
* }); // -> [1, 3, 5];
*
* // get fastest benchmarks
* Benchmark.filter(benches, 'fastest');
*
* // get slowest benchmarks
* Benchmark.filter(benches, 'slowest');
*
* // get benchmarks that completed without erroring
* Benchmark.filter(benches, 'successful');
*/
function filter(array, callback, thisArg) {
var result;
if (callback == 'successful') {
// callback to exclude those that are errored, unrun, or have hz of Infinity
callback = function(bench) { return bench.cycles && isFinite(bench.hz); };
}
else if (callback == 'fastest' || callback == 'slowest') {
// get successful, sort by period + margin of error, and filter fastest/slowest
result = filter(array, 'successful').sort(function(a, b) {
a = a.stats; b = b.stats;
return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback == 'fastest' ? 1 : -1);
});
result = filter(result, function(bench) {
return result[0].compare(bench) == 0;
});
}
return result || reduce(array, function(result, value, index) {
return callback.call(thisArg, value, index, array) ? (result.push(value), result) : result;
}, []);
}
/**
* A generic `Array#forEach` like method.
* Callbacks may terminate the loop by explicitly returning `false`.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @param {Mixed} thisArg The `this` binding for the callback.
* @returns {Array} Returns the array iterated over.
*/
function forEach(array, callback, thisArg) {
var index = -1,
length = (array = Object(array)).length >>> 0;
if (thisArg !== undefined) {
callback = bind(callback, thisArg);
}
while (++index < length) {
if (index in array &&
callback(array[index], index, array) === false) {
break;
}
}
return array;
}
/**
* Iterates over an object's own properties, executing the `callback` for each.
* Callbacks may terminate the loop by explicitly returning `false`.
*
* @static
* @memberOf Benchmark
* @param {Object} object The object to iterate over.
* @param {Function} callback The function executed per own property.
* @param {Mixed} thisArg The `this` binding for the callback.
* @returns {Object} Returns the object iterated over.
*/
function forOwn(object, callback, thisArg) {
return forProps(object, callback, { 'bind': thisArg, 'which': 'own' });
}
/**
* Converts a number to a more readable comma-separated string representation.
*
* @static
* @memberOf Benchmark
* @param {Number} number The number to convert.
* @returns {String} The more readable string representation.
*/
function formatNumber(number) {
number = String(number).split('.');
return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') +
(number[1] ? '.' + number[1] : '');
}
/**
* Checks if an object has the specified key as a direct property.
*
* @static
* @memberOf Benchmark
* @param {Object} object The object to check.
* @param {String} key The key to check for.
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
*/
function hasKey() {
// lazy define for worst case fallback (not as accurate)
hasKey = function(object, key) {
var parent = object != null && (object.constructor || Object).prototype;
return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
};
// for modern browsers
if (isClassOf(hasOwnProperty, 'Function')) {
hasKey = function(object, key) {
return object != null && hasOwnProperty.call(object, key);
};
}
// for Safari 2
else if ({}.__proto__ == Object.prototype) {
hasKey = function(object, key) {
var result = false;
if (object != null) {
object = Object(object);
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
}
return result;
};
}
return hasKey.apply(this, arguments);
}
/**
* A generic `Array#indexOf` like method.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {Mixed} value The value to search for.
* @param {Number} [fromIndex=0] The index to start searching from.
* @returns {Number} The index of the matched value or `-1`.
*/
function indexOf(array, value, fromIndex) {
var index = toInteger(fromIndex),
length = (array = Object(array)).length >>> 0;
index = (index < 0 ? max(0, length + index) : index) - 1;
while (++index < length) {
if (index in array && value === array[index]) {
return index;
}
}
return -1;
}
/**
* Modify a string by replacing named tokens with matching object property values.
*
* @static
* @memberOf Benchmark
* @param {String} string The string to modify.
* @param {Object} object The template object.
* @returns {String} The modified string.
*/
function interpolate(string, object) {
forOwn(object, function(value, key) {
// escape regexp special characters in `key`
string = string.replace(RegExp('#\\{' + key.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '\\}', 'g'), value);
});
return string;
}
/**
* Invokes a method on all items in an array.
*
* @static
* @memberOf Benchmark
* @param {Array} benches Array of benchmarks to iterate over.
* @param {String|Object} name The name of the method to invoke OR options object.
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
* @returns {Array} A new array of values returned from each method invoked.
* @example
*
* // invoke `reset` on all benchmarks
* Benchmark.invoke(benches, 'reset');
*
* // invoke `emit` with arguments
* Benchmark.invoke(benches, 'emit', 'complete', listener);
*
* // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks
* Benchmark.invoke(benches, {
*
* // invoke the `run` method
* 'name': 'run',
*
* // pass a single argument
* 'args': true,
*
* // treat as queue, removing benchmarks from front of `benches` until empty
* 'queued': true,
*
* // called before any benchmarks have been invoked.
* 'onStart': onStart,
*
* // called between invoking benchmarks
* 'onCycle': onCycle,
*
* // called after all benchmarks have been invoked.
* 'onComplete': onComplete
* });
*/
function invoke(benches, name) {
var args,
bench,
queued,
index = -1,
eventProps = { 'currentTarget': benches },
options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop },
result = map(benches, function(bench) { return bench; });
/**
* Invokes the method of the current object and if synchronous, fetches the next.
*/
function execute() {
var listeners,
async = isAsync(bench);
if (async) {
// use `getNext` as the first listener
bench.on('complete', getNext);
listeners = bench.events.complete;
listeners.splice(0, 0, listeners.pop());
}
// execute method
result[index] = isClassOf(bench && bench[name], 'Function') ? bench[name].apply(bench, args) : undefined;
// if synchronous return true until finished
return !async && getNext();
}
/**
* Fetches the next bench or executes `onComplete` callback.
*/
function getNext(event) {
var cycleEvent,
last = bench,
async = isAsync(last);
if (async) {
last.off('complete', getNext);
last.emit('complete');
}
// emit "cycle" event
eventProps.type = 'cycle';
eventProps.target = last;
cycleEvent = Event(eventProps);
options.onCycle.call(benches, cycleEvent);
// choose next benchmark if not exiting early
if (!cycleEvent.aborted && raiseIndex() !== false) {
bench = queued ? benches[0] : result[index];
if (isAsync(bench)) {
delay(bench, execute);
}
else if (async) {
// resume execution if previously asynchronous but now synchronous
while (execute()) { }
}
else {
// continue synchronous execution
return true;
}
} else {
// emit "complete" event
eventProps.type = 'complete';
options.onComplete.call(benches, Event(eventProps));
}
// When used as a listener `event.aborted = true` will cancel the rest of
// the "complete" listeners because they were already called above and when
// used as part of `getNext` the `return false` will exit the execution while-loop.
if (event) {
event.aborted = true;
} else {
return false;
}
}
/**
* Checks if invoking `Benchmark#run` with asynchronous cycles.
*/
function isAsync(object) {
// avoid using `instanceof` here because of IE memory leak issues with host objects
var async = args[0] && args[0].async;
return Object(object).constructor == Benchmark && name == 'run' &&
((async == null ? object.options.async : async) && support.timeout || object.defer);
}
/**
* Raises `index` to the next defined index or returns `false`.
*/
function raiseIndex() {
var length = result.length;
if (queued) {
// if queued remove the previous bench and subsequent skipped non-entries
do {
++index > 0 && shift.call(benches);
} while ((length = benches.length) && !('0' in benches));
}
else {
while (++index < length && !(index in result)) { }
}
// if we reached the last index then return `false`
return (queued ? length : index < length) ? index : (index = false);
}
// juggle arguments
if (isClassOf(name, 'String')) {
// 2 arguments (array, name)
args = slice.call(arguments, 2);
} else {
// 2 arguments (array, options)
options = extend(options, name);
name = options.name;
args = isClassOf(args = 'args' in options ? options.args : [], 'Array') ? args : [args];
queued = options.queued;
}
// start iterating over the array
if (raiseIndex() !== false) {
// emit "start" event
bench = result[index];
eventProps.type = 'start';
eventProps.target = bench;
options.onStart.call(benches, Event(eventProps));
// end early if the suite was aborted in an "onStart" listener
if (benches.aborted && benches.constructor == Suite && name == 'run') {
// emit "cycle" event
eventProps.type = 'cycle';
options.onCycle.call(benches, Event(eventProps));
// emit "complete" event
eventProps.type = 'complete';
options.onComplete.call(benches, Event(eventProps));
}
// else start
else {
if (isAsync(bench)) {
delay(bench, execute);
} else {
while (execute()) { }
}
}
}
return result;
}
/**
* Creates a string of joined array values or object key-value pairs.
*
* @static
* @memberOf Benchmark
* @param {Array|Object} object The object to operate on.
* @param {String} [separator1=','] The separator used between key-value pairs.
* @param {String} [separator2=': '] The separator used between keys and values.
* @returns {String} The joined result.
*/
function join(object, separator1, separator2) {
var result = [],
length = (object = Object(object)).length,
arrayLike = length === length >>> 0;
separator2 || (separator2 = ': ');
each(object, function(value, key) {
result.push(arrayLike ? value : key + separator2 + value);
});
return result.join(separator1 || ',');
}
/**
* A generic `Array#map` like method.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @param {Mixed} thisArg The `this` binding for the callback.
* @returns {Array} A new array of values returned by the callback.
*/
function map(array, callback, thisArg) {
return reduce(array, function(result, value, index) {
result[index] = callback.call(thisArg, value, index, array);
return result;
}, Array(Object(array).length >>> 0));
}
/**
* Retrieves the value of a specified property from all items in an array.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {String} property The property to pluck.
* @returns {Array} A new array of property values.
*/
function pluck(array, property) {
return map(array, function(object) {
return object == null ? undefined : object[property];
});
}
/**
* A generic `Array#reduce` like method.
*
* @static
* @memberOf Benchmark
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @param {Mixed} accumulator Initial value of the accumulator.
* @returns {Mixed} The accumulator.
*/
function reduce(array, callback, accumulator) {
var noaccum = arguments.length < 3;
forEach(array, function(value, index) {
accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, array);
});
return accumulator;
}
/*--------------------------------------------------------------------------*/
/**
* Aborts all benchmarks in the suite.
*
* @name abort
* @memberOf Benchmark.Suite
* @returns {Object} The suite instance.
*/
function abortSuite() {
var event,
me = this,
resetting = calledBy.resetSuite;
if (me.running) {
event = Event('abort');
me.emit(event);
if (!event.cancelled || resetting) {
// avoid infinite recursion
calledBy.abortSuite = true;
me.reset();
delete calledBy.abortSuite;
if (!resetting) {
me.aborted = true;
invoke(me, 'abort');
}
}
}
return me;
}
/**
* Adds a test to the benchmark suite.
*
* @memberOf Benchmark.Suite
* @param {String} name A name to identify the benchmark.
* @param {Function|String} fn The test to benchmark.
* @param {Object} [options={}] Options object.
* @returns {Object} The benchmark instance.
* @example
*
* // basic usage
* suite.add(fn);
*
* // or using a name first
* suite.add('foo', fn);
*
* // or with options
* suite.add('foo', fn, {
* 'onCycle': onCycle,
* 'onComplete': onComplete
* });
*
* // or name and options
* suite.add('foo', {
* 'fn': fn,
* 'onCycle': onCycle,
* 'onComplete': onComplete
* });
*
* // or options only
* suite.add({
* 'name': 'foo',
* 'fn': fn,
* 'onCycle': onCycle,
* 'onComplete': onComplete
* });
*/
function add(name, fn, options) {
var me = this,
bench = Benchmark(name, fn, options),
event = Event({ 'type': 'add', 'target': bench });
if (me.emit(event), !event.cancelled) {
me.push(bench);
}
return me;
}
/**
* Creates a new suite with cloned benchmarks.
*
* @name clone
* @memberOf Benchmark.Suite
* @param {Object} options Options object to overwrite cloned options.
* @returns {Object} The new suite instance.
*/
function cloneSuite(options) {
var me = this,
result = new me.constructor(extend({}, me.options, options));
// copy own properties
forOwn(me, function(value, key) {
if (!hasKey(result, key)) {
result[key] = value && isClassOf(value.clone, 'Function')
? value.clone()
: deepClone(value);
}
});
return result;
}
/**
* An `Array#filter` like method.
*
* @name filter
* @memberOf Benchmark.Suite
* @param {Function|String} callback The function/alias called per iteration.
* @returns {Object} A new suite of benchmarks that passed callback filter.
*/
function filterSuite(callback) {
var me = this,
result = new me.constructor;
result.push.apply(result, filter(me, callback));
return result;
}
/**
* Resets all benchmarks in the suite.
*
* @name reset
* @memberOf Benchmark.Suite
* @returns {Object} The suite instance.
*/
function resetSuite() {
var event,
me = this,
aborting = calledBy.abortSuite;
if (me.running && !aborting) {
// no worries, `resetSuite()` is called within `abortSuite()`
calledBy.resetSuite = true;
me.abort();
delete calledBy.resetSuite;
}
// reset if the state has changed
else if ((me.aborted || me.running) &&
(me.emit(event = Event('reset')), !event.cancelled)) {
me.running = false;
if (!aborting) {
invoke(me, 'reset');
}
}
return me;
}
/**
* Runs the suite.
*
* @name run
* @memberOf Benchmark.Suite
* @param {Object} [options={}] Options object.
* @returns {Object} The suite instance.
* @example
*
* // basic usage
* suite.run();
*
* // or with options
* suite.run({ 'async': true, 'queued': true });
*/
function runSuite(options) {
var me = this;
me.reset();
me.running = true;
options || (options = {});
invoke(me, {
'name': 'run',
'args': options,
'queued': options.queued,
'onStart': function(event) {
me.emit(event);
},
'onCycle': function(event) {
var bench = event.target;
if (bench.error) {
me.emit({ 'type': 'error', 'target': bench });
}
me.emit(event);
event.aborted = me.aborted;
},
'onComplete': function(event) {
me.running = false;
me.emit(event);
}
});
return me;
}
/*--------------------------------------------------------------------------*/
/**
* Executes all registered listeners of the specified event type.
*
* @memberOf Benchmark, Benchmark.Suite
* @param {String|Object} type The event type or object.
* @returns {Mixed} Returns the return value of the last listener executed.
*/
function emit(type) {
var listeners,
me = this,
event = Event(type),
events = me.events,
args = (arguments[0] = event, arguments);
event.currentTarget || (event.currentTarget = me);
event.target || (event.target = me);
delete event.result;
if (events && (listeners = hasKey(events, event.type) && events[event.type])) {
forEach(listeners.slice(), function(listener) {
if ((event.result = listener.apply(me, args)) === false) {
event.cancelled = true;
}
return !event.aborted;
});
}
return event.result;
}
/**
* Returns an array of event listeners for a given type that can be manipulated
* to add or remove listeners.
*
* @memberOf Benchmark, Benchmark.Suite
* @param {String} type The event type.
* @returns {Array} The listeners array.
*/
function listeners(type) {
var me = this,
events = me.events || (me.events = {});
return hasKey(events, type) ? events[type] : (events[type] = []);
}
/**
* Unregisters a listener for the specified event type(s),
* or unregisters all listeners for the specified event type(s),
* or unregisters all listeners for all event types.
*
* @memberOf Benchmark, Benchmark.Suite
* @param {String} [type] The event type.
* @param {Function} [listener] The function to unregister.
* @returns {Object} The benchmark instance.
* @example
*
* // unregister a listener for an event type
* bench.off('cycle', listener);
*
* // unregister a listener for multiple event types
* bench.off('start cycle', listener);
*
* // unregister all listeners for an event type
* bench.off('cycle');
*
* // unregister all listeners for multiple event types
* bench.off('start cycle complete');
*
* // unregister all listeners for all event types
* bench.off();
*/
function off(type, listener) {
var me = this,
events = me.events;
events && each(type ? type.split(' ') : events, function(listeners, type) {
var index;
if (typeof listeners == 'string') {
type = listeners;
listeners = hasKey(events, type) && events[type];
}
if (listeners) {
if (listener) {
index = indexOf(listeners, listener);
if (index > -1) {
listeners.splice(index, 1);
}
} else {
listeners.length = 0;
}
}
});
return me;
}
/**
* Registers a listener for the specified event type(s).
*
* @memberOf Benchmark, Benchmark.Suite
* @param {String} type The event type.
* @param {Function} listener The function to register.
* @returns {Object} The benchmark instance.
* @example
*
* // register a listener for an event type
* bench.on('cycle', listener);
*
* // register a listener for multiple event types
* bench.on('start cycle', listener);
*/
function on(type, listener) {
var me = this,
events = me.events || (me.events = {});
forEach(type.split(' '), function(type) {
(hasKey(events, type)
? events[type]
: (events[type] = [])
).push(listener);
});
return me;
}
/*--------------------------------------------------------------------------*/
/**
* Aborts the benchmark without recording times.
*
* @memberOf Benchmark
* @returns {Object} The benchmark instance.
*/
function abort() {
var event,
me = this,
resetting = calledBy.reset;
if (me.running) {
event = Event('abort');
me.emit(event);
if (!event.cancelled || resetting) {
// avoid infinite recursion
calledBy.abort = true;
me.reset();
delete calledBy.abort;
if (support.timeout) {
clearTimeout(me._timerId);
delete me._timerId;
}
if (!resetting) {
me.aborted = true;
me.running = false;
}
}
}
return me;
}
/**
* Creates a new benchmark using the same test and options.
*
* @memberOf Benchmark
* @param {Object} options Options object to overwrite cloned options.
* @returns {Object} The new benchmark instance.
* @example
*
* var bizarro = bench.clone({
* 'name': 'doppelganger'
* });
*/
function clone(options) {
var me = this,
result = new me.constructor(extend({}, me, options));
// correct the `options` object
result.options = extend({}, me.options, options);
// copy own custom properties
forOwn(me, function(value, key) {
if (!hasKey(result, key)) {
result[key] = deepClone(value);
}
});
return result;
}
/**
* Determines if a benchmark is faster than another.
*
* @memberOf Benchmark
* @param {Object} other The benchmark to compare.
* @returns {Number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate.
*/
function compare(other) {
var critical,
zStat,
me = this,
sample1 = me.stats.sample,
sample2 = other.stats.sample,
size1 = sample1.length,
size2 = sample2.length,
maxSize = max(size1, size2),
minSize = min(size1, size2),
u1 = getU(sample1, sample2),
u2 = getU(sample2, sample1),
u = min(u1, u2);
function getScore(xA, sampleB) {
return reduce(sampleB, function(total, xB) {
return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5);
}, 0);
}
function getU(sampleA, sampleB) {
return reduce(sampleA, function(total, xA) {
return total + getScore(xA, sampleB);
}, 0);
}
function getZ(u) {
return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12);
}
// exit early if comparing the same benchmark
if (me == other) {
return 0;
}
// reject the null hyphothesis the two samples come from the
// same population (i.e. have the same median) if...
if (size1 + size2 > 30) {
// ...the z-stat is greater than 1.96 or less than -1.96
// http://www.statisticslectures.com/topics/mannwhitneyu/
zStat = getZ(u);
return abs(zStat) > 1.96 ? (zStat > 0 ? -1 : 1) : 0;
}
// ...the U value is less than or equal the critical U value
// http://www.geoib.com/mann-whitney-u-test.html
critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3];
return u <= critical ? (u == u1 ? 1 : -1) : 0;
}
/**
* Reset properties and abort if running.
*
* @memberOf Benchmark
* @returns {Object} The benchmark instance.
*/
function reset() {
var data,
event,
me = this,
index = 0,
changes = { 'length': 0 },
queue = { 'length': 0 };
if (me.running && !calledBy.abort) {
// no worries, `reset()` is called within `abort()`
calledBy.reset = true;
me.abort();
delete calledBy.reset;
}
else {
// a non-recursive solution to check if properties have changed
// http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4
data = { 'destination': me, 'source': extend({}, me.constructor.prototype, me.options) };
do {
forOwn(data.source, function(value, key) {
var changed,
destination = data.destination,
currValue = destination[key];
if (value && typeof value == 'object') {
if (isClassOf(value, 'Array')) {
// check if an array value has changed to a non-array value
if (!isClassOf(currValue, 'Array')) {
changed = currValue = [];
}
// or has changed its length
if (currValue.length != value.length) {
changed = currValue = currValue.slice(0, value.length);
currValue.length = value.length;
}
}
// check if an object has changed to a non-object value
else if (!currValue || typeof currValue != 'object') {
changed = currValue = {};
}
// register a changed object
if (changed) {
changes[changes.length++] = { 'destination': destination, 'key': key, 'value': currValue };
}
queue[queue.length++] = { 'destination': currValue, 'source': value };
}
// register a changed primitive
else if (value !== currValue && !(value == null || isClassOf(value, 'Function'))) {
changes[changes.length++] = { 'destination': destination, 'key': key, 'value': value };
}
});
}
while ((data = queue[index++]));
// if changed emit the `reset` event and if it isn't cancelled reset the benchmark
if (changes.length && (me.emit(event = Event('reset')), !event.cancelled)) {
forEach(changes, function(data) {
data.destination[data.key] = data.value;
});
}
}
return me;
}
/**
* Displays relevant benchmark information when coerced to a string.
*
* @name toString
* @memberOf Benchmark
* @returns {String} A string representation of the benchmark instance.
*/
function toStringBench() {
var me = this,
error = me.error,
hz = me.hz,
id = me.id,
stats = me.stats,
size = stats.sample.length,
pm = support.java ? '+/-' : '\xb1',
result = me.name || (isNaN(id) ? id : '<Test #' + id + '>');
if (error) {
result += ': ' + join(error);
} else {
result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm +
stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)';
}
return result;
}
/*--------------------------------------------------------------------------*/
/**
* Clocks the time taken to execute a test per cycle (secs).
*
* @private
* @param {Object} bench The benchmark instance.
* @returns {Number} The time taken.
*/
function clock() {
var applet,
options = Benchmark.options,
template = { 'begin': 's$=new n$', 'end': 'r$=(new n$-s$)/1e3', 'uid': uid },
timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }];
// lazy define for hi-res timers
clock = function(clone) {
var deferred;
if (clone instanceof Deferred) {
deferred = clone;
clone = deferred.benchmark;
}
var bench = clone._original,
fn = bench.fn,
fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '',
stringable = isStringable(fn);
var source = {
'setup': getSource(bench.setup, preprocess('m$.setup()')),
'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')),
'fnArg': fnArg,
'teardown': getSource(bench.teardown, preprocess('m$.teardown()'))
};
var count = bench.count = clone.count,
decompilable = support.decompilation || stringable,
id = bench.id,
isEmpty = !(source.fn || stringable),
name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id),
ns = timer.ns,
result = 0;
// init `minTime` if needed
clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime);
// repair nanosecond timer
// (some Chrome builds erase the `ns` variable after millions of executions)
if (applet) {
try {
ns.nanoTime();
} catch(e) {
// use non-element to avoid issues with libs that augment them
ns = timer.ns = new applet.Packages.nano;
}
}
// Compile in setup/teardown functions and the test loop.
// Create a new compiled test, instead of using the cached `bench.compiled`,
// to avoid potential engine optimizations enabled over the life of the test.
var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate(
preprocess(deferred
? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' +
// when `deferred.cycles` is `0` then...
'if(!d$.cycles){' +
// set `deferred.fn`
'd$.fn=function(){var #{fnArg}=d$;if(typeof f$=="function"){try{#{fn}\n}catch(e$){f$(d$)}}else{#{fn}\n}};' +
// set `deferred.teardown`
'd$.teardown=function(){d$.cycles=0;if(typeof td$=="function"){try{#{teardown}\n}catch(e$){td$()}}else{#{teardown}\n}};' +
// execute the benchmark's `setup`
'if(typeof su$=="function"){try{#{setup}\n}catch(e$){su$()}}else{#{setup}\n};' +
// start timer
't$.start(d$);' +
// execute `deferred.fn` and return a dummy object
'}d$.fn();return{}'
: 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\n#{begin};' +
'while(i$--){#{fn}\n}#{end};#{teardown}\nreturn{elapsed:r$,uid:"#{uid}"}'),
source
));
try {
if (isEmpty) {
// Firefox may remove dead code from Function#toString results
// http://bugzil.la/536085
throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.');
}
else if (!deferred) {
// pretest to determine if compiled code is exits early, usually by a
// rogue `return` statement, by checking for a return object with the uid
bench.count = 1;
compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled;
bench.count = count;
}
} catch(e) {
compiled = null;
clone.error = e || new Error(String(e));
bench.count = count;
}
// fallback when a test exits early or errors during pretest
if (decompilable && !compiled && !deferred && !isEmpty) {
compiled = createFunction(preprocess('t$'), interpolate(
preprocess(
(clone.error && !stringable
? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count'
: 'function f$(){#{fn}\n}var r$,s$,m$=this,i$=m$.count'
) +
',n$=t$.ns;#{setup}\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' +
'delete m$.f$;#{teardown}\nreturn{elapsed:r$}'
),
source
));
try {
// pretest one more time to check for errors
bench.count = 1;
compiled.call(bench, timer);
bench.compiled = compiled;
bench.count = count;
delete clone.error;
}
catch(e) {
bench.count = count;
if (clone.error) {
compiled = null;
} else {
bench.compiled = compiled;
clone.error = e || new Error(String(e));
}
}
}
// assign `compiled` to `clone` before calling in case a deferred benchmark
// immediately calls `deferred.resolve()`
clone.compiled = compiled;
// if no errors run the full test loop
if (!clone.error) {
result = compiled.call(deferred || bench, timer).elapsed;
}
return result;
};
/*------------------------------------------------------------------------*/
/**
* Gets the current timer's minimum resolution (secs).
*/
function getRes(unit) {
var measured,
begin,
count = 30,
divisor = 1e3,
ns = timer.ns,
sample = [];
// get average smallest measurable time
while (count--) {
if (unit == 'us') {
divisor = 1e6;
if (ns.stop) {
ns.start();
while (!(measured = ns.microseconds())) { }
} else if (ns[perfName]) {
divisor = 1e3;
measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns);
} else {
begin = ns();
while (!(measured = ns() - begin)) { }
}
}
else if (unit == 'ns') {
divisor = 1e9;
if (ns.nanoTime) {
begin = ns.nanoTime();
while (!(measured = ns.nanoTime() - begin)) { }
} else {
begin = (begin = ns())[0] + (begin[1] / divisor);
while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) { }
divisor = 1;
}
}
else {
begin = new ns;
while (!(measured = new ns - begin)) { }
}
// check for broken timers (nanoTime may have issues)
// http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/
if (measured > 0) {
sample.push(measured);
} else {
sample.push(Infinity);
break;
}
}
// convert to seconds
return getMean(sample) / divisor;
}
/**
* Replaces all occurrences of `$` with a unique number and
* template tokens with content.
*/
function preprocess(code) {
return interpolate(code, template).replace(/\$/g, /\d+/.exec(uid));
}
/*------------------------------------------------------------------------*/
// detect nanosecond support from a Java applet
each(doc && doc.applets || [], function(element) {
return !(timer.ns = applet = 'nanoTime' in element && element);
});
// check type in case Safari returns an object instead of a number
try {
if (typeof timer.ns.nanoTime() == 'number') {
timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });
}
} catch(e) { }
// detect Chrome's microsecond timer:
// enable benchmarking via the --enable-benchmarking command
// line switch in at least Chrome 7 to use chrome.Interval
try {
if ((timer.ns = new (window.chrome || window.chromium).Interval)) {
timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
}
} catch(e) { }
// detect `performance.now` microsecond resolution timer
if ((timer.ns = perfName && perfObject)) {
timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
}
// detect Node's nanosecond resolution timer available in Node >= 0.8
if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') {
timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });
}
// detect Wade Simmons' Node microtime module
if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') {
timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });
}
// pick timer with highest resolution
timer = reduce(timers, function(timer, other) {
return other.res < timer.res ? other : timer;
});
// remove unused applet
if (timer.unit != 'ns' && applet) {
applet = destroyElement(applet);
}
// error if there are no working timers
if (timer.res == Infinity) {
throw new Error('Benchmark.js was unable to find a working timer.');
}
// use API of chosen timer
if (timer.unit == 'ns') {
if (timer.ns.nanoTime) {
extend(template, {
'begin': 's$=n$.nanoTime()',
'end': 'r$=(n$.nanoTime()-s$)/1e9'
});
} else {
extend(template, {
'begin': 's$=n$()',
'end': 'r$=n$(s$);r$=r$[0]+(r$[1]/1e9)'
});
}
}
else if (timer.unit == 'us') {
if (timer.ns.stop) {
extend(template, {
'begin': 's$=n$.start()',
'end': 'r$=n$.microseconds()/1e6'
});
} else if (perfName) {
extend(template, {
'begin': 's$=n$.' + perfName + '()',
'end': 'r$=(n$.' + perfName + '()-s$)/1e3'
});
} else {
extend(template, {
'begin': 's$=n$()',
'end': 'r$=(n$()-s$)/1e6'
});
}
}
// define `timer` methods
timer.start = createFunction(preprocess('o$'),
preprocess('var n$=this.ns,#{begin};o$.elapsed=0;o$.timeStamp=s$'));
timer.stop = createFunction(preprocess('o$'),
preprocess('var n$=this.ns,s$=o$.timeStamp,#{end};o$.elapsed=r$'));
// resolve time span required to achieve a percent uncertainty of at most 1%
// http://spiff.rit.edu/classes/phys273/uncert/uncert.html
options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05));
return clock.apply(null, arguments);
}
/*--------------------------------------------------------------------------*/
/**
* Computes stats on benchmark results.
*
* @private
* @param {Object} bench The benchmark instance.
* @param {Object} options The options object.
*/
function compute(bench, options) {
options || (options = {});
var async = options.async,
elapsed = 0,
initCount = bench.initCount,
minSamples = bench.minSamples,
queue = [],
sample = bench.stats.sample;
/**
* Adds a clone to the queue.
*/
function enqueue() {
queue.push(bench.clone({
'_original': bench,
'events': {
'abort': [update],
'cycle': [update],
'error': [update],
'start': [update]
}
}));
}
/**
* Updates the clone/original benchmarks to keep their data in sync.
*/
function update(event) {
var clone = this,
type = event.type;
if (bench.running) {
if (type == 'start') {
// Note: `clone.minTime` prop is inited in `clock()`
clone.count = bench.initCount;
}
else {
if (type == 'error') {
bench.error = clone.error;
}
if (type == 'abort') {
bench.abort();
bench.emit('cycle');
} else {
event.currentTarget = event.target = bench;
bench.emit(event);
}
}
} else if (bench.aborted) {
// clear abort listeners to avoid triggering bench's abort/cycle again
clone.events.abort.length = 0;
clone.abort();
}
}
/**
* Determines if more clones should be queued or if cycling should stop.
*/
function evaluate(event) {
var critical,
df,
mean,
moe,
rme,
sd,
sem,
variance,
clone = event.target,
done = bench.aborted,
now = +new Date,
size = sample.push(clone.times.period),
maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime,
times = bench.times,
varOf = function(sum, x) { return sum + pow(x - mean, 2); };
// exit early for aborted or unclockable tests
if (done || clone.hz == Infinity) {
maxedOut = !(size = sample.length = queue.length = 0);
}
if (!done) {
// sample mean (estimate of the population mean)
mean = getMean(sample);
// sample variance (estimate of the population variance)
variance = reduce(sample, varOf, 0) / (size - 1) || 0;
// sample standard deviation (estimate of the population standard deviation)
sd = sqrt(variance);
// standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean)
sem = sd / sqrt(size);
// degrees of freedom
df = size - 1;
// critical value
critical = tTable[Math.round(df) || 1] || tTable.infinity;
// margin of error
moe = sem * critical;
// relative margin of error
rme = (moe / mean) * 100 || 0;
extend(bench.stats, {
'deviation': sd,
'mean': mean,
'moe': moe,
'rme': rme,
'sem': sem,
'variance': variance
});
// Abort the cycle loop when the minimum sample size has been collected
// and the elapsed time exceeds the maximum time allowed per benchmark.
// We don't count cycle delays toward the max time because delays may be
// increased by browsers that clamp timeouts for inactive tabs.
// https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs
if (maxedOut) {
// reset the `initCount` in case the benchmark is rerun
bench.initCount = initCount;
bench.running = false;
done = true;
times.elapsed = (now - times.timeStamp) / 1e3;
}
if (bench.hz != Infinity) {
bench.hz = 1 / mean;
times.cycle = mean * bench.count;
times.period = mean;
}
}
// if time permits, increase sample size to reduce the margin of error
if (queue.length < 2 && !maxedOut) {
enqueue();
}
// abort the invoke cycle when done
event.aborted = done;
}
// init queue and begin
enqueue();
invoke(queue, {
'name': 'run',
'args': { 'async': async },
'queued': true,
'onCycle': evaluate,
'onComplete': function() { bench.emit('complete'); }
});
}
/*--------------------------------------------------------------------------*/
/**
* Cycles a benchmark until a run `count` can be established.
*
* @private
* @param {Object} clone The cloned benchmark instance.
* @param {Object} options The options object.
*/
function cycle(clone, options) {
options || (options = {});
var deferred;
if (clone instanceof Deferred) {
deferred = clone;
clone = clone.benchmark;
}
var clocked,
cycles,
divisor,
event,
minTime,
period,
async = options.async,
bench = clone._original,
count = clone.count,
times = clone.times;
// continue, if not aborted between cycles
if (clone.running) {
// `minTime` is set to `Benchmark.options.minTime` in `clock()`
cycles = ++clone.cycles;
clocked = deferred ? deferred.elapsed : clock(clone);
minTime = clone.minTime;
if (cycles > bench.cycles) {
bench.cycles = cycles;
}
if (clone.error) {
event = Event('error');
event.message = clone.error;
clone.emit(event);
if (!event.cancelled) {
clone.abort();
}
}
}
// continue, if not errored
if (clone.running) {
// time taken to complete last test cycle
bench.times.cycle = times.cycle = clocked;
// seconds per operation
period = bench.times.period = times.period = clocked / count;
// ops per second
bench.hz = clone.hz = 1 / period;
// avoid working our way up to this next time
bench.initCount = clone.initCount = count;
// do we need to do another cycle?
clone.running = clocked < minTime;
if (clone.running) {
// tests may clock at `0` when `initCount` is a small number,
// to avoid that we set its count to something a bit higher
if (!clocked && (divisor = divisors[clone.cycles]) != null) {
count = floor(4e6 / divisor);
}
// calculate how many more iterations it will take to achive the `minTime`
if (count <= clone.count) {
count += Math.ceil((minTime - clocked) / period);
}
clone.running = count != Infinity;
}
}
// should we exit early?
event = Event('cycle');
clone.emit(event);
if (event.aborted) {
clone.abort();
}
// figure out what to do next
if (clone.running) {
// start a new cycle
clone.count = count;
if (deferred) {
clone.compiled.call(deferred, timer);
} else if (async) {
delay(clone, function() { cycle(clone, options); });
} else {
cycle(clone);
}
}
else {
// fix TraceMonkey bug associated with clock fallbacks
// http://bugzil.la/509069
if (support.browser) {
runScript(uid + '=1;delete ' + uid);
}
// done
clone.emit('complete');
}
}
/*--------------------------------------------------------------------------*/
/**
* Runs the benchmark.
*
* @memberOf Benchmark
* @param {Object} [options={}] Options object.
* @returns {Object} The benchmark instance.
* @example
*
* // basic usage
* bench.run();
*
* // or with options
* bench.run({ 'async': true });
*/
function run(options) {
var me = this,
event = Event('start');
// set `running` to `false` so `reset()` won't call `abort()`
me.running = false;
me.reset();
me.running = true;
me.count = me.initCount;
me.times.timeStamp = +new Date;
me.emit(event);
if (!event.cancelled) {
options = { 'async': ((options = options && options.async) == null ? me.async : options) && support.timeout };
// for clones created within `compute()`
if (me._original) {
if (me.defer) {
Deferred(me);
} else {
cycle(me, options);
}
}
// for original benchmarks
else {
compute(me, options);
}
}
return me;
}
/*--------------------------------------------------------------------------*/
// Firefox 1 erroneously defines variable and argument names of functions on
// the function itself as non-configurable properties with `undefined` values.
// The bugginess continues as the `Benchmark` constructor has an argument
// named `options` and Firefox 1 will not assign a value to `Benchmark.options`,
// making it non-writable in the process, unless it is the first property
// assigned by for-in loop of `extend()`.
extend(Benchmark, {
/**
* The default options copied by benchmark instances.
*
* @static
* @memberOf Benchmark
* @type Object
*/
'options': {
/**
* A flag to indicate that benchmark cycles will execute asynchronously
* by default.
*
* @memberOf Benchmark.options
* @type Boolean
*/
'async': false,
/**
* A flag to indicate that the benchmark clock is deferred.
*
* @memberOf Benchmark.options
* @type Boolean
*/
'defer': false,
/**
* The delay between test cycles (secs).
* @memberOf Benchmark.options
* @type Number
*/
'delay': 0.005,
/**
* Displayed by Benchmark#toString when a `name` is not available
* (auto-generated if absent).
*
* @memberOf Benchmark.options
* @type String
*/
'id': undefined,
/**
* The default number of times to execute a test on a benchmark's first cycle.
*
* @memberOf Benchmark.options
* @type Number
*/
'initCount': 1,
/**
* The maximum time a benchmark is allowed to run before finishing (secs).
*
* Note: Cycle delays aren't counted toward the maximum time.
*
* @memberOf Benchmark.options
* @type Number
*/
'maxTime': 5,
/**
* The minimum sample size required to perform statistical analysis.
*
* @memberOf Benchmark.options
* @type Number
*/
'minSamples': 5,
/**
* The time needed to reduce the percent uncertainty of measurement to 1% (secs).
*
* @memberOf Benchmark.options
* @type Number
*/
'minTime': 0,
/**
* The name of the benchmark.
*
* @memberOf Benchmark.options
* @type String
*/
'name': undefined,
/**
* An event listener called when the benchmark is aborted.
*
* @memberOf Benchmark.options
* @type Function
*/
'onAbort': undefined,
/**
* An event listener called when the benchmark completes running.
*
* @memberOf Benchmark.options
* @type Function
*/
'onComplete': undefined,
/**
* An event listener called after each run cycle.
*
* @memberOf Benchmark.options
* @type Function
*/
'onCycle': undefined,
/**
* An event listener called when a test errors.
*
* @memberOf Benchmark.options
* @type Function
*/
'onError': undefined,
/**
* An event listener called when the benchmark is reset.
*
* @memberOf Benchmark.options
* @type Function
*/
'onReset': undefined,
/**
* An event listener called when the benchmark starts running.
*
* @memberOf Benchmark.options
* @type Function
*/
'onStart': undefined
},
/**
* Platform object with properties describing things like browser name,
* version, and operating system.
*
* @static
* @memberOf Benchmark
* @type Object
*/
'platform': req('platform') || window.platform || {
/**
* The platform description.
*
* @memberOf Benchmark.platform
* @type String
*/
'description': window.navigator && navigator.userAgent || null,
/**
* The name of the browser layout engine.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'layout': null,
/**
* The name of the product hosting the browser.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'product': null,
/**
* The name of the browser/environment.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'name': null,
/**
* The name of the product's manufacturer.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'manufacturer': null,
/**
* The name of the operating system.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'os': null,
/**
* The alpha/beta release indicator.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'prerelease': null,
/**
* The browser/environment version.
*
* @memberOf Benchmark.platform
* @type String|Null
*/
'version': null,
/**
* Return platform description when the platform object is coerced to a string.
*
* @memberOf Benchmark.platform
* @type Function
* @returns {String} The platform description.
*/
'toString': function() {
return this.description || '';
}
},
/**
* The semantic version number.
*
* @static
* @memberOf Benchmark
* @type String
*/
'version': '1.0.0',
// an object of environment/feature detection flags
'support': support,
// clone objects
'deepClone': deepClone,
// iteration utility
'each': each,
// augment objects
'extend': extend,
// generic Array#filter
'filter': filter,
// generic Array#forEach
'forEach': forEach,
// generic own property iteration utility
'forOwn': forOwn,
// converts a number to a comma-separated string
'formatNumber': formatNumber,
// generic Object#hasOwnProperty
// (trigger hasKey's lazy define before assigning it to Benchmark)
'hasKey': (hasKey(Benchmark, ''), hasKey),
// generic Array#indexOf
'indexOf': indexOf,
// template utility
'interpolate': interpolate,
// invokes a method on each item in an array
'invoke': invoke,
// generic Array#join for arrays and objects
'join': join,
// generic Array#map
'map': map,
// retrieves a property value from each item in an array
'pluck': pluck,
// generic Array#reduce
'reduce': reduce
});
/*--------------------------------------------------------------------------*/
extend(Benchmark.prototype, {
/**
* The number of times a test was executed.
*
* @memberOf Benchmark
* @type Number
*/
'count': 0,
/**
* The number of cycles performed while benchmarking.
*
* @memberOf Benchmark
* @type Number
*/
'cycles': 0,
/**
* The number of executions per second.
*
* @memberOf Benchmark
* @type Number
*/
'hz': 0,
/**
* The compiled test function.
*
* @memberOf Benchmark
* @type Function|String
*/
'compiled': undefined,
/**
* The error object if the test failed.
*
* @memberOf Benchmark
* @type Object
*/
'error': undefined,
/**
* The test to benchmark.
*
* @memberOf Benchmark
* @type Function|String
*/
'fn': undefined,
/**
* A flag to indicate if the benchmark is aborted.
*
* @memberOf Benchmark
* @type Boolean
*/
'aborted': false,
/**
* A flag to indicate if the benchmark is running.
*
* @memberOf Benchmark
* @type Boolean
*/
'running': false,
/**
* Compiled into the test and executed immediately **before** the test loop.
*
* @memberOf Benchmark
* @type Function|String
* @example
*
* // basic usage
* var bench = Benchmark({
* 'setup': function() {
* var c = this.count,
* element = document.getElementById('container');
* while (c--) {
* element.appendChild(document.createElement('div'));
* }
* },
* 'fn': function() {
* element.removeChild(element.lastChild);
* }
* });
*
* // compiles to something like:
* var c = this.count,
* element = document.getElementById('container');
* while (c--) {
* element.appendChild(document.createElement('div'));
* }
* var start = new Date;
* while (count--) {
* element.removeChild(element.lastChild);
* }
* var end = new Date - start;
*
* // or using strings
* var bench = Benchmark({
* 'setup': '\
* var a = 0;\n\
* (function() {\n\
* (function() {\n\
* (function() {',
* 'fn': 'a += 1;',
* 'teardown': '\
* }())\n\
* }())\n\
* }())'
* });
*
* // compiles to something like:
* var a = 0;
* (function() {
* (function() {
* (function() {
* var start = new Date;
* while (count--) {
* a += 1;
* }
* var end = new Date - start;
* }())
* }())
* }())
*/
'setup': noop,
/**
* Compiled into the test and executed immediately **after** the test loop.
*
* @memberOf Benchmark
* @type Function|String
*/
'teardown': noop,
/**
* An object of stats including mean, margin or error, and standard deviation.
*
* @memberOf Benchmark
* @type Object
*/
'stats': {
/**
* The margin of error.
*
* @memberOf Benchmark#stats
* @type Number
*/
'moe': 0,
/**
* The relative margin of error (expressed as a percentage of the mean).
*
* @memberOf Benchmark#stats
* @type Number
*/
'rme': 0,
/**
* The standard error of the mean.
*
* @memberOf Benchmark#stats
* @type Number
*/
'sem': 0,
/**
* The sample standard deviation.
*
* @memberOf Benchmark#stats
* @type Number
*/
'deviation': 0,
/**
* The sample arithmetic mean.
*
* @memberOf Benchmark#stats
* @type Number
*/
'mean': 0,
/**
* The array of sampled periods.
*
* @memberOf Benchmark#stats
* @type Array
*/
'sample': [],
/**
* The sample variance.
*
* @memberOf Benchmark#stats
* @type Number
*/
'variance': 0
},
/**
* An object of timing data including cycle, elapsed, period, start, and stop.
*
* @memberOf Benchmark
* @type Object
*/
'times': {
/**
* The time taken to complete the last cycle (secs).
*
* @memberOf Benchmark#times
* @type Number
*/
'cycle': 0,
/**
* The time taken to complete the benchmark (secs).
*
* @memberOf Benchmark#times
* @type Number
*/
'elapsed': 0,
/**
* The time taken to execute the test once (secs).
*
* @memberOf Benchmark#times
* @type Number
*/
'period': 0,
/**
* A timestamp of when the benchmark started (ms).
*
* @memberOf Benchmark#times
* @type Number
*/
'timeStamp': 0
},
// aborts benchmark (does not record times)
'abort': abort,
// creates a new benchmark using the same test and options
'clone': clone,
// compares benchmark's hertz with another
'compare': compare,
// executes listeners
'emit': emit,
// get listeners
'listeners': listeners,
// unregister listeners
'off': off,
// register listeners
'on': on,
// reset benchmark properties
'reset': reset,
// runs the benchmark
'run': run,
// pretty print benchmark info
'toString': toStringBench
});
/*--------------------------------------------------------------------------*/
extend(Deferred.prototype, {
/**
* The deferred benchmark instance.
*
* @memberOf Benchmark.Deferred
* @type Object
*/
'benchmark': null,
/**
* The number of deferred cycles performed while benchmarking.
*
* @memberOf Benchmark.Deferred
* @type Number
*/
'cycles': 0,
/**
* The time taken to complete the deferred benchmark (secs).
*
* @memberOf Benchmark.Deferred
* @type Number
*/
'elapsed': 0,
/**
* A timestamp of when the deferred benchmark started (ms).
*
* @memberOf Benchmark.Deferred
* @type Number
*/
'timeStamp': 0,
// cycles/completes the deferred benchmark
'resolve': resolve
});
/*--------------------------------------------------------------------------*/
extend(Event.prototype, {
/**
* A flag to indicate if the emitters listener iteration is aborted.
*
* @memberOf Benchmark.Event
* @type Boolean
*/
'aborted': false,
/**
* A flag to indicate if the default action is cancelled.
*
* @memberOf Benchmark.Event
* @type Boolean
*/
'cancelled': false,
/**
* The object whose listeners are currently being processed.
*
* @memberOf Benchmark.Event
* @type Object
*/
'currentTarget': undefined,
/**
* The return value of the last executed listener.
*
* @memberOf Benchmark.Event
* @type Mixed
*/
'result': undefined,
/**
* The object to which the event was originally emitted.
*
* @memberOf Benchmark.Event
* @type Object
*/
'target': undefined,
/**
* A timestamp of when the event was created (ms).
*
* @memberOf Benchmark.Event
* @type Number
*/
'timeStamp': 0,
/**
* The event type.
*
* @memberOf Benchmark.Event
* @type String
*/
'type': ''
});
/*--------------------------------------------------------------------------*/
/**
* The default options copied by suite instances.
*
* @static
* @memberOf Benchmark.Suite
* @type Object
*/
Suite.options = {
/**
* The name of the suite.
*
* @memberOf Benchmark.Suite.options
* @type String
*/
'name': undefined
};
/*--------------------------------------------------------------------------*/
extend(Suite.prototype, {
/**
* The number of benchmarks in the suite.
*
* @memberOf Benchmark.Suite
* @type Number
*/
'length': 0,
/**
* A flag to indicate if the suite is aborted.
*
* @memberOf Benchmark.Suite
* @type Boolean
*/
'aborted': false,
/**
* A flag to indicate if the suite is running.
*
* @memberOf Benchmark.Suite
* @type Boolean
*/
'running': false,
/**
* An `Array#forEach` like method.
* Callbacks may terminate the loop by explicitly returning `false`.
*
* @memberOf Benchmark.Suite
* @param {Function} callback The function called per iteration.
* @returns {Object} The suite iterated over.
*/
'forEach': methodize(forEach),
/**
* An `Array#indexOf` like method.
*
* @memberOf Benchmark.Suite
* @param {Mixed} value The value to search for.
* @returns {Number} The index of the matched value or `-1`.
*/
'indexOf': methodize(indexOf),
/**
* Invokes a method on all benchmarks in the suite.
*
* @memberOf Benchmark.Suite
* @param {String|Object} name The name of the method to invoke OR options object.
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
* @returns {Array} A new array of values returned from each method invoked.
*/
'invoke': methodize(invoke),
/**
* Converts the suite of benchmarks to a string.
*
* @memberOf Benchmark.Suite
* @param {String} [separator=','] A string to separate each element of the array.
* @returns {String} The string.
*/
'join': [].join,
/**
* An `Array#map` like method.
*
* @memberOf Benchmark.Suite
* @param {Function} callback The function called per iteration.
* @returns {Array} A new array of values returned by the callback.
*/
'map': methodize(map),
/**
* Retrieves the value of a specified property from all benchmarks in the suite.
*
* @memberOf Benchmark.Suite
* @param {String} property The property to pluck.
* @returns {Array} A new array of property values.
*/
'pluck': methodize(pluck),
/**
* Removes the last benchmark from the suite and returns it.
*
* @memberOf Benchmark.Suite
* @returns {Mixed} The removed benchmark.
*/
'pop': [].pop,
/**
* Appends benchmarks to the suite.
*
* @memberOf Benchmark.Suite
* @returns {Number} The suite's new length.
*/
'push': [].push,
/**
* Sorts the benchmarks of the suite.
*
* @memberOf Benchmark.Suite
* @param {Function} [compareFn=null] A function that defines the sort order.
* @returns {Object} The sorted suite.
*/
'sort': [].sort,
/**
* An `Array#reduce` like method.
*
* @memberOf Benchmark.Suite
* @param {Function} callback The function called per iteration.
* @param {Mixed} accumulator Initial value of the accumulator.
* @returns {Mixed} The accumulator.
*/
'reduce': methodize(reduce),
// aborts all benchmarks in the suite
'abort': abortSuite,
// adds a benchmark to the suite
'add': add,
// creates a new suite with cloned benchmarks
'clone': cloneSuite,
// executes listeners of a specified type
'emit': emit,
// creates a new suite of filtered benchmarks
'filter': filterSuite,
// get listeners
'listeners': listeners,
// unregister listeners
'off': off,
// register listeners
'on': on,
// resets all benchmarks in the suite
'reset': resetSuite,
// runs all benchmarks in the suite
'run': runSuite,
// array methods
'concat': concat,
'reverse': reverse,
'shift': shift,
'slice': slice,
'splice': splice,
'unshift': unshift
});
/*--------------------------------------------------------------------------*/
// expose Deferred, Event and Suite
extend(Benchmark, {
'Deferred': Deferred,
'Event': Event,
'Suite': Suite
});
// expose Benchmark
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// define as an anonymous module so, through path mapping, it can be aliased
define(function() {
return Benchmark;
});
}
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports) {
// in Node.js or RingoJS v0.8.0+
if (typeof module == 'object' && module && module.exports == freeExports) {
(module.exports = Benchmark).Benchmark = Benchmark;
}
// in Narwhal or RingoJS v0.7.0-
else {
freeExports.Benchmark = Benchmark;
}
}
// in a browser or Rhino
else {
// use square bracket notation so Closure Compiler won't munge `Benchmark`
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
window['Benchmark'] = Benchmark;
}
// trigger clock's lazy define early to avoid a security error
if (support.air) {
clock({ '_original': { 'fn': noop, 'count': 1, 'options': {} } });
}
}(this));
var BenchClass = function() {
this.suites = [];
this.THREE = window.THREE ;
window.THREE = undefined;
Benchmark.options.maxTime = 1.0;
return this;
}
BenchClass.prototype.isTHREELoaded = function() {
return _.isObject(this.THREE);
}
BenchClass.prototype.newSuite = function(name) {
var s = new Benchmark.Suite(name);
this.suites.push(s);
return s;
}
BenchClass.prototype.display = function() {
for (x of this.suites) {
var s = new SuiteUI(x);
s.render();
}
}
BenchClass.prototype.warning = function(message) {
console.error(message);
}
var SuiteUI = function(suite) {
this.suite = suite;
this.isRunning = false;
return this;
}
SuiteUI.prototype.render = function() {
var n = document.importNode(this.suiteTemplate, true);
this.elem = n.querySelector("article");
this.results = n.querySelector(".results");
this.title = n.querySelector("h2");
this.runButton = n.querySelector("h3");
this.title.innerText = this.suite.name;
this.runButton.onclick = this.run.bind(this);
this.section.appendChild(n);
}
SuiteUI.prototype.run = function() {
this.runButton.click = _.noop;
this.runButton.innerText = "Running..."
this.suite.on("complete", this.complete.bind(this));
this.suite.run({
async: true
});
}
SuiteUI.prototype.complete = function() {
this.runButton.style.display = "none";
this.results.style.display = "block";
var f = _.orderBy(this.suite, ["hz"], ["desc"]);
for (var i = 0; i < f.length; i++) {
var x = f[i];
var n = document.importNode(this.suiteTestTemplate, true);
n.querySelector(".name").innerText = x.name;
n.querySelector(".ops").innerText = x.hz.toFixed();
n.querySelector(".desv").innerText = x.stats.rme.toFixed(2);
this.results.appendChild(n);
}
}
var Bench = new BenchClass();
window.addEventListener('load', function() {
SuiteUI.prototype.suiteTemplate = document.querySelector("#suite").content;
SuiteUI.prototype.suiteTestTemplate = document.querySelector("#suite-test").content;
SuiteUI.prototype.section = document.querySelector("section");
Bench.display();
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ThreeJS Benchmark Tests - Using Files in /src</title>
</head>
<body>
During this Benchmarking test the browser will be unresponsive.<br/><br/>
Benchmark output is written to the JavaScript console. To access the JavaScript console presss Ctrl-Shift-J.
<script src="benchmark-1.0.0.js"></script>
<!-- add ThreeJS sources to test below -->
<script src="../../src/Three.js"></script>
<script src="../../src/math/Vector2.js"></script>
<script src="../../src/math/Vector3.js"></script>
<script src="../../src/math/Vector4.js"></script>
<script src="../../src/math/Box2.js"></script>
<script src="../../src/math/Box3.js"></script>
<script src="../../src/math/Plane.js"></script>
<script src="../../src/math/Ray.js"></script>
<script src="../../src/math/Sphere.js"></script>
<script src="../../src/math/Triangle.js"></script>
<script src="../../src/math/Matrix3.js"></script>
<script src="../../src/math/Matrix4.js"></script>
<script src="../../src/math/Color.js"></script>
<!-- add class-based unit tests below -->
<script src="core/Float32Array.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ThreeJS Benchmark Tests - Using Files in /src</title>
</head>
<body>
During this Benchmarking test the browser will be unresponsive.<br/><br/>
Benchmark output is written to the JavaScript console. To access the JavaScript console presss Ctrl-Shift-J.
<script src="benchmark-1.0.0.js"></script>
<!-- add class-based unit tests below -->
<script src="core/Vector3Components.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ThreeJS Benchmark Tests - Using Files in /src</title>
</head>
<body>
During this Benchmarking test the browser will be unresponsive.<br/><br/>
Benchmark output is written to the JavaScript console. To access the JavaScript console presss Ctrl-Shift-J.
<script src="benchmark-1.0.0.js"></script>
<!-- add class-based unit tests below -->
<script src="core/Vector3Length.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ThreeJS Benchmark Tests - Using Files in /src</title>
</head>
<body>
During this Benchmarking test the browser will be unresponsive.<br/><br/>
Benchmark output is written to the JavaScript console. To access the JavaScript console presss Ctrl-Shift-J.
<script src="benchmark-1.0.0.js"></script>
<!-- add class-based unit tests below -->
<script src="core/Vector3Storage.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ThreeJS Benchmark Tests - Using Files in /src</title>
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:700" rel="stylesheet" type="text/css">
<link href="normalize.css" rel="stylesheet" type="text/css">
<link href="style.css" rel="stylesheet" type="text/css">
<script src="../../build/three.min.js"></script>
<script src="vendor/lodash.min.js"></script>
<script src="vendor/benchmark-2.1.0.min.js"></script>
<script src="benchmark.js"></script>
<script src="core/Vector3Components.js"></script>
<script src="core/Vector3Storage.js"></script>
<script src="core/Vector3Length.js"></script>
<script src="core/Float32Array.js"></script>
</head>
<body>
<header>
<h1>Three JS Benchmarks Suite</h1>
</header>
<section>
</section>
<template id="suite">
<article>
<header>
<h2></h2>
<h3>Start</h3>
</header>
<div class="results">
<div class"head">
<p class="name">Name</p>
<p class="ops">Ops / Sec</p>
<p class="desv">±</p>
</div>
</div>
</article>
</template>
<template id="suite-test">
<div>
<p class="name"></p>
<p class="ops"></p>
<p class="desv"></p>
</div>
</template>
</body>
</html>
(function() {
var input = new Float32Array( 10000 * 3 ); var input = new Float32Array(10000 * 3);
var output = new Float32Array( 10000 * 3 ); var output = new Float32Array(10000 * 3);
for( var j = 0, jl = input.length; j < jl; j ++ ) { for (var j = 0, jl = input.length; j < jl; j++) {
input[j] = j; input[j] = j;
} }
var inputVectors = []; var inputVectors = [];
var outputVectors = []; var outputVectors = [];
for( var j = 0, jl = input.length/3; j < jl; j ++ ) { for (var j = 0, jl = input.length / 3; j < jl; j++) {
inputVectors.push( new THREE.Vector3( j*3, j*3+1, j*3+2 ) ); inputVectors.push(new THREE.Vector3(j * 3, j * 3 + 1, j * 3 + 2));
outputVectors.push( new THREE.Vector3() ); outputVectors.push(new THREE.Vector3());
} }
var suite = new Benchmark.Suite; var s = Bench.newSuite("Float 32 Arrays");
suite.add('Float32Array-Float32Array', function() { s.add('Float32Array-Float32Array', function() {
var value3 = new Float32Array( 3 ); var value3 = new Float32Array(3);
for (var i = 0, il = input.length / 3; i < il; i += 3) { for (var i = 0, il = input.length / 3; i < il; i += 3) {
value3[0] = input[i + 0]; value3[0] = input[i + 0];
value3[1] = input[i + 1]; value3[1] = input[i + 1];
value3[2] = input[i + 2]; value3[2] = input[i + 2];
value3[0] *= 1.01; value3[0] *= 1.01;
value3[1] *= 1.03; value3[1] *= 1.03;
value3[2] *= 0.98; value3[2] *= 0.98;
output[i + 0] = value3[0]; output[i + 0] = value3[0];
output[i + 1] = value3[1]; output[i + 1] = value3[1];
output[i + 2] = value3[2]; output[i + 2] = value3[2];
} }
}); });
suite.add('Float32Array-Array', function() { s.add('Float32Array-Array', function() {
var value2 = [0,0,0]; var value2 = [0, 0, 0];
for (var i = 0, il = input.length / 3; i < il; i += 3) { for (var i = 0, il = input.length / 3; i < il; i += 3) {
value2[0] = input[i + 0]; value2[0] = input[i + 0];
value2[1] = input[i + 1]; value2[1] = input[i + 1];
value2[2] = input[i + 2]; value2[2] = input[i + 2];
value2[0] *= 1.01; value2[0] *= 1.01;
value2[1] *= 1.03; value2[1] *= 1.03;
value2[2] *= 0.98; value2[2] *= 0.98;
output[i + 0] = value2[0]; output[i + 0] = value2[0];
output[i + 1] = value2[1]; output[i + 1] = value2[1];
output[i + 2] = value2[2]; output[i + 2] = value2[2];
} }
}); });
suite.add('Float32Array-Literal', function() { s.add('Float32Array-Literal', function() {
var x, y, z; var x,
for (var i = 0, il = input.length / 3; i < il; i += 3) { y,
x = input[i + 0]; z;
y = input[i + 1]; for (var i = 0, il = input.length / 3; i < il; i += 3) {
z = input[i + 2]; x = input[i + 0];
x *= 1.01; y = input[i + 1];
y *= 1.03; z = input[i + 2];
z *= 0.98; x *= 1.01;
output[i + 0] = x; y *= 1.03;
output[i + 1] = y; z *= 0.98;
output[i + 2] = z; output[i + 0] = x;
} output[i + 1] = y;
}); output[i + 2] = z;
}
});
suite.add('Float32Array-Vector3', function() { s.add('Float32Array-Vector3', function() {
var value = new THREE.Vector3(); var value = new THREE.Vector3();
for (var i = 0, il = input.length / 3; i < il; i += 3) { for (var i = 0, il = input.length / 3; i < il; i += 3) {
value.x = input[i + 0]; value.x = input[i + 0];
value.y = input[i + 1]; value.y = input[i + 1];
value.z = input[i + 2]; value.z = input[i + 2];
value.x *= 1.01; value.x *= 1.01;
value.y *= 1.03; value.y *= 1.03;
value.z *= 0.98; value.z *= 0.98;
output[i + 0] = value.x; output[i + 0] = value.x;
output[i + 1] = value.y; output[i + 1] = value.y;
output[i + 2] = value.z; output[i + 2] = value.z;
} }
}); });
suite.add('Vector3Array-Direct', function() { })();
for (var i = 0, il = inputVectors.length; i < il; i ++ ) {
outputVectors[i].copy( inputVectors[i] );
outputVectors[i].x *= 1.01;
outputVectors[i].y *= 1.03;
outputVectors[i].z *= 0.98;
}
});
suite.add('Vector3Array-Vector3', function() {
var value = new THREE.Vector3();
for (var i = 0, il = inputVectors.length; i < il; i ++ ) {
value.copy( inputVectors[i] );
value.x *= 1.01;
value.y *= 1.03;
value.z *= 0.98;
outputVectors[i].copy( value );
}
});
suite.on('cycle', function(event, bench) {
console.log(String(event.target));
});
suite.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
console.log( "Done" );
});
suite.run(true);
\ No newline at end of file
THREE = {}; (function() {
THREE.Vector3 = function ( x, y, z ) {
var s = Bench.newSuite("Vector 3 Components");
THREE = {};
THREE.Vector3 = function(x, y, z) {
this.x = x || 0; this.x = x || 0;
this.y = y || 0; this.y = y || 0;
this.z = z || 0; this.z = z || 0;
};
}; THREE.Vector3.prototype = {
THREE.Vector3.prototype = {
constructor: THREE.Vector3, constructor: THREE.Vector3,
setComponent: function(index, value) {
setComponent: function ( index, value ) { this[THREE.Vector3.__indexToName[index]] = value;
this[ THREE.Vector3.__indexToName[ index ] ] = value;
}, },
getComponent: function ( index ) { getComponent: function(index) {
return this[THREE.Vector3.__indexToName[index]];
return this[ THREE.Vector3.__indexToName[ index ] ];
},
setComponent2: function ( index, value ) {
switch( index ) {
case 0: this.x = value; break;
case 1: this.y = value; break;
case 2: this.z = value; break;
default: throw new Error( "index is out of range: " + index );
}
}, },
getComponent2: function ( index ) { setComponent2: function(index, value) {
switch (index) {
switch( index ) { case 0:
this.x = value;
case 0: return this.x; break;
case 1: return this.y; case 1:
case 2: return this.z; this.y = value;
default: throw new Error( "index is out of range: " + index ); break;
case 2:
} this.z = value;
break;
default:
throw new Error("index is out of range: " + index);
}
}, },
getComponent2: function(index) {
getComponent3: function ( index ) { switch (index) {
case 0:
if ( index === 0 ) return this.x; return this.x;
if ( index === 1 ) return this.y; case 1:
if ( index === 2 ) return this.z; return this.y;
case 2:
throw new Error( "index is out of range: " + index ); return this.z;
default:
throw new Error("index is out of range: " + index);
}
}, },
getComponent4: function ( index ) {
if ( index === 0 ) return this.x; getComponent3: function(index) {
else if ( index === 1 ) return this.y; if (index === 0) return this.x;
else if ( index === 2 ) return this.z; if (index === 1) return this.y;
else throw new Error( "index is out of range: " + index ); if (index === 2) return this.z;
throw new Error("index is out of range: " + index);
},
getComponent4: function(index) {
if (index === 0) return this.x;else if (index === 1) return this.y;else if (index === 2) return this.z;
else
throw new Error("index is out of range: " + index);
} }
}; };
THREE.Vector3.__indexToName = {
0: 'x',
1: 'y',
2: 'z'
};
var a = []; THREE.Vector3.__indexToName = {
0: 'x',
1: 'y',
2: 'z'
};
for ( var i = 0; i < 100000; i ++ ) { var a = [];
for (var i = 0; i < 100000; i++) {
a[ i ] = new THREE.Vector3( i * 0.01, i * 2, i * -1.3 ); a[i] = new THREE.Vector3(i * 0.01, i * 2, i * -1.3);
}
}
var suite = new Benchmark.Suite;
suite.add('IndexToName', function() {
s.add('IndexToName', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].getComponent(i % 3);
result += a[i].getComponent( i % 3 );
} }
});
}); s.add('SwitchStatement', function() {
suite.add('SwitchStatement', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].getComponent2(i % 3);
result += a[i].getComponent2( i % 3 );
} }
});
}); s.add('IfAndReturnSeries', function() {
suite.add('IfAndReturnSeries', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].getComponent3(i % 3);
result += a[i].getComponent3( i % 3 );
} }
});
}); s.add('IfReturnElseSeries', function() {
suite.add('IfReturnElseSeries', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].getComponent4(i % 3);
result += a[i].getComponent4( i % 3 );
} }
});
}); })();
suite.on('cycle', function(event, bench) {
console.log(String(event.target));
});
suite.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
console.log( "Done" );
});
suite.run(true);
\ No newline at end of file
THREE = {}; (function() {
THREE.Vector3 = function ( x, y, z ) { var THREE = {};
THREE.Vector3 = function(x, y, z) {
this.x = x || 0; this.x = x || 0;
this.y = y || 0; this.y = y || 0;
this.z = z || 0; this.z = z || 0;
}; };
THREE.Vector3.prototype = {
THREE.Vector3.prototype = {
constructor: THREE.Vector3, constructor: THREE.Vector3,
lengthSq: function() {
lengthSq: function () { return this.x * this.x + this.y * this.y + this.z * this.z;
return this.x * this.x + this.y * this.y + this.z * this.z;
}, },
length: function () { length: function() {
return Math.sqrt(this.lengthSq());
return Math.sqrt( this.lengthSq() );
}, },
length2: function () { length2: function() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
} }
};
var a = []; };
for ( var i = 0; i < 100000; i ++ ) { var a = [];
for (var i = 0; i < 100000; i++) {
a[ i ] = new THREE.Vector3( i * 0.01, i * 2, i * -1.3 ); a[i] = new THREE.Vector3(i * 0.01, i * 2, i * -1.3);
}
}
var suite = new Benchmark.Suite; var suite = Bench.newSuite("Vector 3 Length");
suite.add('NoCallTest', function() {
suite.add('NoCallTest', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { var v = a[i];
var v = a[i]; result += Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
result += Math.sqrt( v.x * v.x + v.y * v.y + v.z * v.z );
} }
});
}); suite.add('InlineCallTest', function() {
suite.add('InlineCallTest', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].length2();
result += a[ i ].length2();
} }
});
}); suite.add('FunctionCallTest', function() {
suite.add('FunctionCallTest', function() {
var result = 0; var result = 0;
for (var i = 0; i < 100000; i++) {
for ( var i = 0; i < 100000; i ++ ) { result += a[i].length();
result += a[ i ].length();
} }
}); });
suite.on('cycle', function(event, bench) {
console.log(String(event.target));
});
suite.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
console.log( "Done" );
});
suite.run(true); })();
\ No newline at end of file
THREE = {}; (function() {
THREE.Vector3 = function ( x, y, z ) { THREE = {};
THREE.Vector3 = function(x, y, z) {
this.x = x || 0; this.x = x || 0;
this.y = y || 0; this.y = y || 0;
this.z = z || 0; this.z = z || 0;
}; };
THREE.Vector3.prototype = { THREE.Vector3.prototype = {
constructor: THREE.Vector3, constructor: THREE.Vector3,
length: function () {
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); length: function() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
} }
};
THREE.Vector3X = function ( x, y, z ) { };
var elements = this.elements = new Float32Array( 3 ); THREE.Vector3X = function(x, y, z) {
var elements = this.elements = new Float32Array(3);
elements[0] = x || 0; elements[0] = x || 0;
elements[1] = y || 1; elements[1] = y || 1;
elements[2] = z || 2; elements[2] = z || 2;
}; };
THREE.Vector3X.prototype = { THREE.Vector3X.prototype = {
constructor: THREE.Vector3X, constructor: THREE.Vector3X,
length: function () {
return Math.sqrt( this.elements[0] * this.elements[0] + this.elements[1] * this.elements[1] + this.elements[2] * this.elements[2] ); length: function() {
return Math.sqrt(this.elements[0] * this.elements[0] + this.elements[1] * this.elements[1] + this.elements[2] * this.elements[2]);
} }
};
};
THREE.Vector3Y = function ( x, y, z ) {
this.elements = [ x || 0, y || 1, z || 2 ]; THREE.Vector3Y = function(x, y, z) {
}; this.elements = [x || 0, y || 1, z || 2];
THREE.Vector3Y.prototype = { };
THREE.Vector3Y.prototype = {
constructor: THREE.Vector3Y, constructor: THREE.Vector3Y,
length: function () {
return Math.sqrt( this.elements[0] * this.elements[0] + this.elements[1] * this.elements[1] + this.elements[2] * this.elements[2] ); length: function() {
return Math.sqrt(this.elements[0] * this.elements[0] + this.elements[1] * this.elements[1] + this.elements[2] * this.elements[2]);
} }
}; };
var suite = new Benchmark.Suite; var suite = Bench.newSuite("Vector 3 Storage");
suite.add('Vector3-Set', function() { suite.add('Vector3-Set', function() {
var array = []; var array = [];
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = new THREE.Vector3( i, i, i ); var v = new THREE.Vector3(i, i, i);
array.push( v ); array.push(v);
} }
var result = 0; var result = 0;
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = array[i]; var v = array[i];
result += v.length(); result += v.length();
} }
}); });
suite.add('Vector3-Float32Array', function() { suite.add('Vector3-Float32Array', function() {
var array = []; var array = [];
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = new THREE.Vector3X( i, i, i ); var v = new THREE.Vector3X(i, i, i);
array.push( v ); array.push(v);
} }
var result = 0; var result = 0;
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = array[i]; var v = array[i];
result += v.length(); result += v.length();
} }
}); });
suite.add('Vector3-Array', function() { suite.add('Vector3-Array', function() {
var array = []; var array = [];
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = new THREE.Vector3Y( i, i, i ); var v = new THREE.Vector3Y(i, i, i);
array.push( v ); array.push(v);
} }
var result = 0; var result = 0;
for ( var i = 0; i < 100000; i ++ ) { for (var i = 0; i < 100000; i++) {
var v = array[i]; var v = array[i];
result += v.length(); result += v.length();
} }
}); });
suite.on('cycle', function(event, bench) {
console.log(String(event.target));
});
suite.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
console.log( "Done" );
});
suite.run(true); })();
\ No newline at end of file
/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Change the default font family in all browsers (opinionated).
* 2. Prevent adjustments of font size after orientation changes in IE and iOS.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove the margin in all browsers (opinionated).
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Add the correct display in IE 9-.
* 1. Add the correct display in Edge, IE, and Firefox.
* 2. Add the correct display in IE.
*/
article,
aside,
details, /* 1 */
figcaption,
figure,
footer,
header,
main, /* 2 */
menu,
nav,
section,
summary { /* 1 */
display: block;
}
/**
* Add the correct display in IE 9-.
*/
audio,
canvas,
progress,
video {
display: inline-block;
}
/**
* Add the correct display in iOS 4-7.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Add the correct display in IE 10-.
* 1. Add the correct display in IE.
*/
template, /* 1 */
[hidden] {
display: none;
}
/* Links
========================================================================== */
/**
* 1. Remove the gray background on active links in IE 10.
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
*/
a {
background-color: transparent; /* 1 */
-webkit-text-decoration-skip: objects; /* 2 */
}
/**
* Remove the outline on focused links when they are also active or hovered
* in all browsers (opinionated).
*/
a:active,
a:hover {
outline-width: 0;
}
/* Text-level semantics
========================================================================== */
/**
* 1. Remove the bottom border in Firefox 39-.
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
*/
b,
strong {
font-weight: inherit;
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* Add the correct font style in Android 4.3-.
*/
dfn {
font-style: italic;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Add the correct background and color in IE 9-.
*/
mark {
background-color: #ff0;
color: #000;
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10-.
*/
img {
border-style: none;
}
/**
* Hide the overflow in IE.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct margin in IE 8.
*/
figure {
margin: 1em 40px;
}
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/* Forms
========================================================================== */
/**
* 1. Change font properties to `inherit` in all browsers (opinionated).
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
select,
textarea {
font: inherit; /* 1 */
margin: 0; /* 2 */
}
/**
* Restore the font weight unset by the previous rule.
*/
optgroup {
font-weight: bold;
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
* controls in Android 4.
* 2. Correct the inability to style clickable types in iOS and Safari.
*/
button,
html [type="button"], /* 1 */
[type="reset"],
[type="submit"] {
-webkit-appearance: button; /* 2 */
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Change the border, margin, and padding in all browsers (opinionated).
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Remove the default vertical scrollbar in IE.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10-.
* 2. Remove the padding in IE 10-.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
*/
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Correct the text style of placeholders in Chrome, Edge, and Safari.
*/
::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
html{
background-color: #FFE0F7;
}
body{
font-family: 'Source Sans Pro', sans-serif;
}
header{
}
header h1{
color: #6F0752;
border-bottom: 4px solid #A23183;
margin: 10px;
}
article{
border: 2px solid #B8509B;
margin:5px 10px;
border-radius:10px;
}
article header{
display: flex;
}
article h2{
color:#6F0752;
font-size:1.2em;
margin:10px;
flex-grow:1;
}
article h3{
color:#6F0752;
font-size:1.0em;
margin:7px;
text-align:right;
flex-grow:0;
background:transparent;
border: 1px solid #B8509B;
border-radius:3px;
padding:3px 7px;
cursor:pointer;
}
article h3:hover{
color:#6F0752;
font-size:1.0em;
margin:7px;
text-align:right;
flex-grow:0;
background:transparent;
border: 1px solid #B8509B;
border-radius:3px;
padding:3px 7px;
}
article .results{
margin:0 10px 10px;
display:none;
}
article .results > div{
display: flex;
}
article .results > div p{
color:#6F0752;
flex-grow: 1;
margin: 0 3px;
font-size:0.8em;
}
.results > div:nth-child(1){
margin-bottom: 3px;
border-bottom: 1px solid #A23183;
}
.results > div:nth-child(2){
background: #6F0752;
}
.results > div:nth-child(2) p{
color: #FFE0F7;
}
.results .name{
flex-basis:60%;
}
.results .time{
flex-basis:20%;
}
.results .desv{
flex-basis:20%;
}
(function(){"use strict";function e(t){function s(e,n,t){var r=this;return r instanceof s?(Y.isPlainObject(e)?t=e:Y.isFunction(e)?(t=n,n=e):Y.isPlainObject(n)?(t=n,n=null,r.name=e):r.name=e,_(r,t),r.id||(r.id=++c),null==r.fn&&(r.fn=n),r.stats=ke(r.stats),void(r.times=ke(r.times))):new s(e,n,t)}function a(e){var n=this;return n instanceof a?(n.benchmark=e,void Q(n)):new a(e)}function l(e){var n=this;return e instanceof l?e:n instanceof l?Y.assign(n,{timeStamp:Y.now()},"string"==typeof e?{type:e}:e):new l(e)}function y(e,n){var t=this;return t instanceof y?(Y.isPlainObject(e)?n=e:t.name=e,void _(t,n)):new y(e,n)}function v(){return v=function(e,n){var t,r=o?o.amd:s,i=$e+"createFunction";return k((o?"define.amd.":"Benchmark.")+i+"=function("+e+"){"+n+"}"),t=r[i],delete r[i],t},v=Ce.browser&&(v("",'return"'+$e+'"')||Y.noop)()==$e?v:ne,v.apply(null,arguments)}function b(e,n){e._timerId=Y.delay(n,1e3*e.delay)}function w(e){Se.appendChild(e),Se.innerHTML=""}function T(e){return!Y.has(e,"toString")&&(/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(e)||0)[1]||""}function S(e){return Y.reduce(e,function(e,n){return e+n})/e.length||0}function $(e){var n="";return C(e)?n=oe(e):Ce.decompilation&&(n=Y.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(e),1)),n=(n||"").replace(/^\s+|\s+$/g,""),/^(?:\/\*+[\w\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(n)?"":n}function x(e,n){if(null==e)return!1;var t=typeof e[n];return!(f.test(t)||"object"==t&&!e[n])}function C(e){return Y.isString(e)||Y.has(e,"toString")&&Y.isFunction(e.toString)}function j(e){try{var n=i&&u(e)}catch(t){}return n||null}function k(e){var n=o?define.amd:s,t=be.createElement("script"),r=be.getElementsByTagName("script")[0],i=r.parentNode,a=$e+"runScript",u="("+(o?"define.amd.":"Benchmark.")+a+"||function(){})();";try{t.appendChild(be.createTextNode(u+e)),n[a]=function(){w(t)}}catch(c){i=i.cloneNode(!1),r=null,t.text=e}i.insertBefore(t,r),delete n[a]}function _(e,n){n=e.options=Y.assign({},ke(e.constructor.options),ke(n)),Y.forOwn(n,function(n,t){null!=n&&(/^on[A-Z]/.test(t)?Y.each(t.split(" "),function(t){e.on(t.slice(2).toLowerCase(),n)}):Y.has(e,t)||(e[t]=ke(n)))})}function O(){var e=this,n=e.benchmark,r=n._original;r.aborted?(e.teardown(),n.running=!1,V(e)):++e.cycles<n.count?n.compiled.call(e,t,je):(je.stop(e),e.teardown(),b(n,function(){V(e)}))}function A(e,n){if("successful"===n)n=function(e){return e.cycles&&Y.isFinite(e.hz)&&!e.error};else if("fastest"===n||"slowest"===n){var t=A(e,"successful").sort(function(e,t){return e=e.stats,t=t.stats,(e.mean+e.moe>t.mean+t.moe?1:-1)*("fastest"===n?1:-1)});return Y.filter(t,function(e){return 0==t[0].compare(e)})}return Y.filter(e,n)}function E(e){return e=oe(e).split("."),e[0].replace(/(?=(?:\d{3})+$)(?!\b)/g,",")+(e[1]?"."+e[1]:"")}function F(e,t){function r(){var e,r=i(c);return r&&(c.on("complete",o),e=c.events.complete,e.splice(0,0,e.pop())),h[p]=Y.isFunction(c&&c[t])?c[t].apply(c,u):n,!r&&o()}function o(n){var t,s=c,u=i(s);if(u&&(s.off("complete",o),s.emit("complete")),m.type="cycle",m.target=s,t=l(m),d.onCycle.call(e,t),t.aborted||a()===!1)m.type="complete",d.onComplete.call(e,l(m));else if(c=f?e[0]:h[p],i(c))b(c,r);else{if(!u)return!0;for(;r(););}return n?void(n.aborted=!0):!1}function i(e){var n=u[0]&&u[0].async;return"run"==t&&e instanceof s&&((null==n?e.options.async:n)&&Ce.timeout||e.defer)}function a(){return p++,f&&p>0&&de.call(e),(f?e.length:p<h.length)?p:p=!1}var u,c,f,p=-1,m={currentTarget:e},d={onStart:Y.noop,onCycle:Y.noop,onComplete:Y.noop},h=Y.toArray(e);if(Y.isString(t)?u=he.call(arguments,2):(d=Y.assign(d,t),t=d.name,u=Y.isArray(u="args"in d?d.args:[])?u:[u],f=d.queued),a()!==!1)if(c=h[p],m.type="start",m.target=c,d.onStart.call(e,l(m)),"run"==t&&e instanceof y&&e.aborted)m.type="cycle",d.onCycle.call(e,l(m)),m.type="complete",d.onComplete.call(e,l(m));else if(i(c))b(c,r);else for(;r(););return h}function B(e,n,t){var r=[],o=(e=re(e)).length,i=o===o>>>0;return t||(t=": "),Y.each(e,function(e,n){r.push(i?e:n+t+e)}),r.join(n||",")}function z(){var e,n=this,t=xe.resetSuite;return n.running&&(e=l("abort"),n.emit(e),(!e.cancelled||t)&&(xe.abortSuite=!0,n.reset(),delete xe.abortSuite,t||(n.aborted=!0,F(n,"abort")))),n}function q(e,n,t){var r=this,o=new s(e,n,t),i=l({type:"add",target:o});return r.emit(i),i.cancelled||r.push(o),r}function N(e){var n=this,t=new n.constructor(Y.assign({},n.options,e));return Y.forOwn(n,function(e,n){Y.has(t,n)||(t[n]=e&&Y.isFunction(e.clone)?e.clone():ke(e))}),t}function I(e){var n=this,t=new n.constructor(n.options);return t.push.apply(t,A(n,e)),t}function D(){var e,n=this,t=xe.abortSuite;return n.running&&!t?(xe.resetSuite=!0,n.abort(),delete xe.resetSuite):!n.aborted&&!n.running||(n.emit(e=l("reset")),e.cancelled)||(n.aborted=n.running=!1,t||F(n,"reset")),n}function P(e){var n=this;return n.reset(),n.running=!0,e||(e={}),F(n,{name:"run",args:e,queued:e.queued,onStart:function(e){n.emit(e)},onCycle:function(e){var t=e.target;t.error&&n.emit({type:"error",target:t}),n.emit(e),e.aborted=n.aborted},onComplete:function(e){n.running=!1,n.emit(e)}}),n}function M(e){var n,t=this,r=l(e),o=t.events,i=(arguments[0]=r,arguments);return r.currentTarget||(r.currentTarget=t),r.target||(r.target=t),delete r.result,o&&(n=Y.has(o,r.type)&&o[r.type])&&Y.each(n.slice(),function(e){return(r.result=e.apply(t,i))===!1&&(r.cancelled=!0),!r.aborted}),r.result}function R(e){var n=this,t=n.events||(n.events={});return Y.has(t,e)?t[e]:t[e]=[]}function L(e,n){var t=this,r=t.events;return r?(Y.each(e?e.split(" "):r,function(e,t){var o;"string"==typeof e&&(t=e,e=Y.has(r,t)&&r[t]),e&&(n?(o=Y.indexOf(e,n),o>-1&&e.splice(o,1)):e.length=0)}),t):t}function W(e,n){var t=this,r=t.events||(t.events={});return Y.each(e.split(" "),function(e){(Y.has(r,e)?r[e]:r[e]=[]).push(n)}),t}function H(){var e,n=this,t=xe.reset;return n.running&&(e=l("abort"),n.emit(e),(!e.cancelled||t)&&(xe.abort=!0,n.reset(),delete xe.abort,Ce.timeout&&(ue(n._timerId),delete n._timerId),t||(n.aborted=!0,n.running=!1))),n}function Z(e){var n=this,t=new n.constructor(Y.assign({},n,e));return t.options=Y.assign({},ke(n.options),ke(e)),Y.forOwn(n,function(e,n){Y.has(t,n)||(t[n]=ke(e))}),t}function G(e){function n(e,n){return Y.reduce(n,function(n,t){return n+(t>e?0:e>t?1:.5)},0)}function t(e,t){return Y.reduce(e,function(e,r){return e+n(r,t)},0)}function r(e){return(e-c*l/2)/ge(c*l*(c+l+1)/12)}var o=this;if(o==e)return 0;var i,s,a=o.stats.sample,u=e.stats.sample,c=a.length,l=u.length,f=le(c,l),p=fe(c,l),m=t(a,u),d=t(u,a),h=fe(m,d);return c+l>30?(s=r(h),ae(s)>1.96?h==m?1:-1:0):(i=5>f||3>p?0:g[f][p-3],i>=h?h==m?1:-1:0)}function J(){var e=this;if(e.running&&!xe.abort)return xe.reset=!0,e.abort(),delete xe.reset,e;var n,t=0,r=[],o=[],i={destination:e,source:Y.assign({},ke(e.constructor.prototype),ke(e.options))};do Y.forOwn(i.source,function(e,n){var t,s=i.destination,a=s[n];"_"!=n.charAt(0)&&(e&&"object"==typeof e?(Y.isArray(e)?(Y.isArray(a)||(t=a=[]),a.length!=e.length&&(t=a=a.slice(0,e.length),a.length=e.length)):a&&"object"==typeof a||(t=a={}),t&&r.push({destination:s,key:n,value:a}),o.push({destination:a,source:e})):e===a||null==e||Y.isFunction(e)||r.push({destination:s,key:n,value:e}))});while(i=o[t++]);return r.length&&(e.emit(n=l("reset")),!n.cancelled)&&Y.each(r,function(e){e.destination[e.key]=e.value}),e}function K(){var e=this,n=e.error,t=e.hz,r=e.id,o=e.stats,i=o.sample.length,s="±",a=e.name||(Y.isNaN(r)?r:"<Test #"+r+">");return a+=n?": "+B(n):" x "+E(t.toFixed(100>t?2:0))+" ops/sec "+s+o.rme.toFixed(2)+"% ("+i+" run"+(1==i?"":"s")+" sampled)"}function Q(){function e(e,n,t,o){var s=e.fn,a=t?T(s)||"deferred":"";return i.uid=$e+p++,Y.assign(i,{setup:n?$(e.setup):r("m#.setup()"),fn:n?$(s):r("m#.fn("+a+")"),fnArg:a,teardown:n?$(e.teardown):r("m#.teardown()")}),"ns"==je.unit?Y.assign(i,{begin:r("s#=n#()"),end:r("r#=n#(s#);r#=r#[0]+(r#[1]/1e9)")}):"us"==je.unit?je.ns.stop?Y.assign(i,{begin:r("s#=n#.start()"),end:r("r#=n#.microseconds()/1e6")}):Y.assign(i,{begin:r("s#=n#()"),end:r("r#=(n#()-s#)/1e6")}):je.ns.now?Y.assign(i,{begin:r("s#=n#.now()"),end:r("r#=(n#.now()-s#)/1e3")}):Y.assign(i,{begin:r("s#=new n#().getTime()"),end:r("r#=(new n#().getTime()-s#)/1e3")}),je.start=v(r("o#"),r("var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#")),je.stop=v(r("o#"),r("var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#")),v(r("window,t#"),"var global = window, clearTimeout = global.clearTimeout, setTimeout = global.setTimeout;\n"+r(o))}function n(e){for(var n,t,r=30,o=1e3,i=je.ns,s=[];r--;){if("us"==e)if(o=1e6,i.stop)for(i.start();!(n=i.microseconds()););else for(t=i();!(n=i()-t););else if("ns"==e){for(o=1e9,t=(t=i())[0]+t[1]/o;!(n=(n=i())[0]+n[1]/o-t););o=1}else if(i.now)for(t=i.now();!(n=i.now()-t););else for(t=(new i).getTime();!(n=(new i).getTime()-t););if(!(n>0)){s.push(1/0);break}s.push(n)}return S(s)/o}function r(e){return Y.template(e.replace(/\#/g,/\d+/.exec(i.uid)))(i)}var o=s.options,i={},u=[{ns:je.ns,res:le(.0015,n("ms")),unit:"ms"}];Q=function(n){var r;n instanceof a&&(r=n,n=r.benchmark);var s=n._original,u=C(s.fn),c=s.count=n.count,l=u||Ce.decompilation&&(n.setup!==Y.noop||n.teardown!==Y.noop),f=s.id,p=s.name||("number"==typeof f?"<Test #"+f+">":f),m=0;n.minTime=s.minTime||(s.minTime=s.options.minTime=o.minTime);var d=r?'var d#=this,${fnArg}=d#,m#=d#.benchmark._original,f#=m#.fn,su#=m#.setup,td#=m#.teardown;if(!d#.cycles){d#.fn=function(){var ${fnArg}=d#;if(typeof f#=="function"){try{${fn}\n}catch(e#){f#(d#)}}else{${fn}\n}};d#.teardown=function(){d#.cycles=0;if(typeof td#=="function"){try{${teardown}\n}catch(e#){td#()}}else{${teardown}\n}};if(typeof su#=="function"){try{${setup}\n}catch(e#){su#()}}else{${setup}\n};t#.start(d#);}d#.fn();return{uid:"${uid}"}':'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};while(i#--){${fn}\n}${end};${teardown}\nreturn{elapsed:r#,uid:"${uid}"}',h=s.compiled=n.compiled=e(s,l,r,d),g=!(i.fn||u);try{if(g)throw new Error('The test "'+p+'" is empty. This may be the result of dead code removal.');r||(s.count=1,h=l&&(h.call(s,t,je)||{}).uid==i.uid&&h,s.count=c)}catch(y){h=null,n.error=y||new Error(oe(y)),s.count=c}if(!h&&!r&&!g){d=(u||l&&!n.error?"function f#(){${fn}\n}var r#,s#,m#=this,i#=m#.count":"var r#,s#,m#=this,f#=m#.fn,i#=m#.count")+",n#=t#.ns;${setup}\n${begin};m#.f#=f#;while(i#--){m#.f#()}${end};delete m#.f#;${teardown}\nreturn{elapsed:r#}",h=e(s,l,r,d);try{s.count=1,h.call(s,t,je),s.count=c,delete n.error}catch(y){s.count=c,n.error||(n.error=y||new Error(oe(y)))}}return n.error||(h=s.compiled=n.compiled=e(s,l,r,d),m=h.call(r||s,t,je).elapsed),m};try{(je.ns=new(t.chrome||t.chromium).Interval)&&u.push({ns:je.ns,res:n("us"),unit:"us"})}catch(c){}if(Te&&"function"==typeof(je.ns=Te.hrtime)&&u.push({ns:je.ns,res:n("ns"),unit:"ns"}),we&&"function"==typeof(je.ns=we.now)&&u.push({ns:je.ns,res:n("us"),unit:"us"}),je=Y.minBy(u,"res"),je.res==1/0)throw new Error("Benchmark.js was unable to find a working timer.");return o.minTime||(o.minTime=le(je.res/2/.01,.05)),Q.apply(null,arguments)}function U(e,n){function t(){c.push(e.clone({_original:e,events:{abort:[r],cycle:[r],error:[r],start:[r]}}))}function r(n){var t=this,r=n.type;e.running?"start"==r?t.count=e.initCount:("error"==r&&(e.error=t.error),"abort"==r?(e.abort(),e.emit("cycle")):(n.currentTarget=n.target=e,e.emit(n))):e.aborted&&(t.events.abort.length=0,t.abort())}function o(n){var r,o,i,f,p,m,d,g,y=n.target,v=e.aborted,b=Y.now(),w=l.push(y.times.period),T=w>=u&&(s+=b-y.times.timeStamp)/1e3>e.maxTime,$=e.times,x=function(e,n){return e+pe(n-i,2)};(v||y.hz==1/0)&&(T=!(w=l.length=c.length=0)),v||(i=S(l),g=Y.reduce(l,x,0)/(w-1)||0,m=ge(g),d=m/ge(w),o=w-1,r=h[te.round(o)||1]||h.infinity,f=d*r,p=f/i*100||0,Y.assign(e.stats,{deviation:m,mean:i,moe:f,rme:p,sem:d,variance:g}),T&&(e.initCount=a,e.running=!1,v=!0,$.elapsed=(b-$.timeStamp)/1e3),e.hz!=1/0&&(e.hz=1/i,$.cycle=i*e.count,$.period=i)),c.length<2&&!T&&t(),n.aborted=v}n||(n={});var i=n.async,s=0,a=e.initCount,u=e.minSamples,c=[],l=e.stats.sample;t(),F(c,{name:"run",args:{async:i},queued:!0,onCycle:o,onComplete:function(){e.emit("complete")}})}function V(e,n){n||(n={});var r;e instanceof a&&(r=e,e=e.benchmark);var o,i,s,u,c,f,p=n.async,m=e._original,h=e.count,g=e.times;e.running&&(i=++e.cycles,o=r?r.elapsed:Q(e),c=e.minTime,i>m.cycles&&(m.cycles=i),e.error&&(u=l("error"),u.message=e.error,e.emit(u),u.cancelled||e.abort())),e.running&&(m.times.cycle=g.cycle=o,f=m.times.period=g.period=o/h,m.hz=e.hz=1/f,m.initCount=e.initCount=h,e.running=c>o,e.running&&(o||null==(s=d[e.cycles])||(h=ce(4e6/s)),h<=e.count&&(h+=te.ceil((c-o)/f)),e.running=h!=1/0)),u=l("cycle"),e.emit(u),u.aborted&&e.abort(),e.running?(e.count=h,r?e.compiled.call(r,t,je):p?b(e,function(){V(e,n)}):V(e)):(Ce.browser&&k($e+"=1;delete "+$e),e.emit("complete"))}function X(e){var n=this,t=l("start");return n.running=!1,n.reset(),n.running=!0,n.count=n.initCount,n.times.timeStamp=Y.now(),n.emit(t),t.cancelled||(e={async:(null==(e=e&&e.async)?n.async:e)&&Ce.timeout},n._original?n.defer?a(n):V(n,e):U(n,e)),n}var Y=t&&t._||j("lodash")||r._;if(!Y)return s.runInContext=e,s;t=t?Y.defaults(r.Object(),t,Y.pick(r,m)):r;var ee=(t.Array,t.Date),ne=t.Function,te=t.Math,re=t.Object,oe=(t.RegExp,t.String),ie=[],se=re.prototype,ae=te.abs,ue=t.clearTimeout,ce=te.floor,le=(te.log,te.max),fe=te.min,pe=te.pow,me=ie.push,de=(t.setTimeout,ie.shift),he=ie.slice,ge=te.sqrt,ye=(se.toString,ie.unshift),ve=j,be=x(t,"document")&&t.document,we=ve("microtime"),Te=x(t,"process")&&t.process,Se=be&&be.createElement("div"),$e="uid"+Y.now(),xe={},Ce={};!function(){Ce.browser=be&&x(t,"navigator")&&!x(t,"phantom"),Ce.timeout=x(t,"setTimeout")&&x(t,"clearTimeout");try{Ce.decompilation="1"===ne(("return ("+function(e){return{x:""+(1+e),y:0}}+")").replace(/__cov__[^;]+;/g,""))()(0).x}catch(e){Ce.decompilation=!1}}();var je={ns:ee,start:null,stop:null},ke=Y.partial(Y.cloneDeepWith,Y,function(e){return!Y.isObject(e)||Y.isArray(e)||Y.isPlainObject(e)?n:e});return Y.assign(s,{options:{async:!1,defer:!1,delay:.005,id:n,initCount:1,maxTime:5,minSamples:5,minTime:0,name:n,onAbort:n,onComplete:n,onCycle:n,onError:n,onReset:n,onStart:n},platform:t.platform||j("platform")||{description:t.navigator&&t.navigator.userAgent||null,layout:null,product:null,name:null,manufacturer:null,os:null,prerelease:null,version:null,toString:function(){return this.description||""}},version:"2.1.0"}),Y.assign(s,{filter:A,formatNumber:E,invoke:F,join:B,runInContext:e,support:Ce}),Y.each(["each","forEach","forOwn","has","indexOf","map","reduce"],function(e){s[e]=Y[e]}),Y.assign(s.prototype,{count:0,cycles:0,hz:0,compiled:n,error:n,fn:n,aborted:!1,running:!1,setup:Y.noop,teardown:Y.noop,stats:{moe:0,rme:0,sem:0,deviation:0,mean:0,sample:[],variance:0},times:{cycle:0,elapsed:0,period:0,timeStamp:0}}),Y.assign(s.prototype,{abort:H,clone:Z,compare:G,emit:M,listeners:R,off:L,on:W,reset:J,run:X,toString:K}),Y.assign(a.prototype,{benchmark:null,cycles:0,elapsed:0,timeStamp:0}),Y.assign(a.prototype,{resolve:O}),Y.assign(l.prototype,{aborted:!1,cancelled:!1,currentTarget:n,result:n,target:n,timeStamp:0,type:""}),y.options={name:n},Y.assign(y.prototype,{length:0,aborted:!1,running:!1}),Y.assign(y.prototype,{abort:z,add:q,clone:N,emit:M,filter:I,join:ie.join,listeners:R,off:L,on:W,pop:ie.pop,push:me,reset:D,run:P,reverse:ie.reverse,shift:de,slice:he,sort:ie.sort,splice:ie.splice,unshift:ye}),Y.assign(s,{Deferred:a,Event:l,Suite:y}),Y.each(["each","forEach","indexOf","map","reduce"],function(e){var n=Y[e];y.prototype[e]=function(){var e=[this];return me.apply(e,arguments),n.apply(Y,e)}}),Y.each(["pop","shift","splice"],function(e){var n=ie[e];y.prototype[e]=function(){var e=this,t=n.apply(e,arguments);return 0===e.length&&delete e[0],t}}),y.prototype.unshift=function(){var e=this;return ye.apply(e,arguments),e.length},s}var n,t={"function":!0,object:!0},r=t[typeof window]&&window||this,o="function"==typeof define&&"object"==typeof define.amd&&define.amd&&define,i=t[typeof exports]&&exports&&!exports.nodeType&&exports,s=t[typeof module]&&module&&!module.nodeType&&module,a=i&&s&&"object"==typeof global&&global;!a||a.global!==a&&a.window!==a&&a.self!==a||(r=a);var u="function"==typeof require&&require,c=0,l=s&&s.exports===i&&i,f=/^(?:boolean|number|string|undefined)$/,p=0,m=["Array","Date","Function","Math","Object","RegExp","String","_","clearTimeout","chrome","chromium","document","navigator","phantom","platform","process","runtime","setTimeout"],d={1:4096,2:512,3:64,4:8,5:0},h={1:12.706,2:4.303,3:3.182,4:2.776,5:2.571,6:2.447,7:2.365,8:2.306,9:2.262,10:2.228,11:2.201,12:2.179,13:2.16,14:2.145,15:2.131,16:2.12,17:2.11,18:2.101,19:2.093,20:2.086,21:2.08,22:2.074,23:2.069,24:2.064,25:2.06,26:2.056,27:2.052,28:2.048,29:2.045,30:2.042,infinity:1.96},g={5:[0,1,2],6:[1,2,3,5],7:[1,3,5,6,8],8:[2,4,6,8,10,13],9:[2,4,7,10,12,15,17],10:[3,5,8,11,14,17,20,23],11:[3,6,9,13,16,19,23,26,30],12:[4,7,11,14,18,22,26,29,33,37],13:[4,8,12,16,20,24,28,33,37,41,45],14:[5,9,13,17,22,26,31,36,40,45,50,55],15:[5,10,14,19,24,29,34,39,44,49,54,59,64],16:[6,11,15,21,26,31,37,42,47,53,59,64,70,75],17:[6,11,17,22,28,34,39,45,51,57,63,67,75,81,87],18:[7,12,18,24,30,36,42,48,55,61,67,74,80,86,93,99],19:[7,13,19,25,32,38,45,52,58,65,72,78,85,92,99,106,113],20:[8,14,20,27,34,41,48,55,62,69,76,83,90,98,105,112,119,127],21:[8,15,22,29,36,43,50,58,65,73,80,88,96,103,111,119,126,134,142],22:[9,16,23,30,38,45,53,61,69,77,85,93,101,109,117,125,133,141,150,158],23:[9,17,24,32,40,48,56,64,73,81,89,98,106,115,123,132,140,149,157,166,175],24:[10,17,25,33,42,50,59,67,76,85,94,102,111,120,129,138,147,156,165,174,183,192],25:[10,18,27,35,44,53,62,71,80,89,98,107,117,126,135,145,154,163,173,182,192,201,211],26:[11,19,28,37,46,55,64,74,83,93,102,112,122,132,141,151,161,171,181,191,200,210,220,230],27:[11,20,29,38,48,57,67,77,87,97,107,118,125,138,147,158,168,178,188,199,209,219,230,240,250],28:[12,21,30,40,50,60,70,80,90,101,111,122,132,143,154,164,175,186,196,207,218,228,239,250,261,272],29:[13,22,32,42,52,62,73,83,94,105,116,127,138,149,160,171,182,193,204,215,226,238,249,260,271,282,294],30:[13,23,33,43,54,65,76,87,98,109,120,131,143,154,166,177,189,200,212,223,235,247,258,270,282,293,305,317]};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define(["lodash","platform"],function(n,t){return e({_:n,platform:t})});else{var y=e();i&&s?(l&&((s.exports=y).Benchmark=y),i.Benchmark=y):r.Benchmark=y}}).call(this);
\ No newline at end of file
/**
* @license
* lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
*/
;(function(){function t(t,n){return t.set(n[0],n[1]),t}function n(t,n){return t.add(n),t}function r(t,n,r){switch(r.length){case 0:return t.call(n);case 1:return t.call(n,r[0]);case 2:return t.call(n,r[0],r[1]);case 3:return t.call(n,r[0],r[1],r[2])}return t.apply(n,r)}function e(t,n,r,e){for(var u=-1,o=t?t.length:0;++u<o;){var i=t[u];n(e,i,r(i),t)}return e}function u(t,n){for(var r=-1,e=t?t.length:0;++r<e&&false!==n(t[r],r,t););return t}function o(t,n){for(var r=t?t.length:0;r--&&false!==n(t[r],r,t););
return t}function i(t,n){for(var r=-1,e=t?t.length:0;++r<e;)if(!n(t[r],r,t))return false;return true}function f(t,n){for(var r=-1,e=t?t.length:0,u=0,o=[];++r<e;){var i=t[r];n(i,r,t)&&(o[u++]=i)}return o}function c(t,n){return!(!t||!t.length)&&-1<d(t,n,0)}function a(t,n,r){for(var e=-1,u=t?t.length:0;++e<u;)if(r(n,t[e]))return true;return false}function l(t,n){for(var r=-1,e=t?t.length:0,u=Array(e);++r<e;)u[r]=n(t[r],r,t);return u}function s(t,n){for(var r=-1,e=n.length,u=t.length;++r<e;)t[u+r]=n[r];return t}function h(t,n,r,e){
var u=-1,o=t?t.length:0;for(e&&o&&(r=t[++u]);++u<o;)r=n(r,t[u],u,t);return r}function p(t,n,r,e){var u=t?t.length:0;for(e&&u&&(r=t[--u]);u--;)r=n(r,t[u],u,t);return r}function _(t,n){for(var r=-1,e=t?t.length:0;++r<e;)if(n(t[r],r,t))return true;return false}function v(t,n,r){var e;return r(t,function(t,r,u){return n(t,r,u)?(e=r,false):void 0}),e}function g(t,n,r,e){var u=t.length;for(r+=e?1:-1;e?r--:++r<u;)if(n(t[r],r,t))return r;return-1}function d(t,n,r){if(n!==n)return M(t,r);--r;for(var e=t.length;++r<e;)if(t[r]===n)return r;
return-1}function y(t,n,r,e){--r;for(var u=t.length;++r<u;)if(e(t[r],n))return r;return-1}function b(t,n){var r=t?t.length:0;return r?w(t,n)/r:V}function x(t,n,r,e,u){return u(t,function(t,u,o){r=e?(e=false,t):n(r,t,u,o)}),r}function j(t,n){var r=t.length;for(t.sort(n);r--;)t[r]=t[r].c;return t}function w(t,n){for(var r,e=-1,u=t.length;++e<u;){var o=n(t[e]);o!==T&&(r=r===T?o:r+o)}return r}function m(t,n){for(var r=-1,e=Array(t);++r<t;)e[r]=n(r);return e}function A(t,n){return l(n,function(n){return[n,t[n]];
})}function O(t){return function(n){return t(n)}}function k(t,n){return l(n,function(n){return t[n]})}function E(t,n){return t.has(n)}function S(t,n){for(var r=-1,e=t.length;++r<e&&-1<d(n,t[r],0););return r}function I(t,n){for(var r=t.length;r--&&-1<d(n,t[r],0););return r}function R(t){return t&&t.Object===Object?t:null}function W(t){return zt[t]}function B(t){return Ut[t]}function L(t){return"\\"+Dt[t]}function M(t,n,r){var e=t.length;for(n+=r?1:-1;r?n--:++n<e;){var u=t[n];if(u!==u)return n}return-1;
}function C(t){var n=false;if(null!=t&&typeof t.toString!="function")try{n=!!(t+"")}catch(r){}return n}function z(t){for(var n,r=[];!(n=t.next()).done;)r.push(n.value);return r}function U(t){var n=-1,r=Array(t.size);return t.forEach(function(t,e){r[++n]=[e,t]}),r}function $(t,n){for(var r=-1,e=t.length,u=0,o=[];++r<e;){var i=t[r];i!==n&&"__lodash_placeholder__"!==i||(t[r]="__lodash_placeholder__",o[u++]=r)}return o}function D(t){var n=-1,r=Array(t.size);return t.forEach(function(t){r[++n]=t}),r}function F(t){
var n=-1,r=Array(t.size);return t.forEach(function(t){r[++n]=[t,t]}),r}function N(t){if(!t||!Wt.test(t))return t.length;for(var n=It.lastIndex=0;It.test(t);)n++;return n}function P(t){return $t[t]}function Z(R){function At(t,n){return R.setTimeout.call(Kt,t,n)}function Ot(t){if(Te(t)&&!yi(t)&&!(t instanceof Ut)){if(t instanceof zt)return t;if(Wu.call(t,"__wrapped__"))return ae(t)}return new zt(t)}function kt(){}function zt(t,n){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!n,this.__index__=0,
this.__values__=T}function Ut(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function $t(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function Dt(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function Pt(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function Zt(t){var n=-1,r=t?t.length:0;
for(this.__data__=new Pt;++n<r;)this.add(t[n])}function qt(t){this.__data__=new Dt(t)}function Vt(t,n,r,e){return t===T||Ce(t,ku[r])&&!Wu.call(e,r)?n:t}function Jt(t,n,r){(r===T||Ce(t[n],r))&&(typeof n!="number"||r!==T||n in t)||(t[n]=r)}function Yt(t,n,r){var e=t[n];Wu.call(t,n)&&Ce(e,r)&&(r!==T||n in t)||(t[n]=r)}function Ht(t,n){for(var r=t.length;r--;)if(Ce(t[r][0],n))return r;return-1}function Qt(t,n,r,e){return Ao(t,function(t,u,o){n(e,t,r(t),o)}),e}function Xt(t,n){return t&&sr(n,iu(n),t)}
function tn(t,n){for(var r=-1,e=null==t,u=n.length,o=Array(u);++r<u;)o[r]=e?T:uu(t,n[r]);return o}function nn(t,n,r){return t===t&&(r!==T&&(t=r>=t?t:r),n!==T&&(t=t>=n?t:n)),t}function rn(t,n,r,e,o,i,f){var c;if(e&&(c=i?e(t,o,i,f):e(t)),c!==T)return c;if(!Ze(t))return t;if(o=yi(t)){if(c=Kr(t),!n)return lr(t,c)}else{var a=qr(t),l="[object Function]"==a||"[object GeneratorFunction]"==a;if(bi(t))return or(t,n);if("[object Object]"==a||"[object Arguments]"==a||l&&!i){if(C(t))return i?t:{};if(c=Gr(l?{}:t),
!n)return hr(t,Xt(c,t))}else{if(!Ct[a])return i?t:{};c=Jr(t,a,rn,n)}}if(f||(f=new qt),i=f.get(t))return i;if(f.set(t,c),!o)var s=r?gn(t,iu,Tr):iu(t);return u(s||t,function(u,o){s&&(o=u,u=t[o]),Yt(c,o,rn(u,n,r,e,o,t,f))}),c}function en(t){var n=iu(t),r=n.length;return function(e){if(null==e)return!r;for(var u=r;u--;){var o=n[u],i=t[o],f=e[o];if(f===T&&!(o in Object(e))||!i(f))return false}return true}}function un(t){return Ze(t)?Tu(t):{}}function on(t,n,r){if(typeof t!="function")throw new Au("Expected a function");
return At(function(){t.apply(T,r)},n)}function fn(t,n,r,e){var u=-1,o=c,i=true,f=t.length,s=[],h=n.length;if(!f)return s;r&&(n=l(n,O(r))),e?(o=a,i=false):n.length>=200&&(o=E,i=false,n=new Zt(n));t:for(;++u<f;){var p=t[u],_=r?r(p):p,p=e||0!==p?p:0;if(i&&_===_){for(var v=h;v--;)if(n[v]===_)continue t;s.push(p)}else o(n,_,e)||s.push(p)}return s}function cn(t,n){var r=true;return Ao(t,function(t,e,u){return r=!!n(t,e,u)}),r}function an(t,n,r){for(var e=-1,u=t.length;++e<u;){var o=t[e],i=n(o);if(null!=i&&(f===T?i===i&&!Je(i):r(i,f)))var f=i,c=o;
}return c}function ln(t,n){var r=[];return Ao(t,function(t,e,u){n(t,e,u)&&r.push(t)}),r}function sn(t,n,r,e,u){var o=-1,i=t.length;for(r||(r=Hr),u||(u=[]);++o<i;){var f=t[o];n>0&&r(f)?n>1?sn(f,n-1,r,e,u):s(u,f):e||(u[u.length]=f)}return u}function hn(t,n){return t&&ko(t,n,iu)}function pn(t,n){return t&&Eo(t,n,iu)}function _n(t,n){return f(n,function(n){return Fe(t[n])})}function vn(t,n){n=ne(n,t)?[n]:er(n);for(var r=0,e=n.length;null!=t&&e>r;)t=t[fe(n[r++])];return r&&r==e?t:T}function gn(t,n,r){
return n=n(t),yi(t)?n:s(n,r(t))}function dn(t,n){return t>n}function yn(t,n){return null!=t&&(Wu.call(t,n)||typeof t=="object"&&n in t&&null===Ju(Object(t)))}function bn(t,n){return null!=t&&n in Object(t)}function xn(t,n,r){for(var e=r?a:c,u=t[0].length,o=t.length,i=o,f=Array(o),s=1/0,h=[];i--;){var p=t[i];i&&n&&(p=l(p,O(n))),s=to(p.length,s),f[i]=!r&&(n||u>=120&&p.length>=120)?new Zt(i&&p):T}var p=t[0],_=-1,v=f[0];t:for(;++_<u&&s>h.length;){var g=p[_],d=n?n(g):g,g=r||0!==g?g:0;if(v?!E(v,d):!e(h,d,r)){
for(i=o;--i;){var y=f[i];if(y?!E(y,d):!e(t[i],d,r))continue t}v&&v.push(d),h.push(g)}}return h}function jn(t,n,r){var e={};return hn(t,function(t,u,o){n(e,r(t),u,o)}),e}function wn(t,n,e){return ne(n,t)||(n=er(n),t=ie(t,n),n=ve(n)),n=null==t?t:t[fe(n)],null==n?T:r(n,t,e)}function mn(t,n,r,e,u){if(t===n)n=true;else if(null==t||null==n||!Ze(t)&&!Te(n))n=t!==t&&n!==n;else t:{var o=yi(t),i=yi(n),f="[object Array]",c="[object Array]";o||(f=qr(t),f="[object Arguments]"==f?"[object Object]":f),i||(c=qr(n),
c="[object Arguments]"==c?"[object Object]":c);var a="[object Object]"==f&&!C(t),i="[object Object]"==c&&!C(n);if((c=f==c)&&!a)u||(u=new qt),n=o||Ye(t)?zr(t,n,mn,r,e,u):Ur(t,n,f,mn,r,e,u);else{if(!(2&e)&&(o=a&&Wu.call(t,"__wrapped__"),f=i&&Wu.call(n,"__wrapped__"),o||f)){t=o?t.value():t,n=f?n.value():n,u||(u=new qt),n=mn(t,n,r,e,u);break t}if(c)n:if(u||(u=new qt),o=2&e,f=iu(t),i=f.length,c=iu(n).length,i==c||o){for(a=i;a--;){var l=f[a];if(!(o?l in n:yn(n,l))){n=false;break n}}if(c=u.get(t))n=c==n;else{
c=true,u.set(t,n);for(var s=o;++a<i;){var l=f[a],h=t[l],p=n[l];if(r)var _=o?r(p,h,l,n,t,u):r(h,p,l,t,n,u);if(_===T?h!==p&&!mn(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l)}c&&!s&&(r=t.constructor,e=n.constructor,r!=e&&"constructor"in t&&"constructor"in n&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u["delete"](t),n=c}}else n=false;else n=false}}return n}function An(t,n,r,e){var u=r.length,o=u,i=!e;if(null==t)return!o;for(t=Object(t);u--;){var f=r[u];if(i&&f[2]?f[1]!==t[f[0]]:!(f[0]in t))return false;
}for(;++u<o;){var f=r[u],c=f[0],a=t[c],l=f[1];if(i&&f[2]){if(a===T&&!(c in t))return false}else{if(f=new qt,e)var s=e(a,l,c,t,n,f);if(s===T?!mn(l,a,e,3,f):!s)return false}}return true}function On(t){return!Ze(t)||Iu&&Iu in t?false:(Fe(t)||C(t)?zu:yt).test(ce(t))}function kn(t){return typeof t=="function"?t:null==t?pu:typeof t=="object"?yi(t)?Wn(t[0],t[1]):Rn(t):du(t)}function En(t){t=null==t?t:Object(t);var n,r=[];for(n in t)r.push(n);return r}function Sn(t,n){return n>t}function In(t,n){var r=-1,e=Ue(t)?Array(t.length):[];
return Ao(t,function(t,u,o){e[++r]=n(t,u,o)}),e}function Rn(t){var n=Pr(t);return 1==n.length&&n[0][2]?ue(n[0][0],n[0][1]):function(r){return r===t||An(r,t,n)}}function Wn(t,n){return ne(t)&&n===n&&!Ze(n)?ue(fe(t),n):function(r){var e=uu(r,t);return e===T&&e===n?ou(r,t):mn(n,e,T,3)}}function Bn(t,n,r,e,o){if(t!==n){if(!yi(n)&&!Ye(n))var i=fu(n);u(i||n,function(u,f){if(i&&(f=u,u=n[f]),Ze(u)){o||(o=new qt);var c=f,a=o,l=t[c],s=n[c],h=a.get(s);if(h)Jt(t,c,h);else{var h=e?e(l,s,c+"",t,n,a):T,p=h===T;p&&(h=s,
yi(s)||Ye(s)?yi(l)?h=l:$e(l)?h=lr(l):(p=false,h=rn(s,true)):Ve(s)||ze(s)?ze(l)?h=ru(l):!Ze(l)||r&&Fe(l)?(p=false,h=rn(s,true)):h=l:p=false),a.set(s,h),p&&Bn(h,s,r,e,a),a["delete"](s),Jt(t,c,h)}}else c=e?e(t[f],u,f+"",t,n,o):T,c===T&&(c=u),Jt(t,f,c)})}}function Ln(t,n){var r=t.length;return r?(n+=0>n?r:0,Xr(n,r)?t[n]:T):void 0}function Mn(t,n,r){var e=-1;return n=l(n.length?n:[pu],O(Fr())),t=In(t,function(t){return{a:l(n,function(n){return n(t)}),b:++e,c:t}}),j(t,function(t,n){var e;t:{e=-1;for(var u=t.a,o=n.a,i=u.length,f=r.length;++e<i;){
var c=fr(u[e],o[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break t}}e=t.b-n.b}return e})}function Cn(t,n){return t=Object(t),h(n,function(n,r){return r in t&&(n[r]=t[r]),n},{})}function zn(t,n){for(var r=-1,e=gn(t,fu,Bo),u=e.length,o={};++r<u;){var i=e[r],f=t[i];n(f,i)&&(o[i]=f)}return o}function Un(t){return function(n){return null==n?T:n[t]}}function $n(t){return function(n){return vn(n,t)}}function Dn(t,n,r,e){var u=e?y:d,o=-1,i=n.length,f=t;for(t===n&&(n=lr(n)),r&&(f=l(t,O(r)));++o<i;)for(var c=0,a=n[o],a=r?r(a):a;-1<(c=u(f,a,c,e));)f!==t&&Vu.call(f,c,1),
Vu.call(t,c,1);return t}function Fn(t,n){for(var r=t?n.length:0,e=r-1;r--;){var u=n[r];if(r==e||u!==o){var o=u;if(Xr(u))Vu.call(t,u,1);else if(ne(u,t))delete t[fe(u)];else{var u=er(u),i=ie(t,u);null!=i&&delete i[fe(ve(u))]}}}}function Nn(t,n){return t+Gu(ro()*(n-t+1))}function Pn(t,n){var r="";if(!t||1>n||n>9007199254740991)return r;do n%2&&(r+=t),(n=Gu(n/2))&&(t+=t);while(n);return r}function Zn(t,n,r,e){n=ne(n,t)?[n]:er(n);for(var u=-1,o=n.length,i=o-1,f=t;null!=f&&++u<o;){var c=fe(n[u]);if(Ze(f)){
var a=r;if(u!=i){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=null==l?Xr(n[u+1])?[]:{}:l)}Yt(f,c,a)}f=f[c]}return t}function Tn(t,n,r){var e=-1,u=t.length;for(0>n&&(n=-n>u?0:u+n),r=r>u?u:r,0>r&&(r+=u),u=n>r?0:r-n>>>0,n>>>=0,r=Array(u);++e<u;)r[e]=t[e+n];return r}function qn(t,n){var r;return Ao(t,function(t,e,u){return r=n(t,e,u),!r}),!!r}function Vn(t,n,r){var e=0,u=t?t.length:e;if(typeof n=="number"&&n===n&&2147483647>=u){for(;u>e;){var o=e+u>>>1,i=t[o];null!==i&&!Je(i)&&(r?n>=i:n>i)?e=o+1:u=o}return u}
return Kn(t,n,pu,r)}function Kn(t,n,r,e){n=r(n);for(var u=0,o=t?t.length:0,i=n!==n,f=null===n,c=Je(n),a=n===T;o>u;){var l=Gu((u+o)/2),s=r(t[l]),h=s!==T,p=null===s,_=s===s,v=Je(s);(i?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?n>=s:n>s)?u=l+1:o=l}return to(o,4294967294)}function Gn(t,n){for(var r=-1,e=t.length,u=0,o=[];++r<e;){var i=t[r],f=n?n(i):i;if(!r||!Ce(f,c)){var c=f;o[u++]=0===i?0:i}}return o}function Jn(t){return typeof t=="number"?t:Je(t)?V:+t}function Yn(t){if(typeof t=="string")return t;
if(Je(t))return mo?mo.call(t):"";var n=t+"";return"0"==n&&1/t==-q?"-0":n}function Hn(t,n,r){var e=-1,u=c,o=t.length,i=true,f=[],l=f;if(r)i=false,u=a;else if(o>=200){if(u=n?null:Io(t))return D(u);i=false,u=E,l=new Zt}else l=n?[]:f;t:for(;++e<o;){var s=t[e],h=n?n(s):s,s=r||0!==s?s:0;if(i&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue t;n&&l.push(h),f.push(s)}else u(l,h,r)||(l!==f&&l.push(h),f.push(s))}return f}function Qn(t,n,r,e){for(var u=t.length,o=e?u:-1;(e?o--:++o<u)&&n(t[o],o,t););return r?Tn(t,e?0:o,e?o+1:u):Tn(t,e?o+1:0,e?u:o);
}function Xn(t,n){var r=t;return r instanceof Ut&&(r=r.value()),h(n,function(t,n){return n.func.apply(n.thisArg,s([t],n.args))},r)}function tr(t,n,r){for(var e=-1,u=t.length;++e<u;)var o=o?s(fn(o,t[e],n,r),fn(t[e],o,n,r)):t[e];return o&&o.length?Hn(o,n,r):[]}function nr(t,n,r){for(var e=-1,u=t.length,o=n.length,i={};++e<u;)r(i,t[e],o>e?n[e]:T);return i}function rr(t){return $e(t)?t:[]}function er(t){return yi(t)?t:Co(t)}function ur(t,n,r){var e=t.length;return r=r===T?e:r,!n&&r>=e?t:Tn(t,n,r)}function or(t,n){
if(n)return t.slice();var r=new t.constructor(t.length);return t.copy(r),r}function ir(t){var n=new t.constructor(t.byteLength);return new Fu(n).set(new Fu(t)),n}function fr(t,n){if(t!==n){var r=t!==T,e=null===t,u=t===t,o=Je(t),i=n!==T,f=null===n,c=n===n,a=Je(n);if(!f&&!a&&!o&&t>n||o&&i&&c&&!f&&!a||e&&i&&c||!r&&c||!u)return 1;if(!e&&!o&&!a&&n>t||a&&r&&u&&!e&&!o||f&&r&&u||!i&&u||!c)return-1}return 0}function cr(t,n,r,e){var u=-1,o=t.length,i=r.length,f=-1,c=n.length,a=Xu(o-i,0),l=Array(c+a);for(e=!e;++f<c;)l[f]=n[f];
for(;++u<i;)(e||o>u)&&(l[r[u]]=t[u]);for(;a--;)l[f++]=t[u++];return l}function ar(t,n,r,e){var u=-1,o=t.length,i=-1,f=r.length,c=-1,a=n.length,l=Xu(o-f,0),s=Array(l+a);for(e=!e;++u<l;)s[u]=t[u];for(l=u;++c<a;)s[l+c]=n[c];for(;++i<f;)(e||o>u)&&(s[l+r[i]]=t[u++]);return s}function lr(t,n){var r=-1,e=t.length;for(n||(n=Array(e));++r<e;)n[r]=t[r];return n}function sr(t,n,r,e){r||(r={});for(var u=-1,o=n.length;++u<o;){var i=n[u],f=e?e(r[i],t[i],i,r,t):t[i];Yt(r,i,f)}return r}function hr(t,n){return sr(t,Tr(t),n);
}function pr(t,n){return function(r,u){var o=yi(r)?e:Qt,i=n?n():{};return o(r,t,Fr(u),i)}}function _r(t){return Me(function(n,r){var e=-1,u=r.length,o=u>1?r[u-1]:T,i=u>2?r[2]:T,o=t.length>3&&typeof o=="function"?(u--,o):T;for(i&&te(r[0],r[1],i)&&(o=3>u?T:o,u=1),n=Object(n);++e<u;)(i=r[e])&&t(n,i,e,o);return n})}function vr(t,n){return function(r,e){if(null==r)return r;if(!Ue(r))return t(r,e);for(var u=r.length,o=n?u:-1,i=Object(r);(n?o--:++o<u)&&false!==e(i[o],o,i););return r}}function gr(t){return function(n,r,e){
var u=-1,o=Object(n);e=e(n);for(var i=e.length;i--;){var f=e[t?i:++u];if(false===r(o[f],f,o))break}return n}}function dr(t,n,r){function e(){return(this&&this!==Kt&&this instanceof e?o:t).apply(u?r:this,arguments)}var u=1&n,o=xr(t);return e}function yr(t){return function(n){n=eu(n);var r=Wt.test(n)?n.match(It):T,e=r?r[0]:n.charAt(0);return n=r?ur(r,1).join(""):n.slice(1),e[t]()+n}}function br(t){return function(n){return h(su(lu(n).replace(Et,"")),t,"")}}function xr(t){return function(){var n=arguments;
switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3]);case 5:return new t(n[0],n[1],n[2],n[3],n[4]);case 6:return new t(n[0],n[1],n[2],n[3],n[4],n[5]);case 7:return new t(n[0],n[1],n[2],n[3],n[4],n[5],n[6])}var r=un(t.prototype),n=t.apply(r,n);return Ze(n)?n:r}}function jr(t,n,e){function u(){for(var i=arguments.length,f=Array(i),c=i,a=Dr(u);c--;)f[c]=arguments[c];return c=3>i&&f[0]!==a&&f[i-1]!==a?[]:$(f,a),
i-=c.length,e>i?Br(t,n,Ar,u.placeholder,T,f,c,T,T,e-i):r(this&&this!==Kt&&this instanceof u?o:t,this,f)}var o=xr(t);return u}function wr(t){return function(n,r,e){var u=Object(n);if(r=Fr(r,3),!Ue(n))var o=iu(n);return e=t(o||n,function(t,n){return o&&(n=t,t=u[n]),r(t,n,u)},e),e>-1?n[o?o[e]:e]:T}}function mr(t){return Me(function(n){n=sn(n,1);var r=n.length,e=r,u=zt.prototype.thru;for(t&&n.reverse();e--;){var o=n[e];if(typeof o!="function")throw new Au("Expected a function");if(u&&!i&&"wrapper"==$r(o))var i=new zt([],true);
}for(e=i?e:r;++e<r;)var o=n[e],u=$r(o),f="wrapper"==u?Ro(o):T,i=f&&re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?i[$r(f[0])].apply(i,f[3]):1==o.length&&re(o)?i[u]():i.thru(o);return function(){var t=arguments,e=t[0];if(i&&1==t.length&&yi(e)&&e.length>=200)return i.plant(e).value();for(var u=0,t=r?n[u].apply(this,t):e;++u<r;)t=n[u].call(this,t);return t}})}function Ar(t,n,r,e,u,o,i,f,c,a){function l(){for(var d=arguments.length,y=Array(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=Dr(l),b=y.length;for(x=0;b--;)y[b]===j&&x++;
}if(e&&(y=cr(y,e,u,_)),o&&(y=ar(y,o,i,_)),d-=x,_&&a>d)return j=$(y,j),Br(t,n,Ar,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[t]:t,d=y.length,f){x=y.length;for(var w=to(f.length,x),m=lr(y);w--;){var A=f[w];y[w]=Xr(A,x)?m[A]:T}}else v&&d>1&&y.reverse();return s&&d>c&&(y.length=c),this&&this!==Kt&&this instanceof l&&(b=g||xr(b)),b.apply(j,y)}var s=128&n,h=1&n,p=2&n,_=24&n,v=512&n,g=p?T:xr(t);return l}function Or(t,n){return function(r,e){return jn(r,t,n(e))}}function kr(t){return function(n,r){var e;
if(n===T&&r===T)return 0;if(n!==T&&(e=n),r!==T){if(e===T)return r;typeof n=="string"||typeof r=="string"?(n=Yn(n),r=Yn(r)):(n=Jn(n),r=Jn(r)),e=t(n,r)}return e}}function Er(t){return Me(function(n){return n=1==n.length&&yi(n[0])?l(n[0],O(Fr())):l(sn(n,1,Qr),O(Fr())),Me(function(e){var u=this;return t(n,function(t){return r(t,u,e)})})})}function Sr(t,n){n=n===T?" ":Yn(n);var r=n.length;return 2>r?r?Pn(n,t):n:(r=Pn(n,Ku(t/N(n))),Wt.test(n)?ur(r.match(It),0,t).join(""):r.slice(0,t))}function Ir(t,n,e,u){
function o(){for(var n=-1,c=arguments.length,a=-1,l=u.length,s=Array(l+c),h=this&&this!==Kt&&this instanceof o?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++n];return r(h,i?e:this,s)}var i=1&n,f=xr(t);return o}function Rr(t){return function(n,r,e){e&&typeof e!="number"&&te(n,r,e)&&(r=e=T),n=nu(n),n=n===n?n:0,r===T?(r=n,n=0):r=nu(r)||0,e=e===T?r>n?1:-1:nu(e)||0;var u=-1;r=Xu(Ku((r-n)/(e||1)),0);for(var o=Array(r);r--;)o[t?r:++u]=n,n+=e;return o}}function Wr(t){return function(n,r){return typeof n=="string"&&typeof r=="string"||(n=nu(n),
r=nu(r)),t(n,r)}}function Br(t,n,r,e,u,o,i,f,c,a){var l=8&n,s=l?i:T;i=l?T:i;var h=l?o:T;return o=l?T:o,n=(n|(l?32:64))&~(l?64:32),4&n||(n&=-4),n=[t,n,u,h,s,o,i,f,c,a],r=r.apply(T,n),re(t)&&Mo(r,n),r.placeholder=e,r}function Lr(t){var n=wu[t];return function(t,r){if(t=nu(t),r=to(Xe(r),292)){var e=(eu(t)+"e").split("e"),e=n(e[0]+"e"+(+e[1]+r)),e=(eu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return n(t)}}function Mr(t){return function(n){var r=qr(n);return"[object Map]"==r?U(n):"[object Set]"==r?F(n):A(n,t(n));
}}function Cr(t,n,r,e,u,o,i,f){var c=2&n;if(!c&&typeof t!="function")throw new Au("Expected a function");var a=e?e.length:0;if(a||(n&=-97,e=u=T),i=i===T?i:Xu(Xe(i),0),f=f===T?f:Xe(f),a-=u?u.length:0,64&n){var l=e,s=u;e=u=T}var h=c?T:Ro(t);return o=[t,n,r,e,u,l,s,o,i,f],h&&(r=o[1],t=h[1],n=r|t,e=128==t&&8==r||128==t&&256==r&&h[8]>=o[7].length||384==t&&h[8]>=h[7].length&&8==r,131>n||e)&&(1&t&&(o[2]=h[2],n|=1&r?0:4),(r=h[3])&&(e=o[3],o[3]=e?cr(e,r,h[4]):r,o[4]=e?$(o[3],"__lodash_placeholder__"):h[4]),
(r=h[5])&&(e=o[5],o[5]=e?ar(e,r,h[6]):r,o[6]=e?$(o[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(o[7]=r),128&t&&(o[8]=null==o[8]?h[8]:to(o[8],h[8])),null==o[9]&&(o[9]=h[9]),o[0]=h[0],o[1]=n),t=o[0],n=o[1],r=o[2],e=o[3],u=o[4],f=o[9]=null==o[9]?c?0:t.length:Xu(o[9]-a,0),!f&&24&n&&(n&=-25),(h?So:Mo)(n&&1!=n?8==n||16==n?jr(t,n,f):32!=n&&33!=n||u.length?Ar.apply(T,o):Ir(t,n,r,e):dr(t,n,r),o)}function zr(t,n,r,e,u,o){var i=2&u,f=t.length,c=n.length;if(f!=c&&!(i&&c>f))return false;if(c=o.get(t))return c==n;
var c=-1,a=true,l=1&u?new Zt:T;for(o.set(t,n);++c<f;){var s=t[c],h=n[c];if(e)var p=i?e(h,s,c,n,t,o):e(s,h,c,t,n,o);if(p!==T){if(p)continue;a=false;break}if(l){if(!_(n,function(t,n){return l.has(n)||s!==t&&!r(s,t,e,u,o)?void 0:l.add(n)})){a=false;break}}else if(s!==h&&!r(s,h,e,u,o)){a=false;break}}return o["delete"](t),a}function Ur(t,n,r,e,u,o,i){switch(r){case"[object DataView]":if(t.byteLength!=n.byteLength||t.byteOffset!=n.byteOffset)break;t=t.buffer,n=n.buffer;case"[object ArrayBuffer]":if(t.byteLength!=n.byteLength||!e(new Fu(t),new Fu(n)))break;
return true;case"[object Boolean]":case"[object Date]":return+t==+n;case"[object Error]":return t.name==n.name&&t.message==n.message;case"[object Number]":return t!=+t?n!=+n:t==+n;case"[object RegExp]":case"[object String]":return t==n+"";case"[object Map]":var f=U;case"[object Set]":if(f||(f=D),t.size!=n.size&&!(2&o))break;return(r=i.get(t))?r==n:(o|=1,i.set(t,n),zr(f(t),f(n),e,u,o,i));case"[object Symbol]":if(wo)return wo.call(t)==wo.call(n)}return false}function $r(t){for(var n=t.name+"",r=_o[n],e=Wu.call(_o,n)?r.length:0;e--;){
var u=r[e],o=u.func;if(null==o||o==t)return u.name}return n}function Dr(t){return(Wu.call(Ot,"placeholder")?Ot:t).placeholder}function Fr(){var t=Ot.iteratee||_u,t=t===_u?kn:t;return arguments.length?t(arguments[0],arguments[1]):t}function Nr(t,n){var r=t.__data__,e=typeof n;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==n:null===n)?r[typeof n=="string"?"string":"hash"]:r.map}function Pr(t){for(var n=iu(t),r=n.length;r--;){var e=n[r],u=t[e];n[r]=[e,u,u===u&&!Ze(u)]}return n;
}function Zr(t,n){var r=null==t?T:t[n];return On(r)?r:T}function Tr(t){return Pu(Object(t))}function qr(t){return Mu.call(t)}function Vr(t,n,r){n=ne(n,t)?[n]:er(n);for(var e,u=-1,o=n.length;++u<o;){var i=fe(n[u]);if(!(e=null!=t&&r(t,i)))break;t=t[i]}return e?e:(o=t?t.length:0,!!o&&Pe(o)&&Xr(i,o)&&(yi(t)||Ge(t)||ze(t)))}function Kr(t){var n=t.length,r=t.constructor(n);return n&&"string"==typeof t[0]&&Wu.call(t,"index")&&(r.index=t.index,r.input=t.input),r}function Gr(t){return typeof t.constructor!="function"||ee(t)?{}:un(Ju(Object(t)));
}function Jr(r,e,u,o){var i=r.constructor;switch(e){case"[object ArrayBuffer]":return ir(r);case"[object Boolean]":case"[object Date]":return new i(+r);case"[object DataView]":return e=o?ir(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":
return e=o?ir(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.length);case"[object Map]":return e=o?u(U(r),true):U(r),h(e,t,new r.constructor);case"[object Number]":case"[object String]":return new i(r);case"[object RegExp]":return e=new r.constructor(r.source,_t.exec(r)),e.lastIndex=r.lastIndex,e;case"[object Set]":return e=o?u(D(r),true):D(r),h(e,n,new r.constructor);case"[object Symbol]":return wo?Object(wo.call(r)):{}}}function Yr(t){var n=t?t.length:T;return Pe(n)&&(yi(t)||Ge(t)||ze(t))?m(n,String):null;
}function Hr(t){return yi(t)||ze(t)}function Qr(t){return yi(t)&&!(2==t.length&&!Fe(t[0]))}function Xr(t,n){return n=null==n?9007199254740991:n,!!n&&(typeof t=="number"||xt.test(t))&&t>-1&&0==t%1&&n>t}function te(t,n,r){if(!Ze(r))return false;var e=typeof n;return("number"==e?Ue(r)&&Xr(n,r.length):"string"==e&&n in r)?Ce(r[n],t):false}function ne(t,n){if(yi(t))return false;var r=typeof t;return"number"==r||"symbol"==r||"boolean"==r||null==t||Je(t)?true:ut.test(t)||!et.test(t)||null!=n&&t in Object(n)}function re(t){
var n=$r(t),r=Ot[n];return typeof r=="function"&&n in Ut.prototype?t===r?true:(n=Ro(r),!!n&&t===n[0]):false}function ee(t){var n=t&&t.constructor;return t===(typeof n=="function"&&n.prototype||ku)}function ue(t,n){return function(r){return null==r?false:r[t]===n&&(n!==T||t in Object(r))}}function oe(t,n,r,e,u,o){return Ze(t)&&Ze(n)&&Bn(t,n,T,oe,o.set(n,t)),t}function ie(t,n){return 1==n.length?t:vn(t,Tn(n,0,-1))}function fe(t){if(typeof t=="string"||Je(t))return t;var n=t+"";return"0"==n&&1/t==-q?"-0":n}function ce(t){
if(null!=t){try{return Ru.call(t)}catch(n){}return t+""}return""}function ae(t){if(t instanceof Ut)return t.clone();var n=new zt(t.__wrapped__,t.__chain__);return n.__actions__=lr(t.__actions__),n.__index__=t.__index__,n.__values__=t.__values__,n}function le(t,n,r){var e=t?t.length:0;return e?(n=r||n===T?1:Xe(n),Tn(t,0>n?0:n,e)):[]}function se(t,n,r){var e=t?t.length:0;return e?(n=r||n===T?1:Xe(n),n=e-n,Tn(t,0,0>n?0:n)):[]}function he(t,n,r){var e=t?t.length:0;return e?(r=null==r?0:Xe(r),0>r&&(r=Xu(e+r,0)),
g(t,Fr(n,3),r)):-1}function pe(t,n,r){var e=t?t.length:0;if(!e)return-1;var u=e-1;return r!==T&&(u=Xe(r),u=0>r?Xu(e+u,0):to(u,e-1)),g(t,Fr(n,3),u,true)}function _e(t){return t&&t.length?t[0]:T}function ve(t){var n=t?t.length:0;return n?t[n-1]:T}function ge(t,n){return t&&t.length&&n&&n.length?Dn(t,n):t}function de(t){return t?uo.call(t):t}function ye(t){if(!t||!t.length)return[];var n=0;return t=f(t,function(t){return $e(t)?(n=Xu(t.length,n),true):void 0}),m(n,function(n){return l(t,Un(n))})}function be(t,n){
if(!t||!t.length)return[];var e=ye(t);return null==n?e:l(e,function(t){return r(n,T,t)})}function xe(t){return t=Ot(t),t.__chain__=true,t}function je(t,n){return n(t)}function we(){return this}function me(t,n){return(yi(t)?u:Ao)(t,Fr(n,3))}function Ae(t,n){return(yi(t)?o:Oo)(t,Fr(n,3))}function Oe(t,n){return(yi(t)?l:In)(t,Fr(n,3))}function ke(t,n,r){var e=-1,u=He(t),o=u.length,i=o-1;for(n=(r?te(t,n,r):n===T)?1:nn(Xe(n),0,o);++e<n;)t=Nn(e,i),r=u[t],u[t]=u[e],u[e]=r;return u.length=n,u}function Ee(){
return xu.now()}function Se(t,n,r){return n=r?T:n,n=t&&null==n?t.length:n,Cr(t,128,T,T,T,T,n)}function Ie(t,n){var r;if(typeof n!="function")throw new Au("Expected a function");return t=Xe(t),function(){return 0<--t&&(r=n.apply(this,arguments)),1>=t&&(n=T),r}}function Re(t,n,r){return n=r?T:n,t=Cr(t,8,T,T,T,T,T,n),t.placeholder=Re.placeholder,t}function We(t,n,r){return n=r?T:n,t=Cr(t,16,T,T,T,T,T,n),t.placeholder=We.placeholder,t}function Be(t,n,r){function e(n){var r=c,e=a;return c=a=T,_=n,s=t.apply(e,r);
}function u(t){var r=t-p;return t-=_,p===T||r>=n||0>r||g&&t>=l}function o(){var t=Ee();if(u(t))return i(t);var r;r=t-_,t=n-(t-p),r=g?to(t,l-r):t,h=At(o,r)}function i(t){return h=T,d&&c?e(t):(c=a=T,s)}function f(){var t=Ee(),r=u(t);if(c=arguments,a=this,p=t,r){if(h===T)return _=t=p,h=At(o,n),v?e(t):s;if(g)return h=At(o,n),e(p)}return h===T&&(h=At(o,n)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof t!="function")throw new Au("Expected a function");return n=nu(n)||0,Ze(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Xu(nu(r.maxWait)||0,n):l,
d="trailing"in r?!!r.trailing:d),f.cancel=function(){_=0,c=p=a=h=T},f.flush=function(){return h===T?s:i(Ee())},f}function Le(t,n){function r(){var e=arguments,u=n?n.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=t.apply(this,e),r.cache=o.set(u,e),e)}if(typeof t!="function"||n&&typeof n!="function")throw new Au("Expected a function");return r.cache=new(Le.Cache||Pt),r}function Me(t,n){if(typeof t!="function")throw new Au("Expected a function");return n=Xu(n===T?t.length-1:Xe(n),0),function(){
for(var e=arguments,u=-1,o=Xu(e.length-n,0),i=Array(o);++u<o;)i[u]=e[n+u];switch(n){case 0:return t.call(this,i);case 1:return t.call(this,e[0],i);case 2:return t.call(this,e[0],e[1],i)}for(o=Array(n+1),u=-1;++u<n;)o[u]=e[u];return o[n]=i,r(t,this,o)}}function Ce(t,n){return t===n||t!==t&&n!==n}function ze(t){return $e(t)&&Wu.call(t,"callee")&&(!qu.call(t,"callee")||"[object Arguments]"==Mu.call(t))}function Ue(t){return null!=t&&Pe(Wo(t))&&!Fe(t)}function $e(t){return Te(t)&&Ue(t)}function De(t){
return Te(t)?"[object Error]"==Mu.call(t)||typeof t.message=="string"&&typeof t.name=="string":false}function Fe(t){return t=Ze(t)?Mu.call(t):"","[object Function]"==t||"[object GeneratorFunction]"==t}function Ne(t){return typeof t=="number"&&t==Xe(t)}function Pe(t){return typeof t=="number"&&t>-1&&0==t%1&&9007199254740991>=t}function Ze(t){var n=typeof t;return!!t&&("object"==n||"function"==n)}function Te(t){return!!t&&typeof t=="object"}function qe(t){return typeof t=="number"||Te(t)&&"[object Number]"==Mu.call(t);
}function Ve(t){return!Te(t)||"[object Object]"!=Mu.call(t)||C(t)?false:(t=Ju(Object(t)),null===t?true:(t=Wu.call(t,"constructor")&&t.constructor,typeof t=="function"&&t instanceof t&&Ru.call(t)==Lu))}function Ke(t){return Ze(t)&&"[object RegExp]"==Mu.call(t)}function Ge(t){return typeof t=="string"||!yi(t)&&Te(t)&&"[object String]"==Mu.call(t)}function Je(t){return typeof t=="symbol"||Te(t)&&"[object Symbol]"==Mu.call(t)}function Ye(t){return Te(t)&&Pe(t.length)&&!!Mt[Mu.call(t)]}function He(t){if(!t)return[];
if(Ue(t))return Ge(t)?t.match(It):lr(t);if(Zu&&t[Zu])return z(t[Zu]());var n=qr(t);return("[object Map]"==n?U:"[object Set]"==n?D:cu)(t)}function Qe(t){return t?(t=nu(t),t===q||t===-q?1.7976931348623157e308*(0>t?-1:1):t===t?t:0):0===t?t:0}function Xe(t){t=Qe(t);var n=t%1;return t===t?n?t-n:t:0}function tu(t){return t?nn(Xe(t),0,4294967295):0}function nu(t){if(typeof t=="number")return t;if(Je(t))return V;if(Ze(t)&&(t=Fe(t.valueOf)?t.valueOf():t,t=Ze(t)?t+"":t),typeof t!="string")return 0===t?t:+t;
t=t.replace(ct,"");var n=dt.test(t);return n||bt.test(t)?Nt(t.slice(2),n?2:8):gt.test(t)?V:+t}function ru(t){return sr(t,fu(t))}function eu(t){return null==t?"":Yn(t)}function uu(t,n,r){return t=null==t?T:vn(t,n),t===T?r:t}function ou(t,n){return null!=t&&Vr(t,n,bn)}function iu(t){var n=ee(t);if(!n&&!Ue(t))return Qu(Object(t));var r,e=Yr(t),u=!!e,e=e||[],o=e.length;for(r in t)!yn(t,r)||u&&("length"==r||Xr(r,o))||n&&"constructor"==r||e.push(r);return e}function fu(t){for(var n=-1,r=ee(t),e=En(t),u=e.length,o=Yr(t),i=!!o,o=o||[],f=o.length;++n<u;){
var c=e[n];i&&("length"==c||Xr(c,f))||"constructor"==c&&(r||!Wu.call(t,c))||o.push(c)}return o}function cu(t){return t?k(t,iu(t)):[]}function au(t){return qi(eu(t).toLowerCase())}function lu(t){return(t=eu(t))&&t.replace(jt,W).replace(St,"")}function su(t,n,r){return t=eu(t),n=r?T:n,n===T&&(n=Bt.test(t)?Rt:st),t.match(n)||[]}function hu(t){return function(){return t}}function pu(t){return t}function _u(t){return kn(typeof t=="function"?t:rn(t,true))}function vu(t,n,r){var e=iu(n),o=_n(n,e);null!=r||Ze(n)&&(o.length||!e.length)||(r=n,
n=t,t=this,o=_n(n,iu(n)));var i=!(Ze(r)&&"chain"in r&&!r.chain),f=Fe(t);return u(o,function(r){var e=n[r];t[r]=e,f&&(t.prototype[r]=function(){var n=this.__chain__;if(i||n){var r=t(this.__wrapped__);return(r.__actions__=lr(this.__actions__)).push({func:e,args:arguments,thisArg:t}),r.__chain__=n,r}return e.apply(t,s([this.value()],arguments))})}),t}function gu(){}function du(t){return ne(t)?Un(fe(t)):$n(t)}function yu(){return[]}function bu(){return false}R=R?Gt.defaults({},R,Gt.pick(Kt,Lt)):Kt;var xu=R.Date,ju=R.Error,wu=R.Math,mu=R.RegExp,Au=R.TypeError,Ou=R.Array.prototype,ku=R.Object.prototype,Eu=R.String.prototype,Su=R["__core-js_shared__"],Iu=function(){
var t=/[^.]+$/.exec(Su&&Su.keys&&Su.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),Ru=R.Function.prototype.toString,Wu=ku.hasOwnProperty,Bu=0,Lu=Ru.call(Object),Mu=ku.toString,Cu=Kt._,zu=mu("^"+Ru.call(Wu).replace(it,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Uu=Tt?R.Buffer:T,$u=R.Reflect,Du=R.Symbol,Fu=R.Uint8Array,Nu=$u?$u.f:T,Pu=Object.getOwnPropertySymbols,Zu=typeof(Zu=Du&&Du.iterator)=="symbol"?Zu:T,Tu=Object.create,qu=ku.propertyIsEnumerable,Vu=Ou.splice,Ku=wu.ceil,Gu=wu.floor,Ju=Object.getPrototypeOf,Yu=R.isFinite,Hu=Ou.join,Qu=Object.keys,Xu=wu.max,to=wu.min,no=R.parseInt,ro=wu.random,eo=Eu.replace,uo=Ou.reverse,oo=Eu.split,io=Zr(R,"DataView"),fo=Zr(R,"Map"),co=Zr(R,"Promise"),ao=Zr(R,"Set"),lo=Zr(R,"WeakMap"),so=Zr(Object,"create"),ho=lo&&new lo,po=!qu.call({
valueOf:1},"valueOf"),_o={},vo=ce(io),go=ce(fo),yo=ce(co),bo=ce(ao),xo=ce(lo),jo=Du?Du.prototype:T,wo=jo?jo.valueOf:T,mo=jo?jo.toString:T;Ot.templateSettings={escape:tt,evaluate:nt,interpolate:rt,variable:"",imports:{_:Ot}},Ot.prototype=kt.prototype,Ot.prototype.constructor=Ot,zt.prototype=un(kt.prototype),zt.prototype.constructor=zt,Ut.prototype=un(kt.prototype),Ut.prototype.constructor=Ut,$t.prototype.clear=function(){this.__data__=so?so(null):{}},$t.prototype["delete"]=function(t){return this.has(t)&&delete this.__data__[t];
},$t.prototype.get=function(t){var n=this.__data__;return so?(t=n[t],"__lodash_hash_undefined__"===t?T:t):Wu.call(n,t)?n[t]:T},$t.prototype.has=function(t){var n=this.__data__;return so?n[t]!==T:Wu.call(n,t)},$t.prototype.set=function(t,n){return this.__data__[t]=so&&n===T?"__lodash_hash_undefined__":n,this},Dt.prototype.clear=function(){this.__data__=[]},Dt.prototype["delete"]=function(t){var n=this.__data__;return t=Ht(n,t),0>t?false:(t==n.length-1?n.pop():Vu.call(n,t,1),true)},Dt.prototype.get=function(t){
var n=this.__data__;return t=Ht(n,t),0>t?T:n[t][1]},Dt.prototype.has=function(t){return-1<Ht(this.__data__,t)},Dt.prototype.set=function(t,n){var r=this.__data__,e=Ht(r,t);return 0>e?r.push([t,n]):r[e][1]=n,this},Pt.prototype.clear=function(){this.__data__={hash:new $t,map:new(fo||Dt),string:new $t}},Pt.prototype["delete"]=function(t){return Nr(this,t)["delete"](t)},Pt.prototype.get=function(t){return Nr(this,t).get(t)},Pt.prototype.has=function(t){return Nr(this,t).has(t)},Pt.prototype.set=function(t,n){
return Nr(this,t).set(t,n),this},Zt.prototype.add=Zt.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},Zt.prototype.has=function(t){return this.__data__.has(t)},qt.prototype.clear=function(){this.__data__=new Dt},qt.prototype["delete"]=function(t){return this.__data__["delete"](t)},qt.prototype.get=function(t){return this.__data__.get(t)},qt.prototype.has=function(t){return this.__data__.has(t)},qt.prototype.set=function(t,n){var r=this.__data__;return r instanceof Dt&&200==r.__data__.length&&(r=this.__data__=new Pt(r.__data__)),
r.set(t,n),this};var Ao=vr(hn),Oo=vr(pn,true),ko=gr(),Eo=gr(true);Nu&&!qu.call({valueOf:1},"valueOf")&&(En=function(t){return z(Nu(t))});var So=ho?function(t,n){return ho.set(t,n),t}:pu,Io=ao&&1/D(new ao([,-0]))[1]==q?function(t){return new ao(t)}:gu,Ro=ho?function(t){return ho.get(t)}:gu,Wo=Un("length");Pu||(Tr=yu);var Bo=Pu?function(t){for(var n=[];t;)s(n,Tr(t)),t=Ju(Object(t));return n}:Tr;(io&&"[object DataView]"!=qr(new io(new ArrayBuffer(1)))||fo&&"[object Map]"!=qr(new fo)||co&&"[object Promise]"!=qr(co.resolve())||ao&&"[object Set]"!=qr(new ao)||lo&&"[object WeakMap]"!=qr(new lo))&&(qr=function(t){
var n=Mu.call(t);if(t=(t="[object Object]"==n?t.constructor:T)?ce(t):T)switch(t){case vo:return"[object DataView]";case go:return"[object Map]";case yo:return"[object Promise]";case bo:return"[object Set]";case xo:return"[object WeakMap]"}return n});var Lo=Su?Fe:bu,Mo=function(){var t=0,n=0;return function(r,e){var u=Ee(),o=16-(u-n);if(n=u,o>0){if(150<=++t)return r}else t=0;return So(r,e)}}(),Co=Le(function(t){var n=[];return eu(t).replace(ot,function(t,r,e,u){n.push(e?u.replace(ht,"$1"):r||t)}),
n}),zo=Me(function(t,n){return $e(t)?fn(t,sn(n,1,$e,true)):[]}),Uo=Me(function(t,n){var r=ve(n);return $e(r)&&(r=T),$e(t)?fn(t,sn(n,1,$e,true),Fr(r)):[]}),$o=Me(function(t,n){var r=ve(n);return $e(r)&&(r=T),$e(t)?fn(t,sn(n,1,$e,true),T,r):[]}),Do=Me(function(t){var n=l(t,rr);return n.length&&n[0]===t[0]?xn(n):[]}),Fo=Me(function(t){var n=ve(t),r=l(t,rr);return n===ve(r)?n=T:r.pop(),r.length&&r[0]===t[0]?xn(r,Fr(n)):[]}),No=Me(function(t){var n=ve(t),r=l(t,rr);return n===ve(r)?n=T:r.pop(),r.length&&r[0]===t[0]?xn(r,T,n):[];
}),Po=Me(ge),Zo=Me(function(t,n){n=sn(n,1);var r=t?t.length:0,e=tn(t,n);return Fn(t,l(n,function(t){return Xr(t,r)?+t:t}).sort(fr)),e}),To=Me(function(t){return Hn(sn(t,1,$e,true))}),qo=Me(function(t){var n=ve(t);return $e(n)&&(n=T),Hn(sn(t,1,$e,true),Fr(n))}),Vo=Me(function(t){var n=ve(t);return $e(n)&&(n=T),Hn(sn(t,1,$e,true),T,n)}),Ko=Me(function(t,n){return $e(t)?fn(t,n):[]}),Go=Me(function(t){return tr(f(t,$e))}),Jo=Me(function(t){var n=ve(t);return $e(n)&&(n=T),tr(f(t,$e),Fr(n))}),Yo=Me(function(t){
var n=ve(t);return $e(n)&&(n=T),tr(f(t,$e),T,n)}),Ho=Me(ye),Qo=Me(function(t){var n=t.length,n=n>1?t[n-1]:T,n=typeof n=="function"?(t.pop(),n):T;return be(t,n)}),Xo=Me(function(t){function n(n){return tn(n,t)}t=sn(t,1);var r=t.length,e=r?t[0]:0,u=this.__wrapped__;return!(r>1||this.__actions__.length)&&u instanceof Ut&&Xr(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:je,args:[n],thisArg:T}),new zt(u,this.__chain__).thru(function(t){return r&&!t.length&&t.push(T),t})):this.thru(n)}),ti=pr(function(t,n,r){
Wu.call(t,r)?++t[r]:t[r]=1}),ni=wr(he),ri=wr(pe),ei=pr(function(t,n,r){Wu.call(t,r)?t[r].push(n):t[r]=[n]}),ui=Me(function(t,n,e){var u=-1,o=typeof n=="function",i=ne(n),f=Ue(t)?Array(t.length):[];return Ao(t,function(t){var c=o?n:i&&null!=t?t[n]:T;f[++u]=c?r(c,t,e):wn(t,n,e)}),f}),oi=pr(function(t,n,r){t[r]=n}),ii=pr(function(t,n,r){t[r?0:1].push(n)},function(){return[[],[]]}),fi=Me(function(t,n){if(null==t)return[];var r=n.length;return r>1&&te(t,n[0],n[1])?n=[]:r>2&&te(n[0],n[1],n[2])&&(n=[n[0]]),
n=1==n.length&&yi(n[0])?n[0]:sn(n,1,Qr),Mn(t,n,[])}),ci=Me(function(t,n,r){var e=1;if(r.length)var u=$(r,Dr(ci)),e=32|e;return Cr(t,e,n,r,u)}),ai=Me(function(t,n,r){var e=3;if(r.length)var u=$(r,Dr(ai)),e=32|e;return Cr(n,e,t,r,u)}),li=Me(function(t,n){return on(t,1,n)}),si=Me(function(t,n,r){return on(t,nu(n)||0,r)});Le.Cache=Pt;var hi=Me(function(t,n){n=1==n.length&&yi(n[0])?l(n[0],O(Fr())):l(sn(n,1,Qr),O(Fr()));var e=n.length;return Me(function(u){for(var o=-1,i=to(u.length,e);++o<i;)u[o]=n[o].call(this,u[o]);
return r(t,this,u)})}),pi=Me(function(t,n){var r=$(n,Dr(pi));return Cr(t,32,T,n,r)}),_i=Me(function(t,n){var r=$(n,Dr(_i));return Cr(t,64,T,n,r)}),vi=Me(function(t,n){return Cr(t,256,T,T,T,sn(n,1))}),gi=Wr(dn),di=Wr(function(t,n){return t>=n}),yi=Array.isArray,bi=Uu?function(t){return t instanceof Uu}:bu,xi=Wr(Sn),ji=Wr(function(t,n){return n>=t}),wi=_r(function(t,n){if(po||ee(n)||Ue(n))sr(n,iu(n),t);else for(var r in n)Wu.call(n,r)&&Yt(t,r,n[r])}),mi=_r(function(t,n){if(po||ee(n)||Ue(n))sr(n,fu(n),t);else for(var r in n)Yt(t,r,n[r]);
}),Ai=_r(function(t,n,r,e){sr(n,fu(n),t,e)}),Oi=_r(function(t,n,r,e){sr(n,iu(n),t,e)}),ki=Me(function(t,n){return tn(t,sn(n,1))}),Ei=Me(function(t){return t.push(T,Vt),r(Ai,T,t)}),Si=Me(function(t){return t.push(T,oe),r(Li,T,t)}),Ii=Or(function(t,n,r){t[n]=r},hu(pu)),Ri=Or(function(t,n,r){Wu.call(t,n)?t[n].push(r):t[n]=[r]},Fr),Wi=Me(wn),Bi=_r(function(t,n,r){Bn(t,n,r)}),Li=_r(function(t,n,r,e){Bn(t,n,r,e)}),Mi=Me(function(t,n){return null==t?{}:(n=l(sn(n,1),fe),Cn(t,fn(gn(t,fu,Bo),n)))}),Ci=Me(function(t,n){
return null==t?{}:Cn(t,l(sn(n,1),fe))}),zi=Mr(iu),Ui=Mr(fu),$i=br(function(t,n,r){return n=n.toLowerCase(),t+(r?au(n):n)}),Di=br(function(t,n,r){return t+(r?"-":"")+n.toLowerCase()}),Fi=br(function(t,n,r){return t+(r?" ":"")+n.toLowerCase()}),Ni=yr("toLowerCase"),Pi=br(function(t,n,r){return t+(r?"_":"")+n.toLowerCase()}),Zi=br(function(t,n,r){return t+(r?" ":"")+qi(n)}),Ti=br(function(t,n,r){return t+(r?" ":"")+n.toUpperCase()}),qi=yr("toUpperCase"),Vi=Me(function(t,n){try{return r(t,T,n)}catch(e){
return De(e)?e:new ju(e)}}),Ki=Me(function(t,n){return u(sn(n,1),function(n){n=fe(n),t[n]=ci(t[n],t)}),t}),Gi=mr(),Ji=mr(true),Yi=Me(function(t,n){return function(r){return wn(r,t,n)}}),Hi=Me(function(t,n){return function(r){return wn(t,r,n)}}),Qi=Er(l),Xi=Er(i),tf=Er(_),nf=Rr(),rf=Rr(true),ef=kr(function(t,n){return t+n}),uf=Lr("ceil"),of=kr(function(t,n){return t/n}),ff=Lr("floor"),cf=kr(function(t,n){return t*n}),af=Lr("round"),lf=kr(function(t,n){return t-n});return Ot.after=function(t,n){if(typeof n!="function")throw new Au("Expected a function");
return t=Xe(t),function(){return 1>--t?n.apply(this,arguments):void 0}},Ot.ary=Se,Ot.assign=wi,Ot.assignIn=mi,Ot.assignInWith=Ai,Ot.assignWith=Oi,Ot.at=ki,Ot.before=Ie,Ot.bind=ci,Ot.bindAll=Ki,Ot.bindKey=ai,Ot.castArray=function(){if(!arguments.length)return[];var t=arguments[0];return yi(t)?t:[t]},Ot.chain=xe,Ot.chunk=function(t,n,r){if(n=(r?te(t,n,r):n===T)?1:Xu(Xe(n),0),r=t?t.length:0,!r||1>n)return[];for(var e=0,u=0,o=Array(Ku(r/n));r>e;)o[u++]=Tn(t,e,e+=n);return o},Ot.compact=function(t){for(var n=-1,r=t?t.length:0,e=0,u=[];++n<r;){
var o=t[n];o&&(u[e++]=o)}return u},Ot.concat=function(){for(var t=arguments.length,n=Array(t?t-1:0),r=arguments[0],e=t;e--;)n[e-1]=arguments[e];return t?s(yi(r)?lr(r):[r],sn(n,1)):[]},Ot.cond=function(t){var n=t?t.length:0,e=Fr();return t=n?l(t,function(t){if("function"!=typeof t[1])throw new Au("Expected a function");return[e(t[0]),t[1]]}):[],Me(function(e){for(var u=-1;++u<n;){var o=t[u];if(r(o[0],this,e))return r(o[1],this,e)}})},Ot.conforms=function(t){return en(rn(t,true))},Ot.constant=hu,Ot.countBy=ti,
Ot.create=function(t,n){var r=un(t);return n?Xt(r,n):r},Ot.curry=Re,Ot.curryRight=We,Ot.debounce=Be,Ot.defaults=Ei,Ot.defaultsDeep=Si,Ot.defer=li,Ot.delay=si,Ot.difference=zo,Ot.differenceBy=Uo,Ot.differenceWith=$o,Ot.drop=le,Ot.dropRight=se,Ot.dropRightWhile=function(t,n){return t&&t.length?Qn(t,Fr(n,3),true,true):[]},Ot.dropWhile=function(t,n){return t&&t.length?Qn(t,Fr(n,3),true):[]},Ot.fill=function(t,n,r,e){var u=t?t.length:0;if(!u)return[];for(r&&typeof r!="number"&&te(t,n,r)&&(r=0,e=u),u=t.length,
r=Xe(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Xe(e),0>e&&(e+=u),e=r>e?0:tu(e);e>r;)t[r++]=n;return t},Ot.filter=function(t,n){return(yi(t)?f:ln)(t,Fr(n,3))},Ot.flatMap=function(t,n){return sn(Oe(t,n),1)},Ot.flatMapDeep=function(t,n){return sn(Oe(t,n),q)},Ot.flatMapDepth=function(t,n,r){return r=r===T?1:Xe(r),sn(Oe(t,n),r)},Ot.flatten=function(t){return t&&t.length?sn(t,1):[]},Ot.flattenDeep=function(t){return t&&t.length?sn(t,q):[]},Ot.flattenDepth=function(t,n){return t&&t.length?(n=n===T?1:Xe(n),sn(t,n)):[];
},Ot.flip=function(t){return Cr(t,512)},Ot.flow=Gi,Ot.flowRight=Ji,Ot.fromPairs=function(t){for(var n=-1,r=t?t.length:0,e={};++n<r;){var u=t[n];e[u[0]]=u[1]}return e},Ot.functions=function(t){return null==t?[]:_n(t,iu(t))},Ot.functionsIn=function(t){return null==t?[]:_n(t,fu(t))},Ot.groupBy=ei,Ot.initial=function(t){return se(t,1)},Ot.intersection=Do,Ot.intersectionBy=Fo,Ot.intersectionWith=No,Ot.invert=Ii,Ot.invertBy=Ri,Ot.invokeMap=ui,Ot.iteratee=_u,Ot.keyBy=oi,Ot.keys=iu,Ot.keysIn=fu,Ot.map=Oe,
Ot.mapKeys=function(t,n){var r={};return n=Fr(n,3),hn(t,function(t,e,u){r[n(t,e,u)]=t}),r},Ot.mapValues=function(t,n){var r={};return n=Fr(n,3),hn(t,function(t,e,u){r[e]=n(t,e,u)}),r},Ot.matches=function(t){return Rn(rn(t,true))},Ot.matchesProperty=function(t,n){return Wn(t,rn(n,true))},Ot.memoize=Le,Ot.merge=Bi,Ot.mergeWith=Li,Ot.method=Yi,Ot.methodOf=Hi,Ot.mixin=vu,Ot.negate=function(t){if(typeof t!="function")throw new Au("Expected a function");return function(){return!t.apply(this,arguments)}},Ot.nthArg=function(t){
return t=Xe(t),Me(function(n){return Ln(n,t)})},Ot.omit=Mi,Ot.omitBy=function(t,n){return n=Fr(n),zn(t,function(t,r){return!n(t,r)})},Ot.once=function(t){return Ie(2,t)},Ot.orderBy=function(t,n,r,e){return null==t?[]:(yi(n)||(n=null==n?[]:[n]),r=e?T:r,yi(r)||(r=null==r?[]:[r]),Mn(t,n,r))},Ot.over=Qi,Ot.overArgs=hi,Ot.overEvery=Xi,Ot.overSome=tf,Ot.partial=pi,Ot.partialRight=_i,Ot.partition=ii,Ot.pick=Ci,Ot.pickBy=function(t,n){return null==t?{}:zn(t,Fr(n))},Ot.property=du,Ot.propertyOf=function(t){
return function(n){return null==t?T:vn(t,n)}},Ot.pull=Po,Ot.pullAll=ge,Ot.pullAllBy=function(t,n,r){return t&&t.length&&n&&n.length?Dn(t,n,Fr(r)):t},Ot.pullAllWith=function(t,n,r){return t&&t.length&&n&&n.length?Dn(t,n,T,r):t},Ot.pullAt=Zo,Ot.range=nf,Ot.rangeRight=rf,Ot.rearg=vi,Ot.reject=function(t,n){var r=yi(t)?f:ln;return n=Fr(n,3),r(t,function(t,r,e){return!n(t,r,e)})},Ot.remove=function(t,n){var r=[];if(!t||!t.length)return r;var e=-1,u=[],o=t.length;for(n=Fr(n,3);++e<o;){var i=t[e];n(i,e,t)&&(r.push(i),
u.push(e))}return Fn(t,u),r},Ot.rest=Me,Ot.reverse=de,Ot.sampleSize=ke,Ot.set=function(t,n,r){return null==t?t:Zn(t,n,r)},Ot.setWith=function(t,n,r,e){return e=typeof e=="function"?e:T,null==t?t:Zn(t,n,r,e)},Ot.shuffle=function(t){return ke(t,4294967295)},Ot.slice=function(t,n,r){var e=t?t.length:0;return e?(r&&typeof r!="number"&&te(t,n,r)?(n=0,r=e):(n=null==n?0:Xe(n),r=r===T?e:Xe(r)),Tn(t,n,r)):[]},Ot.sortBy=fi,Ot.sortedUniq=function(t){return t&&t.length?Gn(t):[]},Ot.sortedUniqBy=function(t,n){
return t&&t.length?Gn(t,Fr(n)):[]},Ot.split=function(t,n,r){return r&&typeof r!="number"&&te(t,n,r)&&(n=r=T),r=r===T?4294967295:r>>>0,r?(t=eu(t))&&(typeof n=="string"||null!=n&&!Ke(n))&&(n=Yn(n),""==n&&Wt.test(t))?ur(t.match(It),0,r):oo.call(t,n,r):[]},Ot.spread=function(t,n){if(typeof t!="function")throw new Au("Expected a function");return n=n===T?0:Xu(Xe(n),0),Me(function(e){var u=e[n];return e=ur(e,0,n),u&&s(e,u),r(t,this,e)})},Ot.tail=function(t){return le(t,1)},Ot.take=function(t,n,r){return t&&t.length?(n=r||n===T?1:Xe(n),
Tn(t,0,0>n?0:n)):[]},Ot.takeRight=function(t,n,r){var e=t?t.length:0;return e?(n=r||n===T?1:Xe(n),n=e-n,Tn(t,0>n?0:n,e)):[]},Ot.takeRightWhile=function(t,n){return t&&t.length?Qn(t,Fr(n,3),false,true):[]},Ot.takeWhile=function(t,n){return t&&t.length?Qn(t,Fr(n,3)):[]},Ot.tap=function(t,n){return n(t),t},Ot.throttle=function(t,n,r){var e=true,u=true;if(typeof t!="function")throw new Au("Expected a function");return Ze(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Be(t,n,{leading:e,maxWait:n,
trailing:u})},Ot.thru=je,Ot.toArray=He,Ot.toPairs=zi,Ot.toPairsIn=Ui,Ot.toPath=function(t){return yi(t)?l(t,fe):Je(t)?[t]:lr(Co(t))},Ot.toPlainObject=ru,Ot.transform=function(t,n,r){var e=yi(t)||Ye(t);if(n=Fr(n,4),null==r)if(e||Ze(t)){var o=t.constructor;r=e?yi(t)?new o:[]:Fe(o)?un(Ju(Object(t))):{}}else r={};return(e?u:hn)(t,function(t,e,u){return n(r,t,e,u)}),r},Ot.unary=function(t){return Se(t,1)},Ot.union=To,Ot.unionBy=qo,Ot.unionWith=Vo,Ot.uniq=function(t){return t&&t.length?Hn(t):[]},Ot.uniqBy=function(t,n){
return t&&t.length?Hn(t,Fr(n)):[]},Ot.uniqWith=function(t,n){return t&&t.length?Hn(t,T,n):[]},Ot.unset=function(t,n){var r;if(null==t)r=true;else{r=t;var e=n,e=ne(e,r)?[e]:er(e);r=ie(r,e),e=fe(ve(e)),r=!(null!=r&&yn(r,e))||delete r[e]}return r},Ot.unzip=ye,Ot.unzipWith=be,Ot.update=function(t,n,r){return null==t?t:Zn(t,n,(typeof r=="function"?r:pu)(vn(t,n)),void 0)},Ot.updateWith=function(t,n,r,e){return e=typeof e=="function"?e:T,null!=t&&(t=Zn(t,n,(typeof r=="function"?r:pu)(vn(t,n)),e)),t},Ot.values=cu,
Ot.valuesIn=function(t){return null==t?[]:k(t,fu(t))},Ot.without=Ko,Ot.words=su,Ot.wrap=function(t,n){return n=null==n?pu:n,pi(n,t)},Ot.xor=Go,Ot.xorBy=Jo,Ot.xorWith=Yo,Ot.zip=Ho,Ot.zipObject=function(t,n){return nr(t||[],n||[],Yt)},Ot.zipObjectDeep=function(t,n){return nr(t||[],n||[],Zn)},Ot.zipWith=Qo,Ot.entries=zi,Ot.entriesIn=Ui,Ot.extend=mi,Ot.extendWith=Ai,vu(Ot,Ot),Ot.add=ef,Ot.attempt=Vi,Ot.camelCase=$i,Ot.capitalize=au,Ot.ceil=uf,Ot.clamp=function(t,n,r){return r===T&&(r=n,n=T),r!==T&&(r=nu(r),
r=r===r?r:0),n!==T&&(n=nu(n),n=n===n?n:0),nn(nu(t),n,r)},Ot.clone=function(t){return rn(t,false,true)},Ot.cloneDeep=function(t){return rn(t,true,true)},Ot.cloneDeepWith=function(t,n){return rn(t,true,true,n)},Ot.cloneWith=function(t,n){return rn(t,false,true,n)},Ot.deburr=lu,Ot.divide=of,Ot.endsWith=function(t,n,r){t=eu(t),n=Yn(n);var e=t.length;return r=r===T?e:nn(Xe(r),0,e),r-=n.length,r>=0&&t.indexOf(n,r)==r},Ot.eq=Ce,Ot.escape=function(t){return(t=eu(t))&&X.test(t)?t.replace(H,B):t},Ot.escapeRegExp=function(t){
return(t=eu(t))&&ft.test(t)?t.replace(it,"\\$&"):t},Ot.every=function(t,n,r){var e=yi(t)?i:cn;return r&&te(t,n,r)&&(n=T),e(t,Fr(n,3))},Ot.find=ni,Ot.findIndex=he,Ot.findKey=function(t,n){return v(t,Fr(n,3),hn)},Ot.findLast=ri,Ot.findLastIndex=pe,Ot.findLastKey=function(t,n){return v(t,Fr(n,3),pn)},Ot.floor=ff,Ot.forEach=me,Ot.forEachRight=Ae,Ot.forIn=function(t,n){return null==t?t:ko(t,Fr(n,3),fu)},Ot.forInRight=function(t,n){return null==t?t:Eo(t,Fr(n,3),fu)},Ot.forOwn=function(t,n){return t&&hn(t,Fr(n,3));
},Ot.forOwnRight=function(t,n){return t&&pn(t,Fr(n,3))},Ot.get=uu,Ot.gt=gi,Ot.gte=di,Ot.has=function(t,n){return null!=t&&Vr(t,n,yn)},Ot.hasIn=ou,Ot.head=_e,Ot.identity=pu,Ot.includes=function(t,n,r,e){return t=Ue(t)?t:cu(t),r=r&&!e?Xe(r):0,e=t.length,0>r&&(r=Xu(e+r,0)),Ge(t)?e>=r&&-1<t.indexOf(n,r):!!e&&-1<d(t,n,r)},Ot.indexOf=function(t,n,r){var e=t?t.length:0;return e?(r=null==r?0:Xe(r),0>r&&(r=Xu(e+r,0)),d(t,n,r)):-1},Ot.inRange=function(t,n,r){return n=nu(n)||0,r===T?(r=n,n=0):r=nu(r)||0,t=nu(t),
t>=to(n,r)&&t<Xu(n,r)},Ot.invoke=Wi,Ot.isArguments=ze,Ot.isArray=yi,Ot.isArrayBuffer=function(t){return Te(t)&&"[object ArrayBuffer]"==Mu.call(t)},Ot.isArrayLike=Ue,Ot.isArrayLikeObject=$e,Ot.isBoolean=function(t){return true===t||false===t||Te(t)&&"[object Boolean]"==Mu.call(t)},Ot.isBuffer=bi,Ot.isDate=function(t){return Te(t)&&"[object Date]"==Mu.call(t)},Ot.isElement=function(t){return!!t&&1===t.nodeType&&Te(t)&&!Ve(t)},Ot.isEmpty=function(t){if(Ue(t)&&(yi(t)||Ge(t)||Fe(t.splice)||ze(t)||bi(t)))return!t.length;
if(Te(t)){var n=qr(t);if("[object Map]"==n||"[object Set]"==n)return!t.size}for(var r in t)if(Wu.call(t,r))return false;return!(po&&iu(t).length)},Ot.isEqual=function(t,n){return mn(t,n)},Ot.isEqualWith=function(t,n,r){var e=(r=typeof r=="function"?r:T)?r(t,n):T;return e===T?mn(t,n,r):!!e},Ot.isError=De,Ot.isFinite=function(t){return typeof t=="number"&&Yu(t)},Ot.isFunction=Fe,Ot.isInteger=Ne,Ot.isLength=Pe,Ot.isMap=function(t){return Te(t)&&"[object Map]"==qr(t)},Ot.isMatch=function(t,n){return t===n||An(t,n,Pr(n));
},Ot.isMatchWith=function(t,n,r){return r=typeof r=="function"?r:T,An(t,n,Pr(n),r)},Ot.isNaN=function(t){return qe(t)&&t!=+t},Ot.isNative=function(t){if(Lo(t))throw new ju("This method is not supported with `core-js`. Try https://github.com/es-shims.");return On(t)},Ot.isNil=function(t){return null==t},Ot.isNull=function(t){return null===t},Ot.isNumber=qe,Ot.isObject=Ze,Ot.isObjectLike=Te,Ot.isPlainObject=Ve,Ot.isRegExp=Ke,Ot.isSafeInteger=function(t){return Ne(t)&&t>=-9007199254740991&&9007199254740991>=t;
},Ot.isSet=function(t){return Te(t)&&"[object Set]"==qr(t)},Ot.isString=Ge,Ot.isSymbol=Je,Ot.isTypedArray=Ye,Ot.isUndefined=function(t){return t===T},Ot.isWeakMap=function(t){return Te(t)&&"[object WeakMap]"==qr(t)},Ot.isWeakSet=function(t){return Te(t)&&"[object WeakSet]"==Mu.call(t)},Ot.join=function(t,n){return t?Hu.call(t,n):""},Ot.kebabCase=Di,Ot.last=ve,Ot.lastIndexOf=function(t,n,r){var e=t?t.length:0;if(!e)return-1;var u=e;if(r!==T&&(u=Xe(r),u=(0>u?Xu(e+u,0):to(u,e-1))+1),n!==n)return M(t,u-1,true);
for(;u--;)if(t[u]===n)return u;return-1},Ot.lowerCase=Fi,Ot.lowerFirst=Ni,Ot.lt=xi,Ot.lte=ji,Ot.max=function(t){return t&&t.length?an(t,pu,dn):T},Ot.maxBy=function(t,n){return t&&t.length?an(t,Fr(n),dn):T},Ot.mean=function(t){return b(t,pu)},Ot.meanBy=function(t,n){return b(t,Fr(n))},Ot.min=function(t){return t&&t.length?an(t,pu,Sn):T},Ot.minBy=function(t,n){return t&&t.length?an(t,Fr(n),Sn):T},Ot.stubArray=yu,Ot.stubFalse=bu,Ot.stubObject=function(){return{}},Ot.stubString=function(){return""},Ot.stubTrue=function(){
return true},Ot.multiply=cf,Ot.nth=function(t,n){return t&&t.length?Ln(t,Xe(n)):T},Ot.noConflict=function(){return Kt._===this&&(Kt._=Cu),this},Ot.noop=gu,Ot.now=Ee,Ot.pad=function(t,n,r){t=eu(t);var e=(n=Xe(n))?N(t):0;return!n||e>=n?t:(n=(n-e)/2,Sr(Gu(n),r)+t+Sr(Ku(n),r))},Ot.padEnd=function(t,n,r){t=eu(t);var e=(n=Xe(n))?N(t):0;return n&&n>e?t+Sr(n-e,r):t},Ot.padStart=function(t,n,r){t=eu(t);var e=(n=Xe(n))?N(t):0;return n&&n>e?Sr(n-e,r)+t:t},Ot.parseInt=function(t,n,r){return r||null==n?n=0:n&&(n=+n),
t=eu(t).replace(ct,""),no(t,n||(vt.test(t)?16:10))},Ot.random=function(t,n,r){if(r&&typeof r!="boolean"&&te(t,n,r)&&(n=r=T),r===T&&(typeof n=="boolean"?(r=n,n=T):typeof t=="boolean"&&(r=t,t=T)),t===T&&n===T?(t=0,n=1):(t=nu(t)||0,n===T?(n=t,t=0):n=nu(n)||0),t>n){var e=t;t=n,n=e}return r||t%1||n%1?(r=ro(),to(t+r*(n-t+Ft("1e-"+((r+"").length-1))),n)):Nn(t,n)},Ot.reduce=function(t,n,r){var e=yi(t)?h:x,u=3>arguments.length;return e(t,Fr(n,4),r,u,Ao)},Ot.reduceRight=function(t,n,r){var e=yi(t)?p:x,u=3>arguments.length;
return e(t,Fr(n,4),r,u,Oo)},Ot.repeat=function(t,n,r){return n=(r?te(t,n,r):n===T)?1:Xe(n),Pn(eu(t),n)},Ot.replace=function(){var t=arguments,n=eu(t[0]);return 3>t.length?n:eo.call(n,t[1],t[2])},Ot.result=function(t,n,r){n=ne(n,t)?[n]:er(n);var e=-1,u=n.length;for(u||(t=T,u=1);++e<u;){var o=null==t?T:t[fe(n[e])];o===T&&(e=u,o=r),t=Fe(o)?o.call(t):o}return t},Ot.round=af,Ot.runInContext=Z,Ot.sample=function(t){t=Ue(t)?t:cu(t);var n=t.length;return n>0?t[Nn(0,n-1)]:T},Ot.size=function(t){if(null==t)return 0;
if(Ue(t)){var n=t.length;return n&&Ge(t)?N(t):n}return Te(t)&&(n=qr(t),"[object Map]"==n||"[object Set]"==n)?t.size:iu(t).length},Ot.snakeCase=Pi,Ot.some=function(t,n,r){var e=yi(t)?_:qn;return r&&te(t,n,r)&&(n=T),e(t,Fr(n,3))},Ot.sortedIndex=function(t,n){return Vn(t,n)},Ot.sortedIndexBy=function(t,n,r){return Kn(t,n,Fr(r))},Ot.sortedIndexOf=function(t,n){var r=t?t.length:0;if(r){var e=Vn(t,n);if(r>e&&Ce(t[e],n))return e}return-1},Ot.sortedLastIndex=function(t,n){return Vn(t,n,true)},Ot.sortedLastIndexBy=function(t,n,r){
return Kn(t,n,Fr(r),true)},Ot.sortedLastIndexOf=function(t,n){if(t&&t.length){var r=Vn(t,n,true)-1;if(Ce(t[r],n))return r}return-1},Ot.startCase=Zi,Ot.startsWith=function(t,n,r){return t=eu(t),r=nn(Xe(r),0,t.length),t.lastIndexOf(Yn(n),r)==r},Ot.subtract=lf,Ot.sum=function(t){return t&&t.length?w(t,pu):0},Ot.sumBy=function(t,n){return t&&t.length?w(t,Fr(n)):0},Ot.template=function(t,n,r){var e=Ot.templateSettings;r&&te(t,n,r)&&(n=T),t=eu(t),n=Ai({},n,e,Vt),r=Ai({},n.imports,e.imports,Vt);var u,o,i=iu(r),f=k(r,i),c=0;
r=n.interpolate||wt;var a="__p+='";r=mu((n.escape||wt).source+"|"+r.source+"|"+(r===rt?pt:wt).source+"|"+(n.evaluate||wt).source+"|$","g");var l="sourceURL"in n?"//# sourceURL="+n.sourceURL+"\n":"";if(t.replace(r,function(n,r,e,i,f,l){return e||(e=i),a+=t.slice(c,l).replace(mt,L),r&&(u=true,a+="'+__e("+r+")+'"),f&&(o=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+n.length,n}),a+="';",(n=n.variable)||(a="with(obj){"+a+"}"),a=(o?a.replace(K,""):a).replace(G,"$1").replace(J,"$1;"),
a="function("+(n||"obj")+"){"+(n?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",n=Vi(function(){return Function(i,l+"return "+a).apply(T,f)}),n.source=a,De(n))throw n;return n},Ot.times=function(t,n){if(t=Xe(t),1>t||t>9007199254740991)return[];var r=4294967295,e=to(t,4294967295);for(n=Fr(n),t-=4294967295,e=m(e,n);++r<t;)n(r);return e},Ot.toFinite=Qe,Ot.toInteger=Xe,Ot.toLength=tu,Ot.toLower=function(t){
return eu(t).toLowerCase()},Ot.toNumber=nu,Ot.toSafeInteger=function(t){return nn(Xe(t),-9007199254740991,9007199254740991)},Ot.toString=eu,Ot.toUpper=function(t){return eu(t).toUpperCase()},Ot.trim=function(t,n,r){return(t=eu(t))&&(r||n===T)?t.replace(ct,""):t&&(n=Yn(n))?(t=t.match(It),n=n.match(It),ur(t,S(t,n),I(t,n)+1).join("")):t},Ot.trimEnd=function(t,n,r){return(t=eu(t))&&(r||n===T)?t.replace(lt,""):t&&(n=Yn(n))?(t=t.match(It),n=I(t,n.match(It))+1,ur(t,0,n).join("")):t},Ot.trimStart=function(t,n,r){
return(t=eu(t))&&(r||n===T)?t.replace(at,""):t&&(n=Yn(n))?(t=t.match(It),n=S(t,n.match(It)),ur(t,n).join("")):t},Ot.truncate=function(t,n){var r=30,e="...";if(Ze(n))var u="separator"in n?n.separator:u,r="length"in n?Xe(n.length):r,e="omission"in n?Yn(n.omission):e;t=eu(t);var o=t.length;if(Wt.test(t))var i=t.match(It),o=i.length;if(r>=o)return t;if(o=r-N(e),1>o)return e;if(r=i?ur(i,0,o).join(""):t.slice(0,o),u===T)return r+e;if(i&&(o+=r.length-o),Ke(u)){if(t.slice(o).search(u)){var f=r;for(u.global||(u=mu(u.source,eu(_t.exec(u))+"g")),
u.lastIndex=0;i=u.exec(f);)var c=i.index;r=r.slice(0,c===T?o:c)}}else t.indexOf(Yn(u),o)!=o&&(u=r.lastIndexOf(u),u>-1&&(r=r.slice(0,u)));return r+e},Ot.unescape=function(t){return(t=eu(t))&&Q.test(t)?t.replace(Y,P):t},Ot.uniqueId=function(t){var n=++Bu;return eu(t)+n},Ot.upperCase=Ti,Ot.upperFirst=qi,Ot.each=me,Ot.eachRight=Ae,Ot.first=_e,vu(Ot,function(){var t={};return hn(Ot,function(n,r){Wu.call(Ot.prototype,r)||(t[r]=n)}),t}(),{chain:false}),Ot.VERSION="4.13.1",u("bind bindKey curry curryRight partial partialRight".split(" "),function(t){
Ot[t].placeholder=Ot}),u(["drop","take"],function(t,n){Ut.prototype[t]=function(r){var e=this.__filtered__;if(e&&!n)return new Ut(this);r=r===T?1:Xu(Xe(r),0);var u=this.clone();return e?u.__takeCount__=to(r,u.__takeCount__):u.__views__.push({size:to(r,4294967295),type:t+(0>u.__dir__?"Right":"")}),u},Ut.prototype[t+"Right"]=function(n){return this.reverse()[t](n).reverse()}}),u(["filter","map","takeWhile"],function(t,n){var r=n+1,e=1==r||3==r;Ut.prototype[t]=function(t){var n=this.clone();return n.__iteratees__.push({
iteratee:Fr(t,3),type:r}),n.__filtered__=n.__filtered__||e,n}}),u(["head","last"],function(t,n){var r="take"+(n?"Right":"");Ut.prototype[t]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(t,n){var r="drop"+(n?"":"Right");Ut.prototype[t]=function(){return this.__filtered__?new Ut(this):this[r](1)}}),Ut.prototype.compact=function(){return this.filter(pu)},Ut.prototype.find=function(t){return this.filter(t).head()},Ut.prototype.findLast=function(t){return this.reverse().find(t);
},Ut.prototype.invokeMap=Me(function(t,n){return typeof t=="function"?new Ut(this):this.map(function(r){return wn(r,t,n)})}),Ut.prototype.reject=function(t){return t=Fr(t,3),this.filter(function(n){return!t(n)})},Ut.prototype.slice=function(t,n){t=Xe(t);var r=this;return r.__filtered__&&(t>0||0>n)?new Ut(r):(0>t?r=r.takeRight(-t):t&&(r=r.drop(t)),n!==T&&(n=Xe(n),r=0>n?r.dropRight(-n):r.take(n-t)),r)},Ut.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},Ut.prototype.toArray=function(){
return this.take(4294967295)},hn(Ut.prototype,function(t,n){var r=/^(?:filter|find|map|reject)|While$/.test(n),e=/^(?:head|last)$/.test(n),u=Ot[e?"take"+("last"==n?"Right":""):n],o=e||/^find/.test(n);u&&(Ot.prototype[n]=function(){function n(t){return t=u.apply(Ot,s([t],f)),e&&h?t[0]:t}var i=this.__wrapped__,f=e?[1]:arguments,c=i instanceof Ut,a=f[0],l=c||yi(i);l&&r&&typeof a=="function"&&1!=a.length&&(c=l=false);var h=this.__chain__,p=!!this.__actions__.length,a=o&&!h,c=c&&!p;return!o&&l?(i=c?i:new Ut(this),
i=t.apply(i,f),i.__actions__.push({func:je,args:[n],thisArg:T}),new zt(i,h)):a&&c?t.apply(this,f):(i=this.thru(n),a?e?i.value()[0]:i.value():i)})}),u("pop push shift sort splice unshift".split(" "),function(t){var n=Ou[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",e=/^(?:pop|shift)$/.test(t);Ot.prototype[t]=function(){var t=arguments;if(e&&!this.__chain__){var u=this.value();return n.apply(yi(u)?u:[],t)}return this[r](function(r){return n.apply(yi(r)?r:[],t)})}}),hn(Ut.prototype,function(t,n){
var r=Ot[n];if(r){var e=r.name+"";(_o[e]||(_o[e]=[])).push({name:n,func:r})}}),_o[Ar(T,2).name]=[{name:"wrapper",func:T}],Ut.prototype.clone=function(){var t=new Ut(this.__wrapped__);return t.__actions__=lr(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=lr(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=lr(this.__views__),t},Ut.prototype.reverse=function(){if(this.__filtered__){var t=new Ut(this);t.__dir__=-1,t.__filtered__=true}else t=this.clone(),
t.__dir__*=-1;return t},Ut.prototype.value=function(){var t,n=this.__wrapped__.value(),r=this.__dir__,e=yi(n),u=0>r,o=e?n.length:0;t=o;for(var i=this.__views__,f=0,c=-1,a=i.length;++c<a;){var l=i[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":t-=s;break;case"take":t=to(t,f+s);break;case"takeRight":f=Xu(f,t-s)}}if(t={start:f,end:t},i=t.start,f=t.end,t=f-i,u=u?f:i-1,i=this.__iteratees__,f=i.length,c=0,a=to(t,this.__takeCount__),!e||200>o||o==t&&a==t)return Xn(n,this.__actions__);e=[];
t:for(;t--&&a>c;){for(u+=r,o=-1,l=n[u];++o<f;){var h=i[o],s=h.type,h=(0,h.iteratee)(l);if(2==s)l=h;else if(!h){if(1==s)continue t;break t}}e[c++]=l}return e},Ot.prototype.at=Xo,Ot.prototype.chain=function(){return xe(this)},Ot.prototype.commit=function(){return new zt(this.value(),this.__chain__)},Ot.prototype.next=function(){this.__values__===T&&(this.__values__=He(this.value()));var t=this.__index__>=this.__values__.length,n=t?T:this.__values__[this.__index__++];return{done:t,value:n}},Ot.prototype.plant=function(t){
for(var n,r=this;r instanceof kt;){var e=ae(r);e.__index__=0,e.__values__=T,n?u.__wrapped__=e:n=e;var u=e,r=r.__wrapped__}return u.__wrapped__=t,n},Ot.prototype.reverse=function(){var t=this.__wrapped__;return t instanceof Ut?(this.__actions__.length&&(t=new Ut(this)),t=t.reverse(),t.__actions__.push({func:je,args:[de],thisArg:T}),new zt(t,this.__chain__)):this.thru(de)},Ot.prototype.toJSON=Ot.prototype.valueOf=Ot.prototype.value=function(){return Xn(this.__wrapped__,this.__actions__)},Zu&&(Ot.prototype[Zu]=we),
Ot}var T,q=1/0,V=NaN,K=/\b__p\+='';/g,G=/\b(__p\+=)''\+/g,J=/(__e\(.*?\)|\b__t\))\+'';/g,Y=/&(?:amp|lt|gt|quot|#39|#96);/g,H=/[&<>"'`]/g,Q=RegExp(Y.source),X=RegExp(H.source),tt=/<%-([\s\S]+?)%>/g,nt=/<%([\s\S]+?)%>/g,rt=/<%=([\s\S]+?)%>/g,et=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,ut=/^\w*$/,ot=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g,it=/[\\^$.*+?()[\]{}|]/g,ft=RegExp(it.source),ct=/^\s+|\s+$/g,at=/^\s+/,lt=/\s+$/,st=/[a-zA-Z0-9]+/g,ht=/\\(\\)?/g,pt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_t=/\w*$/,vt=/^0x/i,gt=/^[-+]0x[0-9a-f]+$/i,dt=/^0b[01]+$/i,yt=/^\[object .+?Constructor\]$/,bt=/^0o[0-7]+$/i,xt=/^(?:0|[1-9]\d*)$/,jt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,wt=/($^)/,mt=/['\n\r\u2028\u2029\\]/g,At="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",Ot="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+At,kt="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",Et=RegExp("['\u2019]","g"),St=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]","g"),It=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+kt+At,"g"),Rt=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d+",Ot].join("|"),"g"),Wt=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),Bt=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Lt="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ isFinite parseInt setTimeout".split(" "),Mt={};
Mt["[object Float32Array]"]=Mt["[object Float64Array]"]=Mt["[object Int8Array]"]=Mt["[object Int16Array]"]=Mt["[object Int32Array]"]=Mt["[object Uint8Array]"]=Mt["[object Uint8ClampedArray]"]=Mt["[object Uint16Array]"]=Mt["[object Uint32Array]"]=true,Mt["[object Arguments]"]=Mt["[object Array]"]=Mt["[object ArrayBuffer]"]=Mt["[object Boolean]"]=Mt["[object DataView]"]=Mt["[object Date]"]=Mt["[object Error]"]=Mt["[object Function]"]=Mt["[object Map]"]=Mt["[object Number]"]=Mt["[object Object]"]=Mt["[object RegExp]"]=Mt["[object Set]"]=Mt["[object String]"]=Mt["[object WeakMap]"]=false;
var Ct={};Ct["[object Arguments]"]=Ct["[object Array]"]=Ct["[object ArrayBuffer]"]=Ct["[object DataView]"]=Ct["[object Boolean]"]=Ct["[object Date]"]=Ct["[object Float32Array]"]=Ct["[object Float64Array]"]=Ct["[object Int8Array]"]=Ct["[object Int16Array]"]=Ct["[object Int32Array]"]=Ct["[object Map]"]=Ct["[object Number]"]=Ct["[object Object]"]=Ct["[object RegExp]"]=Ct["[object Set]"]=Ct["[object String]"]=Ct["[object Symbol]"]=Ct["[object Uint8Array]"]=Ct["[object Uint8ClampedArray]"]=Ct["[object Uint16Array]"]=Ct["[object Uint32Array]"]=true,
Ct["[object Error]"]=Ct["[object Function]"]=Ct["[object WeakMap]"]=false;var zt={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O",
"\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ut={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},$t={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},Dt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Ft=parseFloat,Nt=parseInt,Pt=typeof exports=="object"&&exports,Zt=Pt&&typeof module=="object"&&module,Tt=Zt&&Zt.exports===Pt,qt=R(typeof self=="object"&&self),Vt=R(typeof this=="object"&&this),Kt=R(typeof global=="object"&&global)||qt||Vt||Function("return this")(),Gt=Z();
(qt||{})._=Gt,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return Gt}):Zt?((Zt.exports=Gt)._=Gt,Pt._=Gt):Kt._=Gt}).call(this);
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册