1 | /**
|
2 | * lodash (Custom Build) <https://lodash.com/>
|
3 | * Build: `lodash modularize exports="npm" -o ./`
|
4 | * Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
5 | * Released under MIT license <https://lodash.com/license>
|
6 | * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
7 | * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
8 | */
|
9 |
|
10 | /** Used as the `TypeError` message for "Functions" methods. */
|
11 | var FUNC_ERROR_TEXT = 'Expected a function';
|
12 |
|
13 | /** Used to stand-in for `undefined` hash values. */
|
14 | var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
15 |
|
16 | /** Used as references for various `Number` constants. */
|
17 | var INFINITY = 1 / 0,
|
18 | MAX_SAFE_INTEGER = 9007199254740991;
|
19 |
|
20 | /** `Object#toString` result references. */
|
21 | var funcTag = '[object Function]',
|
22 | genTag = '[object GeneratorFunction]',
|
23 | symbolTag = '[object Symbol]';
|
24 |
|
25 | /** Used to match property names within property paths. */
|
26 | var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
27 | reIsPlainProp = /^\w*$/,
|
28 | reLeadingDot = /^\./,
|
29 | rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
|
30 |
|
31 | /**
|
32 | * Used to match `RegExp`
|
33 | * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
34 | */
|
35 | var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
36 |
|
37 | /** Used to match backslashes in property paths. */
|
38 | var reEscapeChar = /\\(\\)?/g;
|
39 |
|
40 | /** Used to detect host constructors (Safari). */
|
41 | var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
42 |
|
43 | /** Used to detect unsigned integer values. */
|
44 | var reIsUint = /^(?:0|[1-9]\d*)$/;
|
45 |
|
46 | /** Detect free variable `global` from Node.js. */
|
47 | var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
48 |
|
49 | /** Detect free variable `self`. */
|
50 | var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
51 |
|
52 | /** Used as a reference to the global object. */
|
53 | var root = freeGlobal || freeSelf || Function('return this')();
|
54 |
|
55 | /**
|
56 | * Gets the value at `key` of `object`.
|
57 | *
|
58 | * @private
|
59 | * @param {Object} [object] The object to query.
|
60 | * @param {string} key The key of the property to get.
|
61 | * @returns {*} Returns the property value.
|
62 | */
|
63 | function getValue(object, key) {
|
64 | return object == null ? undefined : object[key];
|
65 | }
|
66 |
|
67 | /**
|
68 | * Checks if `value` is a host object in IE < 9.
|
69 | *
|
70 | * @private
|
71 | * @param {*} value The value to check.
|
72 | * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
73 | */
|
74 | function isHostObject(value) {
|
75 | // Many host objects are `Object` objects that can coerce to strings
|
76 | // despite having improperly defined `toString` methods.
|
77 | var result = false;
|
78 | if (value != null && typeof value.toString != 'function') {
|
79 | try {
|
80 | result = !!(value + '');
|
81 | } catch (e) {}
|
82 | }
|
83 | return result;
|
84 | }
|
85 |
|
86 | /** Used for built-in method references. */
|
87 | var arrayProto = Array.prototype,
|
88 | funcProto = Function.prototype,
|
89 | objectProto = Object.prototype;
|
90 |
|
91 | /** Used to detect overreaching core-js shims. */
|
92 | var coreJsData = root['__core-js_shared__'];
|
93 |
|
94 | /** Used to detect methods masquerading as native. */
|
95 | var maskSrcKey = (function() {
|
96 | var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
97 | return uid ? ('Symbol(src)_1.' + uid) : '';
|
98 | }());
|
99 |
|
100 | /** Used to resolve the decompiled source of functions. */
|
101 | var funcToString = funcProto.toString;
|
102 |
|
103 | /** Used to check objects for own properties. */
|
104 | var hasOwnProperty = objectProto.hasOwnProperty;
|
105 |
|
106 | /**
|
107 | * Used to resolve the
|
108 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
109 | * of values.
|
110 | */
|
111 | var objectToString = objectProto.toString;
|
112 |
|
113 | /** Used to detect if a method is native. */
|
114 | var reIsNative = RegExp('^' +
|
115 | funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
116 | .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
117 | );
|
118 |
|
119 | /** Built-in value references. */
|
120 | var Symbol = root.Symbol,
|
121 | splice = arrayProto.splice;
|
122 |
|
123 | /* Built-in method references that are verified to be native. */
|
124 | var Map = getNative(root, 'Map'),
|
125 | nativeCreate = getNative(Object, 'create');
|
126 |
|
127 | /** Used to convert symbols to primitives and strings. */
|
128 | var symbolProto = Symbol ? Symbol.prototype : undefined,
|
129 | symbolToString = symbolProto ? symbolProto.toString : undefined;
|
130 |
|
131 | /**
|
132 | * Creates a hash object.
|
133 | *
|
134 | * @private
|
135 | * @constructor
|
136 | * @param {Array} [entries] The key-value pairs to cache.
|
137 | */
|
138 | function Hash(entries) {
|
139 | var index = -1,
|
140 | length = entries ? entries.length : 0;
|
141 |
|
142 | this.clear();
|
143 | while (++index < length) {
|
144 | var entry = entries[index];
|
145 | this.set(entry[0], entry[1]);
|
146 | }
|
147 | }
|
148 |
|
149 | /**
|
150 | * Removes all key-value entries from the hash.
|
151 | *
|
152 | * @private
|
153 | * @name clear
|
154 | * @memberOf Hash
|
155 | */
|
156 | function hashClear() {
|
157 | this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
158 | }
|
159 |
|
160 | /**
|
161 | * Removes `key` and its value from the hash.
|
162 | *
|
163 | * @private
|
164 | * @name delete
|
165 | * @memberOf Hash
|
166 | * @param {Object} hash The hash to modify.
|
167 | * @param {string} key The key of the value to remove.
|
168 | * @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
169 | */
|
170 | function hashDelete(key) {
|
171 | return this.has(key) && delete this.__data__[key];
|
172 | }
|
173 |
|
174 | /**
|
175 | * Gets the hash value for `key`.
|
176 | *
|
177 | * @private
|
178 | * @name get
|
179 | * @memberOf Hash
|
180 | * @param {string} key The key of the value to get.
|
181 | * @returns {*} Returns the entry value.
|
182 | */
|
183 | function hashGet(key) {
|
184 | var data = this.__data__;
|
185 | if (nativeCreate) {
|
186 | var result = data[key];
|
187 | return result === HASH_UNDEFINED ? undefined : result;
|
188 | }
|
189 | return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
190 | }
|
191 |
|
192 | /**
|
193 | * Checks if a hash value for `key` exists.
|
194 | *
|
195 | * @private
|
196 | * @name has
|
197 | * @memberOf Hash
|
198 | * @param {string} key The key of the entry to check.
|
199 | * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
200 | */
|
201 | function hashHas(key) {
|
202 | var data = this.__data__;
|
203 | return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
|
204 | }
|
205 |
|
206 | /**
|
207 | * Sets the hash `key` to `value`.
|
208 | *
|
209 | * @private
|
210 | * @name set
|
211 | * @memberOf Hash
|
212 | * @param {string} key The key of the value to set.
|
213 | * @param {*} value The value to set.
|
214 | * @returns {Object} Returns the hash instance.
|
215 | */
|
216 | function hashSet(key, value) {
|
217 | var data = this.__data__;
|
218 | data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
219 | return this;
|
220 | }
|
221 |
|
222 | // Add methods to `Hash`.
|
223 | Hash.prototype.clear = hashClear;
|
224 | Hash.prototype['delete'] = hashDelete;
|
225 | Hash.prototype.get = hashGet;
|
226 | Hash.prototype.has = hashHas;
|
227 | Hash.prototype.set = hashSet;
|
228 |
|
229 | /**
|
230 | * Creates an list cache object.
|
231 | *
|
232 | * @private
|
233 | * @constructor
|
234 | * @param {Array} [entries] The key-value pairs to cache.
|
235 | */
|
236 | function ListCache(entries) {
|
237 | var index = -1,
|
238 | length = entries ? entries.length : 0;
|
239 |
|
240 | this.clear();
|
241 | while (++index < length) {
|
242 | var entry = entries[index];
|
243 | this.set(entry[0], entry[1]);
|
244 | }
|
245 | }
|
246 |
|
247 | /**
|
248 | * Removes all key-value entries from the list cache.
|
249 | *
|
250 | * @private
|
251 | * @name clear
|
252 | * @memberOf ListCache
|
253 | */
|
254 | function listCacheClear() {
|
255 | this.__data__ = [];
|
256 | }
|
257 |
|
258 | /**
|
259 | * Removes `key` and its value from the list cache.
|
260 | *
|
261 | * @private
|
262 | * @name delete
|
263 | * @memberOf ListCache
|
264 | * @param {string} key The key of the value to remove.
|
265 | * @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
266 | */
|
267 | function listCacheDelete(key) {
|
268 | var data = this.__data__,
|
269 | index = assocIndexOf(data, key);
|
270 |
|
271 | if (index < 0) {
|
272 | return false;
|
273 | }
|
274 | var lastIndex = data.length - 1;
|
275 | if (index == lastIndex) {
|
276 | data.pop();
|
277 | } else {
|
278 | splice.call(data, index, 1);
|
279 | }
|
280 | return true;
|
281 | }
|
282 |
|
283 | /**
|
284 | * Gets the list cache value for `key`.
|
285 | *
|
286 | * @private
|
287 | * @name get
|
288 | * @memberOf ListCache
|
289 | * @param {string} key The key of the value to get.
|
290 | * @returns {*} Returns the entry value.
|
291 | */
|
292 | function listCacheGet(key) {
|
293 | var data = this.__data__,
|
294 | index = assocIndexOf(data, key);
|
295 |
|
296 | return index < 0 ? undefined : data[index][1];
|
297 | }
|
298 |
|
299 | /**
|
300 | * Checks if a list cache value for `key` exists.
|
301 | *
|
302 | * @private
|
303 | * @name has
|
304 | * @memberOf ListCache
|
305 | * @param {string} key The key of the entry to check.
|
306 | * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
307 | */
|
308 | function listCacheHas(key) {
|
309 | return assocIndexOf(this.__data__, key) > -1;
|
310 | }
|
311 |
|
312 | /**
|
313 | * Sets the list cache `key` to `value`.
|
314 | *
|
315 | * @private
|
316 | * @name set
|
317 | * @memberOf ListCache
|
318 | * @param {string} key The key of the value to set.
|
319 | * @param {*} value The value to set.
|
320 | * @returns {Object} Returns the list cache instance.
|
321 | */
|
322 | function listCacheSet(key, value) {
|
323 | var data = this.__data__,
|
324 | index = assocIndexOf(data, key);
|
325 |
|
326 | if (index < 0) {
|
327 | data.push([key, value]);
|
328 | } else {
|
329 | data[index][1] = value;
|
330 | }
|
331 | return this;
|
332 | }
|
333 |
|
334 | // Add methods to `ListCache`.
|
335 | ListCache.prototype.clear = listCacheClear;
|
336 | ListCache.prototype['delete'] = listCacheDelete;
|
337 | ListCache.prototype.get = listCacheGet;
|
338 | ListCache.prototype.has = listCacheHas;
|
339 | ListCache.prototype.set = listCacheSet;
|
340 |
|
341 | /**
|
342 | * Creates a map cache object to store key-value pairs.
|
343 | *
|
344 | * @private
|
345 | * @constructor
|
346 | * @param {Array} [entries] The key-value pairs to cache.
|
347 | */
|
348 | function MapCache(entries) {
|
349 | var index = -1,
|
350 | length = entries ? entries.length : 0;
|
351 |
|
352 | this.clear();
|
353 | while (++index < length) {
|
354 | var entry = entries[index];
|
355 | this.set(entry[0], entry[1]);
|
356 | }
|
357 | }
|
358 |
|
359 | /**
|
360 | * Removes all key-value entries from the map.
|
361 | *
|
362 | * @private
|
363 | * @name clear
|
364 | * @memberOf MapCache
|
365 | */
|
366 | function mapCacheClear() {
|
367 | this.__data__ = {
|
368 | 'hash': new Hash,
|
369 | 'map': new (Map || ListCache),
|
370 | 'string': new Hash
|
371 | };
|
372 | }
|
373 |
|
374 | /**
|
375 | * Removes `key` and its value from the map.
|
376 | *
|
377 | * @private
|
378 | * @name delete
|
379 | * @memberOf MapCache
|
380 | * @param {string} key The key of the value to remove.
|
381 | * @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
382 | */
|
383 | function mapCacheDelete(key) {
|
384 | return getMapData(this, key)['delete'](key);
|
385 | }
|
386 |
|
387 | /**
|
388 | * Gets the map value for `key`.
|
389 | *
|
390 | * @private
|
391 | * @name get
|
392 | * @memberOf MapCache
|
393 | * @param {string} key The key of the value to get.
|
394 | * @returns {*} Returns the entry value.
|
395 | */
|
396 | function mapCacheGet(key) {
|
397 | return getMapData(this, key).get(key);
|
398 | }
|
399 |
|
400 | /**
|
401 | * Checks if a map value for `key` exists.
|
402 | *
|
403 | * @private
|
404 | * @name has
|
405 | * @memberOf MapCache
|
406 | * @param {string} key The key of the entry to check.
|
407 | * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
408 | */
|
409 | function mapCacheHas(key) {
|
410 | return getMapData(this, key).has(key);
|
411 | }
|
412 |
|
413 | /**
|
414 | * Sets the map `key` to `value`.
|
415 | *
|
416 | * @private
|
417 | * @name set
|
418 | * @memberOf MapCache
|
419 | * @param {string} key The key of the value to set.
|
420 | * @param {*} value The value to set.
|
421 | * @returns {Object} Returns the map cache instance.
|
422 | */
|
423 | function mapCacheSet(key, value) {
|
424 | getMapData(this, key).set(key, value);
|
425 | return this;
|
426 | }
|
427 |
|
428 | // Add methods to `MapCache`.
|
429 | MapCache.prototype.clear = mapCacheClear;
|
430 | MapCache.prototype['delete'] = mapCacheDelete;
|
431 | MapCache.prototype.get = mapCacheGet;
|
432 | MapCache.prototype.has = mapCacheHas;
|
433 | MapCache.prototype.set = mapCacheSet;
|
434 |
|
435 | /**
|
436 | * Assigns `value` to `key` of `object` if the existing value is not equivalent
|
437 | * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
438 | * for equality comparisons.
|
439 | *
|
440 | * @private
|
441 | * @param {Object} object The object to modify.
|
442 | * @param {string} key The key of the property to assign.
|
443 | * @param {*} value The value to assign.
|
444 | */
|
445 | function assignValue(object, key, value) {
|
446 | var objValue = object[key];
|
447 | if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
448 | (value === undefined && !(key in object))) {
|
449 | object[key] = value;
|
450 | }
|
451 | }
|
452 |
|
453 | /**
|
454 | * Gets the index at which the `key` is found in `array` of key-value pairs.
|
455 | *
|
456 | * @private
|
457 | * @param {Array} array The array to inspect.
|
458 | * @param {*} key The key to search for.
|
459 | * @returns {number} Returns the index of the matched value, else `-1`.
|
460 | */
|
461 | function assocIndexOf(array, key) {
|
462 | var length = array.length;
|
463 | while (length--) {
|
464 | if (eq(array[length][0], key)) {
|
465 | return length;
|
466 | }
|
467 | }
|
468 | return -1;
|
469 | }
|
470 |
|
471 | /**
|
472 | * The base implementation of `_.isNative` without bad shim checks.
|
473 | *
|
474 | * @private
|
475 | * @param {*} value The value to check.
|
476 | * @returns {boolean} Returns `true` if `value` is a native function,
|
477 | * else `false`.
|
478 | */
|
479 | function baseIsNative(value) {
|
480 | if (!isObject(value) || isMasked(value)) {
|
481 | return false;
|
482 | }
|
483 | var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
|
484 | return pattern.test(toSource(value));
|
485 | }
|
486 |
|
487 | /**
|
488 | * The base implementation of `_.set`.
|
489 | *
|
490 | * @private
|
491 | * @param {Object} object The object to modify.
|
492 | * @param {Array|string} path The path of the property to set.
|
493 | * @param {*} value The value to set.
|
494 | * @param {Function} [customizer] The function to customize path creation.
|
495 | * @returns {Object} Returns `object`.
|
496 | */
|
497 | function baseSet(object, path, value, customizer) {
|
498 | if (!isObject(object)) {
|
499 | return object;
|
500 | }
|
501 | path = isKey(path, object) ? [path] : castPath(path);
|
502 |
|
503 | var index = -1,
|
504 | length = path.length,
|
505 | lastIndex = length - 1,
|
506 | nested = object;
|
507 |
|
508 | while (nested != null && ++index < length) {
|
509 | var key = toKey(path[index]),
|
510 | newValue = value;
|
511 |
|
512 | if (index != lastIndex) {
|
513 | var objValue = nested[key];
|
514 | newValue = customizer ? customizer(objValue, key, nested) : undefined;
|
515 | if (newValue === undefined) {
|
516 | newValue = isObject(objValue)
|
517 | ? objValue
|
518 | : (isIndex(path[index + 1]) ? [] : {});
|
519 | }
|
520 | }
|
521 | assignValue(nested, key, newValue);
|
522 | nested = nested[key];
|
523 | }
|
524 | return object;
|
525 | }
|
526 |
|
527 | /**
|
528 | * The base implementation of `_.toString` which doesn't convert nullish
|
529 | * values to empty strings.
|
530 | *
|
531 | * @private
|
532 | * @param {*} value The value to process.
|
533 | * @returns {string} Returns the string.
|
534 | */
|
535 | function baseToString(value) {
|
536 | // Exit early for strings to avoid a performance hit in some environments.
|
537 | if (typeof value == 'string') {
|
538 | return value;
|
539 | }
|
540 | if (isSymbol(value)) {
|
541 | return symbolToString ? symbolToString.call(value) : '';
|
542 | }
|
543 | var result = (value + '');
|
544 | return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
545 | }
|
546 |
|
547 | /**
|
548 | * Casts `value` to a path array if it's not one.
|
549 | *
|
550 | * @private
|
551 | * @param {*} value The value to inspect.
|
552 | * @returns {Array} Returns the cast property path array.
|
553 | */
|
554 | function castPath(value) {
|
555 | return isArray(value) ? value : stringToPath(value);
|
556 | }
|
557 |
|
558 | /**
|
559 | * Gets the data for `map`.
|
560 | *
|
561 | * @private
|
562 | * @param {Object} map The map to query.
|
563 | * @param {string} key The reference key.
|
564 | * @returns {*} Returns the map data.
|
565 | */
|
566 | function getMapData(map, key) {
|
567 | var data = map.__data__;
|
568 | return isKeyable(key)
|
569 | ? data[typeof key == 'string' ? 'string' : 'hash']
|
570 | : data.map;
|
571 | }
|
572 |
|
573 | /**
|
574 | * Gets the native function at `key` of `object`.
|
575 | *
|
576 | * @private
|
577 | * @param {Object} object The object to query.
|
578 | * @param {string} key The key of the method to get.
|
579 | * @returns {*} Returns the function if it's native, else `undefined`.
|
580 | */
|
581 | function getNative(object, key) {
|
582 | var value = getValue(object, key);
|
583 | return baseIsNative(value) ? value : undefined;
|
584 | }
|
585 |
|
586 | /**
|
587 | * Checks if `value` is a valid array-like index.
|
588 | *
|
589 | * @private
|
590 | * @param {*} value The value to check.
|
591 | * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
592 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
593 | */
|
594 | function isIndex(value, length) {
|
595 | length = length == null ? MAX_SAFE_INTEGER : length;
|
596 | return !!length &&
|
597 | (typeof value == 'number' || reIsUint.test(value)) &&
|
598 | (value > -1 && value % 1 == 0 && value < length);
|
599 | }
|
600 |
|
601 | /**
|
602 | * Checks if `value` is a property name and not a property path.
|
603 | *
|
604 | * @private
|
605 | * @param {*} value The value to check.
|
606 | * @param {Object} [object] The object to query keys on.
|
607 | * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
608 | */
|
609 | function isKey(value, object) {
|
610 | if (isArray(value)) {
|
611 | return false;
|
612 | }
|
613 | var type = typeof value;
|
614 | if (type == 'number' || type == 'symbol' || type == 'boolean' ||
|
615 | value == null || isSymbol(value)) {
|
616 | return true;
|
617 | }
|
618 | return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
619 | (object != null && value in Object(object));
|
620 | }
|
621 |
|
622 | /**
|
623 | * Checks if `value` is suitable for use as unique object key.
|
624 | *
|
625 | * @private
|
626 | * @param {*} value The value to check.
|
627 | * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
628 | */
|
629 | function isKeyable(value) {
|
630 | var type = typeof value;
|
631 | return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
632 | ? (value !== '__proto__')
|
633 | : (value === null);
|
634 | }
|
635 |
|
636 | /**
|
637 | * Checks if `func` has its source masked.
|
638 | *
|
639 | * @private
|
640 | * @param {Function} func The function to check.
|
641 | * @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
642 | */
|
643 | function isMasked(func) {
|
644 | return !!maskSrcKey && (maskSrcKey in func);
|
645 | }
|
646 |
|
647 | /**
|
648 | * Converts `string` to a property path array.
|
649 | *
|
650 | * @private
|
651 | * @param {string} string The string to convert.
|
652 | * @returns {Array} Returns the property path array.
|
653 | */
|
654 | var stringToPath = memoize(function(string) {
|
655 | string = toString(string);
|
656 |
|
657 | var result = [];
|
658 | if (reLeadingDot.test(string)) {
|
659 | result.push('');
|
660 | }
|
661 | string.replace(rePropName, function(match, number, quote, string) {
|
662 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
|
663 | });
|
664 | return result;
|
665 | });
|
666 |
|
667 | /**
|
668 | * Converts `value` to a string key if it's not a string or symbol.
|
669 | *
|
670 | * @private
|
671 | * @param {*} value The value to inspect.
|
672 | * @returns {string|symbol} Returns the key.
|
673 | */
|
674 | function toKey(value) {
|
675 | if (typeof value == 'string' || isSymbol(value)) {
|
676 | return value;
|
677 | }
|
678 | var result = (value + '');
|
679 | return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
680 | }
|
681 |
|
682 | /**
|
683 | * Converts `func` to its source code.
|
684 | *
|
685 | * @private
|
686 | * @param {Function} func The function to process.
|
687 | * @returns {string} Returns the source code.
|
688 | */
|
689 | function toSource(func) {
|
690 | if (func != null) {
|
691 | try {
|
692 | return funcToString.call(func);
|
693 | } catch (e) {}
|
694 | try {
|
695 | return (func + '');
|
696 | } catch (e) {}
|
697 | }
|
698 | return '';
|
699 | }
|
700 |
|
701 | /**
|
702 | * Creates a function that memoizes the result of `func`. If `resolver` is
|
703 | * provided, it determines the cache key for storing the result based on the
|
704 | * arguments provided to the memoized function. By default, the first argument
|
705 | * provided to the memoized function is used as the map cache key. The `func`
|
706 | * is invoked with the `this` binding of the memoized function.
|
707 | *
|
708 | * **Note:** The cache is exposed as the `cache` property on the memoized
|
709 | * function. Its creation may be customized by replacing the `_.memoize.Cache`
|
710 | * constructor with one whose instances implement the
|
711 | * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
|
712 | * method interface of `delete`, `get`, `has`, and `set`.
|
713 | *
|
714 | * @static
|
715 | * @memberOf _
|
716 | * @since 0.1.0
|
717 | * @category Function
|
718 | * @param {Function} func The function to have its output memoized.
|
719 | * @param {Function} [resolver] The function to resolve the cache key.
|
720 | * @returns {Function} Returns the new memoized function.
|
721 | * @example
|
722 | *
|
723 | * var object = { 'a': 1, 'b': 2 };
|
724 | * var other = { 'c': 3, 'd': 4 };
|
725 | *
|
726 | * var values = _.memoize(_.values);
|
727 | * values(object);
|
728 | * // => [1, 2]
|
729 | *
|
730 | * values(other);
|
731 | * // => [3, 4]
|
732 | *
|
733 | * object.a = 2;
|
734 | * values(object);
|
735 | * // => [1, 2]
|
736 | *
|
737 | * // Modify the result cache.
|
738 | * values.cache.set(object, ['a', 'b']);
|
739 | * values(object);
|
740 | * // => ['a', 'b']
|
741 | *
|
742 | * // Replace `_.memoize.Cache`.
|
743 | * _.memoize.Cache = WeakMap;
|
744 | */
|
745 | function memoize(func, resolver) {
|
746 | if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
|
747 | throw new TypeError(FUNC_ERROR_TEXT);
|
748 | }
|
749 | var memoized = function() {
|
750 | var args = arguments,
|
751 | key = resolver ? resolver.apply(this, args) : args[0],
|
752 | cache = memoized.cache;
|
753 |
|
754 | if (cache.has(key)) {
|
755 | return cache.get(key);
|
756 | }
|
757 | var result = func.apply(this, args);
|
758 | memoized.cache = cache.set(key, result);
|
759 | return result;
|
760 | };
|
761 | memoized.cache = new (memoize.Cache || MapCache);
|
762 | return memoized;
|
763 | }
|
764 |
|
765 | // Assign cache to `_.memoize`.
|
766 | memoize.Cache = MapCache;
|
767 |
|
768 | /**
|
769 | * Performs a
|
770 | * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
771 | * comparison between two values to determine if they are equivalent.
|
772 | *
|
773 | * @static
|
774 | * @memberOf _
|
775 | * @since 4.0.0
|
776 | * @category Lang
|
777 | * @param {*} value The value to compare.
|
778 | * @param {*} other The other value to compare.
|
779 | * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
780 | * @example
|
781 | *
|
782 | * var object = { 'a': 1 };
|
783 | * var other = { 'a': 1 };
|
784 | *
|
785 | * _.eq(object, object);
|
786 | * // => true
|
787 | *
|
788 | * _.eq(object, other);
|
789 | * // => false
|
790 | *
|
791 | * _.eq('a', 'a');
|
792 | * // => true
|
793 | *
|
794 | * _.eq('a', Object('a'));
|
795 | * // => false
|
796 | *
|
797 | * _.eq(NaN, NaN);
|
798 | * // => true
|
799 | */
|
800 | function eq(value, other) {
|
801 | return value === other || (value !== value && other !== other);
|
802 | }
|
803 |
|
804 | /**
|
805 | * Checks if `value` is classified as an `Array` object.
|
806 | *
|
807 | * @static
|
808 | * @memberOf _
|
809 | * @since 0.1.0
|
810 | * @category Lang
|
811 | * @param {*} value The value to check.
|
812 | * @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
813 | * @example
|
814 | *
|
815 | * _.isArray([1, 2, 3]);
|
816 | * // => true
|
817 | *
|
818 | * _.isArray(document.body.children);
|
819 | * // => false
|
820 | *
|
821 | * _.isArray('abc');
|
822 | * // => false
|
823 | *
|
824 | * _.isArray(_.noop);
|
825 | * // => false
|
826 | */
|
827 | var isArray = Array.isArray;
|
828 |
|
829 | /**
|
830 | * Checks if `value` is classified as a `Function` object.
|
831 | *
|
832 | * @static
|
833 | * @memberOf _
|
834 | * @since 0.1.0
|
835 | * @category Lang
|
836 | * @param {*} value The value to check.
|
837 | * @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
838 | * @example
|
839 | *
|
840 | * _.isFunction(_);
|
841 | * // => true
|
842 | *
|
843 | * _.isFunction(/abc/);
|
844 | * // => false
|
845 | */
|
846 | function isFunction(value) {
|
847 | // The use of `Object#toString` avoids issues with the `typeof` operator
|
848 | // in Safari 8-9 which returns 'object' for typed array and other constructors.
|
849 | var tag = isObject(value) ? objectToString.call(value) : '';
|
850 | return tag == funcTag || tag == genTag;
|
851 | }
|
852 |
|
853 | /**
|
854 | * Checks if `value` is the
|
855 | * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
856 | * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
857 | *
|
858 | * @static
|
859 | * @memberOf _
|
860 | * @since 0.1.0
|
861 | * @category Lang
|
862 | * @param {*} value The value to check.
|
863 | * @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
864 | * @example
|
865 | *
|
866 | * _.isObject({});
|
867 | * // => true
|
868 | *
|
869 | * _.isObject([1, 2, 3]);
|
870 | * // => true
|
871 | *
|
872 | * _.isObject(_.noop);
|
873 | * // => true
|
874 | *
|
875 | * _.isObject(null);
|
876 | * // => false
|
877 | */
|
878 | function isObject(value) {
|
879 | var type = typeof value;
|
880 | return !!value && (type == 'object' || type == 'function');
|
881 | }
|
882 |
|
883 | /**
|
884 | * Checks if `value` is object-like. A value is object-like if it's not `null`
|
885 | * and has a `typeof` result of "object".
|
886 | *
|
887 | * @static
|
888 | * @memberOf _
|
889 | * @since 4.0.0
|
890 | * @category Lang
|
891 | * @param {*} value The value to check.
|
892 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
893 | * @example
|
894 | *
|
895 | * _.isObjectLike({});
|
896 | * // => true
|
897 | *
|
898 | * _.isObjectLike([1, 2, 3]);
|
899 | * // => true
|
900 | *
|
901 | * _.isObjectLike(_.noop);
|
902 | * // => false
|
903 | *
|
904 | * _.isObjectLike(null);
|
905 | * // => false
|
906 | */
|
907 | function isObjectLike(value) {
|
908 | return !!value && typeof value == 'object';
|
909 | }
|
910 |
|
911 | /**
|
912 | * Checks if `value` is classified as a `Symbol` primitive or object.
|
913 | *
|
914 | * @static
|
915 | * @memberOf _
|
916 | * @since 4.0.0
|
917 | * @category Lang
|
918 | * @param {*} value The value to check.
|
919 | * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
920 | * @example
|
921 | *
|
922 | * _.isSymbol(Symbol.iterator);
|
923 | * // => true
|
924 | *
|
925 | * _.isSymbol('abc');
|
926 | * // => false
|
927 | */
|
928 | function isSymbol(value) {
|
929 | return typeof value == 'symbol' ||
|
930 | (isObjectLike(value) && objectToString.call(value) == symbolTag);
|
931 | }
|
932 |
|
933 | /**
|
934 | * Converts `value` to a string. An empty string is returned for `null`
|
935 | * and `undefined` values. The sign of `-0` is preserved.
|
936 | *
|
937 | * @static
|
938 | * @memberOf _
|
939 | * @since 4.0.0
|
940 | * @category Lang
|
941 | * @param {*} value The value to process.
|
942 | * @returns {string} Returns the string.
|
943 | * @example
|
944 | *
|
945 | * _.toString(null);
|
946 | * // => ''
|
947 | *
|
948 | * _.toString(-0);
|
949 | * // => '-0'
|
950 | *
|
951 | * _.toString([1, 2, 3]);
|
952 | * // => '1,2,3'
|
953 | */
|
954 | function toString(value) {
|
955 | return value == null ? '' : baseToString(value);
|
956 | }
|
957 |
|
958 | /**
|
959 | * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
|
960 | * it's created. Arrays are created for missing index properties while objects
|
961 | * are created for all other missing properties. Use `_.setWith` to customize
|
962 | * `path` creation.
|
963 | *
|
964 | * **Note:** This method mutates `object`.
|
965 | *
|
966 | * @static
|
967 | * @memberOf _
|
968 | * @since 3.7.0
|
969 | * @category Object
|
970 | * @param {Object} object The object to modify.
|
971 | * @param {Array|string} path The path of the property to set.
|
972 | * @param {*} value The value to set.
|
973 | * @returns {Object} Returns `object`.
|
974 | * @example
|
975 | *
|
976 | * var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
977 | *
|
978 | * _.set(object, 'a[0].b.c', 4);
|
979 | * console.log(object.a[0].b.c);
|
980 | * // => 4
|
981 | *
|
982 | * _.set(object, ['x', '0', 'y', 'z'], 5);
|
983 | * console.log(object.x[0].y.z);
|
984 | * // => 5
|
985 | */
|
986 | function set(object, path, value) {
|
987 | return object == null ? object : baseSet(object, path, value);
|
988 | }
|
989 |
|
990 | module.exports = set;
|