index.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /**
  2. * lodash 3.3.0 (Custom Build) <https://lodash.com/>
  3. * Build: `lodash modern modularize exports="npm" -o ./`
  4. * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
  5. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  6. * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  7. * Available under MIT license <https://lodash.com/license>
  8. */
  9. var arrayCopy = require('lodash._arraycopy'),
  10. arrayEach = require('lodash._arrayeach'),
  11. baseAssign = require('lodash._baseassign'),
  12. baseFor = require('lodash._basefor'),
  13. isArray = require('lodash.isarray'),
  14. keys = require('lodash.keys');
  15. /** `Object#toString` result references. */
  16. var argsTag = '[object Arguments]',
  17. arrayTag = '[object Array]',
  18. boolTag = '[object Boolean]',
  19. dateTag = '[object Date]',
  20. errorTag = '[object Error]',
  21. funcTag = '[object Function]',
  22. mapTag = '[object Map]',
  23. numberTag = '[object Number]',
  24. objectTag = '[object Object]',
  25. regexpTag = '[object RegExp]',
  26. setTag = '[object Set]',
  27. stringTag = '[object String]',
  28. weakMapTag = '[object WeakMap]';
  29. var arrayBufferTag = '[object ArrayBuffer]',
  30. float32Tag = '[object Float32Array]',
  31. float64Tag = '[object Float64Array]',
  32. int8Tag = '[object Int8Array]',
  33. int16Tag = '[object Int16Array]',
  34. int32Tag = '[object Int32Array]',
  35. uint8Tag = '[object Uint8Array]',
  36. uint8ClampedTag = '[object Uint8ClampedArray]',
  37. uint16Tag = '[object Uint16Array]',
  38. uint32Tag = '[object Uint32Array]';
  39. /** Used to match `RegExp` flags from their coerced string values. */
  40. var reFlags = /\w*$/;
  41. /** Used to identify `toStringTag` values supported by `_.clone`. */
  42. var cloneableTags = {};
  43. cloneableTags[argsTag] = cloneableTags[arrayTag] =
  44. cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
  45. cloneableTags[dateTag] = cloneableTags[float32Tag] =
  46. cloneableTags[float64Tag] = cloneableTags[int8Tag] =
  47. cloneableTags[int16Tag] = cloneableTags[int32Tag] =
  48. cloneableTags[numberTag] = cloneableTags[objectTag] =
  49. cloneableTags[regexpTag] = cloneableTags[stringTag] =
  50. cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
  51. cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
  52. cloneableTags[errorTag] = cloneableTags[funcTag] =
  53. cloneableTags[mapTag] = cloneableTags[setTag] =
  54. cloneableTags[weakMapTag] = false;
  55. /** Used for native method references. */
  56. var objectProto = Object.prototype;
  57. /** Used to check objects for own properties. */
  58. var hasOwnProperty = objectProto.hasOwnProperty;
  59. /**
  60. * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  61. * of values.
  62. */
  63. var objToString = objectProto.toString;
  64. /** Native method references. */
  65. var ArrayBuffer = global.ArrayBuffer,
  66. Uint8Array = global.Uint8Array;
  67. /**
  68. * The base implementation of `_.clone` without support for argument juggling
  69. * and `this` binding `customizer` functions.
  70. *
  71. * @private
  72. * @param {*} value The value to clone.
  73. * @param {boolean} [isDeep] Specify a deep clone.
  74. * @param {Function} [customizer] The function to customize cloning values.
  75. * @param {string} [key] The key of `value`.
  76. * @param {Object} [object] The object `value` belongs to.
  77. * @param {Array} [stackA=[]] Tracks traversed source objects.
  78. * @param {Array} [stackB=[]] Associates clones with source counterparts.
  79. * @returns {*} Returns the cloned value.
  80. */
  81. function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
  82. var result;
  83. if (customizer) {
  84. result = object ? customizer(value, key, object) : customizer(value);
  85. }
  86. if (result !== undefined) {
  87. return result;
  88. }
  89. if (!isObject(value)) {
  90. return value;
  91. }
  92. var isArr = isArray(value);
  93. if (isArr) {
  94. result = initCloneArray(value);
  95. if (!isDeep) {
  96. return arrayCopy(value, result);
  97. }
  98. } else {
  99. var tag = objToString.call(value),
  100. isFunc = tag == funcTag;
  101. if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
  102. result = initCloneObject(isFunc ? {} : value);
  103. if (!isDeep) {
  104. return baseAssign(result, value);
  105. }
  106. } else {
  107. return cloneableTags[tag]
  108. ? initCloneByTag(value, tag, isDeep)
  109. : (object ? value : {});
  110. }
  111. }
  112. // Check for circular references and return its corresponding clone.
  113. stackA || (stackA = []);
  114. stackB || (stackB = []);
  115. var length = stackA.length;
  116. while (length--) {
  117. if (stackA[length] == value) {
  118. return stackB[length];
  119. }
  120. }
  121. // Add the source value to the stack of traversed objects and associate it with its clone.
  122. stackA.push(value);
  123. stackB.push(result);
  124. // Recursively populate clone (susceptible to call stack limits).
  125. (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
  126. result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
  127. });
  128. return result;
  129. }
  130. /**
  131. * The base implementation of `_.forOwn` without support for callback
  132. * shorthands and `this` binding.
  133. *
  134. * @private
  135. * @param {Object} object The object to iterate over.
  136. * @param {Function} iteratee The function invoked per iteration.
  137. * @returns {Object} Returns `object`.
  138. */
  139. function baseForOwn(object, iteratee) {
  140. return baseFor(object, iteratee, keys);
  141. }
  142. /**
  143. * Creates a clone of the given array buffer.
  144. *
  145. * @private
  146. * @param {ArrayBuffer} buffer The array buffer to clone.
  147. * @returns {ArrayBuffer} Returns the cloned array buffer.
  148. */
  149. function bufferClone(buffer) {
  150. var result = new ArrayBuffer(buffer.byteLength),
  151. view = new Uint8Array(result);
  152. view.set(new Uint8Array(buffer));
  153. return result;
  154. }
  155. /**
  156. * Initializes an array clone.
  157. *
  158. * @private
  159. * @param {Array} array The array to clone.
  160. * @returns {Array} Returns the initialized clone.
  161. */
  162. function initCloneArray(array) {
  163. var length = array.length,
  164. result = new array.constructor(length);
  165. // Add array properties assigned by `RegExp#exec`.
  166. if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
  167. result.index = array.index;
  168. result.input = array.input;
  169. }
  170. return result;
  171. }
  172. /**
  173. * Initializes an object clone.
  174. *
  175. * @private
  176. * @param {Object} object The object to clone.
  177. * @returns {Object} Returns the initialized clone.
  178. */
  179. function initCloneObject(object) {
  180. var Ctor = object.constructor;
  181. if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
  182. Ctor = Object;
  183. }
  184. return new Ctor;
  185. }
  186. /**
  187. * Initializes an object clone based on its `toStringTag`.
  188. *
  189. * **Note:** This function only supports cloning values with tags of
  190. * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  191. *
  192. * @private
  193. * @param {Object} object The object to clone.
  194. * @param {string} tag The `toStringTag` of the object to clone.
  195. * @param {boolean} [isDeep] Specify a deep clone.
  196. * @returns {Object} Returns the initialized clone.
  197. */
  198. function initCloneByTag(object, tag, isDeep) {
  199. var Ctor = object.constructor;
  200. switch (tag) {
  201. case arrayBufferTag:
  202. return bufferClone(object);
  203. case boolTag:
  204. case dateTag:
  205. return new Ctor(+object);
  206. case float32Tag: case float64Tag:
  207. case int8Tag: case int16Tag: case int32Tag:
  208. case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
  209. var buffer = object.buffer;
  210. return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
  211. case numberTag:
  212. case stringTag:
  213. return new Ctor(object);
  214. case regexpTag:
  215. var result = new Ctor(object.source, reFlags.exec(object));
  216. result.lastIndex = object.lastIndex;
  217. }
  218. return result;
  219. }
  220. /**
  221. * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
  222. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  223. *
  224. * @static
  225. * @memberOf _
  226. * @category Lang
  227. * @param {*} value The value to check.
  228. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  229. * @example
  230. *
  231. * _.isObject({});
  232. * // => true
  233. *
  234. * _.isObject([1, 2, 3]);
  235. * // => true
  236. *
  237. * _.isObject(1);
  238. * // => false
  239. */
  240. function isObject(value) {
  241. // Avoid a V8 JIT bug in Chrome 19-20.
  242. // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
  243. var type = typeof value;
  244. return !!value && (type == 'object' || type == 'function');
  245. }
  246. module.exports = baseClone;