You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

676 lines
17 KiB

4 years ago
  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 `TypeError` message for "Functions" methods. */
  10. var FUNC_ERROR_TEXT = 'Expected a function';
  11. /** Used to stand-in for `undefined` hash values. */
  12. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  13. /** `Object#toString` result references. */
  14. var funcTag = '[object Function]',
  15. genTag = '[object GeneratorFunction]';
  16. /**
  17. * Used to match `RegExp`
  18. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  19. */
  20. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  21. /** Used to detect host constructors (Safari). */
  22. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  23. /** Detect free variable `global` from Node.js. */
  24. var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
  25. /** Detect free variable `self`. */
  26. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  27. /** Used as a reference to the global object. */
  28. var root = freeGlobal || freeSelf || Function('return this')();
  29. /**
  30. * Gets the value at `key` of `object`.
  31. *
  32. * @private
  33. * @param {Object} [object] The object to query.
  34. * @param {string} key The key of the property to get.
  35. * @returns {*} Returns the property value.
  36. */
  37. function getValue(object, key) {
  38. return object == null ? undefined : object[key];
  39. }
  40. /**
  41. * Checks if `value` is a host object in IE < 9.
  42. *
  43. * @private
  44. * @param {*} value The value to check.
  45. * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
  46. */
  47. function isHostObject(value) {
  48. // Many host objects are `Object` objects that can coerce to strings
  49. // despite having improperly defined `toString` methods.
  50. var result = false;
  51. if (value != null && typeof value.toString != 'function') {
  52. try {
  53. result = !!(value + '');
  54. } catch (e) {}
  55. }
  56. return result;
  57. }
  58. /** Used for built-in method references. */
  59. var arrayProto = Array.prototype,
  60. funcProto = Function.prototype,
  61. objectProto = Object.prototype;
  62. /** Used to detect overreaching core-js shims. */
  63. var coreJsData = root['__core-js_shared__'];
  64. /** Used to detect methods masquerading as native. */
  65. var maskSrcKey = (function() {
  66. var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  67. return uid ? ('Symbol(src)_1.' + uid) : '';
  68. }());
  69. /** Used to resolve the decompiled source of functions. */
  70. var funcToString = funcProto.toString;
  71. /** Used to check objects for own properties. */
  72. var hasOwnProperty = objectProto.hasOwnProperty;
  73. /**
  74. * Used to resolve the
  75. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  76. * of values.
  77. */
  78. var objectToString = objectProto.toString;
  79. /** Used to detect if a method is native. */
  80. var reIsNative = RegExp('^' +
  81. funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  82. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  83. );
  84. /** Built-in value references. */
  85. var splice = arrayProto.splice;
  86. /* Built-in method references that are verified to be native. */
  87. var Map = getNative(root, 'Map'),
  88. nativeCreate = getNative(Object, 'create');
  89. /**
  90. * Creates a hash object.
  91. *
  92. * @private
  93. * @constructor
  94. * @param {Array} [entries] The key-value pairs to cache.
  95. */
  96. function Hash(entries) {
  97. var index = -1,
  98. length = entries ? entries.length : 0;
  99. this.clear();
  100. while (++index < length) {
  101. var entry = entries[index];
  102. this.set(entry[0], entry[1]);
  103. }
  104. }
  105. /**
  106. * Removes all key-value entries from the hash.
  107. *
  108. * @private
  109. * @name clear
  110. * @memberOf Hash
  111. */
  112. function hashClear() {
  113. this.__data__ = nativeCreate ? nativeCreate(null) : {};
  114. }
  115. /**
  116. * Removes `key` and its value from the hash.
  117. *
  118. * @private
  119. * @name delete
  120. * @memberOf Hash
  121. * @param {Object} hash The hash to modify.
  122. * @param {string} key The key of the value to remove.
  123. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  124. */
  125. function hashDelete(key) {
  126. return this.has(key) && delete this.__data__[key];
  127. }
  128. /**
  129. * Gets the hash value for `key`.
  130. *
  131. * @private
  132. * @name get
  133. * @memberOf Hash
  134. * @param {string} key The key of the value to get.
  135. * @returns {*} Returns the entry value.
  136. */
  137. function hashGet(key) {
  138. var data = this.__data__;
  139. if (nativeCreate) {
  140. var result = data[key];
  141. return result === HASH_UNDEFINED ? undefined : result;
  142. }
  143. return hasOwnProperty.call(data, key) ? data[key] : undefined;
  144. }
  145. /**
  146. * Checks if a hash value for `key` exists.
  147. *
  148. * @private
  149. * @name has
  150. * @memberOf Hash
  151. * @param {string} key The key of the entry to check.
  152. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  153. */
  154. function hashHas(key) {
  155. var data = this.__data__;
  156. return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
  157. }
  158. /**
  159. * Sets the hash `key` to `value`.
  160. *
  161. * @private
  162. * @name set
  163. * @memberOf Hash
  164. * @param {string} key The key of the value to set.
  165. * @param {*} value The value to set.
  166. * @returns {Object} Returns the hash instance.
  167. */
  168. function hashSet(key, value) {
  169. var data = this.__data__;
  170. data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  171. return this;
  172. }
  173. // Add methods to `Hash`.
  174. Hash.prototype.clear = hashClear;
  175. Hash.prototype['delete'] = hashDelete;
  176. Hash.prototype.get = hashGet;
  177. Hash.prototype.has = hashHas;
  178. Hash.prototype.set = hashSet;
  179. /**
  180. * Creates an list cache object.
  181. *
  182. * @private
  183. * @constructor
  184. * @param {Array} [entries] The key-value pairs to cache.
  185. */
  186. function ListCache(entries) {
  187. var index = -1,
  188. length = entries ? entries.length : 0;
  189. this.clear();
  190. while (++index < length) {
  191. var entry = entries[index];
  192. this.set(entry[0], entry[1]);
  193. }
  194. }
  195. /**
  196. * Removes all key-value entries from the list cache.
  197. *
  198. * @private
  199. * @name clear
  200. * @memberOf ListCache
  201. */
  202. function listCacheClear() {
  203. this.__data__ = [];
  204. }
  205. /**
  206. * Removes `key` and its value from the list cache.
  207. *
  208. * @private
  209. * @name delete
  210. * @memberOf ListCache
  211. * @param {string} key The key of the value to remove.
  212. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  213. */
  214. function listCacheDelete(key) {
  215. var data = this.__data__,
  216. index = assocIndexOf(data, key);
  217. if (index < 0) {
  218. return false;
  219. }
  220. var lastIndex = data.length - 1;
  221. if (index == lastIndex) {
  222. data.pop();
  223. } else {
  224. splice.call(data, index, 1);
  225. }
  226. return true;
  227. }
  228. /**
  229. * Gets the list cache value for `key`.
  230. *
  231. * @private
  232. * @name get
  233. * @memberOf ListCache
  234. * @param {string} key The key of the value to get.
  235. * @returns {*} Returns the entry value.
  236. */
  237. function listCacheGet(key) {
  238. var data = this.__data__,
  239. index = assocIndexOf(data, key);
  240. return index < 0 ? undefined : data[index][1];
  241. }
  242. /**
  243. * Checks if a list cache value for `key` exists.
  244. *
  245. * @private
  246. * @name has
  247. * @memberOf ListCache
  248. * @param {string} key The key of the entry to check.
  249. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  250. */
  251. function listCacheHas(key) {
  252. return assocIndexOf(this.__data__, key) > -1;
  253. }
  254. /**
  255. * Sets the list cache `key` to `value`.
  256. *
  257. * @private
  258. * @name set
  259. * @memberOf ListCache
  260. * @param {string} key The key of the value to set.
  261. * @param {*} value The value to set.
  262. * @returns {Object} Returns the list cache instance.
  263. */
  264. function listCacheSet(key, value) {
  265. var data = this.__data__,
  266. index = assocIndexOf(data, key);
  267. if (index < 0) {
  268. data.push([key, value]);
  269. } else {
  270. data[index][1] = value;
  271. }
  272. return this;
  273. }
  274. // Add methods to `ListCache`.
  275. ListCache.prototype.clear = listCacheClear;
  276. ListCache.prototype['delete'] = listCacheDelete;
  277. ListCache.prototype.get = listCacheGet;
  278. ListCache.prototype.has = listCacheHas;
  279. ListCache.prototype.set = listCacheSet;
  280. /**
  281. * Creates a map cache object to store key-value pairs.
  282. *
  283. * @private
  284. * @constructor
  285. * @param {Array} [entries] The key-value pairs to cache.
  286. */
  287. function MapCache(entries) {
  288. var index = -1,
  289. length = entries ? entries.length : 0;
  290. this.clear();
  291. while (++index < length) {
  292. var entry = entries[index];
  293. this.set(entry[0], entry[1]);
  294. }
  295. }
  296. /**
  297. * Removes all key-value entries from the map.
  298. *
  299. * @private
  300. * @name clear
  301. * @memberOf MapCache
  302. */
  303. function mapCacheClear() {
  304. this.__data__ = {
  305. 'hash': new Hash,
  306. 'map': new (Map || ListCache),
  307. 'string': new Hash
  308. };
  309. }
  310. /**
  311. * Removes `key` and its value from the map.
  312. *
  313. * @private
  314. * @name delete
  315. * @memberOf MapCache
  316. * @param {string} key The key of the value to remove.
  317. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  318. */
  319. function mapCacheDelete(key) {
  320. return getMapData(this, key)['delete'](key);
  321. }
  322. /**
  323. * Gets the map value for `key`.
  324. *
  325. * @private
  326. * @name get
  327. * @memberOf MapCache
  328. * @param {string} key The key of the value to get.
  329. * @returns {*} Returns the entry value.
  330. */
  331. function mapCacheGet(key) {
  332. return getMapData(this, key).get(key);
  333. }
  334. /**
  335. * Checks if a map value for `key` exists.
  336. *
  337. * @private
  338. * @name has
  339. * @memberOf MapCache
  340. * @param {string} key The key of the entry to check.
  341. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  342. */
  343. function mapCacheHas(key) {
  344. return getMapData(this, key).has(key);
  345. }
  346. /**
  347. * Sets the map `key` to `value`.
  348. *
  349. * @private
  350. * @name set
  351. * @memberOf MapCache
  352. * @param {string} key The key of the value to set.
  353. * @param {*} value The value to set.
  354. * @returns {Object} Returns the map cache instance.
  355. */
  356. function mapCacheSet(key, value) {
  357. getMapData(this, key).set(key, value);
  358. return this;
  359. }
  360. // Add methods to `MapCache`.
  361. MapCache.prototype.clear = mapCacheClear;
  362. MapCache.prototype['delete'] = mapCacheDelete;
  363. MapCache.prototype.get = mapCacheGet;
  364. MapCache.prototype.has = mapCacheHas;
  365. MapCache.prototype.set = mapCacheSet;
  366. /**
  367. * Gets the index at which the `key` is found in `array` of key-value pairs.
  368. *
  369. * @private
  370. * @param {Array} array The array to inspect.
  371. * @param {*} key The key to search for.
  372. * @returns {number} Returns the index of the matched value, else `-1`.
  373. */
  374. function assocIndexOf(array, key) {
  375. var length = array.length;
  376. while (length--) {
  377. if (eq(array[length][0], key)) {
  378. return length;
  379. }
  380. }
  381. return -1;
  382. }
  383. /**
  384. * The base implementation of `_.isNative` without bad shim checks.
  385. *
  386. * @private
  387. * @param {*} value The value to check.
  388. * @returns {boolean} Returns `true` if `value` is a native function,
  389. * else `false`.
  390. */
  391. function baseIsNative(value) {
  392. if (!isObject(value) || isMasked(value)) {
  393. return false;
  394. }
  395. var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
  396. return pattern.test(toSource(value));
  397. }
  398. /**
  399. * Gets the data for `map`.
  400. *
  401. * @private
  402. * @param {Object} map The map to query.
  403. * @param {string} key The reference key.
  404. * @returns {*} Returns the map data.
  405. */
  406. function getMapData(map, key) {
  407. var data = map.__data__;
  408. return isKeyable(key)
  409. ? data[typeof key == 'string' ? 'string' : 'hash']
  410. : data.map;
  411. }
  412. /**
  413. * Gets the native function at `key` of `object`.
  414. *
  415. * @private
  416. * @param {Object} object The object to query.
  417. * @param {string} key The key of the method to get.
  418. * @returns {*} Returns the function if it's native, else `undefined`.
  419. */
  420. function getNative(object, key) {
  421. var value = getValue(object, key);
  422. return baseIsNative(value) ? value : undefined;
  423. }
  424. /**
  425. * Checks if `value` is suitable for use as unique object key.
  426. *
  427. * @private
  428. * @param {*} value The value to check.
  429. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  430. */
  431. function isKeyable(value) {
  432. var type = typeof value;
  433. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  434. ? (value !== '__proto__')
  435. : (value === null);
  436. }
  437. /**
  438. * Checks if `func` has its source masked.
  439. *
  440. * @private
  441. * @param {Function} func The function to check.
  442. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  443. */
  444. function isMasked(func) {
  445. return !!maskSrcKey && (maskSrcKey in func);
  446. }
  447. /**
  448. * Converts `func` to its source code.
  449. *
  450. * @private
  451. * @param {Function} func The function to process.
  452. * @returns {string} Returns the source code.
  453. */
  454. function toSource(func) {
  455. if (func != null) {
  456. try {
  457. return funcToString.call(func);
  458. } catch (e) {}
  459. try {
  460. return (func + '');
  461. } catch (e) {}
  462. }
  463. return '';
  464. }
  465. /**
  466. * Creates a function that memoizes the result of `func`. If `resolver` is
  467. * provided, it determines the cache key for storing the result based on the
  468. * arguments provided to the memoized function. By default, the first argument
  469. * provided to the memoized function is used as the map cache key. The `func`
  470. * is invoked with the `this` binding of the memoized function.
  471. *
  472. * **Note:** The cache is exposed as the `cache` property on the memoized
  473. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  474. * constructor with one whose instances implement the
  475. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  476. * method interface of `delete`, `get`, `has`, and `set`.
  477. *
  478. * @static
  479. * @memberOf _
  480. * @since 0.1.0
  481. * @category Function
  482. * @param {Function} func The function to have its output memoized.
  483. * @param {Function} [resolver] The function to resolve the cache key.
  484. * @returns {Function} Returns the new memoized function.
  485. * @example
  486. *
  487. * var object = { 'a': 1, 'b': 2 };
  488. * var other = { 'c': 3, 'd': 4 };
  489. *
  490. * var values = _.memoize(_.values);
  491. * values(object);
  492. * // => [1, 2]
  493. *
  494. * values(other);
  495. * // => [3, 4]
  496. *
  497. * object.a = 2;
  498. * values(object);
  499. * // => [1, 2]
  500. *
  501. * // Modify the result cache.
  502. * values.cache.set(object, ['a', 'b']);
  503. * values(object);
  504. * // => ['a', 'b']
  505. *
  506. * // Replace `_.memoize.Cache`.
  507. * _.memoize.Cache = WeakMap;
  508. */
  509. function memoize(func, resolver) {
  510. if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
  511. throw new TypeError(FUNC_ERROR_TEXT);
  512. }
  513. var memoized = function() {
  514. var args = arguments,
  515. key = resolver ? resolver.apply(this, args) : args[0],
  516. cache = memoized.cache;
  517. if (cache.has(key)) {
  518. return cache.get(key);
  519. }
  520. var result = func.apply(this, args);
  521. memoized.cache = cache.set(key, result);
  522. return result;
  523. };
  524. memoized.cache = new (memoize.Cache || MapCache);
  525. return memoized;
  526. }
  527. // Assign cache to `_.memoize`.
  528. memoize.Cache = MapCache;
  529. /**
  530. * Performs a
  531. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  532. * comparison between two values to determine if they are equivalent.
  533. *
  534. * @static
  535. * @memberOf _
  536. * @since 4.0.0
  537. * @category Lang
  538. * @param {*} value The value to compare.
  539. * @param {*} other The other value to compare.
  540. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  541. * @example
  542. *
  543. * var object = { 'a': 1 };
  544. * var other = { 'a': 1 };
  545. *
  546. * _.eq(object, object);
  547. * // => true
  548. *
  549. * _.eq(object, other);
  550. * // => false
  551. *
  552. * _.eq('a', 'a');
  553. * // => true
  554. *
  555. * _.eq('a', Object('a'));
  556. * // => false
  557. *
  558. * _.eq(NaN, NaN);
  559. * // => true
  560. */
  561. function eq(value, other) {
  562. return value === other || (value !== value && other !== other);
  563. }
  564. /**
  565. * Checks if `value` is classified as a `Function` object.
  566. *
  567. * @static
  568. * @memberOf _
  569. * @since 0.1.0
  570. * @category Lang
  571. * @param {*} value The value to check.
  572. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  573. * @example
  574. *
  575. * _.isFunction(_);
  576. * // => true
  577. *
  578. * _.isFunction(/abc/);
  579. * // => false
  580. */
  581. function isFunction(value) {
  582. // The use of `Object#toString` avoids issues with the `typeof` operator
  583. // in Safari 8-9 which returns 'object' for typed array and other constructors.
  584. var tag = isObject(value) ? objectToString.call(value) : '';
  585. return tag == funcTag || tag == genTag;
  586. }
  587. /**
  588. * Checks if `value` is the
  589. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  590. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  591. *
  592. * @static
  593. * @memberOf _
  594. * @since 0.1.0
  595. * @category Lang
  596. * @param {*} value The value to check.
  597. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  598. * @example
  599. *
  600. * _.isObject({});
  601. * // => true
  602. *
  603. * _.isObject([1, 2, 3]);
  604. * // => true
  605. *
  606. * _.isObject(_.noop);
  607. * // => true
  608. *
  609. * _.isObject(null);
  610. * // => false
  611. */
  612. function isObject(value) {
  613. var type = typeof value;
  614. return !!value && (type == 'object' || type == 'function');
  615. }
  616. module.exports = memoize;