1255 lines
36 KiB
JavaScript
1255 lines
36 KiB
JavaScript
/**
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|
* Released under MIT license <https://lodash.com/license>
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
*/
|
|
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|
var FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
/** Used as the internal argument placeholder. */
|
|
var PLACEHOLDER = '__lodash_placeholder__';
|
|
|
|
/** Used to compose bitmasks for function metadata. */
|
|
var BIND_FLAG = 1,
|
|
BIND_KEY_FLAG = 2,
|
|
CURRY_BOUND_FLAG = 4,
|
|
CURRY_FLAG = 8,
|
|
CURRY_RIGHT_FLAG = 16,
|
|
PARTIAL_FLAG = 32,
|
|
PARTIAL_RIGHT_FLAG = 64,
|
|
ARY_FLAG = 128,
|
|
REARG_FLAG = 256,
|
|
FLIP_FLAG = 512;
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var INFINITY = 1 / 0,
|
|
MAX_SAFE_INTEGER = 9007199254740991,
|
|
MAX_INTEGER = 1.7976931348623157e+308,
|
|
NAN = 0 / 0;
|
|
|
|
/** Used to associate wrap methods with their bit flags. */
|
|
var wrapFlags = [
|
|
['ary', ARY_FLAG],
|
|
['bind', BIND_FLAG],
|
|
['bindKey', BIND_KEY_FLAG],
|
|
['curry', CURRY_FLAG],
|
|
['curryRight', CURRY_RIGHT_FLAG],
|
|
['flip', FLIP_FLAG],
|
|
['partial', PARTIAL_FLAG],
|
|
['partialRight', PARTIAL_RIGHT_FLAG],
|
|
['rearg', REARG_FLAG]
|
|
];
|
|
|
|
/** `Object#toString` result references. */
|
|
var funcTag = '[object Function]',
|
|
genTag = '[object GeneratorFunction]',
|
|
symbolTag = '[object Symbol]';
|
|
|
|
/**
|
|
* Used to match `RegExp`
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|
*/
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
|
|
/** Used to match leading and trailing whitespace. */
|
|
var reTrim = /^\s+|\s+$/g;
|
|
|
|
/** Used to match wrap detail comments. */
|
|
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
|
|
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
|
|
reSplitDetails = /,? & /;
|
|
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
|
|
/** Used to detect binary string values. */
|
|
var reIsBinary = /^0b[01]+$/i;
|
|
|
|
/** Used to detect host constructors (Safari). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used to detect octal string values. */
|
|
var reIsOctal = /^0o[0-7]+$/i;
|
|
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
|
|
/** Built-in method references without a dependency on `root`. */
|
|
var freeParseInt = parseInt;
|
|
|
|
/** Detect free variable `global` from Node.js. */
|
|
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
|
|
|
/** Detect free variable `self`. */
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
|
|
/** Used as a reference to the global object. */
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|
|
|
/**
|
|
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to invoke.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} args The arguments to invoke `func` with.
|
|
* @returns {*} Returns the result of `func`.
|
|
*/
|
|
function apply(func, thisArg, args) {
|
|
switch (args.length) {
|
|
case 0: return func.call(thisArg);
|
|
case 1: return func.call(thisArg, args[0]);
|
|
case 2: return func.call(thisArg, args[0], args[1]);
|
|
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
}
|
|
return func.apply(thisArg, args);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array ? array.length : 0;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.includes` for arrays without support for
|
|
* specifying an index to search from.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to inspect.
|
|
* @param {*} target The value to search for.
|
|
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
|
*/
|
|
function arrayIncludes(array, value) {
|
|
var length = array ? array.length : 0;
|
|
return !!length && baseIndexOf(array, value, 0) > -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.findIndex` and `_.findLastIndex` without
|
|
* support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseFindIndex(array, predicate, fromIndex, fromRight) {
|
|
var length = array.length,
|
|
index = fromIndex + (fromRight ? 1 : -1);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
if (predicate(array[index], index, array)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.indexOf` without `fromIndex` bounds checks.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOf(array, value, fromIndex) {
|
|
if (value !== value) {
|
|
return baseFindIndex(array, baseIsNaN, fromIndex);
|
|
}
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNaN` without support for number objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
|
*/
|
|
function baseIsNaN(value) {
|
|
return value !== value;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of `placeholder` occurrences in `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} placeholder The placeholder to search for.
|
|
* @returns {number} Returns the placeholder count.
|
|
*/
|
|
function countHolders(array, placeholder) {
|
|
var length = array.length,
|
|
result = 0;
|
|
|
|
while (length--) {
|
|
if (array[length] === placeholder) {
|
|
result++;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {*} Returns the property value.
|
|
*/
|
|
function getValue(object, key) {
|
|
return object == null ? undefined : object[key];
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a host object in IE < 9.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
|
*/
|
|
function isHostObject(value) {
|
|
// Many host objects are `Object` objects that can coerce to strings
|
|
// despite having improperly defined `toString` methods.
|
|
var result = false;
|
|
if (value != null && typeof value.toString != 'function') {
|
|
try {
|
|
result = !!(value + '');
|
|
} catch (e) {}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Replaces all `placeholder` elements in `array` with an internal placeholder
|
|
* and returns an array of their indexes.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {*} placeholder The placeholder to replace.
|
|
* @returns {Array} Returns the new array of placeholder indexes.
|
|
*/
|
|
function replaceHolders(array, placeholder) {
|
|
var index = -1,
|
|
length = array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (value === placeholder || value === PLACEHOLDER) {
|
|
array[index] = PLACEHOLDER;
|
|
result[resIndex++] = index;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Used for built-in method references. */
|
|
var funcProto = Function.prototype,
|
|
objectProto = Object.prototype;
|
|
|
|
/** Used to detect overreaching core-js shims. */
|
|
var coreJsData = root['__core-js_shared__'];
|
|
|
|
/** Used to detect methods masquerading as native. */
|
|
var maskSrcKey = (function() {
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|
}());
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = funcProto.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/**
|
|
* Used to resolve the
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var objectToString = objectProto.toString;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/** Built-in value references. */
|
|
var objectCreate = Object.create;
|
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
var nativeMax = Math.max,
|
|
nativeMin = Math.min;
|
|
|
|
/* Used to set `toString` methods. */
|
|
var defineProperty = (function() {
|
|
var func = getNative(Object, 'defineProperty'),
|
|
name = getNative.name;
|
|
|
|
return (name && name.length > 2) ? func : undefined;
|
|
}());
|
|
|
|
/**
|
|
* The base implementation of `_.create` without support for assigning
|
|
* properties to the created object.
|
|
*
|
|
* @private
|
|
* @param {Object} prototype The object to inherit from.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function baseCreate(proto) {
|
|
return isObject(proto) ? objectCreate(proto) : {};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
* else `false`.
|
|
*/
|
|
function baseIsNative(value) {
|
|
if (!isObject(value) || isMasked(value)) {
|
|
return false;
|
|
}
|
|
var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
|
|
return pattern.test(toSource(value));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseRest(func, start) {
|
|
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
array = Array(length);
|
|
|
|
while (++index < length) {
|
|
array[index] = args[start + index];
|
|
}
|
|
index = -1;
|
|
var otherArgs = Array(start + 1);
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = array;
|
|
return apply(func, this, otherArgs);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates an array that is the composition of partially applied arguments,
|
|
* placeholders, and provided arguments into a single array of arguments.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to prepend to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgs(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersLength = holders.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(leftLength + rangeLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
result[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (++argsIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[holders[argsIndex]] = args[argsIndex];
|
|
}
|
|
}
|
|
while (rangeLength--) {
|
|
result[leftIndex++] = args[argsIndex++];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This function is like `composeArgs` except that the arguments composition
|
|
* is tailored for `_.partialRight`.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to append to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgsRight(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersIndex = -1,
|
|
holdersLength = holders.length,
|
|
rightIndex = -1,
|
|
rightLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(rangeLength + rightLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++argsIndex < rangeLength) {
|
|
result[argsIndex] = args[argsIndex];
|
|
}
|
|
var offset = argsIndex;
|
|
while (++rightIndex < rightLength) {
|
|
result[offset + rightIndex] = partials[rightIndex];
|
|
}
|
|
while (++holdersIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Copies the values of `source` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} source The array to copy values from.
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function copyArray(source, array) {
|
|
var index = -1,
|
|
length = source.length;
|
|
|
|
array || (array = Array(length));
|
|
while (++index < length) {
|
|
array[index] = source[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the optional `this`
|
|
* binding of `thisArg`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createBind(func, bitmask, thisArg) {
|
|
var isBind = bitmask & BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return fn.apply(isBind ? thisArg : this, arguments);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that produces an instance of `Ctor` regardless of
|
|
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
|
|
*
|
|
* @private
|
|
* @param {Function} Ctor The constructor to wrap.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCtor(Ctor) {
|
|
return function() {
|
|
// Use a `switch` statement to work with class constructors. See
|
|
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
|
|
// for more details.
|
|
var args = arguments;
|
|
switch (args.length) {
|
|
case 0: return new Ctor;
|
|
case 1: return new Ctor(args[0]);
|
|
case 2: return new Ctor(args[0], args[1]);
|
|
case 3: return new Ctor(args[0], args[1], args[2]);
|
|
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
|
|
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
|
|
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
}
|
|
var thisBinding = baseCreate(Ctor.prototype),
|
|
result = Ctor.apply(thisBinding, args);
|
|
|
|
// Mimic the constructor's `return` behavior.
|
|
// See https://es5.github.io/#x13.2.2 for more details.
|
|
return isObject(result) ? result : thisBinding;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to enable currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {number} arity The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCurry(func, bitmask, arity) {
|
|
var Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length,
|
|
placeholder = getHolder(wrapper);
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
|
|
? []
|
|
: replaceHolders(args, placeholder);
|
|
|
|
length -= holders.length;
|
|
if (length < arity) {
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, undefined,
|
|
args, holders, undefined, undefined, arity - length);
|
|
}
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return apply(fn, this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with optional `this`
|
|
* binding of `thisArg`, partial application, and currying.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [partialsRight] The arguments to append to those provided
|
|
* to the new function.
|
|
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
|
|
var isAry = bitmask & ARY_FLAG,
|
|
isBind = bitmask & BIND_FLAG,
|
|
isBindKey = bitmask & BIND_KEY_FLAG,
|
|
isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
|
|
isFlip = bitmask & FLIP_FLAG,
|
|
Ctor = isBindKey ? undefined : createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length;
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
if (isCurried) {
|
|
var placeholder = getHolder(wrapper),
|
|
holdersCount = countHolders(args, placeholder);
|
|
}
|
|
if (partials) {
|
|
args = composeArgs(args, partials, holders, isCurried);
|
|
}
|
|
if (partialsRight) {
|
|
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
|
|
}
|
|
length -= holdersCount;
|
|
if (isCurried && length < arity) {
|
|
var newHolders = replaceHolders(args, placeholder);
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
|
|
args, newHolders, argPos, ary, arity - length
|
|
);
|
|
}
|
|
var thisBinding = isBind ? thisArg : this,
|
|
fn = isBindKey ? thisBinding[func] : func;
|
|
|
|
length = args.length;
|
|
if (argPos) {
|
|
args = reorder(args, argPos);
|
|
} else if (isFlip && length > 1) {
|
|
args.reverse();
|
|
}
|
|
if (isAry && ary < length) {
|
|
args.length = ary;
|
|
}
|
|
if (this && this !== root && this instanceof wrapper) {
|
|
fn = Ctor || createCtor(fn);
|
|
}
|
|
return fn.apply(thisBinding, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the `this` binding
|
|
* of `thisArg` and `partials` prepended to the arguments it receives.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} partials The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createPartial(func, bitmask, thisArg, partials) {
|
|
var isBind = bitmask & BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var argsIndex = -1,
|
|
argsLength = arguments.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
args = Array(leftLength + argsLength),
|
|
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
args[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (argsLength--) {
|
|
args[leftIndex++] = arguments[++argsIndex];
|
|
}
|
|
return apply(fn, isBind ? thisArg : this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to continue currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {Function} wrapFunc The function to create the `func` wrapper.
|
|
* @param {*} placeholder The placeholder value.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isCurry = bitmask & CURRY_FLAG,
|
|
newHolders = isCurry ? holders : undefined,
|
|
newHoldersRight = isCurry ? undefined : holders,
|
|
newPartials = isCurry ? partials : undefined,
|
|
newPartialsRight = isCurry ? undefined : partials;
|
|
|
|
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
|
|
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
|
|
|
|
if (!(bitmask & CURRY_BOUND_FLAG)) {
|
|
bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
|
|
}
|
|
|
|
var result = wrapFunc(func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity);
|
|
result.placeholder = placeholder;
|
|
return setWrapToString(result, func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that either curries or invokes `func` with optional
|
|
* `this` binding and partially applied arguments.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags.
|
|
* The bitmask may be composed of the following flags:
|
|
* 1 - `_.bind`
|
|
* 2 - `_.bindKey`
|
|
* 4 - `_.curry` or `_.curryRight` of a bound function
|
|
* 8 - `_.curry`
|
|
* 16 - `_.curryRight`
|
|
* 32 - `_.partial`
|
|
* 64 - `_.partialRight`
|
|
* 128 - `_.rearg`
|
|
* 256 - `_.ary`
|
|
* 512 - `_.flip`
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to be partially applied.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isBindKey = bitmask & BIND_KEY_FLAG;
|
|
if (!isBindKey && typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
var length = partials ? partials.length : 0;
|
|
if (!length) {
|
|
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
|
|
partials = holders = undefined;
|
|
}
|
|
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
|
|
arity = arity === undefined ? arity : toInteger(arity);
|
|
length -= holders ? holders.length : 0;
|
|
|
|
if (bitmask & PARTIAL_RIGHT_FLAG) {
|
|
var partialsRight = partials,
|
|
holdersRight = holders;
|
|
|
|
partials = holders = undefined;
|
|
}
|
|
|
|
var newData = [
|
|
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
|
|
argPos, ary, arity
|
|
];
|
|
|
|
func = newData[0];
|
|
bitmask = newData[1];
|
|
thisArg = newData[2];
|
|
partials = newData[3];
|
|
holders = newData[4];
|
|
arity = newData[9] = newData[9] == null
|
|
? (isBindKey ? 0 : func.length)
|
|
: nativeMax(newData[9] - length, 0);
|
|
|
|
if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
|
|
bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
|
|
}
|
|
if (!bitmask || bitmask == BIND_FLAG) {
|
|
var result = createBind(func, bitmask, thisArg);
|
|
} else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
|
|
result = createCurry(func, bitmask, arity);
|
|
} else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
|
|
result = createPartial(func, bitmask, thisArg, partials);
|
|
} else {
|
|
result = createHybrid.apply(undefined, newData);
|
|
}
|
|
return setWrapToString(result, func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Gets the argument placeholder value for `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to inspect.
|
|
* @returns {*} Returns the placeholder value.
|
|
*/
|
|
function getHolder(func) {
|
|
var object = func;
|
|
return object.placeholder;
|
|
}
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = getValue(object, key);
|
|
return baseIsNative(value) ? value : undefined;
|
|
}
|
|
|
|
/**
|
|
* Extracts wrapper details from the `source` body comment.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to inspect.
|
|
* @returns {Array} Returns the wrapper details.
|
|
*/
|
|
function getWrapDetails(source) {
|
|
var match = source.match(reWrapDetails);
|
|
return match ? match[1].split(reSplitDetails) : [];
|
|
}
|
|
|
|
/**
|
|
* Inserts wrapper `details` in a comment at the top of the `source` body.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to modify.
|
|
* @returns {Array} details The details to insert.
|
|
* @returns {string} Returns the modified source.
|
|
*/
|
|
function insertWrapDetails(source, details) {
|
|
var length = details.length,
|
|
lastIndex = length - 1;
|
|
|
|
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
|
|
details = details.join(length > 2 ? ', ' : ' ');
|
|
return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
return !!length &&
|
|
(typeof value == 'number' || reIsUint.test(value)) &&
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` has its source masked.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to check.
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|
*/
|
|
function isMasked(func) {
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|
}
|
|
|
|
/**
|
|
* Reorder `array` according to the specified indexes where the element at
|
|
* the first index is assigned as the first element, the element at
|
|
* the second index is assigned as the second element, and so on.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to reorder.
|
|
* @param {Array} indexes The arranged array indexes.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function reorder(array, indexes) {
|
|
var arrLength = array.length,
|
|
length = nativeMin(indexes.length, arrLength),
|
|
oldArray = copyArray(array);
|
|
|
|
while (length--) {
|
|
var index = indexes[length];
|
|
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
|
|
* with wrapper details in a comment at the top of the source body.
|
|
*
|
|
* @private
|
|
* @param {Function} wrapper The function to modify.
|
|
* @param {Function} reference The reference function.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Function} Returns `wrapper`.
|
|
*/
|
|
var setWrapToString = !defineProperty ? identity : function(wrapper, reference, bitmask) {
|
|
var source = (reference + '');
|
|
return defineProperty(wrapper, 'toString', {
|
|
'configurable': true,
|
|
'enumerable': false,
|
|
'value': constant(insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)))
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Converts `func` to its source code.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to process.
|
|
* @returns {string} Returns the source code.
|
|
*/
|
|
function toSource(func) {
|
|
if (func != null) {
|
|
try {
|
|
return funcToString.call(func);
|
|
} catch (e) {}
|
|
try {
|
|
return (func + '');
|
|
} catch (e) {}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Updates wrapper `details` based on `bitmask` flags.
|
|
*
|
|
* @private
|
|
* @returns {Array} details The details to modify.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Array} Returns `details`.
|
|
*/
|
|
function updateWrapDetails(details, bitmask) {
|
|
arrayEach(wrapFlags, function(pair) {
|
|
var value = '_.' + pair[0];
|
|
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
|
|
details.push(value);
|
|
}
|
|
});
|
|
return details.sort();
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of `thisArg`
|
|
* and `partials` prepended to the arguments it receives.
|
|
*
|
|
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
|
|
* may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
|
|
* property of bound functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to bind.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new bound function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, punctuation) {
|
|
* return greeting + ' ' + this.user + punctuation;
|
|
* }
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
*
|
|
* var bound = _.bind(greet, object, 'hi');
|
|
* bound('!');
|
|
* // => 'hi fred!'
|
|
*
|
|
* // Bound with placeholders.
|
|
* var bound = _.bind(greet, object, _, '!');
|
|
* bound('hi');
|
|
* // => 'hi fred!'
|
|
*/
|
|
var bind = baseRest(function(func, thisArg, partials) {
|
|
var bitmask = BIND_FLAG;
|
|
if (partials.length) {
|
|
var holders = replaceHolders(partials, getHolder(bind));
|
|
bitmask |= PARTIAL_FLAG;
|
|
}
|
|
return createWrap(func, bitmask, thisArg, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in Safari 8-9 which returns 'object' for typed array and other constructors.
|
|
var tag = isObject(value) ? objectToString.call(value) : '';
|
|
return tag == funcTag || tag == genTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is the
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(_.noop);
|
|
* // => true
|
|
*
|
|
* _.isObject(null);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
var type = typeof value;
|
|
return !!value && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
* and has a `typeof` result of "object".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObjectLike({});
|
|
* // => true
|
|
*
|
|
* _.isObjectLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObjectLike(_.noop);
|
|
* // => false
|
|
*
|
|
* _.isObjectLike(null);
|
|
* // => false
|
|
*/
|
|
function isObjectLike(value) {
|
|
return !!value && typeof value == 'object';
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSymbol(Symbol.iterator);
|
|
* // => true
|
|
*
|
|
* _.isSymbol('abc');
|
|
* // => false
|
|
*/
|
|
function isSymbol(value) {
|
|
return typeof value == 'symbol' ||
|
|
(isObjectLike(value) && objectToString.call(value) == symbolTag);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a finite number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.12.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted number.
|
|
* @example
|
|
*
|
|
* _.toFinite(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toFinite(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toFinite(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toFinite('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toFinite(value) {
|
|
if (!value) {
|
|
return value === 0 ? value : 0;
|
|
}
|
|
value = toNumber(value);
|
|
if (value === INFINITY || value === -INFINITY) {
|
|
var sign = (value < 0 ? -1 : 1);
|
|
return sign * MAX_INTEGER;
|
|
}
|
|
return value === value ? value : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to an integer.
|
|
*
|
|
* **Note:** This method is loosely based on
|
|
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toInteger(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toInteger(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toInteger('3.2');
|
|
* // => 3
|
|
*/
|
|
function toInteger(value) {
|
|
var result = toFinite(value),
|
|
remainder = result % 1;
|
|
|
|
return result === result ? (remainder ? result - remainder : result) : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
* @example
|
|
*
|
|
* _.toNumber(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toNumber(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toNumber(Infinity);
|
|
* // => Infinity
|
|
*
|
|
* _.toNumber('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toNumber(value) {
|
|
if (typeof value == 'number') {
|
|
return value;
|
|
}
|
|
if (isSymbol(value)) {
|
|
return NAN;
|
|
}
|
|
if (isObject(value)) {
|
|
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
value = isObject(other) ? (other + '') : other;
|
|
}
|
|
if (typeof value != 'string') {
|
|
return value === 0 ? value : +value;
|
|
}
|
|
value = value.replace(reTrim, '');
|
|
var isBinary = reIsBinary.test(value);
|
|
return (isBinary || reIsOctal.test(value))
|
|
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
: (reIsBadHex.test(value) ? NAN : +value);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that returns `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Util
|
|
* @param {*} value The value to return from the new function.
|
|
* @returns {Function} Returns the new constant function.
|
|
* @example
|
|
*
|
|
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
|
*
|
|
* console.log(objects);
|
|
* // => [{ 'a': 1 }, { 'a': 1 }]
|
|
*
|
|
* console.log(objects[0] === objects[1]);
|
|
* // => true
|
|
*/
|
|
function constant(value) {
|
|
return function() {
|
|
return value;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* This method returns the first argument it receives.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} value Any value.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
*
|
|
* console.log(_.identity(object) === object);
|
|
* // => true
|
|
*/
|
|
function identity(value) {
|
|
return value;
|
|
}
|
|
|
|
// Assign default placeholders.
|
|
bind.placeholder = {};
|
|
|
|
module.exports = bind;
|