mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
8.3 KiB
266 lines
8.3 KiB
/**
|
|
* lodash 3.3.2 (Custom Build) <https://lodash.com/>
|
|
* Build: `lodash modern modularize exports="npm" -o ./`
|
|
* Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
* Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
* Available under MIT license <https://lodash.com/license>
|
|
*/
|
|
var arrayCopy = require('lodash._arraycopy'),
|
|
arrayEach = require('lodash._arrayeach'),
|
|
createAssigner = require('lodash._createassigner'),
|
|
isArguments = require('lodash.isarguments'),
|
|
isArray = require('lodash.isarray'),
|
|
isPlainObject = require('lodash.isplainobject'),
|
|
isTypedArray = require('lodash.istypedarray'),
|
|
keys = require('lodash.keys'),
|
|
toPlainObject = require('lodash.toplainobject');
|
|
|
|
/**
|
|
* Checks if `value` is object-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
*/
|
|
function isObjectLike(value) {
|
|
return !!value && typeof value == 'object';
|
|
}
|
|
|
|
/**
|
|
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
* of an array-like value.
|
|
*/
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
/**
|
|
* The base implementation of `_.merge` without support for argument juggling,
|
|
* multiple sources, and `this` binding `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseMerge(object, source, customizer, stackA, stackB) {
|
|
if (!isObject(object)) {
|
|
return object;
|
|
}
|
|
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
|
|
props = isSrcArr ? undefined : keys(source);
|
|
|
|
arrayEach(props || source, function(srcValue, key) {
|
|
if (props) {
|
|
key = srcValue;
|
|
srcValue = source[key];
|
|
}
|
|
if (isObjectLike(srcValue)) {
|
|
stackA || (stackA = []);
|
|
stackB || (stackB = []);
|
|
baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
|
|
}
|
|
else {
|
|
var value = object[key],
|
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
|
isCommon = result === undefined;
|
|
|
|
if (isCommon) {
|
|
result = srcValue;
|
|
}
|
|
if ((result !== undefined || (isSrcArr && !(key in object))) &&
|
|
(isCommon || (result === result ? (result !== value) : (value === value)))) {
|
|
object[key] = result;
|
|
}
|
|
}
|
|
});
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
* deep merges and tracks traversed objects enabling objects with circular
|
|
* references to be merged.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {string} key The key of the value to merge.
|
|
* @param {Function} mergeFunc The function to merge values.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
|
|
var length = stackA.length,
|
|
srcValue = source[key];
|
|
|
|
while (length--) {
|
|
if (stackA[length] == srcValue) {
|
|
object[key] = stackB[length];
|
|
return;
|
|
}
|
|
}
|
|
var value = object[key],
|
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
|
isCommon = result === undefined;
|
|
|
|
if (isCommon) {
|
|
result = srcValue;
|
|
if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
|
|
result = isArray(value)
|
|
? value
|
|
: (isArrayLike(value) ? arrayCopy(value) : []);
|
|
}
|
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
result = isArguments(value)
|
|
? toPlainObject(value)
|
|
: (isPlainObject(value) ? value : {});
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
}
|
|
}
|
|
// Add the source value to the stack of traversed objects and associate
|
|
// it with its merged value.
|
|
stackA.push(srcValue);
|
|
stackB.push(result);
|
|
|
|
if (isCommon) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
|
|
} else if (result === result ? (result !== value) : (value === value)) {
|
|
object[key] = result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gets the "length" property value of `object`.
|
|
*
|
|
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
|
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {*} Returns the "length" value.
|
|
*/
|
|
var getLength = baseProperty('length');
|
|
|
|
/**
|
|
* Checks if `value` is array-like.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(getLength(value));
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @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(1);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
// Avoid a V8 JIT bug in Chrome 19-20.
|
|
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
|
|
var type = typeof value;
|
|
return !!value && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
/**
|
|
* Recursively merges own enumerable properties of the source object(s), that
|
|
* don't resolve to `undefined` into the destination object. Subsequent sources
|
|
* overwrite property assignments of previous sources. If `customizer` is
|
|
* provided it is invoked to produce the merged values of the destination and
|
|
* source properties. If `customizer` returns `undefined` merging is handled
|
|
* by the method instead. The `customizer` is bound to `thisArg` and invoked
|
|
* with five arguments: (objectValue, sourceValue, key, object, source).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @param {*} [thisArg] The `this` binding of `customizer`.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
|
|
* };
|
|
*
|
|
* var ages = {
|
|
* 'data': [{ 'age': 36 }, { 'age': 40 }]
|
|
* };
|
|
*
|
|
* _.merge(users, ages);
|
|
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
|
|
*
|
|
* // using a customizer callback
|
|
* var object = {
|
|
* 'fruits': ['apple'],
|
|
* 'vegetables': ['beet']
|
|
* };
|
|
*
|
|
* var other = {
|
|
* 'fruits': ['banana'],
|
|
* 'vegetables': ['carrot']
|
|
* };
|
|
*
|
|
* _.merge(object, other, function(a, b) {
|
|
* if (_.isArray(a)) {
|
|
* return a.concat(b);
|
|
* }
|
|
* });
|
|
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
|
|
*/
|
|
var merge = createAssigner(baseMerge);
|
|
|
|
module.exports = merge;
|
|
|