PageRenderTime 55ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/front/node_modules/lodash/dist/lodash.js

https://gitlab.com/boxnia/NFU_MOVIL
JavaScript | 1579 lines | 1087 code | 55 blank | 437 comment | 128 complexity | aa7c661f74d34673f101e73bf0a11b39 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 1.0.2 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash modern -o ./dist/lodash.js`
  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, undefined) {
  11. /** Detect free variable `exports` */
  12. var freeExports = typeof exports == 'object' && exports;
  13. /** Detect free variable `module` */
  14. var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
  15. /** Detect free variable `global` and use it as `window` */
  16. var freeGlobal = typeof global == 'object' && global;
  17. if (freeGlobal.global === freeGlobal) {
  18. window = freeGlobal;
  19. }
  20. /** Used for array and object method references */
  21. var arrayRef = [],
  22. objectRef = {};
  23. /** Used to generate unique IDs */
  24. var idCounter = 0;
  25. /** Used internally to indicate various things */
  26. var indicatorObject = objectRef;
  27. /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */
  28. var largeArraySize = 30;
  29. /** Used to restore the original `_` reference in `noConflict` */
  30. var oldDash = window._;
  31. /** Used to match HTML entities */
  32. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  33. /** Used to match empty string literals in compiled template source */
  34. var reEmptyStringLeading = /\b__p \+= '';/g,
  35. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  36. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  37. /** Used to match regexp flags from their coerced string values */
  38. var reFlags = /\w*$/;
  39. /** Used to detect if a method is native */
  40. var reNative = RegExp('^' +
  41. (objectRef.valueOf + '')
  42. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  43. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  44. );
  45. /**
  46. * Used to match ES6 template delimiters
  47. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  48. */
  49. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  50. /** Used to match "interpolate" template delimiters */
  51. var reInterpolate = /<%=([\s\S]+?)%>/g;
  52. /** Used to ensure capturing order of template delimiters */
  53. var reNoMatch = /($^)/;
  54. /** Used to match HTML characters */
  55. var reUnescapedHtml = /[&<>"']/g;
  56. /** Used to match unescaped characters in compiled string literals */
  57. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  58. /** Used to make template sourceURLs easier to identify */
  59. var templateCounter = 0;
  60. /** Native method shortcuts */
  61. var ceil = Math.ceil,
  62. concat = arrayRef.concat,
  63. floor = Math.floor,
  64. getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  65. hasOwnProperty = objectRef.hasOwnProperty,
  66. push = arrayRef.push,
  67. toString = objectRef.toString;
  68. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  69. var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
  70. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  71. nativeIsFinite = window.isFinite,
  72. nativeIsNaN = window.isNaN,
  73. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  74. nativeMax = Math.max,
  75. nativeMin = Math.min,
  76. nativeRandom = Math.random;
  77. /** `Object#toString` result shortcuts */
  78. var argsClass = '[object Arguments]',
  79. arrayClass = '[object Array]',
  80. boolClass = '[object Boolean]',
  81. dateClass = '[object Date]',
  82. funcClass = '[object Function]',
  83. numberClass = '[object Number]',
  84. objectClass = '[object Object]',
  85. regexpClass = '[object RegExp]',
  86. stringClass = '[object String]';
  87. /** Detect various environments */
  88. var isIeOpera = !!window.attachEvent,
  89. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  90. /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
  91. var isBindFast = nativeBind && !isV8;
  92. /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
  93. var isKeysFast = nativeKeys && (isIeOpera || isV8);
  94. /** Used to identify object classifications that `_.clone` supports */
  95. var cloneableClasses = {};
  96. cloneableClasses[funcClass] = false;
  97. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  98. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  99. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  100. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  101. /** Used to lookup a built-in constructor by [[Class]] */
  102. var ctorByClass = {};
  103. ctorByClass[arrayClass] = Array;
  104. ctorByClass[boolClass] = Boolean;
  105. ctorByClass[dateClass] = Date;
  106. ctorByClass[objectClass] = Object;
  107. ctorByClass[numberClass] = Number;
  108. ctorByClass[regexpClass] = RegExp;
  109. ctorByClass[stringClass] = String;
  110. /** Used to determine if values are of the language type Object */
  111. var objectTypes = {
  112. 'boolean': false,
  113. 'function': true,
  114. 'object': true,
  115. 'number': false,
  116. 'string': false,
  117. 'undefined': false
  118. };
  119. /** Used to escape characters for inclusion in compiled string literals */
  120. var stringEscapes = {
  121. '\\': '\\',
  122. "'": "'",
  123. '\n': 'n',
  124. '\r': 'r',
  125. '\t': 't',
  126. '\u2028': 'u2028',
  127. '\u2029': 'u2029'
  128. };
  129. /*--------------------------------------------------------------------------*/
  130. /**
  131. * Creates a `lodash` object, that wraps the given `value`, to enable method
  132. * chaining.
  133. *
  134. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  135. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  136. * and `unshift`
  137. *
  138. * The chainable wrapper functions are:
  139. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
  140. * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
  141. * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
  142. * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
  143. * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
  144. * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
  145. * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
  146. * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
  147. *
  148. * The non-chainable wrapper functions are:
  149. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
  150. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
  151. * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
  152. * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
  153. * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
  154. * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
  155. *
  156. * The wrapper functions `first` and `last` return wrapped values when `n` is
  157. * passed, otherwise they return unwrapped values.
  158. *
  159. * @name _
  160. * @constructor
  161. * @category Chaining
  162. * @param {Mixed} value The value to wrap in a `lodash` instance.
  163. * @returns {Object} Returns a `lodash` instance.
  164. */
  165. function lodash(value) {
  166. // exit early if already wrapped, even if wrapped by a different `lodash` constructor
  167. if (value && typeof value == 'object' && value.__wrapped__) {
  168. return value;
  169. }
  170. // allow invoking `lodash` without the `new` operator
  171. if (!(this instanceof lodash)) {
  172. return new lodash(value);
  173. }
  174. this.__wrapped__ = value;
  175. }
  176. /**
  177. * By default, the template delimiters used by Lo-Dash are similar to those in
  178. * embedded Ruby (ERB). Change the following template settings to use alternative
  179. * delimiters.
  180. *
  181. * @static
  182. * @memberOf _
  183. * @type Object
  184. */
  185. lodash.templateSettings = {
  186. /**
  187. * Used to detect `data` property values to be HTML-escaped.
  188. *
  189. * @memberOf _.templateSettings
  190. * @type RegExp
  191. */
  192. 'escape': /<%-([\s\S]+?)%>/g,
  193. /**
  194. * Used to detect code to be evaluated.
  195. *
  196. * @memberOf _.templateSettings
  197. * @type RegExp
  198. */
  199. 'evaluate': /<%([\s\S]+?)%>/g,
  200. /**
  201. * Used to detect `data` property values to inject.
  202. *
  203. * @memberOf _.templateSettings
  204. * @type RegExp
  205. */
  206. 'interpolate': reInterpolate,
  207. /**
  208. * Used to reference the data object in the template text.
  209. *
  210. * @memberOf _.templateSettings
  211. * @type String
  212. */
  213. 'variable': '',
  214. /**
  215. * Used to import variables into the compiled template.
  216. *
  217. * @memberOf _.templateSettings
  218. * @type Object
  219. */
  220. 'imports': {
  221. /**
  222. * A reference to the `lodash` function.
  223. *
  224. * @memberOf _.templateSettings.imports
  225. * @type Function
  226. */
  227. '_': lodash
  228. }
  229. };
  230. /*--------------------------------------------------------------------------*/
  231. /**
  232. * The template used to create iterator functions.
  233. *
  234. * @private
  235. * @param {Obect} data The data object used to populate the text.
  236. * @returns {String} Returns the interpolated text.
  237. */
  238. var iteratorTemplate = function(obj) {
  239. var __p = 'var index, iterable = ' +
  240. (obj.firstArg ) +
  241. ', result = iterable;\nif (!iterable) return result;\n' +
  242. (obj.top ) +
  243. ';\n';
  244. if (obj.arrays) {
  245. __p += 'var length = iterable.length; index = -1;\nif (' +
  246. (obj.arrays ) +
  247. ') {\n while (++index < length) {\n ' +
  248. (obj.loop ) +
  249. '\n }\n}\nelse { ';
  250. } ;
  251. if (obj.isKeysFast && obj.useHas) {
  252. __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ' +
  253. (obj.loop ) +
  254. '\n } ';
  255. } else {
  256. __p += '\n for (index in iterable) {';
  257. if (obj.useHas) {
  258. __p += '\n if (';
  259. if (obj.useHas) {
  260. __p += 'hasOwnProperty.call(iterable, index)';
  261. } ;
  262. __p += ') { ';
  263. } ;
  264. __p +=
  265. (obj.loop ) +
  266. '; ';
  267. if (obj.useHas) {
  268. __p += '\n }';
  269. } ;
  270. __p += '\n } ';
  271. } ;
  272. if (obj.arrays) {
  273. __p += '\n}';
  274. } ;
  275. __p +=
  276. (obj.bottom ) +
  277. ';\nreturn result';
  278. return __p
  279. };
  280. /** Reusable iterator options for `assign` and `defaults` */
  281. var defaultsIteratorOptions = {
  282. 'args': 'object, source, guard',
  283. 'top':
  284. 'var args = arguments,\n' +
  285. ' argsIndex = 0,\n' +
  286. " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
  287. 'while (++argsIndex < argsLength) {\n' +
  288. ' iterable = args[argsIndex];\n' +
  289. ' if (iterable && objectTypes[typeof iterable]) {',
  290. 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
  291. 'bottom': ' }\n}'
  292. };
  293. /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
  294. var eachIteratorOptions = {
  295. 'args': 'collection, callback, thisArg',
  296. 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
  297. 'arrays': "typeof length == 'number'",
  298. 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
  299. };
  300. /** Reusable iterator options for `forIn` and `forOwn` */
  301. var forOwnIteratorOptions = {
  302. 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
  303. 'arrays': false
  304. };
  305. /*--------------------------------------------------------------------------*/
  306. /**
  307. * Creates a function optimized to search large arrays for a given `value`,
  308. * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
  309. *
  310. * @private
  311. * @param {Array} array The array to search.
  312. * @param {Mixed} value The value to search for.
  313. * @param {Number} [fromIndex=0] The index to search from.
  314. * @param {Number} [largeSize=30] The length at which an array is considered large.
  315. * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
  316. */
  317. function cachedContains(array, fromIndex, largeSize) {
  318. fromIndex || (fromIndex = 0);
  319. var length = array.length,
  320. isLarge = (length - fromIndex) >= (largeSize || largeArraySize);
  321. if (isLarge) {
  322. var cache = {},
  323. index = fromIndex - 1;
  324. while (++index < length) {
  325. // manually coerce `value` to a string because `hasOwnProperty`, in some
  326. // older versions of Firefox, coerces objects incorrectly
  327. var key = array[index] + '';
  328. (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
  329. }
  330. }
  331. return function(value) {
  332. if (isLarge) {
  333. var key = value + '';
  334. return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
  335. }
  336. return indexOf(array, value, fromIndex) > -1;
  337. }
  338. }
  339. /**
  340. * Used by `_.max` and `_.min` as the default `callback` when a given
  341. * `collection` is a string value.
  342. *
  343. * @private
  344. * @param {String} value The character to inspect.
  345. * @returns {Number} Returns the code unit of given character.
  346. */
  347. function charAtCallback(value) {
  348. return value.charCodeAt(0);
  349. }
  350. /**
  351. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  352. * them in ascending order.
  353. *
  354. * @private
  355. * @param {Object} a The object to compare to `b`.
  356. * @param {Object} b The object to compare to `a`.
  357. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  358. */
  359. function compareAscending(a, b) {
  360. var ai = a.index,
  361. bi = b.index;
  362. a = a.criteria;
  363. b = b.criteria;
  364. // ensure a stable sort in V8 and other engines
  365. // http://code.google.com/p/v8/issues/detail?id=90
  366. if (a !== b) {
  367. if (a > b || typeof a == 'undefined') {
  368. return 1;
  369. }
  370. if (a < b || typeof b == 'undefined') {
  371. return -1;
  372. }
  373. }
  374. return ai < bi ? -1 : 1;
  375. }
  376. /**
  377. * Creates a function that, when called, invokes `func` with the `this` binding
  378. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  379. * bound function.
  380. *
  381. * @private
  382. * @param {Function|String} func The function to bind or the method name.
  383. * @param {Mixed} [thisArg] The `this` binding of `func`.
  384. * @param {Array} partialArgs An array of arguments to be partially applied.
  385. * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
  386. * @returns {Function} Returns the new bound function.
  387. */
  388. function createBound(func, thisArg, partialArgs, rightIndicator) {
  389. var isFunc = isFunction(func),
  390. isPartial = !partialArgs,
  391. key = thisArg;
  392. // juggle arguments
  393. if (isPartial) {
  394. partialArgs = thisArg;
  395. }
  396. if (!isFunc) {
  397. thisArg = func;
  398. }
  399. function bound() {
  400. // `Function#bind` spec
  401. // http://es5.github.com/#x15.3.4.5
  402. var args = arguments,
  403. thisBinding = isPartial ? this : thisArg;
  404. if (!isFunc) {
  405. func = thisArg[key];
  406. }
  407. if (partialArgs.length) {
  408. args = args.length
  409. ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  410. : partialArgs;
  411. }
  412. if (this instanceof bound) {
  413. // ensure `new bound` is an instance of `bound` and `func`
  414. noop.prototype = func.prototype;
  415. thisBinding = new noop;
  416. noop.prototype = null;
  417. // mimic the constructor's `return` behavior
  418. // http://es5.github.com/#x13.2.2
  419. var result = func.apply(thisBinding, args);
  420. return isObject(result) ? result : thisBinding;
  421. }
  422. return func.apply(thisBinding, args);
  423. }
  424. return bound;
  425. }
  426. /**
  427. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  428. * name, the created callback will return the property value for a given element.
  429. * If `func` is an object, the created callback will return `true` for elements
  430. * that contain the equivalent object properties, otherwise it will return `false`.
  431. *
  432. * @private
  433. * @param {Mixed} [func=identity] The value to convert to a callback.
  434. * @param {Mixed} [thisArg] The `this` binding of the created callback.
  435. * @param {Number} [argCount=3] The number of arguments the callback accepts.
  436. * @returns {Function} Returns a callback function.
  437. */
  438. function createCallback(func, thisArg, argCount) {
  439. if (func == null) {
  440. return identity;
  441. }
  442. var type = typeof func;
  443. if (type != 'function') {
  444. if (type != 'object') {
  445. return function(object) {
  446. return object[func];
  447. };
  448. }
  449. var props = keys(func);
  450. return function(object) {
  451. var length = props.length,
  452. result = false;
  453. while (length--) {
  454. if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
  455. break;
  456. }
  457. }
  458. return result;
  459. };
  460. }
  461. if (typeof thisArg != 'undefined') {
  462. if (argCount === 1) {
  463. return function(value) {
  464. return func.call(thisArg, value);
  465. };
  466. }
  467. if (argCount === 2) {
  468. return function(a, b) {
  469. return func.call(thisArg, a, b);
  470. };
  471. }
  472. if (argCount === 4) {
  473. return function(accumulator, value, index, object) {
  474. return func.call(thisArg, accumulator, value, index, object);
  475. };
  476. }
  477. return function(value, index, object) {
  478. return func.call(thisArg, value, index, object);
  479. };
  480. }
  481. return func;
  482. }
  483. /**
  484. * Creates compiled iteration functions.
  485. *
  486. * @private
  487. * @param {Object} [options1, options2, ...] The compile options object(s).
  488. * arrays - A string of code to determine if the iterable is an array or array-like.
  489. * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
  490. * args - A string of comma separated arguments the iteration function will accept.
  491. * top - A string of code to execute before the iteration branches.
  492. * loop - A string of code to execute in the object loop.
  493. * bottom - A string of code to execute after the iteration branches.
  494. *
  495. * @returns {Function} Returns the compiled function.
  496. */
  497. function createIterator() {
  498. var data = {
  499. // support properties
  500. 'isKeysFast': isKeysFast,
  501. // iterator options
  502. 'arrays': 'isArray(iterable)',
  503. 'bottom': '',
  504. 'loop': '',
  505. 'top': '',
  506. 'useHas': true
  507. };
  508. // merge options into a template data object
  509. for (var object, index = 0; object = arguments[index]; index++) {
  510. for (var key in object) {
  511. data[key] = object[key];
  512. }
  513. }
  514. var args = data.args;
  515. data.firstArg = /^[^,]+/.exec(args)[0];
  516. // create the function factory
  517. var factory = Function(
  518. 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
  519. 'objectTypes, nativeKeys',
  520. 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
  521. );
  522. // return the compiled function
  523. return factory(
  524. createCallback, hasOwnProperty, isArguments, isArray, isString,
  525. objectTypes, nativeKeys
  526. );
  527. }
  528. /**
  529. * A function compiled to iterate `arguments` objects, arrays, objects, and
  530. * strings consistenly across environments, executing the `callback` for each
  531. * element in the `collection`. The `callback` is bound to `thisArg` and invoked
  532. * with three arguments; (value, index|key, collection). Callbacks may exit
  533. * iteration early by explicitly returning `false`.
  534. *
  535. * @private
  536. * @type Function
  537. * @param {Array|Object|String} collection The collection to iterate over.
  538. * @param {Function} [callback=identity] The function called per iteration.
  539. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  540. * @returns {Array|Object|String} Returns `collection`.
  541. */
  542. var each = createIterator(eachIteratorOptions);
  543. /**
  544. * Used by `template` to escape characters for inclusion in compiled
  545. * string literals.
  546. *
  547. * @private
  548. * @param {String} match The matched character to escape.
  549. * @returns {String} Returns the escaped character.
  550. */
  551. function escapeStringChar(match) {
  552. return '\\' + stringEscapes[match];
  553. }
  554. /**
  555. * Used by `escape` to convert characters to HTML entities.
  556. *
  557. * @private
  558. * @param {String} match The matched character to escape.
  559. * @returns {String} Returns the escaped character.
  560. */
  561. function escapeHtmlChar(match) {
  562. return htmlEscapes[match];
  563. }
  564. /**
  565. * Checks if `value` is a DOM node in IE < 9.
  566. *
  567. * @private
  568. * @param {Mixed} value The value to check.
  569. * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
  570. */
  571. function isNode(value) {
  572. // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
  573. // methods that are `typeof` "string" and still can coerce nodes to strings
  574. return typeof value.toString != 'function' && typeof (value + '') == 'string';
  575. }
  576. /**
  577. * A no-operation function.
  578. *
  579. * @private
  580. */
  581. function noop() {
  582. // no operation performed
  583. }
  584. /**
  585. * Slices the `collection` from the `start` index up to, but not including,
  586. * the `end` index.
  587. *
  588. * Note: This function is used, instead of `Array#slice`, to support node lists
  589. * in IE < 9 and to ensure dense arrays are returned.
  590. *
  591. * @private
  592. * @param {Array|Object|String} collection The collection to slice.
  593. * @param {Number} start The start index.
  594. * @param {Number} end The end index.
  595. * @returns {Array} Returns the new array.
  596. */
  597. function slice(array, start, end) {
  598. start || (start = 0);
  599. if (typeof end == 'undefined') {
  600. end = array ? array.length : 0;
  601. }
  602. var index = -1,
  603. length = end - start || 0,
  604. result = Array(length < 0 ? 0 : length);
  605. while (++index < length) {
  606. result[index] = array[start + index];
  607. }
  608. return result;
  609. }
  610. /**
  611. * Used by `unescape` to convert HTML entities to characters.
  612. *
  613. * @private
  614. * @param {String} match The matched character to unescape.
  615. * @returns {String} Returns the unescaped character.
  616. */
  617. function unescapeHtmlChar(match) {
  618. return htmlUnescapes[match];
  619. }
  620. /*--------------------------------------------------------------------------*/
  621. /**
  622. * Checks if `value` is an `arguments` object.
  623. *
  624. * @static
  625. * @memberOf _
  626. * @category Objects
  627. * @param {Mixed} value The value to check.
  628. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  629. * @example
  630. *
  631. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  632. * // => true
  633. *
  634. * _.isArguments([1, 2, 3]);
  635. * // => false
  636. */
  637. function isArguments(value) {
  638. return toString.call(value) == argsClass;
  639. }
  640. /**
  641. * Iterates over `object`'s own and inherited enumerable properties, executing
  642. * the `callback` for each property. The `callback` is bound to `thisArg` and
  643. * invoked with three arguments; (value, key, object). Callbacks may exit iteration
  644. * early by explicitly returning `false`.
  645. *
  646. * @static
  647. * @memberOf _
  648. * @type Function
  649. * @category Objects
  650. * @param {Object} object The object to iterate over.
  651. * @param {Function} [callback=identity] The function called per iteration.
  652. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  653. * @returns {Object} Returns `object`.
  654. * @example
  655. *
  656. * function Dog(name) {
  657. * this.name = name;
  658. * }
  659. *
  660. * Dog.prototype.bark = function() {
  661. * alert('Woof, woof!');
  662. * };
  663. *
  664. * _.forIn(new Dog('Dagny'), function(value, key) {
  665. * alert(key);
  666. * });
  667. * // => alerts 'name' and 'bark' (order is not guaranteed)
  668. */
  669. var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
  670. 'useHas': false
  671. });
  672. /**
  673. * Iterates over an object's own enumerable properties, executing the `callback`
  674. * for each property. The `callback` is bound to `thisArg` and invoked with three
  675. * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
  676. * returning `false`.
  677. *
  678. * @static
  679. * @memberOf _
  680. * @type Function
  681. * @category Objects
  682. * @param {Object} object The object to iterate over.
  683. * @param {Function} [callback=identity] The function called per iteration.
  684. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  685. * @returns {Object} Returns `object`.
  686. * @example
  687. *
  688. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  689. * alert(key);
  690. * });
  691. * // => alerts '0', '1', and 'length' (order is not guaranteed)
  692. */
  693. var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
  694. /**
  695. * Checks if `value` is an array.
  696. *
  697. * @static
  698. * @memberOf _
  699. * @category Objects
  700. * @param {Mixed} value The value to check.
  701. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  702. * @example
  703. *
  704. * (function() { return _.isArray(arguments); })();
  705. * // => false
  706. *
  707. * _.isArray([1, 2, 3]);
  708. * // => true
  709. */
  710. var isArray = nativeIsArray || function(value) {
  711. // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
  712. // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
  713. return value instanceof Array || toString.call(value) == arrayClass;
  714. };
  715. /**
  716. * Creates an array composed of the own enumerable property names of `object`.
  717. *
  718. * @static
  719. * @memberOf _
  720. * @category Objects
  721. * @param {Object} object The object to inspect.
  722. * @returns {Array} Returns a new array of property names.
  723. * @example
  724. *
  725. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  726. * // => ['one', 'two', 'three'] (order is not guaranteed)
  727. */
  728. var keys = !nativeKeys ? shimKeys : function(object) {
  729. if (!isObject(object)) {
  730. return [];
  731. }
  732. return nativeKeys(object);
  733. };
  734. /**
  735. * A fallback implementation of `isPlainObject` that checks if a given `value`
  736. * is an object created by the `Object` constructor, assuming objects created
  737. * by the `Object` constructor have no inherited enumerable properties and that
  738. * there are no `Object.prototype` extensions.
  739. *
  740. * @private
  741. * @param {Mixed} value The value to check.
  742. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  743. */
  744. function shimIsPlainObject(value) {
  745. // avoid non-objects and false positives for `arguments` objects
  746. var result = false;
  747. if (!(value && typeof value == 'object') || isArguments(value)) {
  748. return result;
  749. }
  750. // check that the constructor is `Object` (i.e. `Object instanceof Object`)
  751. var ctor = value.constructor;
  752. if ((!isFunction(ctor)) || ctor instanceof ctor) {
  753. // In most environments an object's own properties are iterated before
  754. // its inherited properties. If the last iterated property is an object's
  755. // own property then there are no inherited enumerable properties.
  756. forIn(value, function(value, key) {
  757. result = key;
  758. });
  759. return result === false || hasOwnProperty.call(value, result);
  760. }
  761. return result;
  762. }
  763. /**
  764. * A fallback implementation of `Object.keys` that produces an array of the
  765. * given object's own enumerable property names.
  766. *
  767. * @private
  768. * @param {Object} object The object to inspect.
  769. * @returns {Array} Returns a new array of property names.
  770. */
  771. function shimKeys(object) {
  772. var result = [];
  773. forOwn(object, function(value, key) {
  774. result.push(key);
  775. });
  776. return result;
  777. }
  778. /**
  779. * Used to convert characters to HTML entities:
  780. *
  781. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  782. * don't require escaping in HTML and have no special meaning unless they're part
  783. * of a tag or an unquoted attribute value.
  784. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  785. */
  786. var htmlEscapes = {
  787. '&': '&amp;',
  788. '<': '&lt;',
  789. '>': '&gt;',
  790. '"': '&quot;',
  791. "'": '&#39;'
  792. };
  793. /** Used to convert HTML entities to characters */
  794. var htmlUnescapes = invert(htmlEscapes);
  795. /*--------------------------------------------------------------------------*/
  796. /**
  797. * Assigns own enumerable properties of source object(s) to the destination
  798. * object. Subsequent sources will overwrite propery assignments of previous
  799. * sources. If a `callback` function is passed, it will be executed to produce
  800. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  801. * two arguments; (objectValue, sourceValue).
  802. *
  803. * @static
  804. * @memberOf _
  805. * @type Function
  806. * @alias extend
  807. * @category Objects
  808. * @param {Object} object The destination object.
  809. * @param {Object} [source1, source2, ...] The source objects.
  810. * @param {Function} [callback] The function to customize assigning values.
  811. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  812. * @returns {Object} Returns the destination object.
  813. * @example
  814. *
  815. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  816. * // => { 'name': 'moe', 'age': 40 }
  817. *
  818. * var defaults = _.partialRight(_.assign, function(a, b) {
  819. * return typeof a == 'undefined' ? b : a;
  820. * });
  821. *
  822. * var food = { 'name': 'apple' };
  823. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  824. * // => { 'name': 'apple', 'type': 'fruit' }
  825. */
  826. var assign = createIterator(defaultsIteratorOptions, {
  827. 'top':
  828. defaultsIteratorOptions.top.replace(';',
  829. ';\n' +
  830. "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
  831. ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
  832. "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
  833. ' callback = args[--argsLength];\n' +
  834. '}'
  835. ),
  836. 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
  837. });
  838. /**
  839. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  840. * be cloned, otherwise they will be assigned by reference. If a `callback`
  841. * function is passed, it will be executed to produce the cloned values. If
  842. * `callback` returns `undefined`, cloning will be handled by the method instead.
  843. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  844. *
  845. * @static
  846. * @memberOf _
  847. * @category Objects
  848. * @param {Mixed} value The value to clone.
  849. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  850. * @param {Function} [callback] The function to customize cloning values.
  851. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  852. * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
  853. * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
  854. * @returns {Mixed} Returns the cloned `value`.
  855. * @example
  856. *
  857. * var stooges = [
  858. * { 'name': 'moe', 'age': 40 },
  859. * { 'name': 'larry', 'age': 50 }
  860. * ];
  861. *
  862. * var shallow = _.clone(stooges);
  863. * shallow[0] === stooges[0];
  864. * // => true
  865. *
  866. * var deep = _.clone(stooges, true);
  867. * deep[0] === stooges[0];
  868. * // => false
  869. *
  870. * _.mixin({
  871. * 'clone': _.partialRight(_.clone, function(value) {
  872. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  873. * })
  874. * });
  875. *
  876. * var clone = _.clone(document.body);
  877. * clone.childNodes.length;
  878. * // => 0
  879. */
  880. function clone(value, deep, callback, thisArg, stackA, stackB) {
  881. var result = value;
  882. // allows working with "Collections" methods without using their `callback`
  883. // argument, `index|key`, for this method's `callback`
  884. if (typeof deep == 'function') {
  885. thisArg = callback;
  886. callback = deep;
  887. deep = false;
  888. }
  889. if (typeof callback == 'function') {
  890. callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
  891. result = callback(result);
  892. var done = typeof result != 'undefined';
  893. if (!done) {
  894. result = value;
  895. }
  896. }
  897. // inspect [[Class]]
  898. var isObj = isObject(result);
  899. if (isObj) {
  900. var className = toString.call(result);
  901. if (!cloneableClasses[className]) {
  902. return result;
  903. }
  904. var isArr = isArray(result);
  905. }
  906. // shallow clone
  907. if (!isObj || !deep) {
  908. return isObj && !done
  909. ? (isArr ? slice(result) : assign({}, result))
  910. : result;
  911. }
  912. var ctor = ctorByClass[className];
  913. switch (className) {
  914. case boolClass:
  915. case dateClass:
  916. return done ? result : new ctor(+result);
  917. case numberClass:
  918. case stringClass:
  919. return done ? result : new ctor(result);
  920. case regexpClass:
  921. return done ? result : ctor(result.source, reFlags.exec(result));
  922. }
  923. // check for circular references and return corresponding clone
  924. stackA || (stackA = []);
  925. stackB || (stackB = []);
  926. var length = stackA.length;
  927. while (length--) {
  928. if (stackA[length] == value) {
  929. return stackB[length];
  930. }
  931. }
  932. // init cloned object
  933. if (!done) {
  934. result = isArr ? ctor(result.length) : {};
  935. // add array properties assigned by `RegExp#exec`
  936. if (isArr) {
  937. if (hasOwnProperty.call(value, 'index')) {
  938. result.index = value.index;
  939. }
  940. if (hasOwnProperty.call(value, 'input')) {
  941. result.input = value.input;
  942. }
  943. }
  944. }
  945. // add the source value to the stack of traversed objects
  946. // and associate it with its clone
  947. stackA.push(value);
  948. stackB.push(result);
  949. // recursively populate clone (susceptible to call stack limits)
  950. (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
  951. result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
  952. });
  953. return result;
  954. }
  955. /**
  956. * Creates a deep clone of `value`. If a `callback` function is passed, it will
  957. * be executed to produce the cloned values. If `callback` returns the value it
  958. * was passed, cloning will be handled by the method instead. The `callback` is
  959. * bound to `thisArg` and invoked with one argument; (value).
  960. *
  961. * Note: This function is loosely based on the structured clone algorithm. Functions
  962. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  963. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  964. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  965. *
  966. * @static
  967. * @memberOf _
  968. * @category Objects
  969. * @param {Mixed} value The value to deep clone.
  970. * @param {Function} [callback] The function to customize cloning values.
  971. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  972. * @returns {Mixed} Returns the deep cloned `value`.
  973. * @example
  974. *
  975. * var stooges = [
  976. * { 'name': 'moe', 'age': 40 },
  977. * { 'name': 'larry', 'age': 50 }
  978. * ];
  979. *
  980. * var deep = _.cloneDeep(stooges);
  981. * deep[0] === stooges[0];
  982. * // => false
  983. *
  984. * var view = {
  985. * 'label': 'docs',
  986. * 'node': element
  987. * };
  988. *
  989. * var clone = _.cloneDeep(view, function(value) {
  990. * return _.isElement(value) ? value.cloneNode(true) : value;
  991. * });
  992. *
  993. * clone.node == view.node;
  994. * // => false
  995. */
  996. function cloneDeep(value, callback, thisArg) {
  997. return clone(value, true, callback, thisArg);
  998. }
  999. /**
  1000. * Assigns own enumerable properties of source object(s) to the destination
  1001. * object for all destination properties that resolve to `undefined`. Once a
  1002. * property is set, additional defaults of the same property will be ignored.
  1003. *
  1004. * @static
  1005. * @memberOf _
  1006. * @type Function
  1007. * @category Objects
  1008. * @param {Object} object The destination object.
  1009. * @param {Object} [source1, source2, ...] The source objects.
  1010. * @param- {Object} [guard] Internally used to allow working with `_.reduce`
  1011. * without using its callback's `key` and `object` arguments as sources.
  1012. * @returns {Object} Returns the destination object.
  1013. * @example
  1014. *
  1015. * var food = { 'name': 'apple' };
  1016. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  1017. * // => { 'name': 'apple', 'type': 'fruit' }
  1018. */
  1019. var defaults = createIterator(defaultsIteratorOptions);
  1020. /**
  1021. * Creates a sorted array of all enumerable properties, own and inherited,
  1022. * of `object` that have function values.
  1023. *
  1024. * @static
  1025. * @memberOf _
  1026. * @alias methods
  1027. * @category Objects
  1028. * @param {Object} object The object to inspect.
  1029. * @returns {Array} Returns a new array of property names that have function values.
  1030. * @example
  1031. *
  1032. * _.functions(_);
  1033. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  1034. */
  1035. function functions(object) {
  1036. var result = [];
  1037. forIn(object, function(value, key) {
  1038. if (isFunction(value)) {
  1039. result.push(key);
  1040. }
  1041. });
  1042. return result.sort();
  1043. }
  1044. /**
  1045. * Checks if the specified object `property` exists and is a direct property,
  1046. * instead of an inherited property.
  1047. *
  1048. * @static
  1049. * @memberOf _
  1050. * @category Objects
  1051. * @param {Object} object The object to check.
  1052. * @param {String} property The property to check for.
  1053. * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
  1054. * @example
  1055. *
  1056. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  1057. * // => true
  1058. */
  1059. function has(object, property) {
  1060. return object ? hasOwnProperty.call(object, property) : false;
  1061. }
  1062. /**
  1063. * Creates an object composed of the inverted keys and values of the given `object`.
  1064. *
  1065. * @static
  1066. * @memberOf _
  1067. * @category Objects
  1068. * @param {Object} object The object to invert.
  1069. * @returns {Object} Returns the created inverted object.
  1070. * @example
  1071. *
  1072. * _.invert({ 'first': 'moe', 'second': 'larry' });
  1073. * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
  1074. */
  1075. function invert(object) {
  1076. var index = -1,
  1077. props = keys(object),
  1078. length = props.length,
  1079. result = {};
  1080. while (++index < length) {
  1081. var key = props[index];
  1082. result[object[key]] = key;
  1083. }
  1084. return result;
  1085. }
  1086. /**
  1087. * Checks if `value` is a boolean value.
  1088. *
  1089. * @static
  1090. * @memberOf _
  1091. * @category Objects
  1092. * @param {Mixed} value The value to check.
  1093. * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
  1094. * @example
  1095. *
  1096. * _.isBoolean(null);
  1097. * // => false
  1098. */
  1099. function isBoolean(value) {
  1100. return value === true || value === false || toString.call(value) == boolClass;
  1101. }
  1102. /**
  1103. * Checks if `value` is a date.
  1104. *
  1105. * @static
  1106. * @memberOf _
  1107. * @category Objects
  1108. * @param {Mixed} value The value to check.
  1109. * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
  1110. * @example
  1111. *
  1112. * _.isDate(new Date);
  1113. * // => true
  1114. */
  1115. function isDate(value) {
  1116. return value instanceof Date || toString.call(value) == dateClass;
  1117. }
  1118. /**
  1119. * Checks if `value` is a DOM element.
  1120. *
  1121. * @static
  1122. * @memberOf _
  1123. * @category Objects
  1124. * @param {Mixed} value The value to check.
  1125. * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
  1126. * @example
  1127. *
  1128. * _.isElement(document.body);
  1129. * // => true
  1130. */
  1131. function isElement(value) {
  1132. return value ? value.nodeType === 1 : false;
  1133. }
  1134. /**
  1135. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  1136. * length of `0` and objects with no own enumerable properties are considered
  1137. * "empty".
  1138. *
  1139. * @static
  1140. * @memberOf _
  1141. * @category Objects
  1142. * @param {Array|Object|String} value The value to inspect.
  1143. * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
  1144. * @example
  1145. *
  1146. * _.isEmpty([1, 2, 3]);
  1147. * // => false
  1148. *
  1149. * _.isEmpty({});
  1150. * // => true
  1151. *
  1152. * _.isEmpty('');
  1153. * // => true
  1154. */
  1155. function isEmpty(value) {
  1156. var result = true;
  1157. if (!value) {
  1158. return result;
  1159. }
  1160. var className = toString.call(value),
  1161. length = value.length;
  1162. if ((className == arrayClass || className == stringClass ||
  1163. className == argsClass) ||
  1164. (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
  1165. return !length;
  1166. }
  1167. forOwn(value, function() {
  1168. return (result = false);
  1169. });
  1170. return result;
  1171. }
  1172. /**
  1173. * Performs a deep comparison between two values to determine if they are
  1174. * equivalent to each other. If `callback` is passed, it will be executed to
  1175. * compare values. If `callback` returns `undefined`, comparisons will be handled
  1176. * by the method instead. The `callback` is bound to `thisArg` and invoked with
  1177. * two arguments; (a, b).
  1178. *
  1179. * @static
  1180. * @memberOf _
  1181. * @category Objects
  1182. * @param {Mixed} a The value to compare.
  1183. * @param {Mixed} b The other value to compare.
  1184. * @param {Function} [callback] The function to customize comparing values.
  1185. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1186. * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
  1187. * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
  1188. * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
  1189. * @example
  1190. *
  1191. * var moe = { 'name': 'moe', 'age': 40 };
  1192. * var copy = { 'name': 'moe', 'age': 40 };
  1193. *
  1194. * moe == copy;
  1195. * // => false
  1196. *
  1197. * _.isEqual(moe, copy);
  1198. * // => true
  1199. *
  1200. * var words = ['hello', 'goodbye'];
  1201. * var otherWords = ['hi', 'goodbye'];
  1202. *
  1203. * _.isEqual(words, otherWords, function(a, b) {
  1204. * var reGreet = /^(?:hello|hi)$/i,
  1205. * aGreet = _.isString(a) && reGreet.test(a),
  1206. * bGreet = _.isString(b) && reGreet.test(b);
  1207. *
  1208. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  1209. * });
  1210. * // => true
  1211. */
  1212. function isEqual(a, b, callback, thisArg, stackA, stackB) {
  1213. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  1214. var whereIndicator = callback === indicatorObject;
  1215. if (callback && !whereIndicator) {
  1216. callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
  1217. var result = callback(a, b);
  1218. if (typeof result != 'undefined') {
  1219. return !!result;
  1220. }
  1221. }
  1222. // exit early for identical values
  1223. if (a === b) {
  1224. // treat `+0` vs. `-0` as not equal
  1225. return a !== 0 || (1 / a == 1 / b);
  1226. }
  1227. var type = typeof a,
  1228. otherType = typeof b;
  1229. // exit early for unlike primitive values
  1230. if (a === a &&
  1231. (!a || (type != 'function' && type != 'object')) &&
  1232. (!b || (otherType != 'function' && otherType != 'object'))) {
  1233. return false;
  1234. }
  1235. // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
  1236. // http://es5.github.com/#x15.3.4.4
  1237. if (a == null || b == null) {
  1238. return a === b;
  1239. }
  1240. // compare [[Class]] names
  1241. var className = toString.call(a),
  1242. otherClass = toString.call(b);
  1243. if (className == argsClass) {
  1244. className = objectClass;
  1245. }
  1246. if (otherClass == argsClass) {
  1247. otherClass = objectClass;
  1248. }
  1249. if (className != otherClass) {
  1250. return false;
  1251. }
  1252. switch (className) {
  1253. case boolClass:
  1254. case dateClass:
  1255. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  1256. // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
  1257. return +a == +b;
  1258. case numberClass:
  1259. // treat `NaN` vs. `NaN` as equal
  1260. return a != +a
  1261. ? b != +b
  1262. // but treat `+0` vs. `-0` as not equal
  1263. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  1264. case regexpClass:
  1265. case stringClass:
  1266. // coerce regexes to strings (http://es5.github.com/#x15.10.6.4)
  1267. // treat string primitives and their corresponding object instances as equal
  1268. return a == b + '';
  1269. }
  1270. var isArr = className == arrayClass;
  1271. if (!isArr) {
  1272. // unwrap any `lodash` wrapped values
  1273. if (a.__wrapped__ || b.__wrapped__) {
  1274. return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
  1275. }
  1276. // exit for functions and DOM nodes
  1277. if (className != objectClass) {
  1278. return false;
  1279. }
  1280. // in older versions of Opera, `arguments` objects have `Array` constructors
  1281. var ctorA = a.constructor,
  1282. ctorB = b.constructor;
  1283. // non `Object` object instances with different constructors are not equal
  1284. if (ctorA != ctorB && !(
  1285. isFunction(ctorA) && ctorA instanceof ctorA &&
  1286. isFunction(ctorB) && ctorB instanceof ctorB
  1287. )) {
  1288. return false;
  1289. }
  1290. }
  1291. // assume cyclic structures are equal
  1292. // the algorithm for detecting cyclic structures is adapted from ES 5.1
  1293. // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
  1294. stackA || (stackA = []);
  1295. stackB || (stackB = []);
  1296. var length = stackA.length;
  1297. while (length--) {
  1298. if (stackA[length] == a) {
  1299. return stackB[length] == b;
  1300. }
  1301. }
  1302. var size = 0;
  1303. result = true;
  1304. // add `a` and `b` to the stack of traversed objects
  1305. stackA.push(a);
  1306. stackB.push(b);
  1307. // recursively compare objects and arrays (susceptible to call stack limits)
  1308. if (isArr) {
  1309. length = a.length;
  1310. size = b.length;
  1311. // compare lengths to determine if a deep comparison is necessary
  1312. result = size == a.length;
  1313. if (!result && !whereIndicator) {
  1314. return result;
  1315. }
  1316. // deep compare the contents, ignoring non-numeric properties
  1317. while (size--) {
  1318. var index = length,
  1319. value = b[size];
  1320. if (whereIndicator) {
  1321. while (index--) {
  1322. if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
  1323. break;
  1324. }
  1325. }
  1326. } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
  1327. break;
  1328. }
  1329. }
  1330. return result;
  1331. }
  1332. // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
  1333. // which, in this case, is more costly
  1334. forIn(b, function(value, key, b) {
  1335. if (hasOwnProperty.call(b, key)) {
  1336. // count the number of properties.
  1337. size++;
  1338. // deep compare each property value.
  1339. return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
  1340. }
  1341. });
  1342. if (result && !whereIndicator) {
  1343. // ensure both objects have the same number of properties
  1344. forIn(a, function(value, key, a) {
  1345. if (hasOwnProperty.call(a, key)) {
  1346. // `size` will be `-1` if `a` has more properties than `b`
  1347. return (result = --size > -1);
  1348. }
  1349. });
  1350. }
  1351. return result;
  1352. }
  1353. /**
  1354. * Checks if `value` is, or can be coerced to, a finite number.
  1355. *
  1356. * Note: This is not the same as native `isFinite`, which will return true for
  1357. * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
  1358. *
  1359. * @static
  1360. * @memberOf _
  1361. * @category Objects
  1362. * @param {Mixed} value The value to check.
  1363. * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
  1364. * @example
  1365. *
  1366. * _.isFinite(-101);
  1367. * // => true
  1368. *
  1369. * _.isFinite('10');
  1370. * // => true
  1371. *
  1372. * _.isFinite(true);
  1373. * // => false
  1374. *
  1375. * _.isFinite('');
  1376. * // => false
  1377. *
  1378. * _.isFinite(Infinity);
  1379. * // => false
  1380. */
  1381. function isFinite(value) {
  1382. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  1383. }
  1384. /**
  1385. * Checks if `value` is a function.
  1386. *
  1387. * @static
  1388. * @memberOf _
  1389. * @category Objects
  1390. * @param {Mixed} value The value to check.
  1391. * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
  1392. * @example
  1393. *
  1394. * _.isFunction(_);
  1395. * // => true
  1396. */
  1397. function isFunction(value) {
  1398. return typeof value == 'function';
  1399. }
  1400. // fallback for older versions of Chrome and Safari
  1401. if (isFunction(/x/)) {
  1402. isFunction = function(value) {
  1403. return value instanceof Function || toString.call(value) == funcClass;
  1404. };
  1405. }
  1406. /**
  1407. * Checks if `value` is the language type of Object.
  1408. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1409. *
  1410. * @static
  1411. * @memberOf _
  1412. * @category Objects
  1413. * @param {Mixed} value The value to check.
  1414. * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
  1415. * @example
  1416. *
  1417. * _.isObject({});
  1418. * // => true
  1419. *
  1420. * _.isObject([1, 2, 3]);
  1421. * // => true
  1422. *
  1423. * _.isObject(1);
  1424. * // => false
  1425. */
  1426. function isObject(value) {
  1427. // check if the value is the ECMAScript language type of Object
  1428. // http://es5.github.com/#x8
  1429. // and avoid a V8 bug
  1430. // http://code.google.com/p/v8/issues/detail?id=2291
  1431. return value ? objectTypes[typeof value] : false;
  1432. }
  1433. /**
  1434. * Checks if `value` is `NaN`.
  1435. *
  1436. * Note: This is not the same as native `isNaN`, which will return `true` for
  1437. * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
  1438. *
  1439. * @static
  1440. * @memberOf _
  1441. * @category Objects
  1442. * @param {Mixed} value The value to check.
  1443. * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
  1444. * @example
  1445. *
  1446. * _.isNaN(NaN);
  1447. * // => true
  1448. *
  1449. * _.isNaN(new Number(NaN));
  1450. * // => true
  1451. *
  1452. * isNaN(undefined);
  1453. * // => true
  1454. *
  1455. * _.isNaN(undefined);
  1456. * // => false
  1457. */