lodash-rails 1.2.1 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9089f7760c413d0fbdcce61c9c402fc9fecb166
4
- data.tar.gz: 9a4cb9209a13b45d3448839f166382aba4515064
3
+ metadata.gz: 6c3d07e40e33fc43cb27c4c2b221bee184530e91
4
+ data.tar.gz: 4f03dba97d9e3e66da1167f76b1c10eb2551f389
5
5
  SHA512:
6
- metadata.gz: 6a48be1a691143fcee7c3eb280adedf4225d5fee96969ee6377798fde1407ea9bb2e676bd29464f732784b8e1934e7624a817fef33ee66dc51b7c07293d9b426
7
- data.tar.gz: 44a4d5b5b92f68715d9d488ae77bcb39591005572facf4e93564d3086e0095bb9a4bc41eb36472a73e76334b5c842a5256631db10cc039647eab856507343497
6
+ metadata.gz: 2e3e834d09b482a5276114505827391902cd0ec7f257789f78f26f33f0e4a77f1b88b9032ab4244da30c611262e5799a1af27f2801bc014e0cf05a49e440ab0b
7
+ data.tar.gz: 4856de9a072fecc4d3b5c4cbf6a59b80e3f242f87e09098ab68c3beb6e0a297297faa85e90ff08ea9cf50ebdccee3a6e81e67a1b26d32765e4779fb7a88d7ecf
data/README.md CHANGED
@@ -18,7 +18,7 @@ Add the necessary library to `app/assets/javascripts/application.js`:
18
18
 
19
19
  ## What's included?
20
20
 
21
- Lo-Dash 1.2.1:
21
+ Lo-Dash 1.3.1:
22
22
 
23
23
  * lodash.js
24
24
  * lodash.min.js
@@ -1,5 +1,5 @@
1
1
  module LoDash
2
2
  module Rails
3
- VERSION = "1.2.1"
3
+ VERSION = "1.3.1"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Lo-Dash 1.2.1 (Custom Build) <http://lodash.com/>
3
+ * Lo-Dash 1.3.1 (Custom Build) <http://lodash.com/>
4
4
  * Build: `lodash -o ./dist/lodash.compat.js`
5
5
  * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6
6
  * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
@@ -12,17 +12,9 @@
12
12
  /** Used as a safe reference for `undefined` in pre ES5 environments */
13
13
  var undefined;
14
14
 
15
- /** Detect free variable `exports` */
16
- var freeExports = typeof exports == 'object' && exports;
17
-
18
- /** Detect free variable `module` */
19
- var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
20
-
21
- /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
22
- var freeGlobal = typeof global == 'object' && global;
23
- if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
24
- window = freeGlobal;
25
- }
15
+ /** Used to pool arrays and objects used internally */
16
+ var arrayPool = [],
17
+ objectPool = [];
26
18
 
27
19
  /** Used to generate unique IDs */
28
20
  var idCounter = 0;
@@ -34,7 +26,10 @@
34
26
  var keyPrefix = +new Date + '';
35
27
 
36
28
  /** Used as the size when optimizations are enabled for large arrays */
37
- var largeArraySize = 200;
29
+ var largeArraySize = 75;
30
+
31
+ /** Used as the max size of the `arrayPool` and `objectPool` */
32
+ var maxPoolSize = 40;
38
33
 
39
34
  /** Used to match empty string literals in compiled template source */
40
35
  var reEmptyStringLeading = /\b__p \+= '';/g,
@@ -56,6 +51,9 @@
56
51
  /** Used to match "interpolate" template delimiters */
57
52
  var reInterpolate = /<%=([\s\S]+?)%>/g;
58
53
 
54
+ /** Used to detect functions containing a `this` reference */
55
+ var reThis = (reThis = /\bthis\b/) && reThis.test(runInContext) && reThis;
56
+
59
57
  /** Used to detect and test whitespace */
60
58
  var whitespace = (
61
59
  // whitespace
@@ -82,9 +80,9 @@
82
80
 
83
81
  /** Used to assign default `context` object properties */
84
82
  var contextProps = [
85
- 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object', 'RegExp',
86
- 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', 'parseInt',
87
- 'setImmediate', 'setTimeout'
83
+ 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
84
+ 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
85
+ 'parseInt', 'setImmediate', 'setTimeout'
88
86
  ];
89
87
 
90
88
  /** Used to fix the JScript [[DontEnum]] bug */
@@ -101,6 +99,7 @@
101
99
  arrayClass = '[object Array]',
102
100
  boolClass = '[object Boolean]',
103
101
  dateClass = '[object Date]',
102
+ errorClass = '[object Error]',
104
103
  funcClass = '[object Function]',
105
104
  numberClass = '[object Number]',
106
105
  objectClass = '[object Object]',
@@ -136,6 +135,304 @@
136
135
  '\u2029': 'u2029'
137
136
  };
138
137
 
