UNPKG

25.2 kBJavaScriptView Raw
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. */
11var FUNC_ERROR_TEXT = 'Expected a function';
12
13/** Used to stand-in for `undefined` hash values. */
14var HASH_UNDEFINED = '__lodash_hash_undefined__';
15
16/** Used as references for various `Number` constants. */
17var INFINITY = 1 / 0,
18 MAX_SAFE_INTEGER = 9007199254740991;
19
20/** `Object#toString` result references. */
21var funcTag = '[object Function]',
22 genTag = '[object GeneratorFunction]',
23 symbolTag = '[object Symbol]';
24
25/** Used to match property names within property paths. */
26var 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 */
35var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
36
37/** Used to match backslashes in property paths. */
38var reEscapeChar = /\\(\\)?/g;
39
40/** Used to detect host constructors (Safari). */
41var reIsHostCtor = /^\[object .+?Constructor\]$/;
42
43/** Used to detect unsigned integer values. */
44var reIsUint = /^(?:0|[1-9]\d*)$/;
45
46/** Detect free variable `global` from Node.js. */
47var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
48
49/** Detect free variable `self`. */
50var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
51
52/** Used as a reference to the global object. */
53var 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 */
63function 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 */
74function 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. */
87var arrayProto = Array.prototype,
88 funcProto = Function.prototype,
89 objectProto = Object.prototype;
90
91/** Used to detect overreaching core-js shims. */
92var coreJsData = root['__core-js_shared__'];
93
94/** Used to detect methods masquerading as native. */
95var 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. */
101var funcToString = funcProto.toString;
102
103/** Used to check objects for own properties. */
104var 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 */
111var objectToString = objectProto.toString;
112
113/** Used to detect if a method is native. */
114var reIsNative = RegExp('^' +
115 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
116 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
117);
118
119/** Built-in value references. */
120var Symbol = root.Symbol,
121 splice = arrayProto.splice;
122
123/* Built-in method references that are verified to be native. */
124var Map = getNative(root, 'Map'),
125 nativeCreate = getNative(Object, 'create');
126
127/** Used to convert symbols to primitives and strings. */
128var 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 */
138function 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 */
156function 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 */
170function 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 */
183function 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 */
201function 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 */
216function 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`.
223Hash.prototype.clear = hashClear;
224Hash.prototype['delete'] = hashDelete;
225Hash.prototype.get = hashGet;
226Hash.prototype.has = hashHas;
227Hash.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 */
236function 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 */
254function 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 */
267function 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 */
292function 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 */
308function 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 */
322function 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`.
335ListCache.prototype.clear = listCacheClear;
336ListCache.prototype['delete'] = listCacheDelete;
337ListCache.prototype.get = listCacheGet;
338ListCache.prototype.has = listCacheHas;
339ListCache.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 */
348function 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 */
366function 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 */
383function 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 */
396function 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 */
409function 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 */
423function mapCacheSet(key, value) {
424 getMapData(this, key).set(key, value);
425 return this;
426}
427
428// Add methods to `MapCache`.
429MapCache.prototype.clear = mapCacheClear;
430MapCache.prototype['delete'] = mapCacheDelete;
431MapCache.prototype.get = mapCacheGet;
432MapCache.prototype.has = mapCacheHas;
433MapCache.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 */
445function 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 */
461function 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 */
479function 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 */
497function 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 */
535function 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 */
554function 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 */
566function 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 */
581function 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 */
594function 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 */
609function 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 */
629function 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 */
643function 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 */
654var 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 */
674function 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 */
689function 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 */
745function 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`.
766memoize.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 */
800function 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 */
827var 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 */
846function 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 */
878function 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 */
907function 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 */
928function 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 */
954function 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 */
986function set(object, path, value) {
987 return object == null ? object : baseSet(object, path, value);
988}
989
990module.exports = set;