PageRenderTime 31ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/assets/javascripts/lodash.js

https://gitlab.com/Ruwan-Ranganath/discourse
JavaScript | 1472 lines | 1280 code | 33 blank | 159 comment | 32 complexity | 77ffe574b5fe8c7ce0da0ea4ac322ad5 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 1.3.0 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash minus="template" -d`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  8. * Available under MIT license <http://lodash.com/license>
  9. */
  10. ;(function(window) {
  11. /** Used as a safe reference for `undefined` in pre ES5 environments */
  12. var undefined;
  13. /** Used to pool arrays and objects used internally */
  14. var arrayPool = [],
  15. objectPool = [];
  16. /** Used to generate unique IDs */
  17. var idCounter = 0;
  18. /** Used internally to indicate various things */
  19. var indicatorObject = {};
  20. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  21. var keyPrefix = +new Date + '';
  22. /** Used as the size when optimizations are enabled for large arrays */
  23. var largeArraySize = 75;
  24. /** Used as the max size of the `arrayPool` and `objectPool` */
  25. var maxPoolSize = 10;
  26. /** Used to match empty string literals in compiled template source */
  27. var reEmptyStringLeading = /\b__p \+= '';/g,
  28. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  29. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  30. /** Used to match HTML entities */
  31. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  32. /**
  33. * Used to match ES6 template delimiters
  34. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  35. */
  36. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  37. /** Used to match regexp flags from their coerced string values */
  38. var reFlags = /\w*$/;
  39. /** Used to match "interpolate" template delimiters */
  40. var reInterpolate = /<%=([\s\S]+?)%>/g;
  41. /** Used to detect functions containing a `this` reference */
  42. var reThis = (reThis = /\bthis\b/) && reThis.test(runInContext) && reThis;
  43. /** Used to detect and test whitespace */
  44. var whitespace = (
  45. // whitespace
  46. ' \t\x0B\f\xA0\ufeff' +
  47. // line terminators
  48. '\n\r\u2028\u2029' +
  49. // unicode category "Zs" space separators
  50. '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
  51. );
  52. /** Used to match leading whitespace and zeros to be removed */
  53. var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
  54. /** Used to ensure capturing order of template delimiters */
  55. var reNoMatch = /($^)/;
  56. /** Used to match HTML characters */
  57. var reUnescapedHtml = /[&<>"']/g;
  58. /** Used to match unescaped characters in compiled string literals */
  59. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  60. /** Used to assign default `context` object properties */
  61. var contextProps = [
  62. 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
  63. 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
  64. 'parseInt', 'setImmediate', 'setTimeout'
  65. ];
  66. /** Used to fix the JScript [[DontEnum]] bug */
  67. var shadowedProps = [
  68. 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
  69. 'toLocaleString', 'toString', 'valueOf'
  70. ];
  71. /** Used to make template sourceURLs easier to identify */
  72. var templateCounter = 0;
  73. /** `Object#toString` result shortcuts */
  74. var argsClass = '[object Arguments]',
  75. arrayClass = '[object Array]',
  76. boolClass = '[object Boolean]',
  77. dateClass = '[object Date]',
  78. errorClass = '[object Error]',
  79. funcClass = '[object Function]',
  80. numberClass = '[object Number]',
  81. objectClass = '[object Object]',
  82. regexpClass = '[object RegExp]',
  83. stringClass = '[object String]';
  84. /** Used to identify object classifications that `_.clone` supports */
  85. var cloneableClasses = {};
  86. cloneableClasses[funcClass] = false;
  87. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  88. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  89. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  90. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  91. /** Used to determine if values are of the language type Object */
  92. var objectTypes = {
  93. 'boolean': false,
  94. 'function': true,
  95. 'object': true,
  96. 'number': false,
  97. 'string': false,
  98. 'undefined': false
  99. };
  100. /** Used to escape characters for inclusion in compiled string literals */
  101. var stringEscapes = {
  102. '\\': '\\',
  103. "'": "'",
  104. '\n': 'n',
  105. '\r': 'r',
  106. '\t': 't',
  107. '\u2028': 'u2028',
  108. '\u2029': 'u2029'
  109. };
  110. /** Detect free variable `exports` */
  111. var freeExports = objectTypes[typeof exports] && exports;
  112. /** Detect free variable `module` */
  113. var freeModule = objectTypes[typeof module] && module && module.exports == freeExports && module;
  114. /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
  115. var freeGlobal = objectTypes[typeof global] && global;
  116. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  117. window = freeGlobal;
  118. }
  119. /*--------------------------------------------------------------------------*/
  120. /**
  121. * A basic implementation of `_.indexOf` without support for binary searches
  122. * or `fromIndex` constraints.
  123. *
  124. * @private
  125. * @param {Array} array The array to search.
  126. * @param {Mixed} value The value to search for.
  127. * @param {Number} [fromIndex=0] The index to search from.
  128. * @returns {Number} Returns the index of the matched value or `-1`.
  129. */
  130. function basicIndexOf(array, value, fromIndex) {
  131. var index = (fromIndex || 0) - 1,
  132. length = array.length;
  133. while (++index < length) {
  134. if (array[index] === value) {
  135. return index;
  136. }
  137. }
  138. return -1;
  139. }
  140. /**
  141. * An implementation of `_.contains` for cache objects that mimics the return
  142. * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
  143. *
  144. * @private
  145. * @param {Object} cache The cache object to inspect.
  146. * @param {Mixed} value The value to search for.
  147. * @returns {Number} Returns `0` if `value` is found, else `-1`.
  148. */
  149. function cacheIndexOf(cache, value) {
  150. var type = typeof value;
  151. cache = cache.cache;
  152. if (type == 'boolean' || value == null) {
  153. return cache[value];
  154. }
  155. if (type != 'number' && type != 'string') {
  156. type = 'object';
  157. }
  158. var key = type == 'number' ? value : keyPrefix + value;
  159. cache = cache[type] || (cache[type] = {});
  160. return type == 'object'
  161. ? (cache[key] && basicIndexOf(cache[key], value) > -1 ? 0 : -1)
  162. : (cache[key] ? 0 : -1);
  163. }
  164. /**
  165. * Adds a given `value` to the corresponding cache object.
  166. *
  167. * @private
  168. * @param {Mixed} value The value to add to the cache.
  169. */
  170. function cachePush(value) {
  171. var cache = this.cache,
  172. type = typeof value;
  173. if (type == 'boolean' || value == null) {
  174. cache[value] = true;
  175. } else {
  176. if (type != 'number' && type != 'string') {
  177. type = 'object';
  178. }
  179. var key = type == 'number' ? value : keyPrefix + value,
  180. typeCache = cache[type] || (cache[type] = {});
  181. if (type == 'object') {
  182. if ((typeCache[key] || (typeCache[key] = [])).push(value) == this.array.length) {
  183. cache[type] = false;
  184. }
  185. } else {
  186. typeCache[key] = true;
  187. }
  188. }
  189. }
  190. /**
  191. * Used by `_.max` and `_.min` as the default `callback` when a given
  192. * `collection` is a string value.
  193. *
  194. * @private
  195. * @param {String} value The character to inspect.
  196. * @returns {Number} Returns the code unit of given character.
  197. */
  198. function charAtCallback(value) {
  199. return value.charCodeAt(0);
  200. }
  201. /**
  202. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  203. * them in ascending order.
  204. *
  205. * @private
  206. * @param {Object} a The object to compare to `b`.
  207. * @param {Object} b The object to compare to `a`.
  208. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  209. */
  210. function compareAscending(a, b) {
  211. var ai = a.index,
  212. bi = b.index;
  213. a = a.criteria;
  214. b = b.criteria;
  215. // ensure a stable sort in V8 and other engines
  216. // http://code.google.com/p/v8/issues/detail?id=90
  217. if (a !== b) {
  218. if (a > b || typeof a == 'undefined') {
  219. return 1;
  220. }
  221. if (a < b || typeof b == 'undefined') {
  222. return -1;
  223. }
  224. }
  225. return ai < bi ? -1 : 1;
  226. }
  227. /**
  228. * Creates a cache object to optimize linear searches of large arrays.
  229. *
  230. * @private
  231. * @param {Array} [array=[]] The array to search.
  232. * @returns {Null|Object} Returns the cache object or `null` if caching should not be used.
  233. */
  234. function createCache(array) {
  235. var index = -1,
  236. length = array.length;
  237. var cache = getObject();
  238. cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
  239. var result = getObject();
  240. result.array = array;
  241. result.cache = cache;
  242. result.push = cachePush;
  243. while (++index < length) {
  244. result.push(array[index]);
  245. }
  246. return cache.object === false
  247. ? (releaseObject(result), null)
  248. : result;
  249. }
  250. /**
  251. * Used by `template` to escape characters for inclusion in compiled
  252. * string literals.
  253. *
  254. * @private
  255. * @param {String} match The matched character to escape.
  256. * @returns {String} Returns the escaped character.
  257. */
  258. function escapeStringChar(match) {
  259. return '\\' + stringEscapes[match];
  260. }
  261. /**
  262. * Gets an array from the array pool or creates a new one if the pool is empty.
  263. *
  264. * @private
  265. * @returns {Array} The array from the pool.
  266. */
  267. function getArray() {
  268. return arrayPool.pop() || [];
  269. }
  270. /**
  271. * Gets an object from the object pool or creates a new one if the pool is empty.
  272. *
  273. * @private
  274. * @returns {Object} The object from the pool.
  275. */
  276. function getObject() {
  277. return objectPool.pop() || {
  278. 'args': '',
  279. 'array': null,
  280. 'bottom': '',
  281. 'criteria': null,
  282. 'false': false,
  283. 'firstArg': '',
  284. 'index': 0,
  285. 'init': '',
  286. 'leading': false,
  287. 'loop': '',
  288. 'maxWait': 0,
  289. 'null': false,
  290. 'number': null,
  291. 'object': null,
  292. 'push': null,
  293. 'shadowedProps': null,
  294. 'string': null,
  295. 'top': '',
  296. 'trailing': false,
  297. 'true': false,
  298. 'undefined': false,
  299. 'useHas': false,
  300. 'useKeys': false,
  301. 'value': null
  302. };
  303. }
  304. /**
  305. * Checks if `value` is a DOM node in IE < 9.
  306. *
  307. * @private
  308. * @param {Mixed} value The value to check.
  309. * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
  310. */
  311. function isNode(value) {
  312. // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
  313. // methods that are `typeof` "string" and still can coerce nodes to strings
  314. return typeof value.toString != 'function' && typeof (value + '') == 'string';
  315. }
  316. /**
  317. * A no-operation function.
  318. *
  319. * @private
  320. */
  321. function noop() {
  322. // no operation performed
  323. }
  324. /**
  325. * Releases the given `array` back to the array pool.
  326. *
  327. * @private
  328. * @param {Array} [array] The array to release.
  329. */
  330. function releaseArray(array) {
  331. if (arrayPool.length == maxPoolSize) {
  332. arrayPool.length = maxPoolSize - 1;
  333. }
  334. array.length = 0;
  335. arrayPool.push(array);
  336. }
  337. /**
  338. * Releases the given `object` back to the object pool.
  339. *
  340. * @private
  341. * @param {Object} [object] The object to release.
  342. */
  343. function releaseObject(object) {
  344. var cache = object.cache;
  345. if (cache) {
  346. releaseObject(cache);
  347. }
  348. if (objectPool.length == maxPoolSize) {
  349. objectPool.length = maxPoolSize - 1;
  350. }
  351. object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
  352. objectPool.push(object);
  353. }
  354. /**
  355. * Slices the `collection` from the `start` index up to, but not including,
  356. * the `end` index.
  357. *
  358. * Note: This function is used, instead of `Array#slice`, to support node lists
  359. * in IE < 9 and to ensure dense arrays are returned.
  360. *
  361. * @private
  362. * @param {Array|Object|String} collection The collection to slice.
  363. * @param {Number} start The start index.
  364. * @param {Number} end The end index.
  365. * @returns {Array} Returns the new array.
  366. */
  367. function slice(array, start, end) {
  368. start || (start = 0);
  369. if (typeof end == 'undefined') {
  370. end = array ? array.length : 0;
  371. }
  372. var index = -1,
  373. length = end - start || 0,
  374. result = Array(length < 0 ? 0 : length);
  375. while (++index < length) {
  376. result[index] = array[start + index];
  377. }
  378. return result;
  379. }
  380. /*--------------------------------------------------------------------------*/
  381. /**
  382. * Create a new `lodash` function using the given `context` object.
  383. *
  384. * @static
  385. * @memberOf _
  386. * @category Utilities
  387. * @param {Object} [context=window] The context object.
  388. * @returns {Function} Returns the `lodash` function.
  389. */
  390. function runInContext(context) {
  391. // Avoid issues with some ES3 environments that attempt to use values, named
  392. // after built-in constructors like `Object`, for the creation of literals.
  393. // ES5 clears this up by stating that literals must use built-in constructors.
  394. // See http://es5.github.com/#x11.1.5.
  395. context = context ? _.defaults(window.Object(), context, _.pick(window, contextProps)) : window;
  396. /** Native constructor references */
  397. var Array = context.Array,
  398. Boolean = context.Boolean,
  399. Date = context.Date,
  400. Error = context.Error,
  401. Function = context.Function,
  402. Math = context.Math,
  403. Number = context.Number,
  404. Object = context.Object,
  405. RegExp = context.RegExp,
  406. String = context.String,
  407. TypeError = context.TypeError;
  408. /**
  409. * Used for `Array` method references.
  410. *
  411. * Normally `Array.prototype` would suffice, however, using an array literal
  412. * avoids issues in Narwhal.
  413. */
  414. var arrayRef = [];
  415. /** Used for native method references */
  416. var errorProto = Error.prototype,
  417. objectProto = Object.prototype,
  418. stringProto = String.prototype;
  419. /** Used to restore the original `_` reference in `noConflict` */
  420. var oldDash = context._;
  421. /** Used to detect if a method is native */
  422. var reNative = RegExp('^' +
  423. String(objectProto.valueOf)
  424. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  425. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  426. );
  427. /** Native method shortcuts */
  428. var ceil = Math.ceil,
  429. clearTimeout = context.clearTimeout,
  430. concat = arrayRef.concat,
  431. floor = Math.floor,
  432. fnToString = Function.prototype.toString,
  433. getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  434. hasOwnProperty = objectProto.hasOwnProperty,
  435. push = arrayRef.push,
  436. propertyIsEnumerable = objectProto.propertyIsEnumerable,
  437. setImmediate = context.setImmediate,
  438. setTimeout = context.setTimeout,
  439. toString = objectProto.toString;
  440. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  441. var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
  442. nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
  443. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  444. nativeIsFinite = context.isFinite,
  445. nativeIsNaN = context.isNaN,
  446. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  447. nativeMax = Math.max,
  448. nativeMin = Math.min,
  449. nativeParseInt = context.parseInt,
  450. nativeRandom = Math.random,
  451. nativeSlice = arrayRef.slice;
  452. /** Detect various environments */
  453. var isIeOpera = reNative.test(context.attachEvent),
  454. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  455. /** Used to lookup a built-in constructor by [[Class]] */
  456. var ctorByClass = {};
  457. ctorByClass[arrayClass] = Array;
  458. ctorByClass[boolClass] = Boolean;
  459. ctorByClass[dateClass] = Date;
  460. ctorByClass[funcClass] = Function;
  461. ctorByClass[objectClass] = Object;
  462. ctorByClass[numberClass] = Number;
  463. ctorByClass[regexpClass] = RegExp;
  464. ctorByClass[stringClass] = String;
  465. /** Used to avoid iterating non-enumerable properties in IE < 9 */
  466. var nonEnumProps = {};
  467. nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
  468. nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
  469. nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
  470. nonEnumProps[objectClass] = { 'constructor': true };
  471. (function() {
  472. var length = shadowedProps.length;
  473. while (length--) {
  474. var prop = shadowedProps[length];
  475. for (var className in nonEnumProps) {
  476. if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], prop)) {
  477. nonEnumProps[className][prop] = false;
  478. }
  479. }
  480. }
  481. }());
  482. /*--------------------------------------------------------------------------*/
  483. /**
  484. * Creates a `lodash` object, which wraps the given `value`, to enable method
  485. * chaining.
  486. *
  487. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  488. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  489. * and `unshift`
  490. *
  491. * Chaining is supported in custom builds as long as the `value` method is
  492. * implicitly or explicitly included in the build.
  493. *
  494. * The chainable wrapper functions are:
  495. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  496. * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`,
  497. * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`,
  498. * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`,
  499. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  500. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
  501. * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
  502. * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
  503. * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
  504. *
  505. * The non-chainable wrapper functions are:
  506. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
  507. * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
  508. * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
  509. * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
  510. * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `parseInt`,
  511. * `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`, `size`, `some`,
  512. * `sortedIndex`, `runInContext`, `template`, `unescape`, `uniqueId`, and `value`
  513. *
  514. * The wrapper functions `first` and `last` return wrapped values when `n` is
  515. * passed, otherwise they return unwrapped values.
  516. *
  517. * @name _
  518. * @constructor
  519. * @alias chain
  520. * @category Chaining
  521. * @param {Mixed} value The value to wrap in a `lodash` instance.
  522. * @returns {Object} Returns a `lodash` instance.
  523. * @example
  524. *
  525. * var wrapped = _([1, 2, 3]);
  526. *
  527. * // returns an unwrapped value
  528. * wrapped.reduce(function(sum, num) {
  529. * return sum + num;
  530. * });
  531. * // => 6
  532. *
  533. * // returns a wrapped value
  534. * var squares = wrapped.map(function(num) {
  535. * return num * num;
  536. * });
  537. *
  538. * _.isArray(squares);
  539. * // => false
  540. *
  541. * _.isArray(squares.value());
  542. * // => true
  543. */
  544. function lodash(value) {
  545. // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
  546. return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
  547. ? value
  548. : new lodashWrapper(value);
  549. }
  550. /**
  551. * A fast path for creating `lodash` wrapper objects.
  552. *
  553. * @private
  554. * @param {Mixed} value The value to wrap in a `lodash` instance.
  555. * @returns {Object} Returns a `lodash` instance.
  556. */
  557. function lodashWrapper(value) {
  558. this.__wrapped__ = value;
  559. }
  560. // ensure `new lodashWrapper` is an instance of `lodash`
  561. lodashWrapper.prototype = lodash.prototype;
  562. /**
  563. * An object used to flag environments features.
  564. *
  565. * @static
  566. * @memberOf _
  567. * @type Object
  568. */
  569. var support = lodash.support = {};
  570. (function() {
  571. var ctor = function() { this.x = 1; },
  572. object = { '0': 1, 'length': 1 },
  573. props = [];
  574. ctor.prototype = { 'valueOf': 1, 'y': 1 };
  575. for (var prop in new ctor) { props.push(prop); }
  576. for (prop in arguments) { }
  577. /**
  578. * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
  579. *
  580. * @memberOf _.support
  581. * @type Boolean
  582. */
  583. support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
  584. /**
  585. * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
  586. *
  587. * @memberOf _.support
  588. * @type Boolean
  589. */
  590. support.argsClass = isArguments(arguments);
  591. /**
  592. * Detect if `name` or `message` properties of `Error.prototype` are
  593. * enumerable by default. (IE < 9, Safari < 5.1)
  594. *
  595. * @memberOf _.support
  596. * @type Boolean
  597. */
  598. support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
  599. /**
  600. * Detect if `prototype` properties are enumerable by default.
  601. *
  602. * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
  603. * (if the prototype or a property on the prototype has been set)
  604. * incorrectly sets a function's `prototype` property [[Enumerable]]
  605. * value to `true`.
  606. *
  607. * @memberOf _.support
  608. * @type Boolean
  609. */
  610. support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
  611. /**
  612. * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
  613. *
  614. * @memberOf _.support
  615. * @type Boolean
  616. */
  617. support.fastBind = nativeBind && !isV8;
  618. /**
  619. * Detect if own properties are iterated after inherited properties (all but IE < 9).
  620. *
  621. * @memberOf _.support
  622. * @type Boolean
  623. */
  624. support.ownLast = props[0] != 'x';
  625. /**
  626. * Detect if `arguments` object indexes are non-enumerable
  627. * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
  628. *
  629. * @memberOf _.support
  630. * @type Boolean
  631. */
  632. support.nonEnumArgs = prop != 0;
  633. /**
  634. * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
  635. *
  636. * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
  637. * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
  638. *
  639. * @memberOf _.support
  640. * @type Boolean
  641. */
  642. support.nonEnumShadows = !/valueOf/.test(props);
  643. /**
  644. * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
  645. *
  646. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  647. * and `splice()` functions that fail to remove the last element, `value[0]`,
  648. * of array-like objects even though the `length` property is set to `0`.
  649. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  650. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  651. *
  652. * @memberOf _.support
  653. * @type Boolean
  654. */
  655. support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
  656. /**
  657. * Detect lack of support for accessing string characters by index.
  658. *
  659. * IE < 8 can't access characters by index and IE 8 can only access
  660. * characters by index on string literals.
  661. *
  662. * @memberOf _.support
  663. * @type Boolean
  664. */
  665. support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
  666. /**
  667. * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
  668. * and that the JS engine errors when attempting to coerce an object to
  669. * a string without a `toString` function.
  670. *
  671. * @memberOf _.support
  672. * @type Boolean
  673. */
  674. try {
  675. support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
  676. } catch(e) {
  677. support.nodeClass = true;
  678. }
  679. }(1));
  680. /*--------------------------------------------------------------------------*/
  681. /**
  682. * The template used to create iterator functions.
  683. *
  684. * @private
  685. * @param {Object} data The data object used to populate the text.
  686. * @returns {String} Returns the interpolated text.
  687. */
  688. var iteratorTemplate = function(obj) {
  689. var __p = 'var index, iterable = ' +
  690. (obj.firstArg) +
  691. ', result = ' +
  692. (obj.init) +
  693. ';\nif (!iterable) return result;\n' +
  694. (obj.top) +
  695. ';';
  696. if (obj.array) {
  697. __p += '\nvar length = iterable.length; index = -1;\nif (' +
  698. (obj.array) +
  699. ') { ';
  700. if (support.unindexedChars) {
  701. __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
  702. }
  703. __p += '\n while (++index < length) {\n ' +
  704. (obj.loop) +
  705. ';\n }\n}\nelse { ';
  706. } else if (support.nonEnumArgs) {
  707. __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
  708. (obj.loop) +
  709. ';\n }\n } else { ';
  710. }
  711. if (support.enumPrototypes) {
  712. __p += '\n var skipProto = typeof iterable == \'function\';\n ';
  713. }
  714. if (support.enumErrorProps) {
  715. __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
  716. }
  717. var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
  718. if (obj.useHas && obj.useKeys) {
  719. __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
  720. if (conditions.length) {
  721. __p += ' if (' +
  722. (conditions.join(' && ')) +
  723. ') {\n ';
  724. }
  725. __p +=
  726. (obj.loop) +
  727. '; ';
  728. if (conditions.length) {
  729. __p += '\n }';
  730. }
  731. __p += '\n } ';
  732. } else {
  733. __p += '\n for (index in iterable) {\n';
  734. if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
  735. __p += ' if (' +
  736. (conditions.join(' && ')) +
  737. ') {\n ';
  738. }
  739. __p +=
  740. (obj.loop) +
  741. '; ';
  742. if (conditions.length) {
  743. __p += '\n }';
  744. }
  745. __p += '\n } ';
  746. if (support.nonEnumShadows) {
  747. __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
  748. for (k = 0; k < 7; k++) {
  749. __p += '\n index = \'' +
  750. (obj.shadowedProps[k]) +
  751. '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
  752. if (!obj.useHas) {
  753. __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
  754. }
  755. __p += ') {\n ' +
  756. (obj.loop) +
  757. ';\n } ';
  758. }
  759. __p += '\n } ';
  760. }
  761. }
  762. if (obj.array || support.nonEnumArgs) {
  763. __p += '\n}';
  764. }
  765. __p +=
  766. (obj.bottom) +
  767. ';\nreturn result';
  768. return __p
  769. };
  770. /** Reusable iterator options for `assign` and `defaults` */
  771. var defaultsIteratorOptions = {
  772. 'args': 'object, source, guard',
  773. 'top':
  774. 'var args = arguments,\n' +
  775. ' argsIndex = 0,\n' +
  776. " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
  777. 'while (++argsIndex < argsLength) {\n' +
  778. ' iterable = args[argsIndex];\n' +
  779. ' if (iterable && objectTypes[typeof iterable]) {',
  780. 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
  781. 'bottom': ' }\n}'
  782. };
  783. /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
  784. var eachIteratorOptions = {
  785. 'args': 'collection, callback, thisArg',
  786. 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg)",
  787. 'array': "typeof length == 'number'",
  788. 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
  789. };
  790. /** Reusable iterator options for `forIn` and `forOwn` */
  791. var forOwnIteratorOptions = {
  792. 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
  793. 'array': false
  794. };
  795. /*--------------------------------------------------------------------------*/
  796. /**
  797. * Creates a function that, when called, invokes `func` with the `this` binding
  798. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  799. * bound function.
  800. *
  801. * @private
  802. * @param {Function|String} func The function to bind or the method name.
  803. * @param {Mixed} [thisArg] The `this` binding of `func`.
  804. * @param {Array} partialArgs An array of arguments to be partially applied.
  805. * @param {Object} [idicator] Used to indicate binding by key or partially
  806. * applying arguments from the right.
  807. * @returns {Function} Returns the new bound function.
  808. */
  809. function createBound(func, thisArg, partialArgs, indicator) {
  810. var isFunc = isFunction(func),
  811. isPartial = !partialArgs,
  812. key = thisArg;
  813. // juggle arguments
  814. if (isPartial) {
  815. var rightIndicator = indicator;
  816. partialArgs = thisArg;
  817. }
  818. else if (!isFunc) {
  819. if (!indicator) {
  820. throw new TypeError;
  821. }
  822. thisArg = func;
  823. }
  824. function bound() {
  825. // `Function#bind` spec
  826. // http://es5.github.com/#x15.3.4.5
  827. var args = arguments,
  828. thisBinding = isPartial ? this : thisArg;
  829. if (!isFunc) {
  830. func = thisArg[key];
  831. }
  832. if (partialArgs.length) {
  833. args = args.length
  834. ? (args = nativeSlice.call(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  835. : partialArgs;
  836. }
  837. if (this instanceof bound) {
  838. // ensure `new bound` is an instance of `func`
  839. thisBinding = createObject(func.prototype);
  840. // mimic the constructor's `return` behavior
  841. // http://es5.github.com/#x13.2.2
  842. var result = func.apply(thisBinding, args);
  843. return isObject(result) ? result : thisBinding;
  844. }
  845. return func.apply(thisBinding, args);
  846. }
  847. return bound;
  848. }
  849. /**
  850. * Creates compiled iteration functions.
  851. *
  852. * @private
  853. * @param {Object} [options1, options2, ...] The compile options object(s).
  854. * array - A string of code to determine if the iterable is an array or array-like.
  855. * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
  856. * useKeys - A boolean to specify using `_.keys` for own property iteration.
  857. * args - A string of comma separated arguments the iteration function will accept.
  858. * top - A string of code to execute before the iteration branches.
  859. * loop - A string of code to execute in the object loop.
  860. * bottom - A string of code to execute after the iteration branches.
  861. * @returns {Function} Returns the compiled function.
  862. */
  863. function createIterator() {
  864. var data = getObject();
  865. // data properties
  866. data.shadowedProps = shadowedProps;
  867. // iterator options
  868. data.array = data.bottom = data.loop = data.top = '';
  869. data.init = 'iterable';
  870. data.useHas = true;
  871. data.useKeys = !!keys;
  872. // merge options into a template data object
  873. for (var object, index = 0; object = arguments[index]; index++) {
  874. for (var key in object) {
  875. data[key] = object[key];
  876. }
  877. }
  878. var args = data.args;
  879. data.firstArg = /^[^,]+/.exec(args)[0];
  880. // create the function factory
  881. var factory = Function(
  882. 'errorClass, errorProto, hasOwnProperty, isArguments, isArray, ' +
  883. 'isString, keys, lodash, objectProto, objectTypes, nonEnumProps, ' +
  884. 'stringClass, stringProto, toString',
  885. 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
  886. );
  887. releaseObject(data);
  888. // return the compiled function
  889. return factory(
  890. errorClass, errorProto, hasOwnProperty, isArguments, isArray,
  891. isString, keys, lodash, objectProto, objectTypes, nonEnumProps,
  892. stringClass, stringProto, toString
  893. );
  894. }
  895. /**
  896. * Creates a new object with the specified `prototype`.
  897. *
  898. * @private
  899. * @param {Object} prototype The prototype object.
  900. * @returns {Object} Returns the new object.
  901. */
  902. function createObject(prototype) {
  903. return isObject(prototype) ? nativeCreate(prototype) : {};
  904. }
  905. // fallback for browsers without `Object.create`
  906. if (!nativeCreate) {
  907. var createObject = function(prototype) {
  908. if (isObject(prototype)) {
  909. noop.prototype = prototype;
  910. var result = new noop;
  911. noop.prototype = null;
  912. }
  913. return result || {};
  914. };
  915. }
  916. /**
  917. * Used by `escape` to convert characters to HTML entities.
  918. *
  919. * @private
  920. * @param {String} match The matched character to escape.
  921. * @returns {String} Returns the escaped character.
  922. */
  923. function escapeHtmlChar(match) {
  924. return htmlEscapes[match];
  925. }
  926. /**
  927. * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
  928. * customized, this method returns the custom method, otherwise it returns
  929. * the `basicIndexOf` function.
  930. *
  931. * @private
  932. * @returns {Function} Returns the "indexOf" function.
  933. */
  934. function getIndexOf(array, value, fromIndex) {
  935. var result = (result = lodash.indexOf) === indexOf ? basicIndexOf : result;
  936. return result;
  937. }
  938. /**
  939. * Creates a function that juggles arguments, allowing argument overloading
  940. * for `_.flatten` and `_.uniq`, before passing them to the given `func`.
  941. *
  942. * @private
  943. * @param {Function} func The function to wrap.
  944. * @returns {Function} Returns the new function.
  945. */
  946. function overloadWrapper(func) {
  947. return function(array, flag, callback, thisArg) {
  948. // juggle arguments
  949. if (typeof flag != 'boolean' && flag != null) {
  950. thisArg = callback;
  951. callback = !(thisArg && thisArg[flag] === array) ? flag : undefined;
  952. flag = false;
  953. }
  954. if (callback != null) {
  955. callback = lodash.createCallback(callback, thisArg);
  956. }
  957. return func(array, flag, callback, thisArg);
  958. };
  959. }
  960. /**
  961. * A fallback implementation of `isPlainObject` which checks if a given `value`
  962. * is an object created by the `Object` constructor, assuming objects created
  963. * by the `Object` constructor have no inherited enumerable properties and that
  964. * there are no `Object.prototype` extensions.
  965. *
  966. * @private
  967. * @param {Mixed} value The value to check.
  968. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  969. */
  970. function shimIsPlainObject(value) {
  971. var ctor,
  972. result;
  973. // avoid non Object objects, `arguments` objects, and DOM elements
  974. if (!(value && toString.call(value) == objectClass) ||
  975. (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
  976. (!support.argsClass && isArguments(value)) ||
  977. (!support.nodeClass && isNode(value))) {
  978. return false;
  979. }
  980. // IE < 9 iterates inherited properties before own properties. If the first
  981. // iterated property is an object's own property then there are no inherited
  982. // enumerable properties.
  983. if (support.ownLast) {
  984. forIn(value, function(value, key, object) {
  985. result = hasOwnProperty.call(object, key);
  986. return false;
  987. });
  988. return result !== false;
  989. }
  990. // In most environments an object's own properties are iterated before
  991. // its inherited properties. If the last iterated property is an object's
  992. // own property then there are no inherited enumerable properties.
  993. forIn(value, function(value, key) {
  994. result = key;
  995. });
  996. return result === undefined || hasOwnProperty.call(value, result);
  997. }
  998. /**
  999. * Used by `unescape` to convert HTML entities to characters.
  1000. *
  1001. * @private
  1002. * @param {String} match The matched character to unescape.
  1003. * @returns {String} Returns the unescaped character.
  1004. */
  1005. function unescapeHtmlChar(match) {
  1006. return htmlUnescapes[match];
  1007. }
  1008. /*--------------------------------------------------------------------------*/
  1009. /**
  1010. * Checks if `value` is an `arguments` object.
  1011. *
  1012. * @static
  1013. * @memberOf _
  1014. * @category Objects
  1015. * @param {Mixed} value The value to check.
  1016. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  1017. * @example
  1018. *
  1019. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  1020. * // => true
  1021. *
  1022. * _.isArguments([1, 2, 3]);
  1023. * // => false
  1024. */
  1025. function isArguments(value) {
  1026. return toString.call(value) == argsClass;
  1027. }
  1028. // fallback for browsers that can't detect `arguments` objects by [[Class]]
  1029. if (!support.argsClass) {
  1030. isArguments = function(value) {
  1031. return value ? hasOwnProperty.call(value, 'callee') : false;
  1032. };
  1033. }
  1034. /**
  1035. * Checks if `value` is an array.
  1036. *
  1037. * @static
  1038. * @memberOf _
  1039. * @category Objects
  1040. * @param {Mixed} value The value to check.
  1041. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  1042. * @example
  1043. *
  1044. * (function() { return _.isArray(arguments); })();
  1045. * // => false
  1046. *
  1047. * _.isArray([1, 2, 3]);
  1048. * // => true
  1049. */
  1050. var isArray = nativeIsArray || function(value) {
  1051. return value ? (typeof value == 'object' && toString.call(value) == arrayClass) : false;
  1052. };
  1053. /**
  1054. * A fallback implementation of `Object.keys` which produces an array of the
  1055. * given object's own enumerable property names.
  1056. *
  1057. * @private
  1058. * @type Function
  1059. * @param {Object} object The object to inspect.
  1060. * @returns {Array} Returns a new array of property names.
  1061. */
  1062. var shimKeys = createIterator({
  1063. 'args': 'object',
  1064. 'init': '[]',
  1065. 'top': 'if (!(objectTypes[typeof object])) return result',
  1066. 'loop': 'result.push(index)'
  1067. });
  1068. /**
  1069. * Creates an array composed of the own enumerable property names of `object`.
  1070. *
  1071. * @static
  1072. * @memberOf _
  1073. * @category Objects
  1074. * @param {Object} object The object to inspect.
  1075. * @returns {Array} Returns a new array of property names.
  1076. * @example
  1077. *
  1078. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  1079. * // => ['one', 'two', 'three'] (order is not guaranteed)
  1080. */
  1081. var keys = !nativeKeys ? shimKeys : function(object) {
  1082. if (!isObject(object)) {
  1083. return [];
  1084. }
  1085. if ((support.enumPrototypes && typeof object == 'function') ||
  1086. (support.nonEnumArgs && object.length && isArguments(object))) {
  1087. return shimKeys(object);
  1088. }
  1089. return nativeKeys(object);
  1090. };
  1091. /**
  1092. * A function compiled to iterate `arguments` objects, arrays, objects, and
  1093. * strings consistenly across environments, executing the `callback` for each
  1094. * element in the `collection`. The `callback` is bound to `thisArg` and invoked
  1095. * with three arguments; (value, index|key, collection). Callbacks may exit
  1096. * iteration early by explicitly returning `false`.
  1097. *
  1098. * @private
  1099. * @type Function
  1100. * @param {Array|Object|String} collection The collection to iterate over.
  1101. * @param {Function} [callback=identity] The function called per iteration.
  1102. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1103. * @returns {Array|Object|String} Returns `collection`.
  1104. */
  1105. var basicEach = createIterator(eachIteratorOptions);
  1106. /**
  1107. * Used to convert characters to HTML entities:
  1108. *
  1109. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  1110. * don't require escaping in HTML and have no special meaning unless they're part
  1111. * of a tag or an unquoted attribute value.
  1112. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  1113. */
  1114. var htmlEscapes = {
  1115. '&': '&amp;',
  1116. '<': '&lt;',
  1117. '>': '&gt;',
  1118. '"': '&quot;',
  1119. "'": '&#39;'
  1120. };
  1121. /** Used to convert HTML entities to characters */
  1122. var htmlUnescapes = invert(htmlEscapes);
  1123. /*--------------------------------------------------------------------------*/
  1124. /**
  1125. * Assigns own enumerable properties of source object(s) to the destination
  1126. * object. Subsequent sources will overwrite property assignments of previous
  1127. * sources. If a `callback` function is passed, it will be executed to produce
  1128. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  1129. * two arguments; (objectValue, sourceValue).
  1130. *
  1131. * @static
  1132. * @memberOf _
  1133. * @type Function
  1134. * @alias extend
  1135. * @category Objects
  1136. * @param {Object} object The destination object.
  1137. * @param {Object} [source1, source2, ...] The source objects.
  1138. * @param {Function} [callback] The function to customize assigning values.
  1139. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1140. * @returns {Object} Returns the destination object.
  1141. * @example
  1142. *
  1143. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  1144. * // => { 'name': 'moe', 'age': 40 }
  1145. *
  1146. * var defaults = _.partialRight(_.assign, function(a, b) {
  1147. * return typeof a == 'undefined' ? b : a;
  1148. * });
  1149. *
  1150. * var food = { 'name': 'apple' };
  1151. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  1152. * // => { 'name': 'apple', 'type': 'fruit' }
  1153. */
  1154. var assign = createIterator(defaultsIteratorOptions, {
  1155. 'top':
  1156. defaultsIteratorOptions.top.replace(';',
  1157. ';\n' +
  1158. "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
  1159. ' var callback = lodash.createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
  1160. "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
  1161. ' callback = args[--argsLength];\n' +
  1162. '}'
  1163. ),
  1164. 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
  1165. });
  1166. /**
  1167. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  1168. * be cloned, otherwise they will be assigned by reference. If a `callback`
  1169. * function is passed, it will be executed to produce the cloned values. If
  1170. * `callback` returns `undefined`, cloning will be handled by the method instead.
  1171. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  1172. *
  1173. * @static
  1174. * @memberOf _
  1175. * @category Objects
  1176. * @param {Mixed} value The value to clone.
  1177. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  1178. * @param {Function} [callback] The function to customize cloning values.
  1179. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1180. * @param- {Array} [stackA=[]] Tracks traversed source objects.
  1181. * @param- {Array} [stackB=[]] Associates clones with source counterparts.
  1182. * @returns {Mixed} Returns the cloned `value`.
  1183. * @example
  1184. *
  1185. * var stooges = [
  1186. * { 'name': 'moe', 'age': 40 },
  1187. * { 'name': 'larry', 'age': 50 }
  1188. * ];
  1189. *
  1190. * var shallow = _.clone(stooges);
  1191. * shallow[0] === stooges[0];
  1192. * // => true
  1193. *
  1194. * var deep = _.clone(stooges, true);
  1195. * deep[0] === stooges[0];
  1196. * // => false
  1197. *
  1198. * _.mixin({
  1199. * 'clone': _.partialRight(_.clone, function(value) {
  1200. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  1201. * })
  1202. * });
  1203. *
  1204. * var clone = _.clone(document.body);
  1205. * clone.childNodes.length;
  1206. * // => 0
  1207. */
  1208. function clone(value, deep, callback, thisArg, stackA, stackB) {
  1209. var result = value;
  1210. // allows working with "Collections" methods without using their `callback`
  1211. // argument, `index|key`, for this method's `callback`
  1212. if (typeof deep != 'boolean' && deep != null) {
  1213. thisArg = callback;
  1214. callback = deep;
  1215. deep = false;
  1216. }
  1217. if (typeof callback == 'function') {
  1218. callback = (typeof thisArg == 'undefined')
  1219. ? callback
  1220. : lodash.createCallback(callback, thisArg, 1);
  1221. result = callback(result);
  1222. if (typeof result != 'undefined') {
  1223. return result;
  1224. }
  1225. result = value;
  1226. }
  1227. // inspect [[Class]]
  1228. var isObj = isObject(result);
  1229. if (isObj) {
  1230. var className = toString.call(result);
  1231. if (!cloneableClasses[className] || (!support.nodeClass && isNode(result))) {
  1232. return result;
  1233. }
  1234. var isArr = isArray(result);
  1235. }
  1236. // shallow clone
  1237. if (!isObj || !deep) {
  1238. return isObj
  1239. ? (isArr ? slice(result) : assign({}, result))
  1240. : result;
  1241. }
  1242. var ctor = ctorByClass[className];
  1243. switch (className) {
  1244. case boolClass:
  1245. case dateClass:
  1246. return new ctor(+result);
  1247. case numberClass:
  1248. case stringClass:
  1249. return new ctor(result);
  1250. case regexpClass:
  1251. return ctor(result.source, reFlags.exec(result));
  1252. }
  1253. // check for circular references and return corresponding clone
  1254. var initedStack = !stackA;
  1255. stackA || (stackA = getArray());
  1256. stackB || (stackB = getArray());
  1257. var length = stackA.length;
  1258. while (length--) {
  1259. if (stackA[length] == value) {
  1260. return stackB[length];
  1261. }
  1262. }
  1263. // init cloned object
  1264. result = isArr ? ctor(result.length) : {};
  1265. // add array properties assigned by `RegExp#exec`
  1266. if (isArr) {
  1267. if (hasOwnProperty.call(value, 'index')) {
  1268. result.index = value.index;
  1269. }
  1270. if (hasOwnProperty.call(value, 'input')) {
  1271. result.input = value.input;
  1272. }
  1273. }
  1274. // add the source value to the stack of traversed objects
  1275. // and associate it with its clone
  1276. stackA.push(value);
  1277. stackB.push(result);
  1278. // recursively populate clone (susceptible to call stack limits)
  1279. (isArr ? basicEach : forOwn)(value, function(objValue, key) {
  1280. result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
  1281. });
  1282. if (initedStack) {
  1283. releaseArray(stackA);
  1284. releaseArray(stackB);
  1285. }
  1286. return result;
  1287. }
  1288. /**
  1289. * Creates a deep clone of `value`. If a `callback` function is passed,
  1290. * it will be executed to produce the cloned values. If `callback` returns
  1291. * `undefined`, cloning will be handled by the method instead. The `callback`
  1292. * is bound to `thisArg` and invoked with one argument; (value).
  1293. *
  1294. * Note: This method is loosely based on the structured clone algorithm. Functions
  1295. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  1296. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  1297. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  1298. *
  1299. * @static
  1300. * @memberOf _
  1301. * @category Objects
  1302. * @param {Mixed} value The value to deep clone.
  1303. * @param {Function} [callback] The function to customize cloning values.
  1304. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1305. * @returns {Mixed} Returns the deep cloned `value`.
  1306. * @example
  1307. *
  1308. * var stooges = [
  1309. * { 'name': 'moe', 'age': 40 },
  1310. * { 'name': 'larry', 'age': 50 }
  1311. * ];
  1312. *
  1313. * var deep = _.cloneDeep(stooges);
  1314. * deep[0] === stooges[0];
  1315. * // => false
  1316. *
  1317. * var view = {
  1318. * 'label': 'docs',
  1319. * 'node': element
  1320. * };
  1321. *
  1322. * var clone = _.cloneDeep(view, function(value) {
  1323. * return _.isElement(value) ? value.cloneNode(true) : undefined;
  1324. * });
  1325. *
  1326. * clone.node == view.node;
  1327. * // => false
  1328. */
  1329. function cloneDeep(value, callback, thisArg) {
  1330. return clone(value, true, callback, thisArg);
  1331. }
  1332. /**
  1333. *