PageRenderTime 29ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

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

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