Compare commits

...

13 Commits

Author SHA1 Message Date
John-David Dalton
87a677c811 Update lodash-amd to v4.17.21 + edadd45 (#6064)
* Fix prototype pollution in _.set and related functions

Prevents setting dangerous properties (__proto__, constructor, prototype)
that could lead to prototype pollution vulnerabilities.

* Fix command injection vulnerability in _.template

- Add validation for the variable option to prevent injection attacks
- Improve sourceURL whitespace normalization to prevent code injection

* Fix cyclic value comparison in _.isEqual

Properly checks both directions when comparing cyclic values to ensure
correct equality comparisons for circular references.

* Improve _.sortBy and _.orderBy performance and array handling

- Add early return for empty arrays in sorted index operations
- Improve array iteratee handling to support nested property paths
- Add missing keysIn import in baseClone

* Refactor _.trim, _.trimEnd, and _.trimStart implementations

Extract shared trim logic into reusable utilities (_baseTrim, _trimmedEndIndex)
for better code organization and consistency. Update related functions
(toNumber, parseInt) to use new utilities. Improve comment accuracy.

* Add documentation for predicate composition with _.overEvery and _.overSome

Enhance documentation to show how _.matches and _.matchesProperty can be
combined using _.overEvery and _.overSome for more powerful filtering.
Add examples demonstrating shorthand predicate syntax.

* Bump to v4.17.21

* Fix prototype pollution in _.unset and _.omit

Prevent prototype pollution on baseUnset function by:
- Blocking "__proto__" if not an own property
- Blocking "constructor.prototype" chains (except when starting at primitive root)
- Skipping non-string keys

See: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg

* Update JSDoc documentation to align with main branch

- Fix sortBy example ages (40 -> 30) for correct sort order demonstration
- Fix _setCacheHas return type (number -> boolean)
2025-12-10 17:03:07 -05:00
John-David Dalton
1068171675 Bump to v4.17.15. 2019-07-17 10:13:46 -07:00
John-David Dalton
bd56fcafdf Bump to v4.17.14. 2019-07-10 06:36:27 -07:00
John-David Dalton
4d706e4a8f Bump to v4.17.13. 2019-07-09 15:21:57 -07:00
John-David Dalton
f42b961697 Bump to v4.17.12. 2019-07-09 13:47:57 -07:00
John-David Dalton
db0dbd39a7 Bump to v4.17.11. 2018-09-11 22:29:45 -07:00
John-David Dalton
bbcefc5447 Bump to v4.17.10. 2018-04-24 15:30:39 -07:00
John-David Dalton
cf8bb34a76 Bump to v4.17.9. 2018-04-24 10:35:43 -07:00
John-David Dalton
6339af7cb1 Bump to v4.17.5. 2018-02-03 16:36:29 -08:00
John-David Dalton
955537d67f Bump to v4.17.4. 2016-12-31 13:33:15 -06:00
John-David Dalton
c7a7540e16 Bump to v4.17.3. 2016-12-21 15:46:13 -06:00
John-David Dalton
0c27706e89 Bump to v4.17.2. 2016-11-15 22:20:52 -08:00
John-David Dalton
76b7758fc7 Bump to v4.17.1. 2016-11-14 20:54:18 -08:00
74 changed files with 747 additions and 421 deletions

View File

@@ -1,4 +1,4 @@
Copyright JS Foundation and other contributors <https://js.foundation/>
Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
Based on Underscore.js, copyright Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>

View File

@@ -1,4 +1,4 @@
# lodash-amd v4.17.0
# lodash-amd v4.17.21
The [Lodash](https://lodash.com/) library exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules.
@@ -27,4 +27,4 @@ require({
});
```
See the [package source](https://github.com/lodash/lodash/tree/4.17.0-amd) for more details.
See the [package source](https://github.com/lodash/lodash/tree/4.17.21-amd) for more details.

View File

@@ -1,4 +1,4 @@
define(['./_Stack', './_arrayEach', './_assignValue', './_baseAssign', './_baseAssignIn', './_cloneBuffer', './_copyArray', './_copySymbols', './_copySymbolsIn', './_getAllKeys', './_getAllKeysIn', './_getTag', './_initCloneArray', './_initCloneByTag', './_initCloneObject', './isArray', './isBuffer', './isObject', './keys'], function(Stack, arrayEach, assignValue, baseAssign, baseAssignIn, cloneBuffer, copyArray, copySymbols, copySymbolsIn, getAllKeys, getAllKeysIn, getTag, initCloneArray, initCloneByTag, initCloneObject, isArray, isBuffer, isObject, keys) {
define(['./_Stack', './_arrayEach', './_assignValue', './_baseAssign', './_baseAssignIn', './_cloneBuffer', './_copyArray', './_copySymbols', './_copySymbolsIn', './_getAllKeys', './_getAllKeysIn', './_getTag', './_initCloneArray', './_initCloneByTag', './_initCloneObject', './isArray', './isBuffer', './isMap', './isObject', './isSet', './keys', './keysIn'], function(Stack, arrayEach, assignValue, baseAssign, baseAssignIn, cloneBuffer, copyArray, copySymbols, copySymbolsIn, getAllKeys, getAllKeysIn, getTag, initCloneArray, initCloneByTag, initCloneObject, isArray, isBuffer, isMap, isObject, isSet, keys, keysIn) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -108,7 +108,7 @@ define(['./_Stack', './_arrayEach', './_assignValue', './_baseAssign', './_baseA
if (!cloneableTags[tag]) {
return object ? value : {};
}
result = initCloneByTag(value, tag, baseClone, isDeep);
result = initCloneByTag(value, tag, isDeep);
}
}
// Check for circular references and return its corresponding clone.
@@ -119,6 +119,16 @@ define(['./_Stack', './_arrayEach', './_assignValue', './_baseAssign', './_baseA
}
stack.set(value, result);
if (isSet(value)) {
value.forEach(function(subValue) {
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
});
} else if (isMap(value)) {
value.forEach(function(subValue, key) {
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
}
var keysFunc = isFull
? (isFlat ? getAllKeysIn : getAllKeys)
: (isFlat ? keysIn : keys);

View File

@@ -1,4 +1,4 @@
define(['./_castPath', './_isKey', './_toKey'], function(castPath, isKey, toKey) {
define(['./_castPath', './_toKey'], function(castPath, toKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -12,7 +12,7 @@ define(['./_castPath', './_isKey', './_toKey'], function(castPath, isKey, toKey)
* @returns {*} Returns the resolved value.
*/
function baseGet(object, path) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = 0,
length = path.length;

View File

@@ -21,8 +21,7 @@ define(['./_Symbol', './_getRawTag', './_objectToString'], function(Symbol, getR
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
value = Object(value);
return (symToStringTag && symToStringTag in value)
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}

View File

@@ -1,4 +1,4 @@
define(['./_apply', './_castPath', './_isKey', './last', './_parent', './_toKey'], function(apply, castPath, isKey, last, parent, toKey) {
define(['./_apply', './_castPath', './last', './_parent', './_toKey'], function(apply, castPath, last, parent, toKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -14,12 +14,9 @@ define(['./_apply', './_castPath', './_isKey', './last', './_parent', './_toKey'
* @returns {*} Returns the result of the invoked method.
*/
function baseInvoke(object, path, args) {
if (!isKey(path, object)) {
path = castPath(path);
object = parent(object, path);
path = last(path);
}
var func = object == null ? object : object[toKey(path)];
path = castPath(path, object);
object = parent(object, path);
var func = object == null ? object : object[toKey(last(path))];
return func == null ? undefined : apply(func, object, args);
}

View File

@@ -1,4 +1,4 @@
define(['./_baseIsEqualDeep', './isObject', './isObjectLike'], function(baseIsEqualDeep, isObject, isObjectLike) {
define(['./_baseIsEqualDeep', './isObjectLike'], function(baseIsEqualDeep, isObjectLike) {
/**
* The base implementation of `_.isEqual` which supports partial comparisons
@@ -18,7 +18,7 @@ define(['./_baseIsEqualDeep', './isObject', './isObjectLike'], function(baseIsEq
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);

View File

@@ -31,17 +31,12 @@ define(['./_Stack', './_equalArrays', './_equalByTag', './_equalObjects', './_ge
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
objTag = objIsArr ? arrayTag : getTag(object),
othTag = othIsArr ? arrayTag : getTag(other);
objTag = objTag == argsTag ? objectTag : objTag;
othTag = othTag == argsTag ? objectTag : othTag;
if (!objIsArr) {
objTag = getTag(object);
objTag = objTag == argsTag ? objectTag : objTag;
}
if (!othIsArr) {
othTag = getTag(other);
othTag = othTag == argsTag ? objectTag : othTag;
}
var objIsObj = objTag == objectTag,
othIsObj = othTag == objectTag,
isSameTag = objTag == othTag;

View File

@@ -1,4 +1,4 @@
define(['./_Stack', './_assignMergeValue', './_baseFor', './_baseMergeDeep', './isObject', './keysIn'], function(Stack, assignMergeValue, baseFor, baseMergeDeep, isObject, keysIn) {
define(['./_Stack', './_assignMergeValue', './_baseFor', './_baseMergeDeep', './isObject', './keysIn', './_safeGet'], function(Stack, assignMergeValue, baseFor, baseMergeDeep, isObject, keysIn, safeGet) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -19,13 +19,13 @@ define(['./_Stack', './_assignMergeValue', './_baseFor', './_baseMergeDeep', './
return;
}
baseFor(source, function(srcValue, key) {
stack || (stack = new Stack);
if (isObject(srcValue)) {
stack || (stack = new Stack);
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
}
else {
var newValue = customizer
? customizer(object[key], srcValue, (key + ''), object, source, stack)
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
: undefined;
if (newValue === undefined) {

View File

@@ -1,4 +1,4 @@
define(['./_assignMergeValue', './_cloneBuffer', './_cloneTypedArray', './_copyArray', './_initCloneObject', './isArguments', './isArray', './isArrayLikeObject', './isBuffer', './isFunction', './isObject', './isPlainObject', './isTypedArray', './toPlainObject'], function(assignMergeValue, cloneBuffer, cloneTypedArray, copyArray, initCloneObject, isArguments, isArray, isArrayLikeObject, isBuffer, isFunction, isObject, isPlainObject, isTypedArray, toPlainObject) {
define(['./_assignMergeValue', './_cloneBuffer', './_cloneTypedArray', './_copyArray', './_initCloneObject', './isArguments', './isArray', './isArrayLikeObject', './isBuffer', './isFunction', './isObject', './isPlainObject', './isTypedArray', './_safeGet', './toPlainObject'], function(assignMergeValue, cloneBuffer, cloneTypedArray, copyArray, initCloneObject, isArguments, isArray, isArrayLikeObject, isBuffer, isFunction, isObject, isPlainObject, isTypedArray, safeGet, toPlainObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -19,8 +19,8 @@ define(['./_assignMergeValue', './_cloneBuffer', './_cloneTypedArray', './_copyA
* counterparts.
*/
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = object[key],
srcValue = source[key],
var objValue = safeGet(object, key),
srcValue = safeGet(source, key),
stacked = stack.get(srcValue);
if (stacked) {
@@ -63,7 +63,7 @@ define(['./_assignMergeValue', './_cloneBuffer', './_cloneTypedArray', './_copyA
if (isArguments(objValue)) {
newValue = toPlainObject(objValue);
}
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
else if (!isObject(objValue) || isFunction(objValue)) {
newValue = initCloneObject(srcValue);
}
}

View File

@@ -1,4 +1,4 @@
define(['./_arrayMap', './_baseIteratee', './_baseMap', './_baseSortBy', './_baseUnary', './_compareMultiple', './identity'], function(arrayMap, baseIteratee, baseMap, baseSortBy, baseUnary, compareMultiple, identity) {
define(['./_arrayMap', './_baseGet', './_baseIteratee', './_baseMap', './_baseSortBy', './_baseUnary', './_compareMultiple', './identity', './isArray'], function(arrayMap, baseGet, baseIteratee, baseMap, baseSortBy, baseUnary, compareMultiple, identity, isArray) {
/**
* The base implementation of `_.orderBy` without param guards.
@@ -10,8 +10,21 @@ define(['./_arrayMap', './_baseIteratee', './_baseMap', './_baseSortBy', './_bas
* @returns {Array} Returns the new sorted array.
*/
function baseOrderBy(collection, iteratees, orders) {
if (iteratees.length) {
iteratees = arrayMap(iteratees, function(iteratee) {
if (isArray(iteratee)) {
return function(value) {
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
}
}
return iteratee;
});
} else {
iteratees = [identity];
}
var index = -1;
iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(baseIteratee));
iteratees = arrayMap(iteratees, baseUnary(baseIteratee));
var result = baseMap(collection, function(value, key, collection) {
var criteria = arrayMap(iteratees, function(iteratee) {

View File

@@ -10,7 +10,6 @@ define(['./_basePickBy', './hasIn'], function(basePickBy, hasIn) {
* @returns {Object} Returns the new object.
*/
function basePick(object, paths) {
object = Object(object);
return basePickBy(object, paths, function(value, path) {
return hasIn(object, path);
});

View File

@@ -1,4 +1,4 @@
define(['./_baseGet', './_baseSet'], function(baseGet, baseSet) {
define(['./_baseGet', './_baseSet', './_castPath'], function(baseGet, baseSet, castPath) {
/**
* The base implementation of `_.pickBy` without support for iteratee shorthands.
@@ -19,7 +19,7 @@ define(['./_baseGet', './_baseSet'], function(baseGet, baseSet) {
value = baseGet(object, path);
if (predicate(value, path)) {
baseSet(result, path, value);
baseSet(result, castPath(path, object), value);
}
}
return result;

View File

@@ -1,4 +1,4 @@
define(['./_castPath', './_isIndex', './_isKey', './last', './_parent', './_toKey'], function(castPath, isIndex, isKey, last, parent, toKey) {
define(['./_baseUnset', './_isIndex'], function(baseUnset, isIndex) {
/** Used for built-in method references. */
var arrayProto = Array.prototype;
@@ -25,17 +25,8 @@ define(['./_castPath', './_isIndex', './_isKey', './last', './_parent', './_toKe
var previous = index;
if (isIndex(index)) {
splice.call(array, index, 1);
}
else if (!isKey(index, array)) {
var path = castPath(index),
object = parent(array, path);
if (object != null) {
delete object[toKey(last(path))];
}
}
else {
delete array[toKey(index)];
} else {
baseUnset(array, index);
}
}
}

View File

@@ -1,4 +1,4 @@
define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject', './_toKey'], function(assignValue, castPath, isIndex, isKey, isObject, toKey) {
define(['./_assignValue', './_castPath', './_isIndex', './isObject', './_toKey'], function(assignValue, castPath, isIndex, isObject, toKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -17,7 +17,7 @@ define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject',
if (!isObject(object)) {
return object;
}
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length,
@@ -28,6 +28,10 @@ define(['./_assignValue', './_castPath', './_isIndex', './_isKey', './isObject',
var key = toKey(path[index]),
newValue = value;
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
return object;
}
if (index != lastIndex) {
var objValue = nested[key];
newValue = customizer ? customizer(objValue, key, nested) : undefined;

View File

@@ -25,11 +25,14 @@ define(['./isSymbol'], function(isSymbol) {
* into `array`.
*/
function baseSortedIndexBy(array, value, iteratee, retHighest) {
value = iteratee(value);
var low = 0,
high = array == null ? 0 : array.length,
valIsNaN = value !== value,
high = array == null ? 0 : array.length;
if (high === 0) {
return 0;
}
value = iteratee(value);
var valIsNaN = value !== value,
valIsNull = value === null,
valIsSymbol = isSymbol(value),
valIsUndefined = value === undefined;

20
_baseTrim.js Normal file
View File

@@ -0,0 +1,20 @@
define(['./_trimmedEndIndex'], function(trimmedEndIndex) {
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/**
* The base implementation of `_.trim`.
*
* @private
* @param {string} string The string to trim.
* @returns {string} Returns the trimmed string.
*/
function baseTrim(string) {
return string
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
: string;
}
return baseTrim;
});

View File

@@ -1,4 +1,4 @@
define(['./_castPath', './_isKey', './last', './_parent', './_toKey'], function(castPath, isKey, last, parent, toKey) {
define(['./_castPath', './last', './_parent', './_toKey'], function(castPath, last, parent, toKey) {
/** Used for built-in method references. */
var objectProto = Object.prototype;
@@ -15,11 +15,48 @@ define(['./_castPath', './_isKey', './last', './_parent', './_toKey'], function(
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
*/
function baseUnset(object, path) {
path = isKey(path, object) ? [path] : castPath(path);
object = parent(object, path);
path = castPath(path, object);
var key = toKey(last(path));
return !(object != null && hasOwnProperty.call(object, key)) || delete object[key];
// Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
var index = -1,
length = path.length;
if (!length) {
return true;
}
var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
while (++index < length) {
var key = path[index];
// skip non-string keys (e.g., Symbols, numbers)
if (typeof key !== 'string') {
continue;
}
// Always block "__proto__" anywhere in the path if it's not expected
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
return false;
}
// Block "constructor.prototype" chains
if (key === 'constructor' &&
(index + 1) < length &&
typeof path[index + 1] === 'string' &&
path[index + 1] === 'prototype') {
// Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
if (isRootPrimitive && index === 0) {
continue;
}
return false;
}
}
var obj = parent(object, path);
return obj == null || delete obj[toKey(last(path))];
}
return baseUnset;

View File

@@ -1,14 +1,18 @@
define(['./isArray', './_stringToPath'], function(isArray, stringToPath) {
define(['./isArray', './_isKey', './_stringToPath', './toString'], function(isArray, isKey, stringToPath, toString) {
/**
* Casts `value` to a path array if it's not one.
*
* @private
* @param {*} value The value to inspect.
* @param {Object} [object] The object to query keys on.
* @returns {Array} Returns the cast property path array.
*/
function castPath(value) {
return isArray(value) ? value : stringToPath(value);
function castPath(value, object) {
if (isArray(value)) {
return value;
}
return isKey(value, object) ? [value] : stringToPath(toString(value));
}
return castPath;

View File

@@ -3,9 +3,6 @@ define(['./_LodashWrapper', './_flatRest', './_getData', './_getFuncName', './is
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -62,8 +59,7 @@ define(['./_LodashWrapper', './_flatRest', './_getData', './_getFuncName', './is
var args = arguments,
value = args[0];
if (wrapper && args.length == 1 &&
isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
if (wrapper && args.length == 1 && isArray(value)) {
return wrapper.plant(value).value();
}
var index = 0,

View File

@@ -1,7 +1,8 @@
define(['./toInteger', './toNumber', './toString'], function(toInteger, toNumber, toString) {
define(['./_root', './toInteger', './toNumber', './toString'], function(root, toInteger, toNumber, toString) {
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
var nativeIsFinite = root.isFinite,
nativeMin = Math.min;
/**
* Creates a function like `_.round`.
@@ -14,8 +15,8 @@ define(['./toInteger', './toNumber', './toString'], function(toInteger, toNumber
var func = Math[methodName];
return function(number, precision) {
number = toNumber(number);
precision = nativeMin(toInteger(precision), 292);
if (precision) {
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
if (precision && nativeIsFinite(number)) {
// Shift with exponential notation to avoid floating-point issues.
// See [MDN](https://mdn.io/round#Examples) for more details.
var pair = (toString(number) + 'e').split('e'),

View File

@@ -77,7 +77,7 @@ define(['./_baseSetData', './_createBind', './_createCurry', './_createHybrid',
thisArg = newData[2];
partials = newData[3];
holders = newData[4];
arity = newData[9] = newData[9] == null
arity = newData[9] = newData[9] === undefined
? (isBindKey ? 0 : func.length)
: nativeMax(newData[9] - length, 0);

View File

@@ -10,7 +10,9 @@ define(['./eq'], function(eq) {
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used by `_.defaults` to customize its `_.assignIn` use.
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties
* of source objects to the destination object for all destination properties
* that resolve to `undefined`.
*
* @private
* @param {*} objValue The destination value.
@@ -19,7 +21,7 @@ define(['./eq'], function(eq) {
* @param {Object} object The parent object of `objValue`.
* @returns {*} Returns the value to assign.
*/
function assignInDefaults(objValue, srcValue, key, object) {
function customDefaultsAssignIn(objValue, srcValue, key, object) {
if (objValue === undefined ||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
return srcValue;
@@ -27,5 +29,5 @@ define(['./eq'], function(eq) {
return objValue;
}
return assignInDefaults;
return customDefaultsAssignIn;
});

View File

@@ -4,7 +4,8 @@ define(['./_baseMerge', './isObject'], function(baseMerge, isObject) {
var undefined;
/**
* Used by `_.defaultsDeep` to customize its `_.merge` use.
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
* objects into destination objects that are passed thru.
*
* @private
* @param {*} objValue The destination value.
@@ -16,15 +17,15 @@ define(['./_baseMerge', './isObject'], function(baseMerge, isObject) {
* counterparts.
* @returns {*} Returns the value to assign.
*/
function mergeDefaults(objValue, srcValue, key, object, source, stack) {
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
// Recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcValue, objValue);
baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
stack['delete'](srcValue);
}
return objValue;
}
return mergeDefaults;
return customDefaultsMerge;
});

20
_customOmitClone.js Normal file
View File

@@ -0,0 +1,20 @@
define(['./isPlainObject'], function(isPlainObject) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/**
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
* objects.
*
* @private
* @param {*} value The value to inspect.
* @param {string} key The key of the property to inspect.
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
*/
function customOmitClone(value) {
return isPlainObject(value) ? undefined : value;
}
return customOmitClone;
});

View File

@@ -28,10 +28,11 @@ define(['./_SetCache', './_arraySome', './_cacheHas'], function(SetCache, arrayS
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
return false;
}
// Assume cyclic values are equal.
var stacked = stack.get(array);
if (stacked && stack.get(other)) {
return stacked == other;
// Check that cyclic values are equal.
var arrStacked = stack.get(array);
var othStacked = stack.get(other);
if (arrStacked && othStacked) {
return arrStacked == other && othStacked == array;
}
var index = -1,
result = true,

View File

@@ -1,4 +1,4 @@
define(['./keys'], function(keys) {
define(['./_getAllKeys'], function(getAllKeys) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -27,9 +27,9 @@ define(['./keys'], function(keys) {
*/
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
objProps = keys(object),
objProps = getAllKeys(object),
objLength = objProps.length,
othProps = keys(other),
othProps = getAllKeys(other),
othLength = othProps.length;
if (objLength != othLength && !isPartial) {
@@ -42,10 +42,11 @@ define(['./keys'], function(keys) {
return false;
}
}
// Assume cyclic values are equal.
var stacked = stack.get(object);
if (stacked && stack.get(other)) {
return stacked == other;
// Check that cyclic values are equal.
var objStacked = stack.get(object);
var othStacked = stack.get(other);
if (objStacked && othStacked) {
return objStacked == other && othStacked == object;
}
var result = true;
stack.set(object, other);

View File

@@ -1,4 +1,10 @@
define(['./_overArg', './stubArray'], function(overArg, stubArray) {
define(['./_arrayFilter', './stubArray'], function(arrayFilter, stubArray) {
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Built-in value references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols = Object.getOwnPropertySymbols;
@@ -10,7 +16,15 @@ define(['./_overArg', './stubArray'], function(overArg, stubArray) {
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
if (object == null) {
return [];
}
object = Object(object);
return arrayFilter(nativeGetSymbols(object), function(symbol) {
return propertyIsEnumerable.call(object, symbol);
});
};
return getSymbols;
});

View File

@@ -1,4 +1,4 @@
define(['./_castPath', './isArguments', './isArray', './_isIndex', './_isKey', './isLength', './_toKey'], function(castPath, isArguments, isArray, isIndex, isKey, isLength, toKey) {
define(['./_castPath', './isArguments', './isArray', './_isIndex', './isLength', './_toKey'], function(castPath, isArguments, isArray, isIndex, isLength, toKey) {
/**
* Checks if `path` exists on `object`.
@@ -10,7 +10,7 @@ define(['./_castPath', './isArguments', './isArray', './_isIndex', './_isKey', '
* @returns {boolean} Returns `true` if `path` exists, else `false`.
*/
function hasPath(object, path, hasFunc) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length,

View File

@@ -1,7 +1,7 @@
define([], function() {
/** Used to detect strings that need a more robust regexp to match words. */
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
/**
* Checks if `string` contains a word composed of Unicode symbols.

View File

@@ -20,7 +20,7 @@ define(['./_nativeCreate'], function(nativeCreate) {
*/
function hashHas(key) {
var data = this.__data__;
return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
}
return hashHas;

View File

@@ -15,7 +15,7 @@ define([], function() {
*/
function initCloneArray(array) {
var length = array.length,
result = array.constructor(length);
result = new array.constructor(length);
// Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {

View File

@@ -1,4 +1,4 @@
define(['./_cloneArrayBuffer', './_cloneDataView', './_cloneMap', './_cloneRegExp', './_cloneSet', './_cloneSymbol', './_cloneTypedArray'], function(cloneArrayBuffer, cloneDataView, cloneMap, cloneRegExp, cloneSet, cloneSymbol, cloneTypedArray) {
define(['./_cloneArrayBuffer', './_cloneDataView', './_cloneRegExp', './_cloneSymbol', './_cloneTypedArray'], function(cloneArrayBuffer, cloneDataView, cloneRegExp, cloneSymbol, cloneTypedArray) {
/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
@@ -26,16 +26,15 @@ define(['./_cloneArrayBuffer', './_cloneDataView', './_cloneMap', './_cloneRegEx
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, cloneFunc, isDeep) {
function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
@@ -54,7 +53,7 @@ define(['./_cloneArrayBuffer', './_cloneDataView', './_cloneMap', './_cloneRegEx
return cloneTypedArray(object, isDeep);
case mapTag:
return cloneMap(object, isDeep, cloneFunc);
return new Ctor;
case numberTag:
case stringTag:
@@ -64,7 +63,7 @@ define(['./_cloneArrayBuffer', './_cloneDataView', './_cloneMap', './_cloneRegEx
return cloneRegExp(object);
case setTag:
return cloneSet(object, isDeep, cloneFunc);
return new Ctor;
case symbolTag:
return cloneSymbol(object);

View File

@@ -15,10 +15,13 @@ define([], function() {
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length &&
(typeof value == 'number' || reIsUint.test(value)) &&
(value > -1 && value % 1 == 0 && value < length);
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
return isIndex;

View File

@@ -1,8 +1,5 @@
define(['./_baseWrapperValue', './_getView', './isArray'], function(baseWrapperValue, getView, isArray) {
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/** Used to indicate the type of lazy iteratees. */
var LAZY_FILTER_FLAG = 1,
LAZY_MAP_FLAG = 2;
@@ -34,8 +31,7 @@ define(['./_baseWrapperValue', './_getView', './isArray'], function(baseWrapperV
resIndex = 0,
takeCount = nativeMin(length, this.__takeCount__);
if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
(arrLength == length && takeCount == length)) {
if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
return baseWrapperValue(array, this.__actions__);
}
var result = [];

View File

@@ -15,6 +15,14 @@ define(['./_freeGlobal'], function(freeGlobal) {
/** Used to access faster Node.js helpers. */
var nodeUtil = (function() {
try {
// Use `util.types` for Node.js 10+.
var types = freeModule && freeModule.require && freeModule.require('util').types;
if (types) {
return types;
}
// Legacy `process.binding('util')` for Node.js < 10.
return freeProcess && freeProcess.binding && freeProcess.binding('util');
} catch (e) {}
}());

View File

@@ -9,7 +9,7 @@ define(['./_baseGet', './_baseSlice'], function(baseGet, baseSlice) {
* @returns {*} Returns the parent value.
*/
function parent(object, path) {
return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
}
return parent;

24
_safeGet.js Normal file
View File

@@ -0,0 +1,24 @@
define([], function() {
/**
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function safeGet(object, key) {
if (key === 'constructor' && typeof object[key] === 'function') {
return;
}
if (key == '__proto__') {
return;
}
return object[key];
}
return safeGet;
});

View File

@@ -7,7 +7,7 @@ define([], function() {
* @name has
* @memberOf SetCache
* @param {*} value The value to search for.
* @returns {number} Returns `true` if `value` is found, else `false`.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
*/
function setCacheHas(value) {
return this.__data__.has(value);

View File

@@ -1,8 +1,7 @@
define(['./_memoizeCapped', './toString'], function(memoizeCapped, toString) {
define(['./_memoizeCapped'], function(memoizeCapped) {
/** Used to match property names within property paths. */
var reLeadingDot = /^\./,
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;
@@ -15,14 +14,12 @@ define(['./_memoizeCapped', './toString'], function(memoizeCapped, toString) {
* @returns {Array} Returns the property path array.
*/
var stringToPath = memoizeCapped(function(string) {
string = toString(string);
var result = [];
if (reLeadingDot.test(string)) {
if (string.charCodeAt(0) === 46 /* . */) {
result.push('');
}
string.replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
string.replace(rePropName, function(match, number, quote, subString) {
result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
});
return result;
});

22
_trimmedEndIndex.js Normal file
View File

@@ -0,0 +1,22 @@
define([], function() {
/** Used to match a single whitespace character. */
var reWhitespace = /\s/;
/**
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
* character of `string`.
*
* @private
* @param {string} string The string to inspect.
* @returns {number} Returns the index of the last non-whitespace character.
*/
function trimmedEndIndex(string) {
var index = string.length;
while (index-- && reWhitespace.test(string.charAt(index))) {}
return index;
}
return trimmedEndIndex;
});

View File

@@ -40,8 +40,8 @@ define([], function() {
reOptMod = rsModifier + '?',
rsOptVar = '[' + rsVarRange + ']?',
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
rsSeq = rsOptVar + reOptMod + rsOptJoin,
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;

View File

@@ -109,9 +109,11 @@ define(['./isObject', './now', './toNumber'], function(isObject, now, toNumber)
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
result = wait - timeSinceLastCall;
timeWaiting = wait - timeSinceLastCall;
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
@@ -172,6 +174,7 @@ define(['./isObject', './now', './toNumber'], function(isObject, now, toNumber)
}
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}

View File

@@ -1,8 +1,14 @@
define(['./_apply', './_assignInDefaults', './assignInWith', './_baseRest'], function(apply, assignInDefaults, assignInWith, baseRest) {
define(['./_baseRest', './eq', './_isIterateeCall', './keysIn'], function(baseRest, eq, isIterateeCall, keysIn) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Assigns own and inherited enumerable string keyed properties of source
* objects to the destination object for all destination properties that
@@ -24,9 +30,35 @@ define(['./_apply', './_assignInDefaults', './assignInWith', './_baseRest'], fun
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
var defaults = baseRest(function(args) {
args.push(undefined, assignInDefaults);
return apply(assignInWith, undefined, args);
var defaults = baseRest(function(object, sources) {
object = Object(object);
var index = -1;
var length = sources.length;
var guard = length > 2 ? sources[2] : undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
length = 1;
}
while (++index < length) {
var source = sources[index];
var props = keysIn(source);
var propsIndex = -1;
var propsLength = props.length;
while (++propsIndex < propsLength) {
var key = props[propsIndex];
var value = object[key];
if (value === undefined ||
(eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
object[key] = source[key];
}
}
}
return object;
});
return defaults;

View File

@@ -1,4 +1,4 @@
define(['./_apply', './_baseRest', './_mergeDefaults', './mergeWith'], function(apply, baseRest, mergeDefaults, mergeWith) {
define(['./_apply', './_baseRest', './_customDefaultsMerge', './mergeWith'], function(apply, baseRest, customDefaultsMerge, mergeWith) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -23,7 +23,7 @@ define(['./_apply', './_baseRest', './_mergeDefaults', './mergeWith'], function(
* // => { 'a': { 'b': 2, 'c': 3 } }
*/
var defaultsDeep = baseRest(function(args) {
args.push(undefined, mergeDefaults);
args.push(undefined, customDefaultsMerge);
return apply(mergeWith, undefined, args);
});

View File

@@ -36,6 +36,10 @@ define(['./_arrayFilter', './_baseFilter', './_baseIteratee', './isArray'], func
* // The `_.property` iteratee shorthand.
* _.filter(users, 'active');
* // => objects for ['barney']
*
* // Combining several predicates using `_.overEvery` or `_.overSome`.
* _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
* // => objects for ['fred', 'barney']
*/
function filter(collection, predicate) {
var func = isArray(collection) ? arrayFilter : baseFilter;

View File

@@ -1,5 +1,15 @@
define(['./constant', './_createInverter', './identity'], function(constant, createInverter, identity) {
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Creates an object composed of the inverted keys and values of `object`.
* If `object` contains duplicate values, subsequent values overwrite
@@ -19,6 +29,11 @@ define(['./constant', './_createInverter', './identity'], function(constant, cre
* // => { '1': 'c', '2': 'b' }
*/
var invert = createInverter(function(result, value, key) {
if (value != null &&
typeof value.toString != 'function') {
value = nativeObjectToString.call(value);
}
result[value] = key;
}, constant(identity));

View File

@@ -6,6 +6,13 @@ define(['./_baseIteratee', './_createInverter'], function(baseIteratee, createIn
/** 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 nativeObjectToString = objectProto.toString;
/**
* This method is like `_.invert` except that the inverted object is generated
* from the results of running each element of `object` thru `iteratee`. The
@@ -33,6 +40,11 @@ define(['./_baseIteratee', './_createInverter'], function(baseIteratee, createIn
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
*/
var invertBy = createInverter(function(result, value, key) {
if (value != null &&
typeof value.toString != 'function') {
value = nativeObjectToString.call(value);
}
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {

View File

@@ -1,7 +1,4 @@
define(['./_apply', './_baseEach', './_baseInvoke', './_baseRest', './isArrayLike', './_isKey'], function(apply, baseEach, baseInvoke, baseRest, isArrayLike, isKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
define(['./_apply', './_baseEach', './_baseInvoke', './_baseRest', './isArrayLike'], function(apply, baseEach, baseInvoke, baseRest, isArrayLike) {
/**
* Invokes the method at `path` of each element in `collection`, returning
@@ -29,12 +26,10 @@ define(['./_apply', './_baseEach', './_baseInvoke', './_baseRest', './isArrayLik
var invokeMap = baseRest(function(collection, path, args) {
var index = -1,
isFunc = typeof path == 'function',
isProp = isKey(path),
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value) {
var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
});
return result;
});

View File

@@ -8,7 +8,7 @@ define(['./_baseIsEqual'], function(baseIsEqual) {
* date objects, error objects, maps, numbers, `Object` objects, regexes,
* sets, strings, symbols, and typed arrays. `Object` objects are compared
* by their own, not inherited, enumerable properties. Functions and DOM
* nodes are **not** supported.
* nodes are compared by strict equality, i.e. `===`.
*
* @static
* @memberOf _

485
main.js
View File

@@ -2,7 +2,7 @@
* @license
* Lodash (Custom Build) <https://lodash.com/>
* Build: `lodash exports="amd" -d -o ./main.js`
* Copyright JS Foundation and other contributors <https://js.foundation/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.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
@@ -13,7 +13,7 @@
var undefined;
/** Used as the semantic version number. */
var VERSION = '4.17.0';
var VERSION = '4.17.21';
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
@@ -144,7 +144,6 @@
/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/,
reLeadingDot = /^\./,
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
/**
@@ -244,8 +243,8 @@
reOptMod = rsModifier + '?',
rsOptVar = '[' + rsVarRange + ']?',
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
rsSeq = rsOptVar + reOptMod + rsOptJoin,
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
@@ -278,7 +277,7 @@
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
/** Used to detect strings that need a more robust regexp to match words. */
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
/** Used to assign default `context` object properties. */
var contextProps = [
@@ -438,6 +437,14 @@
/** Used to access faster Node.js helpers. */
var nodeUtil = (function() {
try {
// Use `util.types` for Node.js 10+.
var types = freeModule && freeModule.require && freeModule.require('util').types;
if (types) {
return types;
}
// Legacy `process.binding('util')` for Node.js < 10.
return freeProcess && freeProcess.binding && freeProcess.binding('util');
} catch (e) {}
}());
@@ -452,34 +459,6 @@
/*--------------------------------------------------------------------------*/
/**
* Adds the key-value `pair` to `map`.
*
* @private
* @param {Object} map The map to modify.
* @param {Array} pair The key-value pair to add.
* @returns {Object} Returns `map`.
*/
function addMapEntry(map, pair) {
// Don't return `map.set` because it's not chainable in IE 11.
map.set(pair[0], pair[1]);
return map;
}
/**
* Adds `value` to `set`.
*
* @private
* @param {Object} set The set to modify.
* @param {*} value The value to add.
* @returns {Object} Returns `set`.
*/
function addSetEntry(set, value) {
// Don't return `set.add` because it's not chainable in IE 11.
set.add(value);
return set;
}
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
@@ -1568,9 +1547,9 @@
* Shortcut fusion is an optimization to merge iteratee calls; this avoids
* the creation of intermediate arrays and can greatly reduce the number of
* iteratee executions. Sections of a chain sequence qualify for shortcut
* fusion if the section is applied to an array of at least `200` elements
* and any iteratees accept only one argument. The heuristic for whether a
* section qualifies for shortcut fusion is subject to change.
* fusion if the section is applied to an array and iteratees accept only
* one argument. The heuristic for whether a section qualifies for shortcut
* fusion is subject to change.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
@@ -1729,8 +1708,8 @@
/**
* By default, the template delimiters used by lodash are like those in
* embedded Ruby (ERB). Change the following template settings to use
* alternative delimiters.
* embedded Ruby (ERB) as well as ES2015 template strings. Change the
* following template settings to use alternative delimiters.
*
* @static
* @memberOf _
@@ -1877,8 +1856,7 @@
resIndex = 0,
takeCount = nativeMin(length, this.__takeCount__);
if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
(arrLength == length && takeCount == length)) {
if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
return baseWrapperValue(array, this.__actions__);
}
var result = [];
@@ -1992,7 +1970,7 @@
*/
function hashHas(key) {
var data = this.__data__;
return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
}
/**
@@ -2465,24 +2443,6 @@
return shuffleSelf(copyArray(array));
}
/**
* Used by `_.defaults` to customize its `_.assignIn` use.
*
* @private
* @param {*} objValue The destination value.
* @param {*} srcValue The source value.
* @param {string} key The key of the property to assign.
* @param {Object} object The parent object of `objValue`.
* @returns {*} Returns the value to assign.
*/
function assignInDefaults(objValue, srcValue, key, object) {
if (objValue === undefined ||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
return srcValue;
}
return objValue;
}
/**
* This function is like `assignValue` except that it doesn't assign
* `undefined` values.
@@ -2697,7 +2657,7 @@
if (!cloneableTags[tag]) {
return object ? value : {};
}
result = initCloneByTag(value, tag, baseClone, isDeep);
result = initCloneByTag(value, tag, isDeep);
}
}
// Check for circular references and return its corresponding clone.
@@ -2708,6 +2668,16 @@
}
stack.set(value, result);
if (isSet(value)) {
value.forEach(function(subValue) {
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
});
} else if (isMap(value)) {
value.forEach(function(subValue, key) {
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
}
var keysFunc = isFull
? (isFlat ? getAllKeysIn : getAllKeys)
: (isFlat ? keysIn : keys);
@@ -3057,7 +3027,7 @@
* @returns {*} Returns the resolved value.
*/
function baseGet(object, path) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = 0,
length = path.length;
@@ -3095,8 +3065,7 @@
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
value = Object(value);
return (symToStringTag && symToStringTag in value)
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
@@ -3243,12 +3212,9 @@
* @returns {*} Returns the result of the invoked method.
*/
function baseInvoke(object, path, args) {
if (!isKey(path, object)) {
path = castPath(path);
object = parent(object, path);
path = last(path);
}
var func = object == null ? object : object[toKey(path)];
path = castPath(path, object);
object = parent(object, path);
var func = object == null ? object : object[toKey(last(path))];
return func == null ? undefined : apply(func, object, args);
}
@@ -3303,7 +3269,7 @@
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
@@ -3326,17 +3292,12 @@
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
objTag = objIsArr ? arrayTag : getTag(object),
othTag = othIsArr ? arrayTag : getTag(other);
objTag = objTag == argsTag ? objectTag : objTag;
othTag = othTag == argsTag ? objectTag : othTag;
if (!objIsArr) {
objTag = getTag(object);
objTag = objTag == argsTag ? objectTag : objTag;
}
if (!othIsArr) {
othTag = getTag(other);
othTag = othTag == argsTag ? objectTag : othTag;
}
var objIsObj = objTag == objectTag,
othIsObj = othTag == objectTag,
isSameTag = objTag == othTag;
@@ -3638,13 +3599,13 @@
return;
}
baseFor(source, function(srcValue, key) {
stack || (stack = new Stack);
if (isObject(srcValue)) {
stack || (stack = new Stack);
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
}
else {
var newValue = customizer
? customizer(object[key], srcValue, (key + ''), object, source, stack)
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
: undefined;
if (newValue === undefined) {
@@ -3671,8 +3632,8 @@
* counterparts.
*/
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = object[key],
srcValue = source[key],
var objValue = safeGet(object, key),
srcValue = safeGet(source, key),
stacked = stack.get(srcValue);
if (stacked) {
@@ -3715,7 +3676,7 @@
if (isArguments(objValue)) {
newValue = toPlainObject(objValue);
}
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
else if (!isObject(objValue) || isFunction(objValue)) {
newValue = initCloneObject(srcValue);
}
}
@@ -3784,7 +3745,6 @@
* @returns {Object} Returns the new object.
*/
function basePick(object, paths) {
object = Object(object);
return basePickBy(object, paths, function(value, path) {
return hasIn(object, path);
});
@@ -3809,7 +3769,7 @@
value = baseGet(object, path);
if (predicate(value, path)) {
baseSet(result, path, value);
baseSet(result, castPath(path, object), value);
}
}
return result;
@@ -3885,17 +3845,8 @@
var previous = index;
if (isIndex(index)) {
splice.call(array, index, 1);
}
else if (!isKey(index, array)) {
var path = castPath(index),
object = parent(array, path);
if (object != null) {
delete object[toKey(last(path))];
}
}
else {
delete array[toKey(index)];
} else {
baseUnset(array, index);
}
}
}
@@ -4016,7 +3967,7 @@
if (!isObject(object)) {
return object;
}
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length,
@@ -4357,11 +4308,9 @@
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
*/
function baseUnset(object, path) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
object = parent(object, path);
var key = toKey(last(path));
return !(object != null && hasOwnProperty.call(object, key)) || delete object[key];
return object == null || delete object[toKey(last(path))];
}
/**
@@ -4501,10 +4450,14 @@
*
* @private
* @param {*} value The value to inspect.
* @param {Object} [object] The object to query keys on.
* @returns {Array} Returns the cast property path array.
*/
function castPath(value) {
return isArray(value) ? value : stringToPath(value);
function castPath(value, object) {
if (isArray(value)) {
return value;
}
return isKey(value, object) ? [value] : stringToPath(toString(value));
}
/**
@@ -4588,20 +4541,6 @@
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
}
/**
* Creates a clone of `map`.
*
* @private
* @param {Object} map The map to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned map.
*/
function cloneMap(map, isDeep, cloneFunc) {
var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
return arrayReduce(array, addMapEntry, new map.constructor);
}
/**
* Creates a clone of `regexp`.
*
@@ -4615,20 +4554,6 @@
return result;
}
/**
* Creates a clone of `set`.
*
* @private
* @param {Object} set The set to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned set.
*/
function cloneSet(set, isDeep, cloneFunc) {
var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
return arrayReduce(array, addSetEntry, new set.constructor);
}
/**
* Creates a clone of the `symbol` object.
*
@@ -5184,8 +5109,7 @@
var args = arguments,
value = args[0];
if (wrapper && args.length == 1 &&
isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
if (wrapper && args.length == 1 && isArray(value)) {
return wrapper.plant(value).value();
}
var index = 0,
@@ -5492,8 +5416,8 @@
var func = Math[methodName];
return function(number, precision) {
number = toNumber(number);
precision = nativeMin(toInteger(precision), 292);
if (precision) {
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
if (precision && nativeIsFinite(number)) {
// Shift with exponential notation to avoid floating-point issues.
// See [MDN](https://mdn.io/round#Examples) for more details.
var pair = (toString(number) + 'e').split('e'),
@@ -5597,7 +5521,7 @@
thisArg = newData[2];
partials = newData[3];
holders = newData[4];
arity = newData[9] = newData[9] == null
arity = newData[9] = newData[9] === undefined
? (isBindKey ? 0 : func.length)
: nativeMax(newData[9] - length, 0);
@@ -5617,6 +5541,63 @@
return setWrapToString(setter(result, newData), func, bitmask);
}
/**
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties
* of source objects to the destination object for all destination properties
* that resolve to `undefined`.
*
* @private
* @param {*} objValue The destination value.
* @param {*} srcValue The source value.
* @param {string} key The key of the property to assign.
* @param {Object} object The parent object of `objValue`.
* @returns {*} Returns the value to assign.
*/
function customDefaultsAssignIn(objValue, srcValue, key, object) {
if (objValue === undefined ||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
return srcValue;
}
return objValue;
}
/**
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
* objects into destination objects that are passed thru.
*
* @private
* @param {*} objValue The destination value.
* @param {*} srcValue The source value.
* @param {string} key The key of the property to merge.
* @param {Object} object The parent object of `objValue`.
* @param {Object} source The parent object of `srcValue`.
* @param {Object} [stack] Tracks traversed source values and their merged
* counterparts.
* @returns {*} Returns the value to assign.
*/
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
// Recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcValue, objValue);
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
stack['delete'](srcValue);
}
return objValue;
}
/**
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
* objects.
*
* @private
* @param {*} value The value to inspect.
* @param {string} key The key of the property to inspect.
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
*/
function customOmitClone(value) {
return isPlainObject(value) ? undefined : value;
}
/**
* A specialized version of `baseIsEqualDeep` for arrays with support for
* partial deep comparisons.
@@ -5788,9 +5769,9 @@
*/
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
objProps = keys(object),
objProps = getAllKeys(object),
objLength = objProps.length,
othProps = keys(other),
othProps = getAllKeys(other),
othLength = othProps.length;
if (objLength != othLength && !isPartial) {
@@ -6028,7 +6009,15 @@
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
if (object == null) {
return [];
}
object = Object(object);
return arrayFilter(nativeGetSymbols(object), function(symbol) {
return propertyIsEnumerable.call(object, symbol);
});
};
/**
* Creates an array of the own and inherited enumerable symbols of `object`.
@@ -6129,7 +6118,7 @@
* @returns {boolean} Returns `true` if `path` exists, else `false`.
*/
function hasPath(object, path, hasFunc) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length,
@@ -6159,7 +6148,7 @@
*/
function initCloneArray(array) {
var length = array.length,
result = array.constructor(length);
result = new array.constructor(length);
// Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
@@ -6186,16 +6175,15 @@
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {Function} cloneFunc The function to clone values.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, cloneFunc, isDeep) {
function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
@@ -6214,7 +6202,7 @@
return cloneTypedArray(object, isDeep);
case mapTag:
return cloneMap(object, isDeep, cloneFunc);
return new Ctor;
case numberTag:
case stringTag:
@@ -6224,7 +6212,7 @@
return cloneRegExp(object);
case setTag:
return cloneSet(object, isDeep, cloneFunc);
return new Ctor;
case symbolTag:
return cloneSymbol(object);
@@ -6271,10 +6259,13 @@
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length &&
(typeof value == 'number' || reIsUint.test(value)) &&
(value > -1 && value % 1 == 0 && value < length);
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
/**
@@ -6514,29 +6505,6 @@
return data;
}
/**
* Used by `_.defaultsDeep` to customize its `_.merge` use.
*
* @private
* @param {*} objValue The destination value.
* @param {*} srcValue The source value.
* @param {string} key The key of the property to merge.
* @param {Object} object The parent object of `objValue`.
* @param {Object} source The parent object of `srcValue`.
* @param {Object} [stack] Tracks traversed source values and their merged
* counterparts.
* @returns {*} Returns the value to assign.
*/
function mergeDefaults(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
// Recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcValue, objValue);
baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
stack['delete'](srcValue);
}
return objValue;
}
/**
* This function is like
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
@@ -6606,7 +6574,7 @@
* @returns {*} Returns the parent value.
*/
function parent(object, path) {
return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
}
/**
@@ -6631,6 +6599,26 @@
return array;
}
/**
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function safeGet(object, key) {
if (key === 'constructor' && typeof object[key] === 'function') {
return;
}
if (key == '__proto__') {
return;
}
return object[key];
}
/**
* Sets metadata for `func`.
*
@@ -6746,14 +6734,12 @@
* @returns {Array} Returns the property path array.
*/
var stringToPath = memoizeCapped(function(string) {
string = toString(string);
var result = [];
if (reLeadingDot.test(string)) {
if (string.charCodeAt(0) === 46 /* . */) {
result.push('');
}
string.replace(rePropName, function(match, number, quote, string) {
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
string.replace(rePropName, function(match, number, quote, subString) {
result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
});
return result;
});
@@ -8281,7 +8267,7 @@
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false},
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
@@ -9482,12 +9468,10 @@
var invokeMap = baseRest(function(collection, path, args) {
var index = -1,
isFunc = typeof path == 'function',
isProp = isKey(path),
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value) {
var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
});
return result;
});
@@ -10363,9 +10347,11 @@
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
result = wait - timeSinceLastCall;
timeWaiting = wait - timeSinceLastCall;
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
@@ -10426,6 +10412,7 @@
}
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
@@ -10852,18 +10839,14 @@
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
start = start == null ? 0 : nativeMax(toInteger(start), 0);
return baseRest(function(args) {
var array = args[start],
lastIndex = args.length - 1,
otherArgs = castSlice(args, 0, start);
if (array) {
arrayPush(otherArgs, array);
}
if (start != lastIndex) {
arrayPush(otherArgs, castSlice(args, start + 1));
}
return apply(func, this, otherArgs);
});
}
@@ -11526,7 +11509,7 @@
* date objects, error objects, maps, numbers, `Object` objects, regexes,
* sets, strings, symbols, and typed arrays. `Object` objects are compared
* by their own, not inherited, enumerable properties. Functions and DOM
* nodes are **not** supported.
* nodes are compared by strict equality, i.e. `===`.
*
* @static
* @memberOf _
@@ -12546,7 +12529,9 @@
* // => 3
*/
function toSafeInteger(value) {
return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
return value
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
: (value === 0 ? value : 0);
}
/**
@@ -12799,9 +12784,35 @@
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
var defaults = baseRest(function(args) {
args.push(undefined, assignInDefaults);
return apply(assignInWith, undefined, args);
var defaults = baseRest(function(object, sources) {
object = Object(object);
var index = -1;
var length = sources.length;
var guard = length > 2 ? sources[2] : undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
length = 1;
}
while (++index < length) {
var source = sources[index];
var props = keysIn(source);
var propsIndex = -1;
var propsLength = props.length;
while (++propsIndex < propsLength) {
var key = props[propsIndex];
var value = object[key];
if (value === undefined ||
(eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
object[key] = source[key];
}
}
}
return object;
});
/**
@@ -12824,7 +12835,7 @@
* // => { 'a': { 'b': 2, 'c': 3 } }
*/
var defaultsDeep = baseRest(function(args) {
args.push(undefined, mergeDefaults);
args.push(undefined, customDefaultsMerge);
return apply(mergeWith, undefined, args);
});
@@ -13198,6 +13209,11 @@
* // => { '1': 'c', '2': 'b' }
*/
var invert = createInverter(function(result, value, key) {
if (value != null &&
typeof value.toString != 'function') {
value = nativeObjectToString.call(value);
}
result[value] = key;
}, constant(identity));
@@ -13228,6 +13244,11 @@
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
*/
var invertBy = createInverter(function(result, value, key) {
if (value != null &&
typeof value.toString != 'function') {
value = nativeObjectToString.call(value);
}
if (hasOwnProperty.call(result, value)) {
result[value].push(key);
} else {
@@ -13478,9 +13499,16 @@
if (object == null) {
return result;
}
var isDeep = false;
paths = arrayMap(paths, function(path) {
path = castPath(path, object);
isDeep || (isDeep = path.length > 1);
return path;
});
copyObject(object, getAllKeysIn(object), result);
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG);
if (isDeep) {
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
}
var length = paths.length;
while (length--) {
baseUnset(result, paths[length]);
@@ -13530,7 +13558,7 @@
* // => { 'a': 1, 'c': 3 }
*/
var pick = flatRest(function(object, paths) {
return object == null ? {} : basePick(object, arrayMap(paths, toKey));
return object == null ? {} : basePick(object, paths);
});
/**
@@ -13552,7 +13580,16 @@
* // => { 'a': 1, 'c': 3 }
*/
function pickBy(object, predicate) {
return object == null ? {} : basePickBy(object, getAllKeysIn(object), getIteratee(predicate));
if (object == null) {
return {};
}
var props = arrayMap(getAllKeysIn(object), function(prop) {
return [prop];
});
predicate = getIteratee(predicate);
return basePickBy(object, props, function(value, path) {
return predicate(value, path[0]);
});
}
/**
@@ -13585,15 +13622,15 @@
* // => 'default'
*/
function result(object, path, defaultValue) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length;
// Ensure the loop is entered when path is empty.
if (!length) {
object = undefined;
length = 1;
object = undefined;
}
while (++index < length) {
var value = object == null ? undefined : object[toKey(path[index])];
@@ -14619,7 +14656,10 @@
*/
function startsWith(string, target, position) {
string = toString(string);
position = baseClamp(toInteger(position), 0, string.length);
position = position == null
? 0
: baseClamp(toInteger(position), 0, string.length);
target = baseToString(target);
return string.slice(position, position + target.length) == target;
}
@@ -14738,9 +14778,9 @@
options = undefined;
}
string = toString(string);
options = assignInWith({}, options, settings, assignInDefaults);
options = assignInWith({}, options, settings, customDefaultsAssignIn);
var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
importsKeys = keys(imports),
importsValues = baseValues(imports, importsKeys);
@@ -14759,9 +14799,12 @@
, 'g');
// Use a sourceURL for easier debugging.
// The sourceURL gets injected into the source that's eval-ed, so be careful
// with lookup (in case of e.g. prototype pollution), and strip newlines if any.
// A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection.
var sourceURL = '//# sourceURL=' +
('sourceURL' in options
? options.sourceURL
(hasOwnProperty.call(options, 'sourceURL')
? (options.sourceURL + '').replace(/[\r\n]/g, ' ')
: ('lodash.templateSources[' + (++templateCounter) + ']')
) + '\n';
@@ -14794,7 +14837,9 @@
// If `variable` is not specified wrap a with-statement around the generated
// code to add the data object to the top of the scope chain.
var variable = options.variable;
// Like with sourceURL, we take care to not check the option's prototype,
// as this configuration is a code injection vector.
var variable = hasOwnProperty.call(options, 'variable') && options.variable;
if (!variable) {
source = 'with (obj) {\n' + source + '\n}\n';
}
@@ -16103,7 +16148,7 @@
if (isArray(value)) {
return arrayMap(value, toKey);
}
return isSymbol(value) ? [value] : copyArray(stringToPath(value));
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
}
/**
@@ -16824,14 +16869,13 @@
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
arrayEach(['drop', 'take'], function(methodName, index) {
LazyWrapper.prototype[methodName] = function(n) {
var filtered = this.__filtered__;
if (filtered && !index) {
return new LazyWrapper(this);
}
n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
var result = this.clone();
if (filtered) {
var result = (this.__filtered__ && !index)
? new LazyWrapper(this)
: this.clone();
if (result.__filtered__) {
result.__takeCount__ = nativeMin(n, result.__takeCount__);
} else {
result.__views__.push({
@@ -17000,10 +17044,11 @@
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
var lodashFunc = lodash[methodName];
if (lodashFunc) {
var key = (lodashFunc.name + ''),
names = realNames[key] || (realNames[key] = []);
names.push({ 'name': methodName, 'func': lodashFunc });
var key = lodashFunc.name + '';
if (!hasOwnProperty.call(realNames, key)) {
realNames[key] = [];
}
realNames[key].push({ 'name': methodName, 'func': lodashFunc });
}
});

View File

@@ -15,6 +15,9 @@ define(['./_baseClone', './_baseMatches'], function(baseClone, baseMatches) {
* values against any array or object value, respectively. See `_.isEqual`
* for a list of supported value comparisons.
*
* **Note:** Multiple values can be checked by combining several matchers
* using `_.overSome`
*
* @static
* @memberOf _
* @since 3.0.0
@@ -30,6 +33,10 @@ define(['./_baseClone', './_baseMatches'], function(baseClone, baseMatches) {
*
* _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
* // => [{ 'a': 4, 'b': 5, 'c': 6 }]
*
* // Checking for several possible values
* _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
* // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
*/
function matches(source) {
return baseMatches(baseClone(source, CLONE_DEEP_FLAG));

View File

@@ -12,6 +12,9 @@ define(['./_baseClone', './_baseMatchesProperty'], function(baseClone, baseMatch
* `srcValue` values against any array or object value, respectively. See
* `_.isEqual` for a list of supported value comparisons.
*
* **Note:** Multiple values can be checked by combining several matchers
* using `_.overSome`
*
* @static
* @memberOf _
* @since 3.2.0
@@ -28,6 +31,10 @@ define(['./_baseClone', './_baseMatchesProperty'], function(baseClone, baseMatch
*
* _.find(objects, _.matchesProperty('a', 4));
* // => { 'a': 4, 'b': 5, 'c': 6 }
*
* // Checking for several possible values
* _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
* // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
*/
function matchesProperty(path, srcValue) {
return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));

13
omit.js
View File

@@ -1,4 +1,4 @@
define(['./_baseClone', './_baseUnset', './_copyObject', './_flatRest', './_getAllKeysIn'], function(baseClone, baseUnset, copyObject, flatRest, getAllKeysIn) {
define(['./_arrayMap', './_baseClone', './_baseUnset', './_castPath', './_copyObject', './_customOmitClone', './_flatRest', './_getAllKeysIn'], function(arrayMap, baseClone, baseUnset, castPath, copyObject, customOmitClone, flatRest, getAllKeysIn) {
/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
@@ -30,9 +30,16 @@ define(['./_baseClone', './_baseUnset', './_copyObject', './_flatRest', './_getA
if (object == null) {
return result;
}
var isDeep = false;
paths = arrayMap(paths, function(path) {
path = castPath(path, object);
isDeep || (isDeep = path.length > 1);
return path;
});
copyObject(object, getAllKeysIn(object), result);
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG);
if (isDeep) {
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
}
var length = paths.length;
while (length--) {
baseUnset(result, paths[length]);

View File

@@ -4,6 +4,10 @@ define(['./_arrayEvery', './_createOver'], function(arrayEvery, createOver) {
* Creates a function that checks if **all** of the `predicates` return
* truthy when invoked with the arguments it receives.
*
* Following shorthands are possible for providing predicates.
* Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
* Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
*
* @static
* @memberOf _
* @since 4.0.0

View File

@@ -4,6 +4,10 @@ define(['./_arraySome', './_createOver'], function(arraySome, createOver) {
* Creates a function that checks if **any** of the `predicates` return
* truthy when invoked with the arguments it receives.
*
* Following shorthands are possible for providing predicates.
* Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
* Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
*
* @static
* @memberOf _
* @since 4.0.0
@@ -23,6 +27,9 @@ define(['./_arraySome', './_createOver'], function(arraySome, createOver) {
*
* func(NaN);
* // => false
*
* var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
* var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
*/
var overSome = createOver(arraySome);

View File

@@ -1,6 +1,6 @@
{
"name": "lodash-amd",
"version": "4.17.0",
"version": "4.17.21",
"description": "Lodash exported as AMD modules.",
"keywords": "amd, modules, stdlib, util",
"homepage": "https://lodash.com/custom-builds",
@@ -8,11 +8,10 @@
"repository": "lodash/lodash",
"license": "MIT",
"main": "main.js",
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"author": "John-David Dalton <john.david.dalton@gmail.com>",
"contributors": [
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"Blaine Bublitz <blaine.bublitz@gmail.com> (https://github.com/phated)",
"Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"
"John-David Dalton <john.david.dalton@gmail.com>",
"Mathias Bynens <mathias@qiwi.be>"
],
"scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" }
"scripts": { "test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\"" }
}

View File

@@ -1,6 +1,6 @@
define(['./_root', './toString'], function(root, toString) {
/** Used to match leading and trailing whitespace. */
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/* Built-in method references for those with the same name as other `lodash` methods. */

View File

@@ -1,4 +1,4 @@
define(['./_arrayMap', './_basePick', './_flatRest', './_toKey'], function(arrayMap, basePick, flatRest, toKey) {
define(['./_basePick', './_flatRest'], function(basePick, flatRest) {
/**
* Creates an object composed of the picked `object` properties.
@@ -18,7 +18,7 @@ define(['./_arrayMap', './_basePick', './_flatRest', './_toKey'], function(array
* // => { 'a': 1, 'c': 3 }
*/
var pick = flatRest(function(object, paths) {
return object == null ? {} : basePick(object, arrayMap(paths, toKey));
return object == null ? {} : basePick(object, paths);
});
return pick;

View File

@@ -1,4 +1,4 @@
define(['./_baseIteratee', './_basePickBy', './_getAllKeysIn'], function(baseIteratee, basePickBy, getAllKeysIn) {
define(['./_arrayMap', './_baseIteratee', './_basePickBy', './_getAllKeysIn'], function(arrayMap, baseIteratee, basePickBy, getAllKeysIn) {
/**
* Creates an object composed of the `object` properties `predicate` returns
@@ -19,7 +19,16 @@ define(['./_baseIteratee', './_basePickBy', './_getAllKeysIn'], function(baseIte
* // => { 'a': 1, 'c': 3 }
*/
function pickBy(object, predicate) {
return object == null ? {} : basePickBy(object, getAllKeysIn(object), baseIteratee(predicate));
if (object == null) {
return {};
}
var props = arrayMap(getAllKeysIn(object), function(prop) {
return [prop];
});
predicate = baseIteratee(predicate);
return basePickBy(object, props, function(value, path) {
return predicate(value, path[0]);
});
}
return pickBy;

View File

@@ -1,4 +1,4 @@
define(['./_castPath', './isFunction', './_isKey', './_toKey'], function(castPath, isFunction, isKey, toKey) {
define(['./_castPath', './isFunction', './_toKey'], function(castPath, isFunction, toKey) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
@@ -33,15 +33,15 @@ define(['./_castPath', './isFunction', './_isKey', './_toKey'], function(castPat
* // => 'default'
*/
function result(object, path, defaultValue) {
path = isKey(path, object) ? [path] : castPath(path);
path = castPath(path, object);
var index = -1,
length = path.length;
// Ensure the loop is entered when path is empty.
if (!length) {
object = undefined;
length = 1;
object = undefined;
}
while (++index < length) {
var value = object == null ? undefined : object[toKey(path[index])];

View File

@@ -19,15 +19,15 @@ define(['./_baseFlatten', './_baseOrderBy', './_baseRest', './_isIterateeCall'],
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 40 },
* { 'user': 'fred', 'age': 30 },
* { 'user': 'barney', 'age': 34 }
* ];
*
* _.sortBy(users, [function(o) { return o.user; }]);
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
*
* _.sortBy(users, ['user', 'age']);
* // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
* // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
*/
var sortBy = baseRest(function(collection, iteratees) {
if (collection == null) {

View File

@@ -1,8 +1,5 @@
define(['./_apply', './_arrayPush', './_baseRest', './_castSlice', './toInteger'], function(apply, arrayPush, baseRest, castSlice, toInteger) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
@@ -47,18 +44,14 @@ define(['./_apply', './_arrayPush', './_baseRest', './_castSlice', './toInteger'
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
start = start == null ? 0 : nativeMax(toInteger(start), 0);
return baseRest(function(args) {
var array = args[start],
lastIndex = args.length - 1,
otherArgs = castSlice(args, 0, start);
if (array) {
arrayPush(otherArgs, array);
}
if (start != lastIndex) {
arrayPush(otherArgs, castSlice(args, start + 1));
}
return apply(func, this, otherArgs);
});
}

View File

@@ -25,7 +25,10 @@ define(['./_baseClamp', './_baseToString', './toInteger', './toString'], functio
*/
function startsWith(string, target, position) {
string = toString(string);
position = baseClamp(toInteger(position), 0, string.length);
position = position == null
? 0
: baseClamp(toInteger(position), 0, string.length);
target = baseToString(target);
return string.slice(position, position + target.length) == target;
}

View File

@@ -16,7 +16,7 @@ define(['./_baseIteratee', './_baseWhile'], function(baseIteratee, baseWhile) {
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false},
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*

View File

@@ -1,13 +1,28 @@
define(['./_assignInDefaults', './assignInWith', './attempt', './_baseValues', './_escapeStringChar', './isError', './_isIterateeCall', './keys', './_reInterpolate', './templateSettings', './toString'], function(assignInDefaults, assignInWith, attempt, baseValues, escapeStringChar, isError, isIterateeCall, keys, reInterpolate, templateSettings, toString) {
define(['./assignInWith', './attempt', './_baseValues', './_customDefaultsAssignIn', './_escapeStringChar', './isError', './_isIterateeCall', './keys', './_reInterpolate', './templateSettings', './toString'], function(assignInWith, attempt, baseValues, customDefaultsAssignIn, escapeStringChar, isError, isIterateeCall, keys, reInterpolate, templateSettings, toString) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Error message constants. */
var INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
/** Used to match empty string literals in compiled template source. */
var reEmptyStringLeading = /\b__p \+= '';/g,
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
/**
* Used to validate the `validate` option in `_.template` variable.
*
* Forbids characters which could potentially change the meaning of the function argument definition:
* - "()," (modification of function parameters)
* - "=" (default value)
* - "[]{}" (destructuring of function parameters)
* - "/" (beginning of a comment)
* - whitespace
*/
var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
/**
* Used to match
* [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
@@ -20,6 +35,12 @@ define(['./_assignInDefaults', './assignInWith', './attempt', './_baseValues', '
/** Used to match unescaped characters in compiled string literals. */
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates a compiled template function that can interpolate data properties
* in "interpolate" delimiters, HTML-escape interpolated data properties in
@@ -134,9 +155,9 @@ define(['./_assignInDefaults', './assignInWith', './attempt', './_baseValues', '
options = undefined;
}
string = toString(string);
options = assignInWith({}, options, settings, assignInDefaults);
options = assignInWith({}, options, settings, customDefaultsAssignIn);
var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
importsKeys = keys(imports),
importsValues = baseValues(imports, importsKeys);
@@ -155,7 +176,14 @@ define(['./_assignInDefaults', './assignInWith', './attempt', './_baseValues', '
, 'g');
// Use a sourceURL for easier debugging.
var sourceURL = 'sourceURL' in options ? '//# sourceURL=' + options.sourceURL + '\n' : '';
// The sourceURL gets injected into the source that's eval-ed, so be careful
// to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
// and escape the comment, thus injecting code that gets evaled.
var sourceURL = hasOwnProperty.call(options, 'sourceURL')
? ('//# sourceURL=' +
(options.sourceURL + '').replace(/\s/g, ' ') +
'\n')
: '';
string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
interpolateValue || (interpolateValue = esTemplateValue);
@@ -186,10 +214,16 @@ define(['./_assignInDefaults', './assignInWith', './attempt', './_baseValues', '
// If `variable` is not specified wrap a with-statement around the generated
// code to add the data object to the top of the scope chain.
var variable = options.variable;
var variable = hasOwnProperty.call(options, 'variable') && options.variable;
if (!variable) {
source = 'with (obj) {\n' + source + '\n}\n';
}
// Throw an error if a forbidden character was found in `variable`, to prevent
// potential command injection attacks.
else if (reForbiddenIdentifierChars.test(variable)) {
throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
}
// Cleanup code by stripping empty strings.
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
.replace(reEmptyStringMiddle, '$1')

View File

@@ -2,8 +2,8 @@ define(['./escape', './_reEscape', './_reEvaluate', './_reInterpolate'], functio
/**
* By default, the template delimiters used by lodash are like those in
* embedded Ruby (ERB). Change the following template settings to use
* alternative delimiters.
* embedded Ruby (ERB) as well as ES2015 template strings. Change the
* following template settings to use alternative delimiters.
*
* @static
* @memberOf _

View File

@@ -1,11 +1,8 @@
define(['./isObject', './isSymbol'], function(isObject, isSymbol) {
define(['./_baseTrim', './isObject', './isSymbol'], function(baseTrim, isObject, isSymbol) {
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
@@ -55,7 +52,7 @@ define(['./isObject', './isSymbol'], function(isObject, isSymbol) {
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
value = baseTrim(value);
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)

View File

@@ -1,4 +1,4 @@
define(['./_arrayMap', './_copyArray', './isArray', './isSymbol', './_stringToPath', './_toKey'], function(arrayMap, copyArray, isArray, isSymbol, stringToPath, toKey) {
define(['./_arrayMap', './_copyArray', './isArray', './isSymbol', './_stringToPath', './_toKey', './toString'], function(arrayMap, copyArray, isArray, isSymbol, stringToPath, toKey, toString) {
/**
* Converts `value` to a property path array.
@@ -21,7 +21,7 @@ define(['./_arrayMap', './_copyArray', './isArray', './isSymbol', './_stringToPa
if (isArray(value)) {
return arrayMap(value, toKey);
}
return isSymbol(value) ? [value] : copyArray(stringToPath(value));
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
}
return toPath;

View File

@@ -28,7 +28,9 @@ define(['./_baseClamp', './toInteger'], function(baseClamp, toInteger) {
* // => 3
*/
function toSafeInteger(value) {
return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
return value
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
: (value === 0 ? value : 0);
}
return toSafeInteger;

View File

@@ -1,11 +1,8 @@
define(['./_baseToString', './_castSlice', './_charsEndIndex', './_charsStartIndex', './_stringToArray', './toString'], function(baseToString, castSlice, charsEndIndex, charsStartIndex, stringToArray, toString) {
define(['./_baseTrim', './_baseToString', './_castSlice', './_charsEndIndex', './_charsStartIndex', './_stringToArray', './toString'], function(baseTrim, baseToString, castSlice, charsEndIndex, charsStartIndex, stringToArray, toString) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/**
* Removes leading and trailing whitespace or specified characters from `string`.
*
@@ -31,7 +28,7 @@ define(['./_baseToString', './_castSlice', './_charsEndIndex', './_charsStartInd
function trim(string, chars, guard) {
string = toString(string);
if (string && (guard || chars === undefined)) {
return string.replace(reTrim, '');
return baseTrim(string);
}
if (!string || !(chars = baseToString(chars))) {
return string;

View File

@@ -1,11 +1,8 @@
define(['./_baseToString', './_castSlice', './_charsEndIndex', './_stringToArray', './toString'], function(baseToString, castSlice, charsEndIndex, stringToArray, toString) {
define(['./_baseToString', './_castSlice', './_charsEndIndex', './_stringToArray', './_trimmedEndIndex', './toString'], function(baseToString, castSlice, charsEndIndex, stringToArray, trimmedEndIndex, toString) {
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Used to match leading and trailing whitespace. */
var reTrimEnd = /\s+$/;
/**
* Removes trailing whitespace or specified characters from `string`.
*
@@ -28,7 +25,7 @@ define(['./_baseToString', './_castSlice', './_charsEndIndex', './_stringToArray
function trimEnd(string, chars, guard) {
string = toString(string);
if (string && (guard || chars === undefined)) {
return string.replace(reTrimEnd, '');
return string.slice(0, trimmedEndIndex(string) + 1);
}
if (!string || !(chars = baseToString(chars))) {
return string;

View File

@@ -3,7 +3,7 @@ define(['./_baseToString', './_castSlice', './_charsStartIndex', './_stringToArr
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
var undefined;
/** Used to match leading and trailing whitespace. */
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/**

View File

@@ -24,9 +24,9 @@ define(['./_LazyWrapper', './_LodashWrapper', './_baseLodash', './isArray', './i
* Shortcut fusion is an optimization to merge iteratee calls; this avoids
* the creation of intermediate arrays and can greatly reduce the number of
* iteratee executions. Sections of a chain sequence qualify for shortcut
* fusion if the section is applied to an array of at least `200` elements
* and any iteratees accept only one argument. The heuristic for whether a
* section qualifies for shortcut fusion is subject to change.
* fusion if the section is applied to an array and iteratees accept only
* one argument. The heuristic for whether a section qualifies for shortcut
* fusion is subject to change.
*
* Chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.