index.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  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. /** Used as the size to enable large array optimizations. */
  10. var LARGE_ARRAY_SIZE = 200;
  11. /** Used to stand-in for `undefined` hash values. */
  12. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  13. /** Used as references for various `Number` constants. */
  14. var INFINITY = 1 / 0;
  15. /** `Object#toString` result references. */
  16. var funcTag = '[object Function]',
  17. genTag = '[object GeneratorFunction]';
  18. /**
  19. * Used to match `RegExp`
  20. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  21. */
  22. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  23. /** Used to detect host constructors (Safari). */
  24. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  25. /** Detect free variable `global` from Node.js. */
  26. var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
  27. /** Detect free variable `self`. */
  28. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  29. /** Used as a reference to the global object. */
  30. var root = freeGlobal || freeSelf || Function('return this')();
  31. /**
  32. * A specialized version of `_.includes` for arrays without support for
  33. * specifying an index to search from.
  34. *
  35. * @private
  36. * @param {Array} [array] The array to inspect.
  37. * @param {*} target The value to search for.
  38. * @returns {boolean} Returns `true` if `target` is found, else `false`.
  39. */
  40. function arrayIncludes(array, value) {
  41. var length = array ? array.length : 0;
  42. return !!length && baseIndexOf(array, value, 0) > -1;
  43. }
  44. /**
  45. * This function is like `arrayIncludes` except that it accepts a comparator.
  46. *
  47. * @private
  48. * @param {Array} [array] The array to inspect.
  49. * @param {*} target The value to search for.
  50. * @param {Function} comparator The comparator invoked per element.
  51. * @returns {boolean} Returns `true` if `target` is found, else `false`.
  52. */
  53. function arrayIncludesWith(array, value, comparator) {
  54. var index = -1,
  55. length = array ? array.length : 0;
  56. while (++index < length) {
  57. if (comparator(value, array[index])) {
  58. return true;
  59. }
  60. }
  61. return false;
  62. }
  63. /**
  64. * The base implementation of `_.findIndex` and `_.findLastIndex` without
  65. * support for iteratee shorthands.
  66. *
  67. * @private
  68. * @param {Array} array The array to inspect.
  69. * @param {Function} predicate The function invoked per iteration.
  70. * @param {number} fromIndex The index to search from.
  71. * @param {boolean} [fromRight] Specify iterating from right to left.
  72. * @returns {number} Returns the index of the matched value, else `-1`.
  73. */
  74. function baseFindIndex(array, predicate, fromIndex, fromRight) {
  75. var length = array.length,
  76. index = fromIndex + (fromRight ? 1 : -1);
  77. while ((fromRight ? index-- : ++index < length)) {
  78. if (predicate(array[index], index, array)) {
  79. return index;
  80. }
  81. }
  82. return -1;
  83. }
  84. /**
  85. * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
  86. *
  87. * @private
  88. * @param {Array} array The array to inspect.
  89. * @param {*} value The value to search for.
  90. * @param {number} fromIndex The index to search from.
  91. * @returns {number} Returns the index of the matched value, else `-1`.
  92. */
  93. function baseIndexOf(array, value, fromIndex) {
  94. if (value !== value) {
  95. return baseFindIndex(array, baseIsNaN, fromIndex);
  96. }
  97. var index = fromIndex - 1,
  98. length = array.length;
  99. while (++index < length) {
  100. if (array[index] === value) {
  101. return index;
  102. }
  103. }
  104. return -1;
  105. }
  106. /**
  107. * The base implementation of `_.isNaN` without support for number objects.
  108. *
  109. * @private
  110. * @param {*} value The value to check.
  111. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
  112. */
  113. function baseIsNaN(value) {
  114. return value !== value;
  115. }
  116. /**
  117. * Checks if a cache value for `key` exists.
  118. *
  119. * @private
  120. * @param {Object} cache The cache to query.
  121. * @param {string} key The key of the entry to check.
  122. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  123. */
  124. function cacheHas(cache, key) {
  125. return cache.has(key);
  126. }
  127. /**
  128. * Gets the value at `key` of `object`.
  129. *
  130. * @private
  131. * @param {Object} [object] The object to query.
  132. * @param {string} key The key of the property to get.
  133. * @returns {*} Returns the property value.
  134. */
  135. function getValue(object, key) {
  136. return object == null ? undefined : object[key];
  137. }
  138. /**
  139. * Checks if `value` is a host object in IE < 9.
  140. *
  141. * @private
  142. * @param {*} value The value to check.
  143. * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
  144. */
  145. function isHostObject(value) {
  146. // Many host objects are `Object` objects that can coerce to strings
  147. // despite having improperly defined `toString` methods.
  148. var result = false;
  149. if (value != null && typeof value.toString != 'function') {
  150. try {
  151. result = !!(value + '');
  152. } catch (e) {}
  153. }
  154. return result;
  155. }
  156. /**
  157. * Converts `set` to an array of its values.
  158. *
  159. * @private
  160. * @param {Object} set The set to convert.
  161. * @returns {Array} Returns the values.
  162. */
  163. function setToArray(set) {
  164. var index = -1,
  165. result = Array(set.size);
  166. set.forEach(function(value) {
  167. result[++index] = value;
  168. });
  169. return result;
  170. }
  171. /** Used for built-in method references. */
  172. var arrayProto = Array.prototype,
  173. funcProto = Function.prototype,
  174. objectProto = Object.prototype;
  175. /** Used to detect overreaching core-js shims. */
  176. var coreJsData = root['__core-js_shared__'];
  177. /** Used to detect methods masquerading as native. */
  178. var maskSrcKey = (function() {
  179. var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  180. return uid ? ('Symbol(src)_1.' + uid) : '';
  181. }());
  182. /** Used to resolve the decompiled source of functions. */
  183. var funcToString = funcProto.toString;
  184. /** Used to check objects for own properties. */
  185. var hasOwnProperty = objectProto.hasOwnProperty;
  186. /**
  187. * Used to resolve the
  188. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  189. * of values.
  190. */
  191. var objectToString = objectProto.toString;
  192. /** Used to detect if a method is native. */
  193. var reIsNative = RegExp('^' +
  194. funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  195. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  196. );
  197. /** Built-in value references. */
  198. var splice = arrayProto.splice;
  199. /* Built-in method references that are verified to be native. */
  200. var Map = getNative(root, 'Map'),
  201. Set = getNative(root, 'Set'),
  202. nativeCreate = getNative(Object, 'create');
  203. /**
  204. * Creates a hash object.
  205. *
  206. * @private
  207. * @constructor
  208. * @param {Array} [entries] The key-value pairs to cache.
  209. */
  210. function Hash(entries) {
  211. var index = -1,
  212. length = entries ? entries.length : 0;
  213. this.clear();
  214. while (++index < length) {
  215. var entry = entries[index];
  216. this.set(entry[0], entry[1]);
  217. }
  218. }
  219. /**
  220. * Removes all key-value entries from the hash.
  221. *
  222. * @private
  223. * @name clear
  224. * @memberOf Hash
  225. */
  226. function hashClear() {
  227. this.__data__ = nativeCreate ? nativeCreate(null) : {};
  228. }
  229. /**
  230. * Removes `key` and its value from the hash.
  231. *
  232. * @private
  233. * @name delete
  234. * @memberOf Hash
  235. * @param {Object} hash The hash to modify.
  236. * @param {string} key The key of the value to remove.
  237. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  238. */
  239. function hashDelete(key) {
  240. return this.has(key) && delete this.__data__[key];
  241. }
  242. /**
  243. * Gets the hash value for `key`.
  244. *
  245. * @private
  246. * @name get
  247. * @memberOf Hash
  248. * @param {string} key The key of the value to get.
  249. * @returns {*} Returns the entry value.
  250. */
  251. function hashGet(key) {
  252. var data = this.__data__;
  253. if (nativeCreate) {
  254. var result = data[key];
  255. return result === HASH_UNDEFINED ? undefined : result;
  256. }
  257. return hasOwnProperty.call(data, key) ? data[key] : undefined;
  258. }
  259. /**
  260. * Checks if a hash value for `key` exists.
  261. *
  262. * @private
  263. * @name has
  264. * @memberOf Hash
  265. * @param {string} key The key of the entry to check.
  266. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  267. */
  268. function hashHas(key) {
  269. var data = this.__data__;
  270. return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
  271. }
  272. /**
  273. * Sets the hash `key` to `value`.
  274. *
  275. * @private
  276. * @name set
  277. * @memberOf Hash
  278. * @param {string} key The key of the value to set.
  279. * @param {*} value The value to set.
  280. * @returns {Object} Returns the hash instance.
  281. */
  282. function hashSet(key, value) {
  283. var data = this.__data__;
  284. data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  285. return this;
  286. }
  287. // Add methods to `Hash`.
  288. Hash.prototype.clear = hashClear;
  289. Hash.prototype['delete'] = hashDelete;
  290. Hash.prototype.get = hashGet;
  291. Hash.prototype.has = hashHas;
  292. Hash.prototype.set = hashSet;
  293. /**
  294. * Creates an list cache object.
  295. *
  296. * @private
  297. * @constructor
  298. * @param {Array} [entries] The key-value pairs to cache.
  299. */
  300. function ListCache(entries) {
  301. var index = -1,
  302. length = entries ? entries.length : 0;
  303. this.clear();
  304. while (++index < length) {
  305. var entry = entries[index];
  306. this.set(entry[0], entry[1]);
  307. }
  308. }
  309. /**
  310. * Removes all key-value entries from the list cache.
  311. *
  312. * @private
  313. * @name clear
  314. * @memberOf ListCache
  315. */
  316. function listCacheClear() {
  317. this.__data__ = [];
  318. }
  319. /**
  320. * Removes `key` and its value from the list cache.
  321. *
  322. * @private
  323. * @name delete
  324. * @memberOf ListCache
  325. * @param {string} key The key of the value to remove.
  326. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  327. */
  328. function listCacheDelete(key) {
  329. var data = this.__data__,
  330. index = assocIndexOf(data, key);
  331. if (index < 0) {
  332. return false;
  333. }
  334. var lastIndex = data.length - 1;
  335. if (index == lastIndex) {
  336. data.pop();
  337. } else {
  338. splice.call(data, index, 1);
  339. }
  340. return true;
  341. }
  342. /**
  343. * Gets the list cache value for `key`.
  344. *
  345. * @private
  346. * @name get
  347. * @memberOf ListCache
  348. * @param {string} key The key of the value to get.
  349. * @returns {*} Returns the entry value.
  350. */
  351. function listCacheGet(key) {
  352. var data = this.__data__,
  353. index = assocIndexOf(data, key);
  354. return index < 0 ? undefined : data[index][1];
  355. }
  356. /**
  357. * Checks if a list cache value for `key` exists.
  358. *
  359. * @private
  360. * @name has
  361. * @memberOf ListCache
  362. * @param {string} key The key of the entry to check.
  363. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  364. */
  365. function listCacheHas(key) {
  366. return assocIndexOf(this.__data__, key) > -1;
  367. }
  368. /**
  369. * Sets the list cache `key` to `value`.
  370. *
  371. * @private
  372. * @name set
  373. * @memberOf ListCache
  374. * @param {string} key The key of the value to set.
  375. * @param {*} value The value to set.
  376. * @returns {Object} Returns the list cache instance.
  377. */
  378. function listCacheSet(key, value) {
  379. var data = this.__data__,
  380. index = assocIndexOf(data, key);
  381. if (index < 0) {
  382. data.push([key, value]);
  383. } else {
  384. data[index][1] = value;
  385. }
  386. return this;
  387. }
  388. // Add methods to `ListCache`.
  389. ListCache.prototype.clear = listCacheClear;
  390. ListCache.prototype['delete'] = listCacheDelete;
  391. ListCache.prototype.get = listCacheGet;
  392. ListCache.prototype.has = listCacheHas;
  393. ListCache.prototype.set = listCacheSet;
  394. /**
  395. * Creates a map cache object to store key-value pairs.
  396. *
  397. * @private
  398. * @constructor
  399. * @param {Array} [entries] The key-value pairs to cache.
  400. */
  401. function MapCache(entries) {
  402. var index = -1,
  403. length = entries ? entries.length : 0;
  404. this.clear();
  405. while (++index < length) {
  406. var entry = entries[index];
  407. this.set(entry[0], entry[1]);
  408. }
  409. }
  410. /**
  411. * Removes all key-value entries from the map.
  412. *
  413. * @private
  414. * @name clear
  415. * @memberOf MapCache
  416. */
  417. function mapCacheClear() {
  418. this.__data__ = {
  419. 'hash': new Hash,
  420. 'map': new (Map || ListCache),
  421. 'string': new Hash
  422. };
  423. }
  424. /**
  425. * Removes `key` and its value from the map.
  426. *
  427. * @private
  428. * @name delete
  429. * @memberOf MapCache
  430. * @param {string} key The key of the value to remove.
  431. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  432. */
  433. function mapCacheDelete(key) {
  434. return getMapData(this, key)['delete'](key);
  435. }
  436. /**
  437. * Gets the map value for `key`.
  438. *
  439. * @private
  440. * @name get
  441. * @memberOf MapCache
  442. * @param {string} key The key of the value to get.
  443. * @returns {*} Returns the entry value.
  444. */
  445. function mapCacheGet(key) {
  446. return getMapData(this, key).get(key);
  447. }
  448. /**
  449. * Checks if a map value for `key` exists.
  450. *
  451. * @private
  452. * @name has
  453. * @memberOf MapCache
  454. * @param {string} key The key of the entry to check.
  455. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  456. */
  457. function mapCacheHas(key) {
  458. return getMapData(this, key).has(key);
  459. }
  460. /**
  461. * Sets the map `key` to `value`.
  462. *
  463. * @private
  464. * @name set
  465. * @memberOf MapCache
  466. * @param {string} key The key of the value to set.
  467. * @param {*} value The value to set.
  468. * @returns {Object} Returns the map cache instance.
  469. */
  470. function mapCacheSet(key, value) {
  471. getMapData(this, key).set(key, value);
  472. return this;
  473. }
  474. // Add methods to `MapCache`.
  475. MapCache.prototype.clear = mapCacheClear;
  476. MapCache.prototype['delete'] = mapCacheDelete;
  477. MapCache.prototype.get = mapCacheGet;
  478. MapCache.prototype.has = mapCacheHas;
  479. MapCache.prototype.set = mapCacheSet;
  480. /**
  481. *
  482. * Creates an array cache object to store unique values.
  483. *
  484. * @private
  485. * @constructor
  486. * @param {Array} [values] The values to cache.
  487. */
  488. function SetCache(values) {
  489. var index = -1,
  490. length = values ? values.length : 0;
  491. this.__data__ = new MapCache;
  492. while (++index < length) {
  493. this.add(values[index]);
  494. }
  495. }
  496. /**
  497. * Adds `value` to the array cache.
  498. *
  499. * @private
  500. * @name add
  501. * @memberOf SetCache
  502. * @alias push
  503. * @param {*} value The value to cache.
  504. * @returns {Object} Returns the cache instance.
  505. */
  506. function setCacheAdd(value) {
  507. this.__data__.set(value, HASH_UNDEFINED);
  508. return this;
  509. }
  510. /**
  511. * Checks if `value` is in the array cache.
  512. *
  513. * @private
  514. * @name has
  515. * @memberOf SetCache
  516. * @param {*} value The value to search for.
  517. * @returns {number} Returns `true` if `value` is found, else `false`.
  518. */
  519. function setCacheHas(value) {
  520. return this.__data__.has(value);
  521. }
  522. // Add methods to `SetCache`.
  523. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
  524. SetCache.prototype.has = setCacheHas;
  525. /**
  526. * Gets the index at which the `key` is found in `array` of key-value pairs.
  527. *
  528. * @private
  529. * @param {Array} array The array to inspect.
  530. * @param {*} key The key to search for.
  531. * @returns {number} Returns the index of the matched value, else `-1`.
  532. */
  533. function assocIndexOf(array, key) {
  534. var length = array.length;
  535. while (length--) {
  536. if (eq(array[length][0], key)) {
  537. return length;
  538. }
  539. }
  540. return -1;
  541. }
  542. /**
  543. * The base implementation of `_.isNative` without bad shim checks.
  544. *
  545. * @private
  546. * @param {*} value The value to check.
  547. * @returns {boolean} Returns `true` if `value` is a native function,
  548. * else `false`.
  549. */
  550. function baseIsNative(value) {
  551. if (!isObject(value) || isMasked(value)) {
  552. return false;
  553. }
  554. var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
  555. return pattern.test(toSource(value));
  556. }
  557. /**
  558. * The base implementation of `_.uniqBy` without support for iteratee shorthands.
  559. *
  560. * @private
  561. * @param {Array} array The array to inspect.
  562. * @param {Function} [iteratee] The iteratee invoked per element.
  563. * @param {Function} [comparator] The comparator invoked per element.
  564. * @returns {Array} Returns the new duplicate free array.
  565. */
  566. function baseUniq(array, iteratee, comparator) {
  567. var index = -1,
  568. includes = arrayIncludes,
  569. length = array.length,
  570. isCommon = true,
  571. result = [],
  572. seen = result;
  573. if (comparator) {
  574. isCommon = false;
  575. includes = arrayIncludesWith;
  576. }
  577. else if (length >= LARGE_ARRAY_SIZE) {
  578. var set = iteratee ? null : createSet(array);
  579. if (set) {
  580. return setToArray(set);
  581. }
  582. isCommon = false;
  583. includes = cacheHas;
  584. seen = new SetCache;
  585. }
  586. else {
  587. seen = iteratee ? [] : result;
  588. }
  589. outer:
  590. while (++index < length) {
  591. var value = array[index],
  592. computed = iteratee ? iteratee(value) : value;
  593. value = (comparator || value !== 0) ? value : 0;
  594. if (isCommon && computed === computed) {
  595. var seenIndex = seen.length;
  596. while (seenIndex--) {
  597. if (seen[seenIndex] === computed) {
  598. continue outer;
  599. }
  600. }
  601. if (iteratee) {
  602. seen.push(computed);
  603. }
  604. result.push(value);
  605. }
  606. else if (!includes(seen, computed, comparator)) {
  607. if (seen !== result) {
  608. seen.push(computed);
  609. }
  610. result.push(value);
  611. }
  612. }
  613. return result;
  614. }
  615. /**
  616. * Creates a set object of `values`.
  617. *
  618. * @private
  619. * @param {Array} values The values to add to the set.
  620. * @returns {Object} Returns the new set.
  621. */
  622. var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
  623. return new Set(values);
  624. };
  625. /**
  626. * Gets the data for `map`.
  627. *
  628. * @private
  629. * @param {Object} map The map to query.
  630. * @param {string} key The reference key.
  631. * @returns {*} Returns the map data.
  632. */
  633. function getMapData(map, key) {
  634. var data = map.__data__;
  635. return isKeyable(key)
  636. ? data[typeof key == 'string' ? 'string' : 'hash']
  637. : data.map;
  638. }
  639. /**
  640. * Gets the native function at `key` of `object`.
  641. *
  642. * @private
  643. * @param {Object} object The object to query.
  644. * @param {string} key The key of the method to get.
  645. * @returns {*} Returns the function if it's native, else `undefined`.
  646. */
  647. function getNative(object, key) {
  648. var value = getValue(object, key);
  649. return baseIsNative(value) ? value : undefined;
  650. }
  651. /**
  652. * Checks if `value` is suitable for use as unique object key.
  653. *
  654. * @private
  655. * @param {*} value The value to check.
  656. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  657. */
  658. function isKeyable(value) {
  659. var type = typeof value;
  660. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  661. ? (value !== '__proto__')
  662. : (value === null);
  663. }
  664. /**
  665. * Checks if `func` has its source masked.
  666. *
  667. * @private
  668. * @param {Function} func The function to check.
  669. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  670. */
  671. function isMasked(func) {
  672. return !!maskSrcKey && (maskSrcKey in func);
  673. }
  674. /**
  675. * Converts `func` to its source code.
  676. *
  677. * @private
  678. * @param {Function} func The function to process.
  679. * @returns {string} Returns the source code.
  680. */
  681. function toSource(func) {
  682. if (func != null) {
  683. try {
  684. return funcToString.call(func);
  685. } catch (e) {}
  686. try {
  687. return (func + '');
  688. } catch (e) {}
  689. }
  690. return '';
  691. }
  692. /**
  693. * Creates a duplicate-free version of an array, using
  694. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  695. * for equality comparisons, in which only the first occurrence of each
  696. * element is kept.
  697. *
  698. * @static
  699. * @memberOf _
  700. * @since 0.1.0
  701. * @category Array
  702. * @param {Array} array The array to inspect.
  703. * @returns {Array} Returns the new duplicate free array.
  704. * @example
  705. *
  706. * _.uniq([2, 1, 2]);
  707. * // => [2, 1]
  708. */
  709. function uniq(array) {
  710. return (array && array.length)
  711. ? baseUniq(array)
  712. : [];
  713. }
  714. /**
  715. * Performs a
  716. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  717. * comparison between two values to determine if they are equivalent.
  718. *
  719. * @static
  720. * @memberOf _
  721. * @since 4.0.0
  722. * @category Lang
  723. * @param {*} value The value to compare.
  724. * @param {*} other The other value to compare.
  725. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  726. * @example
  727. *
  728. * var object = { 'a': 1 };
  729. * var other = { 'a': 1 };
  730. *
  731. * _.eq(object, object);
  732. * // => true
  733. *
  734. * _.eq(object, other);
  735. * // => false
  736. *
  737. * _.eq('a', 'a');
  738. * // => true
  739. *
  740. * _.eq('a', Object('a'));
  741. * // => false
  742. *
  743. * _.eq(NaN, NaN);
  744. * // => true
  745. */
  746. function eq(value, other) {
  747. return value === other || (value !== value && other !== other);
  748. }
  749. /**
  750. * Checks if `value` is classified as a `Function` object.
  751. *
  752. * @static
  753. * @memberOf _
  754. * @since 0.1.0
  755. * @category Lang
  756. * @param {*} value The value to check.
  757. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  758. * @example
  759. *
  760. * _.isFunction(_);
  761. * // => true
  762. *
  763. * _.isFunction(/abc/);
  764. * // => false
  765. */
  766. function isFunction(value) {
  767. // The use of `Object#toString` avoids issues with the `typeof` operator
  768. // in Safari 8-9 which returns 'object' for typed array and other constructors.
  769. var tag = isObject(value) ? objectToString.call(value) : '';
  770. return tag == funcTag || tag == genTag;
  771. }
  772. /**
  773. * Checks if `value` is the
  774. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  775. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  776. *
  777. * @static
  778. * @memberOf _
  779. * @since 0.1.0
  780. * @category Lang
  781. * @param {*} value The value to check.
  782. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  783. * @example
  784. *
  785. * _.isObject({});
  786. * // => true
  787. *
  788. * _.isObject([1, 2, 3]);
  789. * // => true
  790. *
  791. * _.isObject(_.noop);
  792. * // => true
  793. *
  794. * _.isObject(null);
  795. * // => false
  796. */
  797. function isObject(value) {
  798. var type = typeof value;
  799. return !!value && (type == 'object' || type == 'function');
  800. }
  801. /**
  802. * This method returns `undefined`.
  803. *
  804. * @static
  805. * @memberOf _
  806. * @since 2.3.0
  807. * @category Util
  808. * @example
  809. *
  810. * _.times(2, _.noop);
  811. * // => [undefined, undefined]
  812. */
  813. function noop() {
  814. // No operation performed.
  815. }
  816. module.exports = uniq;