138
+ /** Detect free variable `exports` */
139
+ var freeExports = objectTypes[typeof exports] && exports;
140
+
141
+ /** Detect free variable `module` */
142
+ var freeModule = objectTypes[typeof module] && module && module.exports == freeExports && module;
143
+
144
+ /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
145
+ var freeGlobal = objectTypes[typeof global] && global;
146
+ if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
147
+ window = freeGlobal;
148
+ }
149
+
150
+ /*--------------------------------------------------------------------------*/
151
+
152
+ /**
153
+ * A basic implementation of `_.indexOf` without support for binary searches
154
+ * or `fromIndex` constraints.
155
+ *
156
+ * @private
157
+ * @param {Array} array The array to search.
158
+ * @param {Mixed} value The value to search for.
159
+ * @param {Number} [fromIndex=0] The index to search from.
160
+ * @returns {Number} Returns the index of the matched value or `-1`.
161
+ */
162
+ function basicIndexOf(array, value, fromIndex) {
163
+ var index = (fromIndex || 0) - 1,
164
+ length = array.length;
165
+
166
+ while (++index < length) {
167
+ if (array[index] === value) {
168
+ return index;
169
+ }
170
+ }
171
+ return -1;
172
+ }
173
+
174
+ /**
175
+ * An implementation of `_.contains` for cache objects that mimics the return
176
+ * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
177
+ *
178
+ * @private
179
+ * @param {Object} cache The cache object to inspect.
180
+ * @param {Mixed} value The value to search for.
181
+ * @returns {Number} Returns `0` if `value` is found, else `-1`.
182
+ */
183
+ function cacheIndexOf(cache, value) {
184
+ var type = typeof value;
185
+ cache = cache.cache;
186
+
187
+ if (type == 'boolean' || value == null) {
188
+ return cache[value];
189
+ }
190
+ if (type != 'number' && type != 'string') {
191
+ type = 'object';
192
+ }
193
+ var key = type == 'number' ? value : keyPrefix + value;
194
+ cache = cache[type] || (cache[type] = {});
195
+
196
+ return type == 'object'
197
+ ? (cache[key] && basicIndexOf(cache[key], value) > -1 ? 0 : -1)
198
+ : (cache[key] ? 0 : -1);
199
+ }
200
+
201
+ /**
202
+ * Adds a given `value` to the corresponding cache object.
203
+ *
204
+ * @private
205
+ * @param {Mixed} value The value to add to the cache.
206
+ */
207
+ function cachePush(value) {
208
+ var cache = this.cache,
209
+ type = typeof value;
210
+
211
+ if (type == 'boolean' || value == null) {
212
+ cache[value] = true;
213
+ } else {
214
+ if (type != 'number' && type != 'string') {
215
+ type = 'object';
216
+ }
217
+ var key = type == 'number' ? value : keyPrefix + value,
218
+ typeCache = cache[type] || (cache[type] = {});
219
+
220
+ if (type == 'object') {
221
+ if ((typeCache[key] || (typeCache[key] = [])).push(value) == this.array.length) {
222
+ cache[type] = false;
223
+ }
224
+ } else {
225
+ typeCache[key] = true;
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Used by `_.max` and `_.min` as the default `callback` when a given
232
+ * `collection` is a string value.
233
+ *
234
+ * @private
235
+ * @param {String} value The character to inspect.
236
+ * @returns {Number} Returns the code unit of given character.
237
+ */
238
+ function charAtCallback(value) {
239
+ return value.charCodeAt(0);
240
+ }
241
+
242
+ /**
243
+ * Used by `sortBy` to compare transformed `collection` values, stable sorting
244
+ * them in ascending order.
245
+ *
246
+ * @private
247
+ * @param {Object} a The object to compare to `b`.
248
+ * @param {Object} b The object to compare to `a`.
249
+ * @returns {Number} Returns the sort order indicator of `1` or `-1`.
250
+ */
251
+ function compareAscending(a, b) {
252
+ var ai = a.index,
253
+ bi = b.index;
254
+
255
+ a = a.criteria;
256
+ b = b.criteria;
257
+
258
+ // ensure a stable sort in V8 and other engines
259
+ // http://code.google.com/p/v8/issues/detail?id=90
260
+ if (a !== b) {
261
+ if (a > b || typeof a == 'undefined') {
262
+ return 1;
263
+ }
264
+ if (a < b || typeof b == 'undefined') {
265
+ return -1;
266
+ }
267
+ }
268
+ return ai < bi ? -1 : 1;
269
+ }
270
+
271
+ /**
272
+ * Creates a cache object to optimize linear searches of large arrays.
273
+ *
274
+ * @private
275
+ * @param {Array} [array=[]] The array to search.
276
+ * @returns {Null|Object} Returns the cache object or `null` if caching should not be used.
277
+ */
278
+ function createCache(array) {
279
+ var index = -1,
280
+ length = array.length;
281
+
282
+ var cache = getObject();
283
+ cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
284
+
285
+ var result = getObject();
286
+ result.array = array;
287
+ result.cache = cache;
288
+ result.push = cachePush;
289
+
290
+ while (++index < length) {
291
+ result.push(array[index]);
292
+ }
293
+ return cache.object === false
294
+ ? (releaseObject(result), null)
295
+ : result;
296
+ }
297
+
298
+ /**
299
+ * Used by `template` to escape characters for inclusion in compiled
300
+ * string literals.
301
+ *
302
+ * @private
303
+ * @param {String} match The matched character to escape.
304
+ * @returns {String} Returns the escaped character.
305
+ */
306
+ function escapeStringChar(match) {
307
+ return '\\' + stringEscapes[match];
308
+ }
309
+
310
+ /**
311
+ * Gets an array from the array pool or creates a new one if the pool is empty.
312
+ *
313
+ * @private
314
+ * @returns {Array} The array from the pool.
315
+ */
316
+ function getArray() {
317
+ return arrayPool.pop() || [];
318
+ }
319
+
320
+ /**
321
+ * Gets an object from the object pool or creates a new one if the pool is empty.
322
+ *
323
+ * @private
324
+ * @returns {Object} The object from the pool.
325
+ */
326
+ function getObject() {
327
+ return objectPool.pop() || {
328
+ 'args': '',
329
+ 'array': null,
330
+ 'bottom': '',
331
+ 'cache': null,
332
+ 'criteria': null,
333
+ 'false': false,
334
+ 'firstArg': '',
335
+ 'index': 0,
336
+ 'init': '',
337
+ 'leading': false,
338
+ 'loop': '',
339
+ 'maxWait': 0,
340
+ 'null': false,
341
+ 'number': null,
342
+ 'object': null,
343
+ 'push': null,
344
+ 'shadowedProps': null,
345
+ 'string': null,
346
+ 'top': '',
347
+ 'trailing': false,
348
+ 'true': false,
349
+ 'undefined': false,
350
+ 'useHas': false,
351
+ 'useKeys': false,
352
+ 'value': null
353
+ };
354
+ }
355
+
356
+ /**
357
+ * Checks if `value` is a DOM node in IE < 9.
358
+ *
359
+ * @private
360
+ * @param {Mixed} value The value to check.
361
+ * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
362
+ */
363
+ function isNode(value) {
364
+ // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
365
+ // methods that are `typeof` "string" and still can coerce nodes to strings
366
+ return typeof value.toString != 'function' && typeof (value + '') == 'string';
367
+ }
368
+
369
+ /**
370
+ * A no-operation function.
371
+ *
372
+ * @private
373
+ */
374
+ function noop() {
375
+ // no operation performed
376
+ }
377
+
378
+ /**
379
+ * Releases the given `array` back to the array pool.
380
+ *
381
+ * @private
382
+ * @param {Array} [array] The array to release.
383
+ */
384
+ function releaseArray(array) {
385
+ array.length = 0;
386
+ if (arrayPool.length < maxPoolSize) {
387
+ arrayPool.push(array);
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Releases the given `object` back to the object pool.
393
+ *
394
+ * @private
395
+ * @param {Object} [object] The object to release.
396
+ */
397
+ function releaseObject(object) {
398
+ var cache = object.cache;
399
+ if (cache) {
400
+ releaseObject(cache);
401
+ }
402
+ object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
403
+ if (objectPool.length < maxPoolSize) {
404
+ objectPool.push(object);
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Slices the `collection` from the `start` index up to, but not including,
410
+ * the `end` index.
411
+ *
412
+ * Note: This function is used, instead of `Array#slice`, to support node lists
413
+ * in IE < 9 and to ensure dense arrays are returned.
414
+ *
415
+ * @private
416
+ * @param {Array|Object|String} collection The collection to slice.
417
+ * @param {Number} start The start index.
418
+ * @param {Number} end The end index.
419
+ * @returns {Array} Returns the new array.
420
+ */
421
+ function slice(array, start, end) {
422
+ start || (start = 0);
423
+ if (typeof end == 'undefined') {
424
+ end = array ? array.length : 0;
425
+ }
426
+ var index = -1,
427
+ length = end - start || 0,
428
+ result = Array(length < 0 ? 0 : length);
429
+
430
+ while (++index < length) {
431
+ result[index] = array[start + index];
432
+ }
433
+ return result;
434
+ }
435
+
139
436
  /*--------------------------------------------------------------------------*/
140
437
 
141
438
  /**
@@ -158,6 +455,7 @@
158
455
  var Array = context.Array,
159
456
  Boolean = context.Boolean,
160
457
  Date = context.Date,
458
+ Error = context.Error,
161
459
  Function = context.Function,
162
460
  Math = context.Math,
163
461
  Number = context.Number,
@@ -166,16 +464,25 @@
166
464
  String = context.String,
167
465
  TypeError = context.TypeError;
168
466
 
169
- /** Used for `Array` and `Object` method references */
170
- var arrayRef = Array(),
171
- objectRef = Object();
467
+ /**
468
+ * Used for `Array` method references.
469
+ *
470
+ * Normally `Array.prototype` would suffice, however, using an array literal
471
+ * avoids issues in Narwhal.
472
+ */
473
+ var arrayRef = [];
474
+
475
+ /** Used for native method references */
476
+ var errorProto = Error.prototype,
477
+ objectProto = Object.prototype,
478
+ stringProto = String.prototype;
172
479
 
173
480
  /** Used to restore the original `_` reference in `noConflict` */
174
481
  var oldDash = context._;
175
482
 
176
483
  /** Used to detect if a method is native */
177
484
  var reNative = RegExp('^' +
178
- String(objectRef.valueOf)
485
+ String(objectProto.valueOf)
179
486
  .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
180
487
  .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
181
488
  );
@@ -185,15 +492,18 @@
185
492
  clearTimeout = context.clearTimeout,
186
493
  concat = arrayRef.concat,
187
494
  floor = Math.floor,
495
+ fnToString = Function.prototype.toString,
188
496
  getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
189
- hasOwnProperty = objectRef.hasOwnProperty,
497
+ hasOwnProperty = objectProto.hasOwnProperty,
190
498
  push = arrayRef.push,
499
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
191
500
  setImmediate = context.setImmediate,
192
501
  setTimeout = context.setTimeout,
193
- toString = objectRef.toString;
502
+ toString = objectProto.toString;
194
503
 
195
504
  /* Native method shortcuts for methods with the same name as other `lodash` methods */
196
505
  var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
506
+ nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
197
507
  nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
198
508
  nativeIsFinite = context.isFinite,
199
509
  nativeIsNaN = context.isNaN,
@@ -213,11 +523,31 @@
213
523
  ctorByClass[arrayClass] = Array;
214
524
  ctorByClass[boolClass] = Boolean;
215
525
  ctorByClass[dateClass] = Date;
526
+ ctorByClass[funcClass] = Function;
216
527
  ctorByClass[objectClass] = Object;
217
528
  ctorByClass[numberClass] = Number;
218
529
  ctorByClass[regexpClass] = RegExp;
219
530
  ctorByClass[stringClass] = String;
220
531
 
532
+ /** Used to avoid iterating non-enumerable properties in IE < 9 */
533
+ var nonEnumProps = {};
534
+ nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
535
+ nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
536
+ nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
537
+ nonEnumProps[objectClass] = { 'constructor': true };
538
+
539
+ (function() {
540
+ var length = shadowedProps.length;
541
+ while (length--) {
542
+ var prop = shadowedProps[length];
543
+ for (var className in nonEnumProps) {
544
+ if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], prop)) {
545
+ nonEnumProps[className][prop] = false;
546
+ }
547
+ }
548
+ }
549
+ }());
550
+
221
551
  /*--------------------------------------------------------------------------*/
222
552
 
223
553
  /**
@@ -239,8 +569,8 @@
239
569
  * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
240
570
  * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
241
571
  * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
242
- * `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `unzip`,
243
- * `values`, `where`, `without`, `wrap`, and `zip`
572
+ * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
573
+ * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
244
574
  *
245
575
  * The non-chainable wrapper functions are:
246
576
  * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
@@ -256,6 +586,7 @@
256
586
  *
257
587
  * @name _
258
588
  * @constructor
589
+ * @alias chain
259
590
  * @category Chaining
260
591
  * @param {Mixed} value The value to wrap in a `lodash` instance.
261
592
  * @returns {Object} Returns a `lodash` instance.
@@ -287,6 +618,19 @@
287
618
  : new lodashWrapper(value);
288
619
  }
289
620
 
621
+ /**
622
+ * A fast path for creating `lodash` wrapper objects.
623
+ *
624
+ * @private
625
+ * @param {Mixed} value The value to wrap in a `lodash` instance.
626
+ * @returns {Object} Returns a `lodash` instance.
627
+ */
628
+ function lodashWrapper(value) {
629
+ this.__wrapped__ = value;
630
+ }
631
+ // ensure `new lodashWrapper` is an instance of `lodash`
632
+ lodashWrapper.prototype = lodash.prototype;
633
+
290
634
  /**
291
635
  * An object used to flag environments features.
292
636
  *
@@ -321,6 +665,15 @@
321
665
  */
322
666
  support.argsClass = isArguments(arguments);
323
667
 
668
+ /**
669
+ * Detect if `name` or `message` properties of `Error.prototype` are
670
+ * enumerable by default. (IE < 9, Safari < 5.1)
671
+ *
672
+ * @memberOf _.support
673
+ * @type Boolean
674
+ */
675
+ support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
676
+
324
677
  /**
325
678
  * Detect if `prototype` properties are enumerable by default.
326
679
  *
@@ -332,7 +685,7 @@
332
685
  * @memberOf _.support
333
686
  * @type Boolean
334
687
  */
335
- support.enumPrototypes = ctor.propertyIsEnumerable('prototype');
688
+ support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
336
689
 
337
690
  /**
338
691
  * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
@@ -488,77 +841,80 @@
488
841
  (obj.init) +
489
842
  ';\nif (!iterable) return result;\n' +
490
843
  (obj.top) +
491
- ';\n';
492
- if (obj.arrays) {
493
- __p += 'var length = iterable.length; index = -1;\nif (' +
494
- (obj.arrays) +
844
+ ';';
845
+ if (obj.array) {
846
+ __p += '\nvar length = iterable.length; index = -1;\nif (' +
847
+ (obj.array) +
495
848
  ') { ';
496
849
  if (support.unindexedChars) {
497
850
  __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
498
851
  }
499
852
  __p += '\n while (++index < length) {\n ' +
500
853
  (obj.loop) +
501
- '\n }\n}\nelse { ';
502
- } else if (support.nonEnumArgs) {
854
+ ';\n }\n}\nelse { ';
855
+ } else if (support.nonEnumArgs) {
503
856
  __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
504
857
  (obj.loop) +
505
- '\n }\n } else { ';
858
+ ';\n }\n } else { ';
506
859
  }
507
860
 
508
861
  if (support.enumPrototypes) {
509
862
  __p += '\n var skipProto = typeof iterable == \'function\';\n ';
510
863
  }
511
864
 
865
+ if (support.enumErrorProps) {
866
+ __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
867
+ }
868
+
869
+ var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
870
+
512
871
  if (obj.useHas && obj.useKeys) {
513
- __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? keys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n ';
514
- if (support.enumPrototypes) {
515
- __p += 'if (!(skipProto && index == \'prototype\')) {\n ';
872
+ __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
873
+ if (conditions.length) {
874
+ __p += ' if (' +
875
+ (conditions.join(' && ')) +
876
+ ') {\n ';
516
877
  }
517
878
  __p +=
518
- (obj.loop);
519
- if (support.enumPrototypes) {
520
- __p += '}\n';
879
+ (obj.loop) +
880
+ '; ';
881
+ if (conditions.length) {
882
+ __p += '\n }';
521
883
  }
522
- __p += ' } ';
884
+ __p += '\n } ';
523
885
  } else {
524
- __p += '\n for (index in iterable) {';
525
- if (support.enumPrototypes || obj.useHas) {
526
- __p += '\n if (';
527
- if (support.enumPrototypes) {
528
- __p += '!(skipProto && index == \'prototype\')';
529
- } if (support.enumPrototypes && obj.useHas) {
530
- __p += ' && ';
531
- } if (obj.useHas) {
532
- __p += 'hasOwnProperty.call(iterable, index)';
533
- }
534
- __p += ') { ';
886
+ __p += '\n for (index in iterable) {\n';
887
+ if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
888
+ __p += ' if (' +
889
+ (conditions.join(' && ')) +
890
+ ') {\n ';
535
891
  }
536
892
  __p +=
537
893
  (obj.loop) +
538
894
  '; ';
539
- if (support.enumPrototypes || obj.useHas) {
895
+ if (conditions.length) {
540
896
  __p += '\n }';
541
897
  }
542
898
  __p += '\n } ';
543
899
  if (support.nonEnumShadows) {
544
- __p += '\n\n var ctor = iterable.constructor;\n ';
545
- for (var k = 0; k < 7; k++) {
546
- __p += '\n index = \'' +
900
+ __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
901
+ for (k = 0; k < 7; k++) {
902
+ __p += '\n index = \'' +
547
903
  (obj.shadowedProps[k]) +
548
- '\';\n if (';
549
- if (obj.shadowedProps[k] == 'constructor') {
550
- __p += '!(ctor && ctor.prototype === iterable) && ';
551
- }
552
- __p += 'hasOwnProperty.call(iterable, index)) {\n ' +
904
+ '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
905
+ if (!obj.useHas) {
906
+ __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
907
+ }
908
+ __p += ') {\n ' +
553
909
  (obj.loop) +
554
- '\n } ';
910
+ ';\n } ';
555
911
  }
556
-
912
+ __p += '\n } ';
557
913
  }
558
914
 
559
915
  }
560
916
 
561
- if (obj.arrays || support.nonEnumArgs) {
917
+ if (obj.array || support.nonEnumArgs) {
562
918
  __p += '\n}';
563
919
  }
564
920
  __p +=
@@ -586,90 +942,18 @@
586
942
  var eachIteratorOptions = {
587
943
  'args': 'collection, callback, thisArg',
588
944
  'top': "callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg)",
589
- 'arrays': "typeof length == 'number'",
945
+ 'array': "typeof length == 'number'",
590
946
  'loop': 'if (callback(iterable[index], index, collection) === false) return result'
591
947
  };
592
948
 
593
949
  /** Reusable iterator options for `forIn` and `forOwn` */
594
950
  var forOwnIteratorOptions = {
595
951
  'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
596
- 'arrays': false
952
+ 'array': false
597
953
  };
598
954
 
599
955
  /*--------------------------------------------------------------------------*/
600
956
 
601
- /**
602
- * Creates a function optimized to search large arrays for a given `value`,
603
- * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
604
- *
605
- * @private
606
- * @param {Array} array The array to search.
607
- * @param {Mixed} value The value to search for.
608
- * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
609
- */
610
- function cachedContains(array) {
611
- var length = array.length,
612
- isLarge = length >= largeArraySize;
613
-
614
- if (isLarge) {
615
- var cache = {},
616
- index = -1;
617
-
618
- while (++index < length) {
619
- var key = keyPrefix + array[index];
620
- (cache[key] || (cache[key] = [])).push(array[index]);
621
- }
622
- }
623
- return function(value) {
624
- if (isLarge) {
625
- var key = keyPrefix + value;
626
- return cache[key] && indexOf(cache[key], value) > -1;
627
- }
628
- return indexOf(array, value) > -1;
629
- }
630
- }
631
-
632
- /**
633
- * Used by `_.max` and `_.min` as the default `callback` when a given
634
- * `collection` is a string value.
635
- *
636
- * @private
637
- * @param {String} value The character to inspect.
638
- * @returns {Number} Returns the code unit of given character.
639
- */
640
- function charAtCallback(value) {
641
- return value.charCodeAt(0);
642
- }
643
-
644
- /**
645
- * Used by `sortBy` to compare transformed `collection` values, stable sorting
646
- * them in ascending order.
647
- *
648
- * @private
649
- * @param {Object} a The object to compare to `b`.
650
- * @param {Object} b The object to compare to `a`.
651
- * @returns {Number} Returns the sort order indicator of `1` or `-1`.
652
- */
653
- function compareAscending(a, b) {
654
- var ai = a.index,
655
- bi = b.index;
656
-
657
- a = a.criteria;
658
- b = b.criteria;
659
-
660
- // ensure a stable sort in V8 and other engines
661
- // http://code.google.com/p/v8/issues/detail?id=90
662
- if (a !== b) {
663
- if (a > b || typeof a == 'undefined') {
664
- return 1;
665
- }
666
- if (a < b || typeof b == 'undefined') {
667
- return -1;
668
- }
669
- }
670
- return ai < bi ? -1 : 1;
671
- }
672
-
673
957
  /**
674
958
  * Creates a function that, when called, invokes `func` with the `this` binding
675
959
  * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
@@ -716,9 +1000,7 @@
716
1000
  }
717
1001
  if (this instanceof bound) {
718
1002
  // ensure `new bound` is an instance of `func`
719
- noop.prototype = func.prototype;
720
- thisBinding = new noop;
721
- noop.prototype = null;
1003
+ thisBinding = createObject(func.prototype);
722
1004
 
723
1005
  // mimic the constructor's `return` behavior
724
1006
  // http://es5.github.com/#x13.2.2
@@ -735,7 +1017,7 @@
735
1017
  *
736
1018
  * @private
737
1019
  * @param {Object} [options1, options2, ...] The compile options object(s).
738
- * arrays - A string of code to determine if the iterable is an array or array-like.
1020
+ * array - A string of code to determine if the iterable is an array or array-like.
739
1021
  * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
740
1022
  * useKeys - A boolean to specify using `_.keys` for own property iteration.
741
1023
  * args - A string of comma separated arguments the iteration function will accept.
@@ -745,18 +1027,15 @@
745
1027
  * @returns {Function} Returns the compiled function.
746
1028
  */
747
1029
  function createIterator() {
748
- var data = {
749
- // data properties
750
- 'shadowedProps': shadowedProps,
751
- // iterator options
752
- 'arrays': 'isArray(iterable)',
753
- 'bottom': '',
754
- 'init': 'iterable',
755
- 'loop': '',
756
- 'top': '',
757
- 'useHas': true,
758
- 'useKeys': !!keys
759
- };
1030
+ var data = getObject();
1031
+
1032
+ // data properties
1033
+ data.shadowedProps = shadowedProps;
1034
+ // iterator options
1035
+ data.array = data.bottom = data.loop = data.top = '';
1036
+ data.init = 'iterable';
1037
+ data.useHas = true;
1038
+ data.useKeys = !!keys;
760
1039
 
761
1040
  // merge options into a template data object
762
1041
  for (var object, index = 0; object = arguments[index]; index++) {
@@ -769,27 +1048,42 @@
769
1048
 
770
1049
  // create the function factory
771
1050
  var factory = Function(
772
- 'hasOwnProperty, isArguments, isArray, isString, keys, ' +
773
- 'lodash, objectTypes',
1051
+ 'errorClass, errorProto, hasOwnProperty, isArguments, isArray, ' +
1052
+ 'isString, keys, lodash, objectProto, objectTypes, nonEnumProps, ' +
1053
+ 'stringClass, stringProto, toString',
774
1054
  'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
775
1055
  );
1056
+
1057
+ releaseObject(data);
1058
+
776
1059
  // return the compiled function
777
1060
  return factory(
778
- hasOwnProperty, isArguments, isArray, isString, keys,
779
- lodash, objectTypes
1061
+ errorClass, errorProto, hasOwnProperty, isArguments, isArray,
1062
+ isString, keys, lodash, objectProto, objectTypes, nonEnumProps,
1063
+ stringClass, stringProto, toString
780
1064
  );
781
1065
  }
782
1066
 
783
1067
  /**
784
- * Used by `template` to escape characters for inclusion in compiled
785
- * string literals.
1068
+ * Creates a new object with the specified `prototype`.
786
1069
  *
787
1070
  * @private
788
- * @param {String} match The matched character to escape.
789
- * @returns {String} Returns the escaped character.
1071
+ * @param {Object} prototype The prototype object.
1072
+ * @returns {Object} Returns the new object.
790
1073
  */
791
- function escapeStringChar(match) {
792
- return '\\' + stringEscapes[match];
1074
+ function createObject(prototype) {
1075
+ return isObject(prototype) ? nativeCreate(prototype) : {};
1076
+ }
1077
+ // fallback for browsers without `Object.create`
1078
+ if (!nativeCreate) {
1079
+ var createObject = function(prototype) {
1080
+ if (isObject(prototype)) {
1081
+ noop.prototype = prototype;
1082
+ var result = new noop;
1083
+ noop.prototype = null;
1084
+ }
1085
+ return result || {};
1086
+ };
793
1087
  }
794
1088
 
795
1089
  /**
@@ -804,38 +1098,39 @@
804
1098
  }
805
1099
 
806
1100
  /**
807
- * Checks if `value` is a DOM node in IE < 9.
1101
+ * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
1102
+ * customized, this method returns the custom method, otherwise it returns
1103
+ * the `basicIndexOf` function.
808
1104
  *
809
1105
  * @private
810
- * @param {Mixed} value The value to check.
811
- * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
1106
+ * @returns {Function} Returns the "indexOf" function.
812
1107
  */
813
- function isNode(value) {
814
- // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
815
- // methods that are `typeof` "string" and still can coerce nodes to strings
816
- return typeof value.toString != 'function' && typeof (value + '') == 'string';
817
- }
818
-
819
- /**
820
- * A fast path for creating `lodash` wrapper objects.
821
- *
822
- * @private
823
- * @param {Mixed} value The value to wrap in a `lodash` instance.
824
- * @returns {Object} Returns a `lodash` instance.
825
- */
826
- function lodashWrapper(value) {
827
- this.__wrapped__ = value;
1108
+ function getIndexOf(array, value, fromIndex) {
1109
+ var result = (result = lodash.indexOf) === indexOf ? basicIndexOf : result;
1110
+ return result;
828
1111
  }
829
- // ensure `new lodashWrapper` is an instance of `lodash`
830
- lodashWrapper.prototype = lodash.prototype;
831
1112
 
832
1113
  /**
833
- * A no-operation function.
1114
+ * Creates a function that juggles arguments, allowing argument overloading
1115
+ * for `_.flatten` and `_.uniq`, before passing them to the given `func`.
834
1116
  *
835
1117
  * @private
1118
+ * @param {Function} func The function to wrap.
1119
+ * @returns {Function} Returns the new function.
836
1120
  */
837
- function noop() {
838
- // no operation performed
1121
+ function overloadWrapper(func) {
1122
+ return function(array, flag, callback, thisArg) {
1123
+ // juggle arguments
1124
+ if (typeof flag != 'boolean' && flag != null) {
1125
+ thisArg = callback;
1126
+ callback = !(thisArg && thisArg[flag] === array) ? flag : undefined;
1127
+ flag = false;
1128
+ }
1129
+ if (callback != null) {
1130
+ callback = lodash.createCallback(callback, thisArg);
1131
+ }
1132
+ return func(array, flag, callback, thisArg);
1133
+ };
839
1134
  }
840
1135
 
841
1136
  /**
@@ -849,62 +1144,33 @@
849
1144
  * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
850
1145
  */
851
1146
  function shimIsPlainObject(value) {
852
- // avoid non-objects and false positives for `arguments` objects
853
- var result = false;
854
- if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
855
- return result;
856
- }
857
- // check that the constructor is `Object` (i.e. `Object instanceof Object`)
858
- var ctor = value.constructor;
859
-
860
- if (isFunction(ctor) ? ctor instanceof ctor : (support.nodeClass || !isNode(value))) {
861
- // IE < 9 iterates inherited properties before own properties. If the first
862
- // iterated property is an object's own property then there are no inherited
863
- // enumerable properties.
864
- if (support.ownLast) {
865
- forIn(value, function(value, key, object) {
866
- result = hasOwnProperty.call(object, key);
867
- return false;
868
- });
869
- return result === true;
870
- }
871
- // In most environments an object's own properties are iterated before
872
- // its inherited properties. If the last iterated property is an object's
873
- // own property then there are no inherited enumerable properties.
874
- forIn(value, function(value, key) {
875
- result = key;
876
- });
877
- return result === false || hasOwnProperty.call(value, result);
878
- }
879
- return result;
880
- }
1147
+ var ctor,
1148
+ result;
881
1149
 
882
- /**
883
- * Slices the `collection` from the `start` index up to, but not including,
884
- * the `end` index.
885
- *
886
- * Note: This function is used, instead of `Array#slice`, to support node lists
887
- * in IE < 9 and to ensure dense arrays are returned.
888
- *
889
- * @private
890
- * @param {Array|Object|String} collection The collection to slice.
891
- * @param {Number} start The start index.
892
- * @param {Number} end The end index.
893
- * @returns {Array} Returns the new array.
894
- */
895
- function slice(array, start, end) {
896
- start || (start = 0);
897
- if (typeof end == 'undefined') {
898
- end = array ? array.length : 0;
1150
+ // avoid non Object objects, `arguments` objects, and DOM elements
1151
+ if (!(value && toString.call(value) == objectClass) ||
1152
+ (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
1153
+ (!support.argsClass && isArguments(value)) ||
1154
+ (!support.nodeClass && isNode(value))) {
1155
+ return false;
899
1156
  }
900
- var index = -1,
901
- length = end - start || 0,
902
- result = Array(length < 0 ? 0 : length);
903
-
904
- while (++index < length) {
905
- result[index] = array[start + index];
1157
+ // IE < 9 iterates inherited properties before own properties. If the first
1158
+ // iterated property is an object's own property then there are no inherited
1159
+ // enumerable properties.
1160
+ if (support.ownLast) {
1161
+ forIn(value, function(value, key, object) {
1162
+ result = hasOwnProperty.call(object, key);
1163
+ return false;
1164
+ });
1165
+ return result !== false;
906
1166
  }
907
- return result;
1167
+ // In most environments an object's own properties are iterated before
1168
+ // its inherited properties. If the last iterated property is an object's
1169
+ // own property then there are no inherited enumerable properties.
1170
+ forIn(value, function(value, key) {
1171
+ result = key;
1172
+ });
1173
+ return result === undefined || hasOwnProperty.call(value, result);
908
1174
  }
909
1175
 
910
1176
  /**
@@ -979,8 +1245,7 @@
979
1245
  'args': 'object',
980
1246
  'init': '[]',
981
1247
  'top': 'if (!(objectTypes[typeof object])) return result',
982
- 'loop': 'result.push(index)',
983
- 'arrays': false
1248
+ 'loop': 'result.push(index)'
984
1249
  });
985
1250
 
986
1251
  /**
@@ -1021,7 +1286,7 @@
1021
1286
  * @param {Mixed} [thisArg] The `this` binding of `callback`.
1022
1287
  * @returns {Array|Object|String} Returns `collection`.
1023
1288
  */
1024
- var each = createIterator(eachIteratorOptions);
1289
+ var basicEach = createIterator(eachIteratorOptions);
1025
1290
 
1026
1291
  /**
1027
1292
  * Used to convert characters to HTML entities:
@@ -1134,7 +1399,7 @@
1134
1399
 
1135
1400
  // allows working with "Collections" methods without using their `callback`
1136
1401
  // argument, `index|key`, for this method's `callback`
1137
- if (typeof deep == 'function') {
1402
+ if (typeof deep != 'boolean' && deep != null) {
1138
1403
  thisArg = callback;
1139
1404
  callback = deep;
1140
1405
  deep = false;
@@ -1179,8 +1444,9 @@
1179
1444
  return ctor(result.source, reFlags.exec(result));
1180
1445
  }
1181
1446
  // check for circular references and return corresponding clone
1182
- stackA || (stackA = []);
1183
- stackB || (stackB = []);
1447
+ var initedStack = !stackA;
1448
+ stackA || (stackA = getArray());
1449
+ stackB || (stackB = getArray());
1184
1450
 
1185
1451
  var length = stackA.length;
1186
1452
  while (length--) {
@@ -1206,10 +1472,14 @@
1206
1472
  stackB.push(result);
1207
1473
 
1208
1474
  // recursively populate clone (susceptible to call stack limits)
1209
- (isArr ? forEach : forOwn)(value, function(objValue, key) {
1475
+ (isArr ? basicEach : forOwn)(value, function(objValue, key) {
1210
1476
  result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
1211
1477
  });
1212
1478
 
1479
+ if (initedStack) {
1480
+ releaseArray(stackA);
1481
+ releaseArray(stackB);
1482
+ }
1213
1483
  return result;
1214
1484
  }
1215
1485
 
@@ -1219,7 +1489,7 @@
1219
1489
  * `undefined`, cloning will be handled by the method instead. The `callback`
1220
1490
  * is bound to `thisArg` and invoked with one argument; (value).
1221
1491
  *
1222
- * Note: This function is loosely based on the structured clone algorithm. Functions
1492
+ * Note: This method is loosely based on the structured clone algorithm. Functions
1223
1493
  * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1224
1494
  * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1225
1495
  * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
@@ -1656,8 +1926,9 @@
1656
1926
  // assume cyclic structures are equal
1657
1927
  // the algorithm for detecting cyclic structures is adapted from ES 5.1
1658
1928
  // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
1659
- stackA || (stackA = []);
1660
- stackB || (stackB = []);
1929
+ var initedStack = !stackA;
1930
+ stackA || (stackA = getArray());
1931
+ stackB || (stackB = getArray());
1661
1932
 
1662
1933
  var length = stackA.length;
1663
1934
  while (length--) {
@@ -1719,6 +1990,10 @@
1719
1990
  }
1720
1991
  });
1721
1992
  }
1993
+ if (initedStack) {
1994
+ releaseArray(stackA);
1995
+ releaseArray(stackB);
1996
+ }
1722
1997
  return result;
1723
1998
  }
1724
1999
 
@@ -1802,7 +2077,7 @@
1802
2077
  // http://es5.github.com/#x8
1803
2078
  // and avoid a V8 bug
1804
2079
  // http://code.google.com/p/v8/issues/detail?id=2291
1805
- return value ? objectTypes[typeof value] : false;
2080
+ return !!(value && objectTypes[typeof value]);
1806
2081
  }
1807
2082
 
1808
2083
  /**
@@ -1923,7 +2198,7 @@
1923
2198
  * // => true
1924
2199
  */
1925
2200
  function isRegExp(value) {
1926
- return value ? (objectTypes[typeof value] && toString.call(value) == regexpClass) : false;
2201
+ return !!(value && objectTypes[typeof value]) && toString.call(value) == regexpClass;
1927
2202
  }
1928
2203
 
1929
2204
  /**
@@ -2028,8 +2303,9 @@
2028
2303
  stackA = args[4],
2029
2304
  stackB = args[5];
2030
2305
  } else {
2031
- stackA = [];
2032
- stackB = [];
2306
+ var initedStack = true;
2307
+ stackA = getArray();
2308
+ stackB = getArray();
2033
2309
 
2034
2310
  // allows working with `_.reduce` and `_.reduceRight` without
2035
2311
  // using their `callback` arguments, `index|key` and `collection`
@@ -2095,6 +2371,11 @@
2095
2371
  object[key] = value;
2096
2372
  });
2097
2373
  }
2374
+
2375
+ if (initedStack) {
2376
+ releaseArray(stackA);
2377
+ releaseArray(stackB);
2378
+ }
2098
2379
  return object;
2099
2380
  }
2100
2381
 
@@ -2125,7 +2406,8 @@
2125
2406
  * // => { 'name': 'moe' }
2126
2407
  */
2127
2408
  function omit(object, callback, thisArg) {
2128
- var isFunc = typeof callback == 'function',
2409
+ var indexOf = getIndexOf(),
2410
+ isFunc = typeof callback == 'function',
2129
2411
  result = {};
2130
2412
 
2131
2413
  if (isFunc) {
@@ -2220,6 +2502,57 @@
2220
2502
  return result;
2221
2503
  }
2222
2504
 
2505
+ /**
2506
+ * An alternative to `_.reduce`, this method transforms an `object` to a new
2507
+ * `accumulator` object which is the result of running each of its elements
2508
+ * through the `callback`, with each `callback` execution potentially mutating
2509
+ * the `accumulator` object. The `callback` is bound to `thisArg` and invoked
2510
+ * with four arguments; (accumulator, value, key, object). Callbacks may exit
2511
+ * iteration early by explicitly returning `false`.
2512
+ *
2513
+ * @static
2514
+ * @memberOf _
2515
+ * @category Objects
2516
+ * @param {Array|Object} collection The collection to iterate over.
2517
+ * @param {Function} [callback=identity] The function called per iteration.
2518
+ * @param {Mixed} [accumulator] The custom accumulator value.
2519
+ * @param {Mixed} [thisArg] The `this` binding of `callback`.
2520
+ * @returns {Mixed} Returns the accumulated value.
2521
+ * @example
2522
+ *
2523
+ * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
2524
+ * num *= num;
2525
+ * if (num % 2) {
2526
+ * return result.push(num) < 3;
2527
+ * }
2528
+ * });
2529
+ * // => [1, 9, 25]
2530
+ *
2531
+ * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2532
+ * result[key] = num * 3;
2533
+ * });
2534
+ * // => { 'a': 3, 'b': 6, 'c': 9 }
2535
+ */
2536
+ function transform(object, callback, accumulator, thisArg) {
2537
+ var isArr = isArray(object);
2538
+ callback = lodash.createCallback(callback, thisArg, 4);
2539
+
2540
+ if (accumulator == null) {
2541
+ if (isArr) {
2542
+ accumulator = [];
2543
+ } else {
2544
+ var ctor = object && object.constructor,
2545
+ proto = ctor && ctor.prototype;
2546
+
2547
+ accumulator = createObject(proto);
2548
+ }
2549
+ }
2550
+ (isArr ? basicEach : forOwn)(object, function(value, index, object) {
2551
+ return callback(accumulator, value, index, object);
2552
+ });
2553
+ return accumulator;
2554
+ }
2555
+
2223
2556
  /**
2224
2557
  * Creates an array composed of the own enumerable property values of `object`.
2225
2558
  *
@@ -2312,17 +2645,18 @@
2312
2645
  */
2313
2646
  function contains(collection, target, fromIndex) {
2314
2647
  var index = -1,
2648
+ indexOf = getIndexOf(),
2315
2649
  length = collection ? collection.length : 0,
2316
2650
  result = false;
2317
2651
 
2318
2652
  fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2319
- if (typeof length == 'number') {
2653
+ if (length && typeof length == 'number') {
2320
2654
  result = (isString(collection)
2321
2655
  ? collection.indexOf(target, fromIndex)
2322
2656
  : indexOf(collection, target, fromIndex)
2323
2657
  ) > -1;
2324
2658
  } else {
2325
- each(collection, function(value) {
2659
+ basicEach(collection, function(value) {
2326
2660
  if (++index >= fromIndex) {
2327
2661
  return !(result = value === target);
2328
2662
  }
@@ -2430,7 +2764,7 @@
2430
2764
  }
2431
2765
  }
2432
2766
  } else {
2433
- each(collection, function(value, index, collection) {
2767
+ basicEach(collection, function(value, index, collection) {
2434
2768
  return (result = !!callback(value, index, collection));
2435
2769
  });
2436
2770
  }
@@ -2492,7 +2826,7 @@
2492
2826
  }
2493
2827
  }
2494
2828
  } else {
2495
- each(collection, function(value, index, collection) {
2829
+ basicEach(collection, function(value, index, collection) {
2496
2830
  if (callback(value, index, collection)) {
2497
2831
  result.push(value);
2498
2832
  }
@@ -2515,7 +2849,7 @@
2515
2849
  *
2516
2850
  * @static
2517
2851
  * @memberOf _
2518
- * @alias detect
2852
+ * @alias detect, findWhere
2519
2853
  * @category Collections
2520
2854
  * @param {Array|Object|String} collection The collection to iterate over.
2521
2855
  * @param {Function|Object|String} [callback=identity] The function called per
@@ -2559,7 +2893,7 @@
2559
2893
  }
2560
2894
  } else {
2561
2895
  var result;
2562
- each(collection, function(value, index, collection) {
2896
+ basicEach(collection, function(value, index, collection) {
2563
2897
  if (callback(value, index, collection)) {
2564
2898
  result = value;
2565
2899
  return false;
@@ -2602,7 +2936,7 @@
2602
2936
  }
2603
2937
  }
2604
2938
  } else {
2605
- each(collection, callback, thisArg);
2939
+ basicEach(collection, callback, thisArg);
2606
2940
  }
2607
2941
  return collection;
2608
2942
  }
@@ -2737,7 +3071,7 @@
2737
3071
  result[index] = callback(collection[index], index, collection);
2738
3072
  }
2739
3073
  } else {
2740
- each(collection, function(value, key, collection) {
3074
+ basicEach(collection, function(value, key, collection) {
2741
3075
  result[++index] = callback(value, key, collection);
2742
3076
  });
2743
3077
  }
@@ -2802,7 +3136,7 @@
2802
3136
  ? charAtCallback
2803
3137
  : lodash.createCallback(callback, thisArg);
2804
3138
 
2805
- each(collection, function(value, index, collection) {
3139
+ basicEach(collection, function(value, index, collection) {
2806
3140
  var current = callback(value, index, collection);
2807
3141
  if (current > computed) {
2808
3142
  computed = current;
@@ -2871,7 +3205,7 @@
2871
3205
  ? charAtCallback
2872
3206
  : lodash.createCallback(callback, thisArg);
2873
3207
 
2874
- each(collection, function(value, index, collection) {
3208
+ basicEach(collection, function(value, index, collection) {
2875
3209
  var current = callback(value, index, collection);
2876
3210
  if (current < computed) {
2877
3211
  computed = current;
@@ -2949,7 +3283,7 @@
2949
3283
  accumulator = callback(accumulator, collection[index], index, collection);
2950
3284
  }
2951
3285
  } else {
2952
- each(collection, function(value, index, collection) {
3286
+ basicEach(collection, function(value, index, collection) {
2953
3287
  accumulator = noaccum
2954
3288
  ? (noaccum = false, value)
2955
3289
  : callback(accumulator, value, index, collection)
@@ -3152,7 +3486,7 @@
3152
3486
  }
3153
3487
  }
3154
3488
  } else {
3155
- each(collection, function(value, index, collection) {
3489
+ basicEach(collection, function(value, index, collection) {
3156
3490
  return !(result = callback(value, index, collection));
3157
3491
  });
3158
3492
  }
@@ -3201,17 +3535,18 @@
3201
3535
 
3202
3536
  callback = lodash.createCallback(callback, thisArg);
3203
3537
  forEach(collection, function(value, key, collection) {
3204
- result[++index] = {
3205
- 'criteria': callback(value, key, collection),
3206
- 'index': index,
3207
- 'value': value
3208
- };
3538
+ var object = result[++index] = getObject();
3539
+ object.criteria = callback(value, key, collection);
3540
+ object.index = index;
3541
+ object.value = value;
3209
3542
  });
3210
3543
 
3211
3544
  length = result.length;
3212
3545
  result.sort(compareAscending);
3213
3546
  while (length--) {
3214
- result[length] = result[length].value;
3547
+ var object = result[length];
3548
+ result[length] = object.value;
3549
+ releaseObject(object);
3215
3550
  }
3216
3551
  return result;
3217
3552
  }
@@ -3311,17 +3646,31 @@
3311
3646
  */
3312
3647
  function difference(array) {
3313
3648
  var index = -1,
3649
+ indexOf = getIndexOf(),
3314
3650
  length = array ? array.length : 0,
3315
- flattened = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
3316
- contains = cachedContains(flattened),
3651
+ seen = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
3317
3652
  result = [];
3318
3653
 
3654
+ var isLarge = length >= largeArraySize && indexOf === basicIndexOf;
3655
+
3656
+ if (isLarge) {
3657
+ var cache = createCache(seen);
3658
+ if (cache) {
3659
+ indexOf = cacheIndexOf;
3660
+ seen = cache;
3661
+ } else {
3662
+ isLarge = false;
3663
+ }
3664
+ }
3319
3665
  while (++index < length) {
3320
3666
  var value = array[index];
3321
- if (!contains(value)) {
3667
+ if (indexOf(seen, value) < 0) {
3322
3668
  result.push(value);
3323
3669
  }
3324
3670
  }
3671
+ if (isLarge) {
3672
+ releaseObject(seen);
3673
+ }
3325
3674
  return result;
3326
3675
  }
3327
3676
 
@@ -3477,20 +3826,11 @@
3477
3826
  * _.flatten(stooges, 'quotes');
3478
3827
  * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
3479
3828
  */
3480
- function flatten(array, isShallow, callback, thisArg) {
3829
+ var flatten = overloadWrapper(function flatten(array, isShallow, callback) {
3481
3830
  var index = -1,
3482
3831
  length = array ? array.length : 0,
3483
3832
  result = [];
3484
3833
 
3485
- // juggle arguments
3486
- if (typeof isShallow != 'boolean' && isShallow != null) {
3487
- thisArg = callback;
3488
- callback = isShallow;
3489
- isShallow = false;
3490
- }
3491
- if (callback != null) {
3492
- callback = lodash.createCallback(callback, thisArg);
3493
- }
3494
3834
  while (++index < length) {
3495
3835
  var value = array[index];
3496
3836
  if (callback) {
@@ -3504,7 +3844,7 @@
3504
3844
  }
3505
3845
  }
3506
3846
  return result;
3507
- }
3847
+ });
3508
3848
 
3509
3849
  /**
3510
3850
  * Gets the index at which the first occurrence of `value` is found using
@@ -3531,21 +3871,14 @@
3531
3871
  * // => 2
3532
3872
  */
3533
3873
  function indexOf(array, value, fromIndex) {
3534
- var index = -1,
3535
- length = array ? array.length : 0;
3536
-
3537
3874
  if (typeof fromIndex == 'number') {
3538
- index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
3875
+ var length = array ? array.length : 0;
3876
+ fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
3539
3877
  } else if (fromIndex) {
3540
- index = sortedIndex(array, value);
3878
+ var index = sortedIndex(array, value);
3541
3879
  return array[index] === value ? index : -1;
3542
3880
  }
3543
- while (++index < length) {
3544
- if (array[index] === value) {
3545
- return index;
3546
- }
3547
- }
3548
- return -1;
3881
+ return array ? basicIndexOf(array, value, fromIndex) : -1;
3549
3882
  }
3550
3883
 
3551
3884
  /**
@@ -3641,35 +3974,45 @@
3641
3974
  function intersection(array) {
3642
3975
  var args = arguments,
3643
3976
  argsLength = args.length,
3644
- cache = { '0': {} },
3977
+ argsIndex = -1,
3978
+ caches = getArray(),
3645
3979
  index = -1,
3980
+ indexOf = getIndexOf(),
3646
3981
  length = array ? array.length : 0,
3647
- isLarge = length >= largeArraySize,
3648
3982
  result = [],
3649
- seen = result;
3983
+ seen = getArray();
3650
3984
 
3985
+ while (++argsIndex < argsLength) {
3986
+ var value = args[argsIndex];
3987
+ caches[argsIndex] = indexOf === basicIndexOf &&
3988
+ (value ? value.length : 0) >= largeArraySize &&
3989
+ createCache(argsIndex ? args[argsIndex] : seen);
3990
+ }
3651
3991
  outer:
3652
3992
  while (++index < length) {
3653
- var value = array[index];
3654
- if (isLarge) {
3655
- var key = keyPrefix + value;
3656
- var inited = cache[0][key]
3657
- ? !(seen = cache[0][key])
3658
- : (seen = cache[0][key] = []);
3659
- }
3660
- if (inited || indexOf(seen, value) < 0) {
3661
- if (isLarge) {
3662
- seen.push(value);
3663
- }
3664
- var argsIndex = argsLength;
3993
+ var cache = caches[0];
3994
+ value = array[index];
3995
+
3996
+ if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
3997
+ argsIndex = argsLength;
3998
+ (cache || seen).push(value);
3665
3999
  while (--argsIndex) {
3666
- if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex])))(value)) {
4000
+ cache = caches[argsIndex];
4001
+ if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
3667
4002
  continue outer;
3668
4003
  }
3669
4004
  }
3670
4005
  result.push(value);
3671
4006
  }
3672
4007
  }
4008
+ while (argsLength--) {
4009
+ cache = caches[argsLength];
4010
+ if (cache) {
4011
+ releaseObject(cache);
4012
+ }
4013
+ }
4014
+ releaseArray(caches);
4015
+ releaseArray(seen);
3673
4016
  return result;
3674
4017
  }
3675
4018
 
@@ -3998,7 +4341,7 @@
3998
4341
  * Creates a duplicate-value-free version of the `array` using strict equality
3999
4342
  * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
4000
4343
  * for `isSorted` will run a faster algorithm. If `callback` is passed, each
4001
- * element of `array` is passed through a `callback` before uniqueness is computed.
4344
+ * element of `array` is passed through the `callback` before uniqueness is computed.
4002
4345
  * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
4003
4346
  *
4004
4347
  * If a property name is passed for `callback`, the created "_.pluck" style
@@ -4027,50 +4370,42 @@
4027
4370
  * _.uniq([1, 1, 2, 2, 3], true);
4028
4371
  * // => [1, 2, 3]
4029
4372
  *
4030
- * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
4031
- * // => [1, 2, 3]
4373
+ * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
4374
+ * // => ['A', 'b', 'C']
4032
4375
  *
4033
- * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
4034
- * // => [1, 2, 3]
4376
+ * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
4377
+ * // => [1, 2.5, 3]
4035
4378
  *
4036
4379
  * // using "_.pluck" callback shorthand
4037
4380
  * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
4038
4381
  * // => [{ 'x': 1 }, { 'x': 2 }]
4039
4382
  */
4040
- function uniq(array, isSorted, callback, thisArg) {
4383
+ var uniq = overloadWrapper(function(array, isSorted, callback) {
4041
4384
  var index = -1,
4385
+ indexOf = getIndexOf(),
4042
4386
  length = array ? array.length : 0,
4043
- result = [],
4044
- seen = result;
4387
+ result = [];
4388
+
4389
+ var isLarge = !isSorted && length >= largeArraySize && indexOf === basicIndexOf,
4390
+ seen = (callback || isLarge) ? getArray() : result;
4045
4391
 
4046
- // juggle arguments
4047
- if (typeof isSorted != 'boolean' && isSorted != null) {
4048
- thisArg = callback;
4049
- callback = isSorted;
4050
- isSorted = false;
4051
- }
4052
- // init value cache for large arrays
4053
- var isLarge = !isSorted && length >= largeArraySize;
4054
4392
  if (isLarge) {
4055
- var cache = {};
4056
- }
4057
- if (callback != null) {
4058
- seen = [];
4059
- callback = lodash.createCallback(callback, thisArg);
4393
+ var cache = createCache(seen);
4394
+ if (cache) {
4395
+ indexOf = cacheIndexOf;
4396
+ seen = cache;
4397
+ } else {
4398
+ isLarge = false;
4399
+ seen = callback ? seen : (releaseArray(seen), result);
4400
+ }
4060
4401
  }
4061
4402
  while (++index < length) {
4062
4403
  var value = array[index],
4063
4404
  computed = callback ? callback(value, index, array) : value;
4064
4405
 
4065
- if (isLarge) {
4066
- var key = keyPrefix + computed;
4067
- var inited = cache[key]
4068
- ? !(seen = cache[key])
4069
- : (seen = cache[key] = []);
4070
- }
4071
4406
  if (isSorted
4072
4407
  ? !index || seen[seen.length - 1] !== computed
4073
- : inited || indexOf(seen, computed) < 0
4408
+ : indexOf(seen, computed) < 0
4074
4409
  ) {
4075
4410
  if (callback || isLarge) {
4076
4411
  seen.push(computed);
@@ -4078,8 +4413,14 @@
4078
4413
  result.push(value);
4079
4414
  }
4080
4415
  }
4416
+ if (isLarge) {
4417
+ releaseArray(seen.array);
4418
+ releaseObject(seen);
4419
+ } else if (callback) {
4420
+ releaseArray(seen);
4421
+ }
4081
4422
  return result;
4082
- }
4423
+ });
4083
4424
 
4084
4425
  /**
4085
4426
  * The inverse of `_.zip`, this method splits groups of elements into arrays
@@ -4097,17 +4438,11 @@
4097
4438
  */
4098
4439
  function unzip(array) {
4099
4440
  var index = -1,
4100
- length = array ? array.length : 0,
4101
- tupleLength = length ? max(pluck(array, 'length')) : 0,
4102
- result = Array(tupleLength);
4441
+ length = array ? max(pluck(array, 'length')) : 0,
4442
+ result = Array(length < 0 ? 0 : length);
4103
4443
 
4104
4444
  while (++index < length) {
4105
- var tupleIndex = -1,
4106
- tuple = array[index];
4107
-
4108
- while (++tupleIndex < tupleLength) {
4109
- (result[tupleIndex] || (result[tupleIndex] = Array(length)))[index] = tuple[tupleIndex];
4110
- }
4445
+ result[index] = pluck(array, index);
4111
4446
  }
4112
4447
  return result;
4113
4448
  }
@@ -4148,14 +4483,7 @@
4148
4483
  * // => [['moe', 30, true], ['larry', 40, false]]
4149
4484
  */
4150
4485
  function zip(array) {
4151
- var index = -1,
4152
- length = array ? max(pluck(arguments, 'length')) : 0,
4153
- result = Array(length);
4154
-
4155
- while (++index < length) {
4156
- result[index] = pluck(arguments, index);
4157
- }
4158
- return result;
4486
+ return array ? unzip(arguments) : [];
4159
4487
  }
4160
4488
 
4161
4489
  /**
@@ -4431,27 +4759,27 @@
4431
4759
  return result;
4432
4760
  };
4433
4761
  }
4434
- if (typeof thisArg != 'undefined') {
4435
- if (argCount === 1) {
4436
- return function(value) {
4437
- return func.call(thisArg, value);
4438
- };
4439
- }
4440
- if (argCount === 2) {
4441
- return function(a, b) {
4442
- return func.call(thisArg, a, b);
4443
- };
4444
- }
4445
- if (argCount === 4) {
4446
- return function(accumulator, value, index, collection) {
4447
- return func.call(thisArg, accumulator, value, index, collection);
4448
- };
4449
- }
4450
- return function(value, index, collection) {
4451
- return func.call(thisArg, value, index, collection);
4762
+ if (typeof thisArg == 'undefined' || (reThis && !reThis.test(fnToString.call(func)))) {
4763
+ return func;
4764
+ }
4765
+ if (argCount === 1) {
4766
+ return function(value) {
4767
+ return func.call(thisArg, value);
4768
+ };
4769
+ }
4770
+ if (argCount === 2) {
4771
+ return function(a, b) {
4772
+ return func.call(thisArg, a, b);
4452
4773
  };
4453
4774
  }
4454
- return func;
4775
+ if (argCount === 4) {
4776
+ return function(accumulator, value, index, collection) {
4777
+ return func.call(thisArg, accumulator, value, index, collection);
4778
+ };
4779
+ }
4780
+ return function(value, index, collection) {
4781
+ return func.call(thisArg, value, index, collection);
4782
+ };
4455
4783
  }
4456
4784
 
4457
4785
  /**
@@ -4472,6 +4800,7 @@
4472
4800
  * @param {Number} wait The number of milliseconds to delay.
4473
4801
  * @param {Object} options The options object.
4474
4802
  * [leading=false] A boolean to specify execution on the leading edge of the timeout.
4803
+ * [maxWait] The maximum time `func` is allowed to be delayed before it's called.
4475
4804
  * [trailing=true] A boolean to specify execution on the trailing edge of the timeout.
4476
4805
  * @returns {Function} Returns the new debounced function.
4477
4806
  * @example
@@ -4486,34 +4815,80 @@
4486
4815
  */
4487
4816
  function debounce(func, wait, options) {
4488
4817
  var args,
4489
- inited,
4490
4818
  result,
4491
4819
  thisArg,
4492
- timeoutId,
4820
+ callCount = 0,
4821
+ lastCalled = 0,
4822
+ maxWait = false,
4823
+ maxTimeoutId = null,
4824
+ timeoutId = null,
4493
4825
  trailing = true;
4494
4826
 
4827
+ function clear() {
4828
+ clearTimeout(maxTimeoutId);
4829
+ clearTimeout(timeoutId);
4830
+ callCount = 0;
4831
+ maxTimeoutId = timeoutId = null;
4832
+ }
4833
+
4495
4834
  function delayed() {
4496
- inited = timeoutId = null;
4497
- if (trailing) {
4835
+ var isCalled = trailing && (!leading || callCount > 1);
4836
+ clear();
4837
+ if (isCalled) {
4838
+ if (maxWait !== false) {
4839
+ lastCalled = new Date;
4840
+ }
4841
+ result = func.apply(thisArg, args);
4842
+ }
4843
+ }
4844
+
4845
+ function maxDelayed() {
4846
+ clear();
4847
+ if (trailing || (maxWait !== wait)) {
4848
+ lastCalled = new Date;
4498
4849
  result = func.apply(thisArg, args);
4499
4850
  }
4500
4851
  }
4852
+
4853
+ wait = nativeMax(0, wait || 0);
4501
4854
  if (options === true) {
4502
4855
  var leading = true;
4503
4856
  trailing = false;
4504
- } else if (options && objectTypes[typeof options]) {
4857
+ } else if (isObject(options)) {
4505
4858
  leading = options.leading;
4859
+ maxWait = 'maxWait' in options && nativeMax(wait, options.maxWait || 0);
4506
4860
  trailing = 'trailing' in options ? options.trailing : trailing;
4507
4861
  }
4508
4862
  return function() {
4509
4863
  args = arguments;
4510
4864
  thisArg = this;
4865
+ callCount++;
4866
+
4867
+ // avoid issues with Titanium and `undefined` timeout ids
4868
+ // https://github.com/appcelerator/titanium_mobile/blob/3_1_0_GA/android/titanium/src/java/ti/modules/titanium/TitaniumModule.java#L185-L192
4511
4869
  clearTimeout(timeoutId);
4512
4870
 
4513
- if (!inited && leading) {
4514
- inited = true;
4515
- result = func.apply(thisArg, args);
4871
+ if (maxWait === false) {
4872
+ if (leading && callCount < 2) {
4873
+ result = func.apply(thisArg, args);
4874
+ }
4516
4875
  } else {
4876
+ var now = new Date;
4877
+ if (!maxTimeoutId && !leading) {
4878
+ lastCalled = now;
4879
+ }
4880
+ var remaining = maxWait - (now - lastCalled);
4881
+ if (remaining <= 0) {
4882
+ clearTimeout(maxTimeoutId);
4883
+ maxTimeoutId = null;
4884
+ lastCalled = now;
4885
+ result = func.apply(thisArg, args);
4886
+ }
4887
+ else if (!maxTimeoutId) {
4888
+ maxTimeoutId = setTimeout(maxDelayed, remaining);
4889
+ }
4890
+ }
4891
+ if (wait !== maxWait) {
4517
4892
  timeoutId = setTimeout(delayed, wait);
4518
4893
  }
4519
4894
  return result;
@@ -4571,7 +4946,8 @@
4571
4946
  * passed, it will be used to determine the cache key for storing the result
4572
4947
  * based on the arguments passed to the memoized function. By default, the first
4573
4948
  * argument passed to the memoized function is used as the cache key. The `func`
4574
- * is executed with the `this` binding of the memoized function.
4949
+ * is executed with the `this` binding of the memoized function. The result
4950
+ * cache is exposed as the `cache` property on the memoized function.
4575
4951
  *
4576
4952
  * @static
4577
4953
  * @memberOf _
@@ -4586,13 +4962,16 @@
4586
4962
  * });
4587
4963
  */
4588
4964
  function memoize(func, resolver) {
4589
- var cache = {};
4590
- return function() {
4591
- var key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
4965
+ function memoized() {
4966
+ var cache = memoized.cache,
4967
+ key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
4968
+
4592
4969
  return hasOwnProperty.call(cache, key)
4593
4970
  ? cache[key]
4594
4971
  : (cache[key] = func.apply(this, arguments));
4595
- };
4972
+ }
4973
+ memoized.cache = {};
4974
+ return memoized;
4596
4975
  }
4597
4976
 
4598
4977
  /**
@@ -4712,47 +5091,23 @@
4712
5091
  * }));
4713
5092
  */
4714
5093
  function throttle(func, wait, options) {
4715
- var args,
4716
- result,
4717
- thisArg,
4718
- timeoutId,
4719
- lastCalled = 0,
4720
- leading = true,
5094
+ var leading = true,
4721
5095
  trailing = true;
4722
5096
 
4723
- function trailingCall() {
4724
- timeoutId = null;
4725
- if (trailing) {
4726
- lastCalled = new Date;
4727
- result = func.apply(thisArg, args);
4728
- }
4729
- }
4730
5097
  if (options === false) {
4731
5098
  leading = false;
4732
- } else if (options && objectTypes[typeof options]) {
5099
+ } else if (isObject(options)) {
4733
5100
  leading = 'leading' in options ? options.leading : leading;
4734
5101
  trailing = 'trailing' in options ? options.trailing : trailing;
4735
5102
  }
4736
- return function() {
4737
- var now = new Date;
4738
- if (!timeoutId && !leading) {
4739
- lastCalled = now;
4740
- }
4741
- var remaining = wait - (now - lastCalled);
4742
- args = arguments;
4743
- thisArg = this;
5103
+ options = getObject();
5104
+ options.leading = leading;
5105
+ options.maxWait = wait;
5106
+ options.trailing = trailing;
4744
5107
 
4745
- if (remaining <= 0) {
4746
- clearTimeout(timeoutId);
4747
- timeoutId = null;
4748
- lastCalled = now;
4749
- result = func.apply(thisArg, args);
4750
- }
4751
- else if (!timeoutId) {
4752
- timeoutId = setTimeout(trailingCall, remaining);
4753
- }
4754
- return result;
4755
- };
5108
+ var result = debounce(func, wait, options);
5109
+ releaseObject(options);
5110
+ return result;
4756
5111
  }
4757
5112
 
4758
5113
  /**
@@ -4805,7 +5160,7 @@
4805
5160
  }
4806
5161
 
4807
5162
  /**
4808
- * This function returns the first argument passed to it.
5163
+ * This method returns the first argument passed to it.
4809
5164
  *
4810
5165
  * @static
4811
5166
  * @memberOf _
@@ -4854,7 +5209,7 @@
4854
5209
 
4855
5210
  push.apply(args, arguments);
4856
5211
  var result = func.apply(lodash, args);
4857
- return (value && typeof value == 'object' && value == result)
5212
+ return (value && typeof value == 'object' && value === result)
4858
5213
  ? this
4859
5214
  : new lodashWrapper(result);
4860
5215
  };
@@ -4928,8 +5283,13 @@
4928
5283
  if (max == null) {
4929
5284
  max = min;
4930
5285
  min = 0;
5286
+ } else {
5287
+ max = +max || 0;
4931
5288
  }
4932
- return min + floor(nativeRandom() * ((+max || 0) - min + 1));
5289
+ var rand = nativeRandom();
5290
+ return (min % 1 || max % 1)
5291
+ ? min + nativeMin(rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1))), max)
5292
+ : min + floor(rand * (max - min + 1));
4933
5293
  }
4934
5294
 
4935
5295
  /**
@@ -5332,6 +5692,7 @@
5332
5692
  lodash.throttle = throttle;
5333
5693
  lodash.times = times;
5334
5694
  lodash.toArray = toArray;
5695
+ lodash.transform = transform;
5335
5696
  lodash.union = union;
5336
5697
  lodash.uniq = uniq;
5337
5698
  lodash.unzip = unzip;
@@ -5356,6 +5717,10 @@
5356
5717
  // add functions to `lodash.prototype`
5357
5718
  mixin(lodash);
5358
5719
 
5720
+ // add Underscore compat
5721
+ lodash.chain = lodash;
5722
+ lodash.prototype.chain = function() { return this; };
5723
+
5359
5724
  /*--------------------------------------------------------------------------*/
5360
5725
 
5361
5726
  // add functions that return unwrapped values when chaining
@@ -5407,6 +5772,7 @@
5407
5772
  lodash.all = every;
5408
5773
  lodash.any = some;
5409
5774
  lodash.detect = find;
5775
+ lodash.findWhere = find;
5410
5776
  lodash.foldl = reduce;
5411
5777
  lodash.foldr = reduceRight;
5412
5778
  lodash.include = contains;
@@ -5452,7 +5818,7 @@
5452
5818
  * @memberOf _
5453
5819
  * @type String
5454
5820
  */
5455
- lodash.VERSION = '1.2.1';
5821
+ lodash.VERSION = '1.3.1';
5456
5822
 
5457
5823
  // add "Chaining" functions to the wrapper
5458
5824
  lodash.prototype.toString = wrapperToString;
@@ -5460,7 +5826,7 @@
5460
5826
  lodash.prototype.valueOf = wrapperValueOf;
5461
5827
 
5462
5828
  // add `Array` functions that return unwrapped values
5463
- each(['join', 'pop', 'shift'], function(methodName) {
5829
+ basicEach(['join', 'pop', 'shift'], function(methodName) {
5464
5830
  var func = arrayRef[methodName];
5465
5831
  lodash.prototype[methodName] = function() {
5466
5832
  return func.apply(this.__wrapped__, arguments);
@@ -5468,7 +5834,7 @@
5468
5834
  });
5469
5835
 
5470
5836
  // add `Array` functions that return the wrapped value
5471
- each(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
5837
+ basicEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
5472
5838
  var func = arrayRef[methodName];
5473
5839
  lodash.prototype[methodName] = function() {
5474
5840
  func.apply(this.__wrapped__, arguments);
@@ -5477,7 +5843,7 @@
5477
5843
  });
5478
5844
 
5479
5845
  // add `Array` functions that return new wrapped values
5480
- each(['concat', 'slice', 'splice'], function(methodName) {
5846
+ basicEach(['concat', 'slice', 'splice'], function(methodName) {
5481
5847
  var func = arrayRef[methodName];
5482
5848
  lodash.prototype[methodName] = function() {
5483
5849
  return new lodashWrapper(func.apply(this.__wrapped__, arguments));
@@ -5487,7 +5853,7 @@
5487
5853
  // avoid array-like object bugs with `Array#shift` and `Array#splice`
5488
5854
  // in Firefox < 10 and IE < 9
5489
5855
  if (!support.spliceObjects) {
5490
- each(['pop', 'shift', 'splice'], function(methodName) {
5856
+ basicEach(['pop', 'shift', 'splice'], function(methodName) {
5491
5857
  var func = arrayRef[methodName],
5492
5858
  isSplice = methodName == 'splice';
5493
5859