torba 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +1 -1
  4. data/lib/torba/remote_sources/npm.rb +7 -1
  5. data/torba.gemspec +2 -3
  6. metadata +4 -72
  7. data/test/acceptance-cli/open_test.rb +0 -101
  8. data/test/acceptance-cli/pack_test.rb +0 -49
  9. data/test/acceptance-cli/show_test.rb +0 -61
  10. data/test/acceptance-cli/verify_test.rb +0 -25
  11. data/test/css_url_to_erb_asset_path_test.rb +0 -139
  12. data/test/fixtures/home_path/01/trumbowyg/icons-2x.png +0 -0
  13. data/test/fixtures/home_path/01/trumbowyg/icons.png +0 -0
  14. data/test/fixtures/home_path/01/trumbowyg/trumbowyg.css.erb +0 -471
  15. data/test/fixtures/home_path/01/trumbowyg/trumbowyg.js +0 -1124
  16. data/test/fixtures/home_path/02/lo_dash/lodash.js +0 -2793
  17. data/test/fixtures/home_path/03/bourbon/_border-image.scss +0 -59
  18. data/test/fixtures/home_path/03/bourbon/_font-source-declaration.scss +0 -43
  19. data/test/fixtures/home_path/03/bourbon/_retina-image.scss +0 -25
  20. data/test/fixtures/torbafiles/01_gh_release.rb +0 -8
  21. data/test/fixtures/torbafiles/01_image_asset_not_specified.rb +0 -7
  22. data/test/fixtures/torbafiles/01_targz.rb +0 -7
  23. data/test/fixtures/torbafiles/01_zip.rb +0 -7
  24. data/test/fixtures/torbafiles/02_npm.rb +0 -1
  25. data/test/fixtures/torbafiles/03_not_existed_assets.rb +0 -5
  26. data/test/fixtures/torbafiles/04_similar_names.rb +0 -2
  27. data/test/import_list_test.rb +0 -53
  28. data/test/manifest_test.rb +0 -142
  29. data/test/package/import_list_test.rb +0 -123
  30. data/test/package/logical_paths_test.rb +0 -28
  31. data/test/package_test.rb +0 -52
  32. data/test/rake_task_test.rb +0 -69
  33. data/test/remote_sources/common_test.rb +0 -62
  34. data/test/remote_sources/get_file_test.rb +0 -12
  35. data/test/remote_sources/github_release_test.rb +0 -42
  36. data/test/remote_sources/npm_test.rb +0 -34
  37. data/test/remote_sources/targz_test.rb +0 -29
  38. data/test/remote_sources/zip_test.rb +0 -26
  39. data/test/test_helper.rb +0 -109
  40. data/test/torba_test.rb +0 -13
@@ -1,2793 +0,0 @@
1
- /*!
2
- * Lo-Dash v0.1.0 <https://github.com/bestiejs/lodash>
3
- * Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
4
- * Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
5
- * <http://documentcloud.github.com/underscore>
6
- * Available under MIT license <http://mths.be/mit>
7
- */
8
- ;(function(window, undefined) {
9
- 'use strict';
10
-
11
- /** Used to escape and unescape characters in templates */
12
- var escapes = {
13
- '\\': '\\',
14
- "'": "'",
15
- 'r': '\r',
16
- 'n': '\n',
17
- 't': '\t',
18
- 'u2028': '\u2028',
19
- 'u2029': '\u2029'
20
- };
21
-
22
- // assign the result as keys and the keys as values
23
- (function() {
24
- for (var prop in escapes) {
25
- escapes[escapes[prop]] = prop;
26
- }
27
- }());
28
-
29
- /** Detect free variable `exports` */
30
- var freeExports = typeof exports == 'object' && exports &&
31
- (typeof global == 'object' && global && global == global.global && (window = global), exports);
32
-
33
- /** Used to generate unique IDs */
34
- var idCounter = 0;
35
-
36
- /** Used to restore the original `_` reference in `noConflict` */
37
- var oldDash = window._;
38
-
39
- /** Used to replace unescape characters with their escaped counterpart */
40
- var reEscaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
41
-
42
- /**
43
- * Used for `templateSettings` properties such as `escape`, `evaluate`,
44
- * or `interpolate` with explicitly assigned falsey values to ensure no match
45
- * is made.
46
- */
47
- var reNoMatch = /.^/;
48
-
49
- /** Used to replace escaped characters with their unescaped counterpart */
50
- var reUnescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
51
-
52
- /** Object#toString result shortcuts */
53
- var arrayClass = '[object Array]',
54
- boolClass = '[object Boolean]',
55
- dateClass = '[object Date]',
56
- funcClass = '[object Function]',
57
- numberClass = '[object Number]',
58
- regexpClass = '[object RegExp]',
59
- stringClass = '[object String]';
60
-
61
- /** Native prototype shortcuts */
62
- var ArrayProto = Array.prototype,
63
- ObjProto = Object.prototype;
64
-
65
- /** Native method shortcuts */
66
- var concat = ArrayProto.concat,
67
- hasOwnProperty = ObjProto.hasOwnProperty,
68
- push = ArrayProto.push,
69
- slice = ArrayProto.slice,
70
- toString = ObjProto.toString,
71
- unshift = ArrayProto.unshift;
72
-
73
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
74
- var nativeIsArray = Array.isArray,
75
- nativeIsFinite = window.isFinite,
76
- nativeKeys = Object.keys;
77
-
78
- /** Timer shortcuts */
79
- var clearInteval = window.clearInterval,
80
- setTimeout = window.setTimeout;
81
-
82
- /** Compilation options for `_.difference` */
83
- var differenceFactoryOptions = {
84
- 'args': 'array',
85
- 'top': 'var values=concat.apply([],slice.call(arguments,1))',
86
- 'init': '[]',
87
- 'inLoop': 'if(indexOf(values,array[index])<0)result.push(array[index])'
88
- };
89
-
90
- /** Compilation options for `_.every` */
91
- var everyFactoryOptions = {
92
- 'init': 'true',
93
- 'inLoop': 'if(!callback(collection[index],index,collection))return !result'
94
- };
95
-
96
- /** Compilation options for `_.extend` */
97
- var extendFactoryOptions = {
98
- 'args': 'object',
99
- 'init': 'object',
100
- 'beforeLoop': 'for(var source,j=1,length=arguments.length;j<length;j++){\nsource=arguments[j]',
101
- 'loopExp': 'index in source',
102
- 'inLoop': 'object[index]=source[index]',
103
- 'useHas': false,
104
- 'afterLoop': '}'
105
- };
106
-
107
- /** Compilation options for `_.filter` */
108
- var filterFactoryOptions = {
109
- 'init': '[]',
110
- 'inLoop': 'callback(collection[index],index,collection)&&result.push(collection[index])'
111
- };
112
-
113
- /** Compilation options for `_.forEach` */
114
- var forEachFactoryOptions = {
115
- 'args': 'collection,callback,thisArg',
116
- 'top':
117
- 'if(!callback){\ncallback=identity\n}\n' +
118
- 'else if(thisArg){\ncallback=bind(callback,thisArg)\n}',
119
- 'init': 'collection',
120
- 'inLoop': 'callback(collection[index],index,collection)'
121
- };
122
-
123
- /** Compilation options for `_.keys` */
124
- var keysFactoryOptions = {
125
- 'args': 'object',
126
- 'top': 'if(object!==Object(object))throw TypeError()',
127
- 'init': '[]',
128
- 'inLoop': 'result.push(index)'
129
- };
130
-
131
- /** Compilation options for `_.map` */
132
- var mapFactoryOptions = {
133
- 'init': '',
134
- 'exits': '[]',
135
- 'beforeLoop': {
136
- 'array': 'result=Array(length)',
137
- 'object': 'result=[]'
138
- },
139
- 'inLoop': {
140
- 'array': 'result[index]=callback(collection[index],index,collection)',
141
- 'object': 'result[result.length]=callback(collection[index],index,collection)'
142
- }
143
- };
144
-
145
- /** Compilation options for `_.max` */
146
- var maxFactoryOptions = {
147
- 'top':
148
- 'var current,result=-Infinity,computed=result;\n' +
149
- 'if(!callback){\n' +
150
- 'if(isArray(collection)&&collection[0]===+collection[0])return Math.max.apply(Math,collection);\n' +
151
- 'if(isEmpty(collection))return result;\n' +
152
- '}else if(thisArg)callback=bind(callback,thisArg)',
153
- 'inLoop':
154
- 'current=callback?callback(collection[index],index,collection):collection[index];\n' +
155
- 'if(current>=computed)computed=current,result=collection[index]'
156
- };
157
-
158
- /*--------------------------------------------------------------------------*/
159
-
160
- /**
161
- * The `lodash` function.
162
- *
163
- * @name _
164
- * @param {Mixed} value The value to wrap in a `Lodash` instance.
165
- * @returns {Object} Returns a `Lodash` instance.
166
- */
167
- function lodash(value) {
168
- // allow invoking `lodash` without the `new` operator
169
- return new Lodash(value);
170
- }
171
-
172
- /**
173
- * Creates a `Lodash` instance that wraps a value to allow chaining.
174
- *
175
- * @private
176
- * @constructor
177
- * @param {Mixed} value The value to wrap.
178
- */
179
- function Lodash(value) {
180
- this._wrapped = value;
181
- }
182
-
183
- /*--------------------------------------------------------------------------*/
184
-
185
- /**
186
- * Checks if a `value` is an array.
187
- *
188
- * @static
189
- * @memberOf _
190
- * @category Objects
191
- * @param {Mixed} value The value to check.
192
- * @returns {Boolean} Returns `true` if the `value` is an array, else `false`.
193
- * @example
194
- *
195
- * (function() { return _.isArray(arguments); })();
196
- * // => false
197
- *
198
- * _.isArray([1, 2, 3]);
199
- * // => true
200
- */
201
- var isArray = nativeIsArray || function isArray(value) {
202
- return toString.call(value) == arrayClass;
203
- };
204
-
205
- /**
206
- * Checks if a `value` is empty. Arrays or strings with a length of 0 and
207
- * objects with no enumerable own properties are considered "empty".
208
- *
209
- * @static
210
- * @memberOf _
211
- * @category Objects
212
- * @param {Mixed} value The value to check.
213
- * @returns {Boolean} Returns `true` if the `value` is empty, else `false`.
214
- * @example
215
- *
216
- * _.isEmpty([1, 2, 3]);
217
- * // => false
218
- *
219
- * _.isEmpty({});
220
- * // => true
221
- */
222
- var isEmpty = iterationFactory({
223
- 'args': 'value',
224
- 'iterate': 'objects',
225
- 'top': 'var className=toString.call(value)',
226
- 'init': 'true',
227
- 'beforeLoop': 'if(className==arrayClass||className==stringClass)return !value.length',
228
- 'inLoop': 'return false'
229
- });
230
-
231
- /*--------------------------------------------------------------------------*/
232
-
233
- /**
234
- * Compiles iteration functions.
235
- *
236
- * @private
237
- * @param {Object} [options1, options2, ..] The compile options objects.
238
- * @returns {Function} Returns the compiled function.
239
- */
240
- function iterationFactory() {
241
- var prop,
242
- index = -1,
243
- array = {},
244
- object = {},
245
- options = {},
246
- props = ['beforeLoop', 'loopExp', 'inLoop', 'afterLoop'];
247
-
248
- while (++index < arguments.length) {
249
- for (prop in arguments[index]) {
250
- options[prop] = arguments[index][prop];
251
- }
252
- }
253
-
254
- while ((prop = props.pop())) {
255
- if (typeof options[prop] == 'object') {
256
- array[prop] = options[prop].array;
257
- object[prop] = options[prop].object;
258
- } else {
259
- array[prop] = object[prop] = options[prop] || '';
260
- }
261
- }
262
-
263
- var args = options.args,
264
- firstArg = /^[^,]+/.exec(args)[0],
265
- init = options.init,
266
- iterate = options.iterate,
267
- arrayBranch = !(args == 'object' || iterate == 'objects'),
268
- objectBranch = !(args == 'array' || iterate == 'arrays'),
269
- useHas = options.useHas !== false;
270
-
271
- return Function('arrayClass,bind,concat,funcClass,hasOwnProperty,identity,' +
272
- 'indexOf,Infinity,isArray,isEmpty,Math,slice,stringClass,' +
273
- 'toString,undefined',
274
- '"use strict";' +
275
- 'return function(' + args + '){\n' +
276
- (options.top || '') + ';\n' +
277
- ('var index, result' + (init ? '=' + init : '')) + ';\n' +
278
- 'if(' + firstArg + '==undefined)return ' + (options.exits || 'result') + ';\n' +
279
- (arrayBranch
280
- ? 'var length=' + firstArg + '.length;\nindex=-1;\n' +
281
- ((objectBranch ? 'if(length===+length){\n' : '') +
282
- (array.beforeLoop || '') + ';\n' +
283
- 'while(' + (array.loopExp || '++index<length') + '){\n' + array.inLoop + '\n}' +
284
- (array.afterLoop || '') + ';\n' +
285
- (objectBranch ? '\n}\n' : ''))
286
- : ''
287
- ) +
288
- (objectBranch
289
- ? ((arrayBranch ? 'else{\n' : '') +
290
- (object.beforeLoop || '') + ';\n' +
291
- 'for(' + (object.loopExp || 'index in ' + firstArg) + '){\n' +
292
- (useHas ? 'if(hasOwnProperty.call(' + /\S+$/.exec(object.loopExp || firstArg)[0] + ',index)){\n' : '') +
293
- object.inLoop +
294
- (useHas ? '\n}' : '') +
295
- '\n}' +
296
- (object.afterLoop || '') + ';\n' +
297
- (arrayBranch ? '\n}\n' : ''))
298
- : ''
299
- ) +
300
- (options.bottom || '') + ';\n' +
301
- 'return ' + (options.returns || 'result') +
302
- '\n}'
303
- )(arrayClass, bind, concat, funcClass, hasOwnProperty, identity,
304
- indexOf, Infinity, isArray, isEmpty, Math, slice, stringClass, toString);
305
- }
306
-
307
- /**
308
- * Unescapes characters, previously escaped for inclusion in compiled string
309
- * literals, so they may compiled into function bodies.
310
- * (Used for template interpolation, evaluation, or escaping)
311
- *
312
- * @private
313
- * @param {String} string The string to unescape.
314
- * @returns {String} Returns the unescaped string.
315
- */
316
- function unescape(string) {
317
- return string.replace(reUnescaper, function(match, escaped) {
318
- return escapes[escaped];
319
- });
320
- }
321
-
322
- /*--------------------------------------------------------------------------*/
323
-
324
- /**
325
- * Checks if a given `target` value is present in a `collection` using strict
326
- * equality for comparisons, i.e. `===`.
327
- *
328
- * @static
329
- * @memberOf _
330
- * @alias include
331
- * @category Collections
332
- * @param {Array|Object} collection The collection to iterate over.
333
- * @param {Mixed} target The value to check for.
334
- * @returns {Boolean} Returns `true` if `target` value is found, else `false`.
335
- * @example
336
- *
337
- * _.contains([1, 2, 3], 3);
338
- * // => true
339
- */
340
- var contains = iterationFactory({
341
- 'args': 'collection,target',
342
- 'init': 'false',
343
- 'inLoop': 'if(collection[index]===target)return true'
344
- });
345
-
346
- /**
347
- * Checks if the `callback` returns truthy for **all** values of a `collection`.
348
- * The `callback` is invoked with 3 arguments; for arrays they are
349
- * (value, index, array) and for objects they are (value, key, object).
350
- *
351
- * @static
352
- * @memberOf _
353
- * @alias all
354
- * @category Collections
355
- * @param {Array|Object} collection The collection to iterate over.
356
- * @param {Function} callback The function called per iteration.
357
- * @param {Mixed} [thisArg] The `this` binding for the callback.
358
- * @returns {Boolean} Returns `true` if all values pass the callback check, else `false`.
359
- * @example
360
- *
361
- * _.every([true, 1, null, 'yes'], Boolean);
362
- * => false
363
- */
364
- var every = iterationFactory(forEachFactoryOptions, everyFactoryOptions);
365
-
366
- /**
367
- * Examines each value in a `collection`, returning an array of all values the
368
- * `callback` returns truthy for. The `callback` is invoked with 3 arguments;
369
- * for arrays they are (value, index, array) and for objects they are
370
- * (value, key, object).
371
- *
372
- * @static
373
- * @memberOf _
374
- * @alias select
375
- * @category Collections
376
- * @param {Array|Object} collection The collection to iterate over.
377
- * @param {Function} callback The function called per iteration.
378
- * @param {Mixed} [thisArg] The `this` binding for the callback.
379
- * @returns {Array} Returns a new array of values that passed callback check.
380
- * @example
381
- *
382
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
383
- * // => [2, 4, 6]
384
- */
385
- var filter = iterationFactory(forEachFactoryOptions, filterFactoryOptions);
386
-
387
- /**
388
- * Examines each value in a `collection`, returning the first one the `callback`
389
- * returns truthy for. The function returns as soon as it finds an acceptable
390
- * value, and does not iterate over the entire `collection`. The `callback` is
391
- * invoked with 3 arguments; for arrays they are (value, index, array) and for
392
- * objects they are (value, key, object).
393
- *
394
- * @static
395
- * @memberOf _
396
- * @alias detect
397
- * @category Collections
398
- * @param {Array|Object} collection The collection to iterate over.
399
- * @param {Function} callback The function called per iteration.
400
- * @param {Mixed} [thisArg] The `this` binding for the callback.
401
- * @returns {Mixed} Returns the value that passed the callback check, else `undefined`.
402
- * @example
403
- *
404
- * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
405
- * // => 2
406
- */
407
- var find = iterationFactory(forEachFactoryOptions, {
408
- 'inLoop': 'if(callback(collection[index],index,collection))return collection[index]'
409
- });
410
-
411
- /**
412
- * Iterates over a `collection`, executing the `callback` for each value in the
413
- * `collection`. The `callback` is bound to the `thisArg` value, if one is passed.
414
- * The `callback` is invoked with 3 arguments; for arrays they are
415
- * (value, index, array) and for objects they are (value, key, object).
416
- *
417
- * @static
418
- * @memberOf _
419
- * @alias each
420
- * @category Collections
421
- * @param {Array|Object} collection The collection to iterate over.
422
- * @param {Function} callback The function called per iteration.
423
- * @param {Mixed} [thisArg] The `this` binding for the callback.
424
- * @returns {Array|Object} Returns the `collection`.
425
- * @example
426
- *
427
- * _.forEach([1, 2, 3], function(num) { alert(num); });
428
- * // => alerts each number in turn...
429
- *
430
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3}, function(num) { alert(num); });
431
- * // => alerts each number in turn...
432
- */
433
- var forEach = iterationFactory(forEachFactoryOptions);
434
-
435
- /**
436
- * Splits a `collection` into sets, grouped by the result of running each value
437
- * through `callback`. The `callback` is invoked with 3 arguments; for arrays
438
- * they are (value, index, array) and for objects they are (value, key, object).
439
- * The `callback` argument may also be the name of a property to group by.
440
- *
441
- * @static
442
- * @memberOf _
443
- * @category Collections
444
- * @param {Array|Object} collection The collection to iterate over.
445
- * @param {Function|String} callback The function called per iteration or
446
- * property name to group by.
447
- * @param {Mixed} [thisArg] The `this` binding for the callback.
448
- * @returns {Object} Returns an object of grouped values.
449
- * @example
450
- *
451
- * _.groupBy([1.3, 2.1, 2.4], function(num) { return Math.floor(num); });
452
- * // => { '1': [1.3], '2': [2.1, 2.4] }
453
- *
454
- * _.groupBy(['one', 'two', 'three'], 'length');
455
- * // => { '3': ['one', 'two'], '5': ['three'] }
456
- */
457
- function groupBy(collection, callback, thisArg) {
458
- var result = {};
459
- if (!isFunction(callback)) {
460
- var prop = callback;
461
- callback = function(collection) { return collection[prop]; };
462
- }
463
- forEach(collection, function(value, index, collection) {
464
- var prop = callback(value, index, collection);
465
- (result[prop] || (result[prop] = [])).push(value);
466
- });
467
- return result;
468
- }
469
-
470
- /**
471
- * Calls the method named by `methodName` for each value of the `collection`.
472
- * Additional arguments will be passed to each invoked method.
473
- *
474
- * @static
475
- * @memberOf _
476
- * @category Collections
477
- * @param {Array|Object} collection The collection to iterate over.
478
- * @param {String} methodName The name of the method to invoke.
479
- * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
480
- * @returns {Array} Returns a new array of values returned from each invoked method.
481
- * @example
482
- *
483
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
484
- * // => [[1, 5, 7], [1, 2, 3]]
485
- */
486
- function invoke(collection, methodName) {
487
- var args = slice.call(arguments, 2),
488
- isFunc = isFunction(methodName);
489
-
490
- return map(collection, function(value) {
491
- return (isFunc ? methodName || value : value[methodName]).apply(value, args);
492
- });
493
- }
494
-
495
- /**
496
- * Produces a new array of values by mapping each value in the `collection`
497
- * through a transformation `callback`. The `callback` is bound to the `thisArg`
498
- * value, if one is passed. The `callback` is invoked with 3 arguments; for
499
- * arrays they are (value, index, array) and for objects they are (value, key, object).
500
- *
501
- * @static
502
- * @memberOf _
503
- * @alias collect
504
- * @category Collections
505
- * @param {Array|Object} collection The collection to iterate over.
506
- * @param {Function} callback The function called per iteration.
507
- * @param {Mixed} [thisArg] The `this` binding for the callback.
508
- * @returns {Array} Returns a new array of values returned by the callback.
509
- * @example
510
- *
511
- * _.map([1, 2, 3], function(num) { return num * 3; });
512
- * // => [3, 6, 9]
513
- *
514
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
515
- * // => [3, 6, 9]
516
- */
517
- var map = iterationFactory(forEachFactoryOptions, mapFactoryOptions);
518
-
519
- /**
520
- * Retrieves the maximum value of a `collection`. If `callback` is passed,
521
- * it will be executed for each value in the `collection` to generate the
522
- * criterion by which the value is ranked. The `callback` is invoked with 3
523
- * arguments; for arrays they are (value, index, array) and for objects they
524
- * are (value, key, object).
525
- *
526
- * @static
527
- * @memberOf _
528
- * @category Collections
529
- * @param {Array|Object} collection The collection to iterate over.
530
- * @param {Function} [callback] The function called per iteration.
531
- * @param {Mixed} [thisArg] The `this` binding for the callback.
532
- * @returns {Mixed} Returns the maximum value.
533
- * @example
534
- *
535
- * var stooges = [
536
- * { 'name': 'moe', 'age': 40 },
537
- * { 'name': 'larry', 'age': 50 },
538
- * { 'name': 'curly', 'age': 60 }
539
- * ];
540
- *
541
- * _.max(stooges, function(stooge) { return stooge.age; });
542
- * // => { 'name': 'curly', 'age': 60 };
543
- */
544
- var max = iterationFactory(forEachFactoryOptions, maxFactoryOptions);
545
-
546
- /**
547
- * Retrieves the minimum value of a `collection`. If `callback` is passed,
548
- * it will be executed for each value in the `collection` to generate the
549
- * criterion by which the value is ranked. The `callback` is invoked with 3
550
- * arguments; for arrays they are (value, index, array) and for objects they
551
- * are (value, key, object).
552
- *
553
- * @static
554
- * @memberOf _
555
- * @category Collections
556
- * @param {Array|Object} collection The collection to iterate over.
557
- * @param {Function} [callback] The function called per iteration.
558
- * @param {Mixed} [thisArg] The `this` binding for the callback.
559
- * @returns {Mixed} Returns the minimum value.
560
- * @example
561
- *
562
- * _.min([10, 5, 100, 2, 1000]);
563
- * // => 2
564
- */
565
- var min = iterationFactory(forEachFactoryOptions, maxFactoryOptions, {
566
- 'top': maxFactoryOptions.top.replace('-', '').replace('max', 'min'),
567
- 'inLoop': maxFactoryOptions.inLoop.replace('>=', '<')
568
- });
569
-
570
- /**
571
- * Retrieves the value of a specified property from all values in a `collection`.
572
- *
573
- * @static
574
- * @memberOf _
575
- * @category Collections
576
- * @param {Array|Object} collection The collection to iterate over.
577
- * @param {String} property The property to pluck.
578
- * @returns {Array} Returns a new array of property values.
579
- * @example
580
- *
581
- * var stooges = [
582
- * { 'name': 'moe', 'age': 40 },
583
- * { 'name': 'larry', 'age': 50 },
584
- * { 'name': 'curly', 'age': 60 }
585
- * ];
586
- *
587
- * _.pluck(stooges, 'name');
588
- * // => ['moe', 'larry', 'curly']
589
- */
590
- var pluck = iterationFactory(mapFactoryOptions, {
591
- 'args': 'collection,property',
592
- 'inLoop': {
593
- 'array': 'result[index]=collection[index][property]',
594
- 'object': 'result[result.length]=collection[index][property]'
595
- }
596
- });
597
-
598
- /**
599
- * Boils down a `collection` to a single value. The initial state of the
600
- * reduction is `accumulator` and each successive step of it should be returned
601
- * by the `callback`. The `callback` is bound to the `thisArg` value, if one is
602
- * passed. The `callback` is invoked with 4 arguments; for arrays they are
603
- * (accumulator, value, index, array) and for objects they are
604
- * (accumulator, value, key, object).
605
- *
606
- * @static
607
- * @memberOf _
608
- * @alias foldl, inject
609
- * @category Collections
610
- * @param {Array|Object} collection The collection to iterate over.
611
- * @param {Function} callback The function called per iteration.
612
- * @param {Mixed} [accumulator] Initial value of the accumulator.
613
- * @param {Mixed} [thisArg] The `this` binding for the callback.
614
- * @returns {Mixed} Returns the accumulated value.
615
- * @example
616
- *
617
- * var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; });
618
- * // => 6
619
- */
620
- var reduce = iterationFactory({
621
- 'args':
622
- 'collection,callback,accumulator,thisArg',
623
- 'top':
624
- 'var initial=arguments.length>2;\n' +
625
- 'if(thisArg)callback=bind(callback,thisArg)',
626
- 'init':
627
- 'accumulator',
628
- 'beforeLoop': {
629
- 'array': 'if(!initial)result=collection[++index]'
630
- },
631
- 'inLoop': {
632
- 'array':
633
- 'result=callback(result,collection[index],index,collection)',
634
- 'object':
635
- 'result=initial\n' +
636
- '?callback(result,collection[index],index,collection)\n' +
637
- ':(initial=true,collection[index])'
638
- }
639
- });
640
-
641
- /**
642
- * The right-associative version of `_.reduce`. The `callback` is bound to the
643
- * `thisArg` value, if one is passed. The `callback` is invoked with 4 arguments;
644
- * for arrays they are (accumulator, value, index, array) and for objects they
645
- * are (accumulator, value, key, object).
646
- *
647
- * @static
648
- * @memberOf _
649
- * @alias foldr
650
- * @category Collections
651
- * @param {Array|Object} collection The collection to iterate over.
652
- * @param {Function} callback The function called per iteration.
653
- * @param {Mixed} [accumulator] Initial value of the accumulator.
654
- * @param {Mixed} [thisArg] The `this` binding for the callback.
655
- * @returns {Mixed} Returns the accumulated value.
656
- * @example
657
- *
658
- * var list = [[0, 1], [2, 3], [4, 5]];
659
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
660
- * // => [4, 5, 2, 3, 0, 1]
661
- */
662
- function reduceRight(collection, callback, result, thisArg) {
663
- var initial = arguments.length > 2;
664
- if (collection == undefined) {
665
- return result;
666
- }
667
- if(thisArg) {
668
- callback = bind(callback, thisArg);
669
- }
670
- var length = collection.length;
671
- if (length === +length) {
672
- if (length && !initial) {
673
- result = collection[--length];
674
- }
675
- while (length--) {
676
- result = callback(result, collection[length], length, collection);
677
- }
678
- return result;
679
- }
680
-
681
- var prop,
682
- props = keys(collection);
683
-
684
- length = props.length;
685
- if (length && !initial) {
686
- result = collection[props[--length]];
687
- }
688
- while (length--) {
689
- prop = props[length];
690
- result = callback(result, collection[prop], prop, collection);
691
- }
692
- return result;
693
- }
694
-
695
- /**
696
- * The opposite of `_.filter`, this method returns the values of a `collection`
697
- * that `callback` does **not** return truthy for. The `callback` is invoked
698
- * with 3 arguments; for arrays they are (value, index, array) and for objects
699
- * they are (value, key, object).
700
- *
701
- * @static
702
- * @memberOf _
703
- * @category Collections
704
- * @param {Array|Object} collection The collection to iterate over.
705
- * @param {Function} callback The function called per iteration.
706
- * @param {Mixed} [thisArg] The `this` binding for the callback.
707
- * @returns {Array} Returns a new array of values that did **not** pass the callback check.
708
- * @example
709
- *
710
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
711
- * // => [1, 3, 5]
712
- */
713
- var reject = iterationFactory(forEachFactoryOptions, filterFactoryOptions, {
714
- 'inLoop': '!' + filterFactoryOptions.inLoop
715
- });
716
-
717
- /**
718
- * Produces a new array of shuffled `collection` values, using a version of the
719
- * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
720
- *
721
- * @static
722
- * @memberOf _
723
- * @category Collections
724
- * @param {Array|Object} collection The collection to shuffle.
725
- * @returns {Array} Returns a new shuffled array.
726
- * @example
727
- *
728
- * _.shuffle([1, 2, 3, 4, 5, 6]);
729
- * // => [4, 1, 6, 3, 5, 2]
730
- */
731
- function shuffle(collection) {
732
- var rand,
733
- result = [];
734
-
735
- forEach(collection, function(value, index) {
736
- rand = Math.floor(Math.random() * (index + 1));
737
- result[index] = result[rand];
738
- result[rand] = value;
739
- });
740
- return result;
741
- }
742
-
743
- /**
744
- * Gets the number of values in the `collection`.
745
- *
746
- * @static
747
- * @memberOf _
748
- * @category Collections
749
- * @param {Array|Object} collection The collection inspect.
750
- * @returns {Number} Returns the number of values in the collection.
751
- * @example
752
- *
753
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
754
- * // => 3
755
- */
756
- function size(collection) {
757
- var className = toString.call(collection);
758
- return className == arrayClass || className == stringClass
759
- ? collection.length
760
- : keys(collection).length;
761
- }
762
-
763
- /**
764
- * Produces a new sorted array, ranked in ascending order by the results of
765
- * running each value of a `collection` through `callback`. The `callback` is
766
- * invoked with 3 arguments; for arrays they are (value, index, array) and for
767
- * objects they are (value, key, object). The `callback` argument may also be
768
- * the name of a property to sort by (e.g. 'length').
769
- *
770
- * @static
771
- * @memberOf _
772
- * @category Collections
773
- * @param {Array|Object} collection The collection to iterate over.
774
- * @param {Function|String} callback The function called per iteration or
775
- * property name to sort by.
776
- * @param {Mixed} [thisArg] The `this` binding for the callback.
777
- * @returns {Array} Returns a new array of sorted values.
778
- * @example
779
- *
780
- * _.sortBy([1, 2, 3, 4, 5, 6], function(num) { return Math.sin(num); });
781
- * // => [5, 4, 6, 3, 1, 2]
782
- */
783
- function sortBy(collection, callback, thisArg) {
784
- if (!isFunction(callback)) {
785
- var prop = callback;
786
- callback = function(collection) { return collection[prop]; };
787
- } else if (thisArg) {
788
- callback = bind(callback, thisArg);
789
- }
790
- return pluck(map(collection, function(value, index) {
791
- return {
792
- 'criteria': callback(value, index, collection),
793
- 'value': value
794
- };
795
- }).sort(function(left, right) {
796
- var a = left.criteria,
797
- b = right.criteria;
798
-
799
- if (a === undefined) {
800
- return 1;
801
- }
802
- if (b === undefined) {
803
- return -1;
804
- }
805
- return a < b ? -1 : a > b ? 1 : 0;
806
- }), 'value');
807
- }
808
-
809
- /**
810
- * Checks if the `callback` returns truthy for **any** value of a `collection`.
811
- * The function returns as soon as it finds passing value, and does not iterate
812
- * over the entire `collection`. The `callback` is invoked with 3 arguments; for
813
- * arrays they are (value, index, array) and for objects they are
814
- * (value, key, object).
815
- *
816
- * @static
817
- * @memberOf _
818
- * @alias any
819
- * @category Collections
820
- * @param {Array|Object} collection The collection to iterate over.
821
- * @param {Function} callback The function called per iteration.
822
- * @param {Mixed} [thisArg] The `this` binding for the callback.
823
- * @returns {Boolean} Returns `true` if any value passes the callback check, else `false`.
824
- * @example
825
- *
826
- * _.some([null, 0, 'yes', false]);
827
- * // => true
828
- */
829
- var some = iterationFactory(forEachFactoryOptions, everyFactoryOptions, {
830
- 'init': 'false',
831
- 'inLoop': everyFactoryOptions.inLoop.replace('!', '')
832
- });
833
-
834
- /**
835
- * Uses a binary search to determine the smallest index at which the `value`
836
- * should be inserted into the `collection` in order to maintain the sort order
837
- * of the `collection`. If `callback` is passed, it will be executed for each
838
- * value in the `collection` to compute their sort ranking. The `callback` is
839
- * invoked with 1 argument.
840
- *
841
- * @static
842
- * @memberOf _
843
- * @category Collections
844
- * @param {Array} array The array to iterate over.
845
- * @param {Mixed} value The value to evaluate.
846
- * @param {Function} [callback] The function called per iteration.
847
- * @returns {Number} Returns the index at which the value should be inserted
848
- * into the collection.
849
- * @example
850
- *
851
- * _.sortedIndex([10, 20, 30, 40, 50], 35);
852
- * // => 3
853
- */
854
- function sortedIndex(array, object, callback) {
855
- var low = 0,
856
- high = array.length;
857
-
858
- callback || (callback = identity);
859
- while (low < high) {
860
- var mid = (low + high) >> 1;
861
- callback(array[mid]) < callback(object) ? (low = mid + 1) : (high = mid);
862
- }
863
- return low;
864
- }
865
-
866
- /**
867
- * Converts the `collection`, into an array. Useful for converting the
868
- * `arguments` object.
869
- *
870
- * @static
871
- * @memberOf _
872
- * @category Collections
873
- * @param {Array|Object} collection The collection to convert.
874
- * @returns {Array} Returns the new converted array.
875
- * @example
876
- *
877
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
878
- * // => [2, 3, 4]
879
- */
880
- function toArray(collection) {
881
- if (!collection) {
882
- return [];
883
- }
884
- if (isFunction(collection.toArray)) {
885
- return collection.toArray();
886
- }
887
- var length = collection.length;
888
- if (length === +length) {
889
- return slice.call(collection);
890
- }
891
- return values(collection);
892
- }
893
-
894
- /**
895
- * Produces an array of enumerable own property values of the `collection`.
896
- *
897
- * @static
898
- * @memberOf _
899
- * @alias methods
900
- * @category Collections
901
- * @param {Array|Object} collection The collection to inspect.
902
- * @returns {Array} Returns a new array of property values.
903
- * @example
904
- *
905
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
906
- * // => [1, 2, 3]
907
- */
908
- var values = iterationFactory(mapFactoryOptions, {
909
- 'args': 'collection',
910
- 'inLoop': {
911
- 'array': 'result[index]=collection[index]',
912
- 'object': 'result[result.length]=collection[index]'
913
- }
914
- });
915
-
916
- /*--------------------------------------------------------------------------*/
917
-
918
- /**
919
- * Produces a new array with all falsey values of `array` removed. The values
920
- * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
921
- *
922
- * @static
923
- * @memberOf _
924
- * @category Arrays
925
- * @param {Array} array The array to compact.
926
- * @returns {Array} Returns a new filtered array.
927
- * @example
928
- *
929
- * _.compact([0, 1, false, 2, '', 3]);
930
- * // => [1, 2, 3]
931
- */
932
- var compact = iterationFactory({
933
- 'args': 'array',
934
- 'init': '[]',
935
- 'inLoop': 'if(array[index])result.push(array[index])'
936
- });
937
-
938
- /**
939
- * Produces a new array of `array` values not present in the other arrays
940
- * using strict equality for comparisons, i.e. `===`.
941
- *
942
- * @static
943
- * @memberOf _
944
- * @category Arrays
945
- * @param {Array} array The array to process.
946
- * @param {Mixed} [array1, array2, ...] Arrays to check.
947
- * @returns {Array} Returns a new array of `array` values not present in the
948
- * other arrays.
949
- * @example
950
- *
951
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
952
- * // => [1, 3, 4]
953
- */
954
- var difference = iterationFactory(differenceFactoryOptions);
955
-
956
- /**
957
- * Gets the first value of the `array`. Pass `n` to return the first `n` values
958
- * of the `array`.
959
- *
960
- * @static
961
- * @memberOf _
962
- * @alias head, take
963
- * @category Arrays
964
- * @param {Array} array The array to query.
965
- * @param {Number} [n] The number of elements to return.
966
- * @param {Object} [guard] Internally used to allow this method to work with
967
- * others like `_.map` without using their callback `index` argument for `n`.
968
- * @returns {Mixed} Returns the first value or an array of the first `n` values
969
- * of the `array`.
970
- * @example
971
- *
972
- * _.first([5, 4, 3, 2, 1]);
973
- * // => 5
974
- */
975
- function first(array, n, guard) {
976
- return (n == undefined || guard) ? array[0] : slice.call(array, 0, n);
977
- }
978
-
979
- /**
980
- * Flattens a nested array (the nesting can be to any depth). If `shallow` is
981
- * truthy, `array` will only be flattened a single level.
982
- *
983
- * @static
984
- * @memberOf _
985
- * @category Arrays
986
- * @param {Array} array The array to compact.
987
- * @param {Boolean} shallow A flag to indicate only flattening a single level.
988
- * @returns {Array} Returns a new flattened array.
989
- * @example
990
- *
991
- * _.flatten([1, [2], [3, [[4]]]]);
992
- * // => [1, 2, 3, 4];
993
- *
994
- * _.flatten([1, [2], [3, [[4]]]], true);
995
- * // => [1, 2, 3, [[4]]];
996
- */
997
- function flatten(array, shallow) {
998
- if (shallow) {
999
- return concat.apply([], array);
1000
- }
1001
- return reduce(array, function(accumulator, value) {
1002
- if (isArray(value)) {
1003
- push.apply(accumulator, flatten(value));
1004
- return accumulator;
1005
- }
1006
- accumulator.push(value);
1007
- return accumulator;
1008
- }, []);
1009
- }
1010
-
1011
- /**
1012
- * Gets the index at which the first occurrence of `value` is found using
1013
- * strict equality for comparisons, i.e. `===`. If the `array` is already
1014
- * sorted, passing `true` for `isSorted` will run a faster binary search.
1015
- *
1016
- * @static
1017
- * @memberOf _
1018
- * @category Arrays
1019
- * @param {Array} array The array to search.
1020
- * @param {Mixed} value The value to search for.
1021
- * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
1022
- * @returns {Number} Returns the index of the matched value or `-1`.
1023
- * @example
1024
- *
1025
- * _.indexOf([1, 2, 3], 2);
1026
- * // => 1
1027
- */
1028
- function indexOf(array, value, isSorted) {
1029
- var index, length;
1030
- if (array == undefined) {
1031
- return -1;
1032
- }
1033
- if (isSorted) {
1034
- index = sortedIndex(array, value);
1035
- return array[index] === value ? index : -1;
1036
- }
1037
- for (index = 0, length = array.length; index < length; index++) {
1038
- if (array[index] === value) {
1039
- return index;
1040
- }
1041
- }
1042
- return -1;
1043
- }
1044
-
1045
- /**
1046
- * Gets all but the last value of the `array`. Pass `n` to exclude the last `n`
1047
- * values from the result.
1048
- *
1049
- * @static
1050
- * @memberOf _
1051
- * @category Arrays
1052
- * @param {Array} array The array to query.
1053
- * @param {Number} [n] The number of elements to return.
1054
- * @param {Object} [guard] Internally used to allow this method to work with
1055
- * others like `_.map` without using their callback `index` argument for `n`.
1056
- * @returns {Array} Returns all but the last value or `n` values of the `array`.
1057
- * @example
1058
- *
1059
- * _.initial([5, 4, 3, 2, 1]);
1060
- * // => [5, 4, 3, 2]
1061
- */
1062
- function initial(array, n, guard) {
1063
- return slice.call(array, 0, -((n == undefined || guard) ? 1 : n));
1064
- }
1065
-
1066
- /**
1067
- * Computes the intersection of all the passed-in arrays.
1068
- *
1069
- * @static
1070
- * @memberOf _
1071
- * @alias intersect
1072
- * @category Arrays
1073
- * @param {Mixed} [array1, array2, ...] Arrays to process.
1074
- * @returns {Array} Returns a new array of unique values, in order, that are
1075
- * present in **all** of the arrays.
1076
- * @example
1077
- *
1078
- * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
1079
- * // => [1, 2]
1080
- */
1081
- function intersection(array) {
1082
- var rest = slice.call(arguments, 1);
1083
- return filter(uniq(array), function(value) {
1084
- return every(rest, function(other) {
1085
- return indexOf(other, value) >= 0;
1086
- });
1087
- });
1088
- }
1089
-
1090
- /**
1091
- * Gets the last value of the `array`. Pass `n` to return the lasy `n` values
1092
- * of the `array`.
1093
- *
1094
- * @static
1095
- * @memberOf _
1096
- * @category Arrays
1097
- * @param {Array} array The array to query.
1098
- * @param {Number} [n] The number of elements to return.
1099
- * @param {Object} [guard] Internally used to allow this method to work with
1100
- * others like `_.map` without using their callback `index` argument for `n`.
1101
- * @returns {Array} Returns all but the last value or `n` values of the `array`.
1102
- * @example
1103
- *
1104
- * _.last([5, 4, 3, 2, 1]);
1105
- * // => 1
1106
- */
1107
- function last(array, n, guard) {
1108
- var length = array.length;
1109
- return (n == undefined || guard) ? array[length - 1] : slice.call(array, -n || length);
1110
- }
1111
-
1112
- /**
1113
- * Gets the index at which the last occurrence of `value` is found using
1114
- * strict equality for comparisons, i.e. `===`.
1115
- *
1116
- * @static
1117
- * @memberOf _
1118
- * @category Arrays
1119
- * @param {Array} array The array to search.
1120
- * @param {Mixed} value The value to search for.
1121
- * @returns {Number} Returns the index of the matched value or `-1`.
1122
- * @example
1123
- *
1124
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
1125
- * // => 4
1126
- */
1127
- function lastIndexOf(array, value) {
1128
- if (array == undefined) {
1129
- return -1;
1130
- }
1131
- var index = array.length;
1132
- while (index--) {
1133
- if (array[index] === value) {
1134
- return index;
1135
- }
1136
- }
1137
- return -1;
1138
- }
1139
-
1140
- /**
1141
- * Creates an array of numbers (positive and/or negative) progressing from
1142
- * `start` up to but not including `stop`. This method is a port of Python's
1143
- * `range()` function. See http://docs.python.org/library/functions.html#range.
1144
- *
1145
- * @static
1146
- * @memberOf _
1147
- * @category Arrays
1148
- * @param {Number} [start=0] The start of the range.
1149
- * @param {Number} end The end of the range.
1150
- * @param {Number} [step=1] The value to increment or descrement by.
1151
- * @returns {Array} Returns a new range array.
1152
- * @example
1153
- *
1154
- * _.range(10);
1155
- * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1156
- *
1157
- * _.range(1, 11);
1158
- * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1159
- *
1160
- * _.range(0, 30, 5);
1161
- * // => [0, 5, 10, 15, 20, 25]
1162
- *
1163
- * _.range(0, -10, -1);
1164
- * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
1165
- *
1166
- * _.range(0);
1167
- * // => []
1168
- */
1169
- function range(start, end, step) {
1170
- step || (step = 1);
1171
- if (arguments.length < 2) {
1172
- end = start || 0;
1173
- start = 0;
1174
- }
1175
-
1176
- var index = -1,
1177
- length = Math.max(Math.ceil((end - start) / step), 0),
1178
- result = Array(length);
1179
-
1180
- while (++index < length) {
1181
- result[index] = start;
1182
- start += step;
1183
- }
1184
- return result;
1185
- }
1186
-
1187
- /**
1188
- * The opposite of `_.initial`, this method gets all but the first value of
1189
- * the `array`. Pass `n` to exclude the first `n` values from the result.
1190
- *
1191
- * @static
1192
- * @memberOf _
1193
- * @alias tail
1194
- * @category Arrays
1195
- * @param {Array} array The array to query.
1196
- * @param {Number} [n] The number of elements to return.
1197
- * @param {Object} [guard] Internally used to allow this method to work with
1198
- * others like `_.map` without using their callback `index` argument for `n`.
1199
- * @returns {Array} Returns all but the first value or `n` values of the `array`.
1200
- * @example
1201
- *
1202
- * _.rest([5, 4, 3, 2, 1]);
1203
- * // => [4, 3, 2, 1]
1204
- */
1205
- function rest(array, n, guard) {
1206
- return slice.call(array, (n == undefined || guard) ? 1 : n);
1207
- }
1208
-
1209
- /**
1210
- * Computes the union of the passed-in arrays.
1211
- *
1212
- * @static
1213
- * @memberOf _
1214
- * @category Arrays
1215
- * @param {Mixed} [array1, array2, ...] Arrays to process.
1216
- * @returns {Array} Returns a new array of unique values, in order, that are
1217
- * present in one or more of the arrays.
1218
- * @example
1219
- *
1220
- * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
1221
- * // => [1, 2, 3, 101, 10]
1222
- */
1223
- function union() {
1224
- return uniq(flatten(arguments, true));
1225
- }
1226
-
1227
- /**
1228
- * Produces a duplicate-value-free version of the `array` using strict equality
1229
- * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
1230
- * for `isSorted` will run a faster algorithm. If `callback` is passed,
1231
- * each value of `array` is passed through a transformation `callback` before
1232
- * uniqueness is computed. The `callback` is invoked with 3 arguments;
1233
- * (value, index, array).
1234
- *
1235
- * @static
1236
- * @memberOf _
1237
- * @alias unique
1238
- * @category Arrays
1239
- * @param {Array} array The array to process.
1240
- * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
1241
- * @param {Function} [callback] A
1242
- * @returns {Array} Returns a duplicate-value-free array.
1243
- * @example
1244
- *
1245
- * _.uniq([1, 2, 1, 3, 1, 4]);
1246
- * // => [1, 2, 3, 4]
1247
- */
1248
- function uniq(array, isSorted, callback) {
1249
- var initial = callback ? map(array, callback) : array,
1250
- result = [];
1251
-
1252
- // the `isSorted` flag is irrelevant if the array only contains two elements.
1253
- if (array.length < 3) {
1254
- isSorted = true;
1255
- }
1256
- reduce(initial, function(accumulator, value, index) {
1257
- if (isSorted ? last(accumulator) !== value || !accumulator.length : indexOf(accumulator, value) < 0) {
1258
- accumulator.push(value);
1259
- result.push(array[index]);
1260
- }
1261
- return accumulator;
1262
- }, []);
1263
-
1264
- return result;
1265
- }
1266
-
1267
- /**
1268
- * Produces a new array with all occurrences of the values removed using strict
1269
- * equality for comparisons, i.e. `===`.
1270
- *
1271
- * @static
1272
- * @memberOf _
1273
- * @category Arrays
1274
- * @param {Array} array The array to filter.
1275
- * @param {Mixed} [value1, value2, ...] Values to remove.
1276
- * @returns {Array} Returns a new filtered array.
1277
- * @example
1278
- *
1279
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
1280
- * // => [2, 3, 4]
1281
- */
1282
- var without = iterationFactory(differenceFactoryOptions, {
1283
- 'top': 'var values=slice.call(arguments,1)',
1284
- 'init': '[]'
1285
- });
1286
-
1287
- /**
1288
- * Merges together the values of each of the arrays with the value at the
1289
- * corresponding position. Useful for separate data sources that are coordinated
1290
- * through matching array indexes. For a matrix of nested arrays, `_.zip.apply(...)`
1291
- * can transpose the matrix in a similar fashion.
1292
- *
1293
- * @static
1294
- * @memberOf _
1295
- * @category Arrays
1296
- * @param {Mixed} [array1, array2, ...] Arrays to process.
1297
- * @returns {Array} Returns a new array of merged arrays.
1298
- * @example
1299
- *
1300
- * _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
1301
- * // => [['moe', 30, true], ['larry', 40, false], ['curly', 50, false]]
1302
- */
1303
- function zip() {
1304
- var index = -1,
1305
- length = max(pluck(arguments, 'length')),
1306
- result = Array(length);
1307
-
1308
- while (++index < length) {
1309
- result[index] = pluck(arguments, index);
1310
- }
1311
- return result;
1312
- }
1313
-
1314
- /*--------------------------------------------------------------------------*/
1315
-
1316
- /**
1317
- * Creates a new function that is restricted to executing only after it is
1318
- * called a given number of `times`.
1319
- *
1320
- * @static
1321
- * @memberOf _
1322
- * @category Functions
1323
- * @param {Number} times The number of times the function must be called before
1324
- * it is executed.
1325
- * @param {Function} func The function to restrict.
1326
- * @returns {Function} Returns the new restricted function.
1327
- * @example
1328
- *
1329
- * var renderNotes = _.after(notes.length, render);
1330
- * _.forEach(notes, function(note) {
1331
- * note.asyncSave({ 'success': renderNotes });
1332
- * });
1333
- * // renderNotes is run once, after all notes have saved.
1334
- */
1335
- function after(times, func) {
1336
- if (times < 1) {
1337
- return func();
1338
- }
1339
- return function() {
1340
- if (--times < 1) {
1341
- return func.apply(this, arguments);
1342
- }
1343
- };
1344
- }
1345
-
1346
- /**
1347
- * Creates a new function that, when called, invokes `func` with the `this`
1348
- * binding of `thisArg` and prepends additional arguments to those passed to
1349
- * the bound function.
1350
- *
1351
- * @static
1352
- * @memberOf _
1353
- * @category Functions
1354
- * @param {Function} func The function to bind.
1355
- * @param @param {Mixed} [thisArg] The `this` binding of `func`.
1356
- * @param {Mixed} [arg1, arg2, ...] Arguments to prepend to those passed to the bound function.
1357
- * @returns {Function} Returns the new bound function.
1358
- * @example
1359
- *
1360
- * var func = function(greeting) { return greeting + ': ' + this.name; };
1361
- * func = _.bind(func, { 'name': 'moe' }, 'hi');
1362
- * func();
1363
- * // => 'hi: moe'
1364
- */
1365
- function bind(func, thisArg) {
1366
- var args = slice.call(arguments, 2),
1367
- argsLength = args.length;
1368
-
1369
- return function() {
1370
- args.length = argsLength;
1371
- push.apply(args, arguments);
1372
- return func.apply(thisArg, args);
1373
- };
1374
- }
1375
-
1376
- /**
1377
- * Binds methods on the `object` to the object, overwriting the non-bound method.
1378
- * If no method names are provided, all the function properties of the `object`
1379
- * will be bound.
1380
- *
1381
- * @static
1382
- * @memberOf _
1383
- * @category Functions
1384
- * @param {Object} object The object to bind and assign the bound methods to.
1385
- * @param {Mixed} [methodName1, methodName2, ...] Method names on the object to bind.
1386
- * @returns {Object} Returns the `object`.
1387
- * @example
1388
- *
1389
- * var buttonView = {
1390
- * 'label': 'lodash',
1391
- * 'onClick': function() { alert('clicked: ' + this.label); },
1392
- * 'onHover': function() { console.log('hovering: ' + this.label); }
1393
- * };
1394
- *
1395
- * _.bindAll(buttonView);
1396
- * jQuery('#lodash_button').on('click', buttonView.onClick);
1397
- * // => When the button is clicked, `this.label` will have the correct value
1398
- */
1399
- function bindAll(object) {
1400
- var funcs = arguments,
1401
- index = 1;
1402
-
1403
- if (funcs.length == 1) {
1404
- index = 0;
1405
- funcs = functions(object);
1406
- }
1407
- for (var length = funcs.length; index < length; index++) {
1408
- object[funcs[index]] = bind(object[funcs[index]], object);
1409
- }
1410
- return object;
1411
- }
1412
-
1413
- /**
1414
- * Creates a new function that is the composition of the passed functions,
1415
- * where each function consumes the return value of the function that follows.
1416
- * In math terms, composing thefunctions `f()`, `g()`, and `h()` produces `f(g(h()))`.
1417
- *
1418
- * @static
1419
- * @memberOf _
1420
- * @category Functions
1421
- * @param {Mixed} [func1, func2, ...] Functions to compose.
1422
- * @returns {Function} Returns the new composed function.
1423
- * @example
1424
- *
1425
- * var greet = function(name) { return 'hi: ' + name; };
1426
- * var exclaim = function(statement) { return statement + '!'; };
1427
- * var welcome = _.compose(exclaim, greet);
1428
- * welcome('moe');
1429
- * // => 'hi: moe!'
1430
- */
1431
- function compose() {
1432
- var funcs = arguments;
1433
- return function() {
1434
- var args = arguments,
1435
- length = funcs.length;
1436
-
1437
- while (length--) {
1438
- args = [funcs[length].apply(this, args)];
1439
- }
1440
- return args[0];
1441
- };
1442
- }
1443
-
1444
- /**
1445
- * Creates a new function that will postpone its execution until after `wait`
1446
- * milliseconds have elapsed since the last time it was invoked. Pass `true`
1447
- * for `immediate` to cause debounce to invoke the function on the leading,
1448
- * instead of the trailing, edge of the `wait` timeout.
1449
- *
1450
- * @static
1451
- * @memberOf _
1452
- * @category Functions
1453
- * @param {Function} func The function to debounce.
1454
- * @param {Number} wait The number of milliseconds to postone.
1455
- * @param {Boolean} immediate A flag to indicate execution is on the leading
1456
- * edge of the timeout.
1457
- * @returns {Function} Returns the new debounced function.
1458
- * @example
1459
- *
1460
- * var lazyLayout = _.debounce(calculateLayout, 300);
1461
- * jQuery(window).on('resize', lazyLayout);
1462
- */
1463
- function debounce(func, wait, immediate) {
1464
- var timeout;
1465
- return function() {
1466
- var args = arguments,
1467
- thisArg = this;
1468
-
1469
- if (immediate && !timeout) {
1470
- func.apply(thisArg, args);
1471
- }
1472
- clearTimeout(timeout);
1473
- timeout = setTimeout(function() {
1474
- timeout = undefined;
1475
- if (!immediate) {
1476
- func.apply(thisArg, args);
1477
- }
1478
- }, wait);
1479
- };
1480
- }
1481
-
1482
- /**
1483
- * Invokes the `func` function after `wait` milliseconds. Additional arguments
1484
- * are passed `func` when it is invoked.
1485
- *
1486
- * @static
1487
- * @memberOf _
1488
- * @category Functions
1489
- * @param {Function} func The function to delay.
1490
- * @param {Number} wait The number of milliseconds to delay execution.
1491
- * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
1492
- * @returns {Number} Returns the `setTimeout` timeout id.
1493
- * @example
1494
- *
1495
- * var log = _.bind(console.log, console);
1496
- * _.delay(log, 1000, 'logged later');
1497
- * // => 'logged later' (Appears after one second.)
1498
- */
1499
- function delay(func, wait) {
1500
- var args = slice.call(arguments, 2);
1501
- return setTimeout(function() { return func.apply(undefined, args); }, wait);
1502
- }
1503
-
1504
- /**
1505
- * Defers invoking the `func` function until the current call stack has cleared.
1506
- * Additional arguments are passed to `func` when it is invoked.
1507
- *
1508
- * @static
1509
- * @memberOf _
1510
- * @category Functions
1511
- * @param {Function} func The function to defer.
1512
- * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
1513
- * @returns {Number} Returns the `setTimeout` timeout id.
1514
- * @example
1515
- *
1516
- * _.defer(function() { alert('deferred'); });
1517
- * // Returns from the function before the alert runs.
1518
- */
1519
- function defer(func) {
1520
- var args = slice.call(arguments, 1);
1521
- return setTimeout(function() { return func.apply(undefined, args); }, 1);
1522
- }
1523
-
1524
- /**
1525
- * Creates a new function that memoizes the result of `func`. If `resolver` is
1526
- * passed, it will be used to determine the cache key for storing the result
1527
- * based on the arguments passed to the memoized function. By default, the first
1528
- * argument passed to the memoized function is used as the cache key.
1529
- *
1530
- * @static
1531
- * @memberOf _
1532
- * @category Functions
1533
- * @param {Function} func The function to have its output memoized.
1534
- * @param {Function} [resolver] A function used to resolve the cache key.
1535
- * @returns {Function} Returns the new memoizing function.
1536
- * @example
1537
- *
1538
- * var fibonacci = _.memoize(function(n) {
1539
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
1540
- * });
1541
- */
1542
- function memoize(func, resolver) {
1543
- var cache = {};
1544
- return function() {
1545
- var prop = resolver ? resolver.apply(this, arguments) : arguments[0];
1546
- return hasOwnProperty.call(cache, prop)
1547
- ? cache[prop]
1548
- : (cache[prop] = func.apply(this, arguments));
1549
- };
1550
- }
1551
-
1552
- /**
1553
- * Creates a new function that is restricted to one execution. Repeat calls to
1554
- * the function will return the value of the first call.
1555
- *
1556
- * @static
1557
- * @memberOf _
1558
- * @category Functions
1559
- * @param {Function} func The function to restrict.
1560
- * @returns {Function} Returns the new restricted function.
1561
- * @example
1562
- *
1563
- * var initialize = _.once(createApplication);
1564
- * initialize();
1565
- * initialize();
1566
- * // Application is only created once.
1567
- */
1568
- function once(func) {
1569
- var result,
1570
- ran = false;
1571
-
1572
- return function() {
1573
- if (ran) {
1574
- return result;
1575
- }
1576
- ran = true;
1577
- result = func.apply(this, arguments);
1578
- return result;
1579
- };
1580
- }
1581
-
1582
- /**
1583
- * Creates a new function that, when invoked, will only call the original
1584
- * function at most once per every `wait` milliseconds.
1585
- *
1586
- * @static
1587
- * @memberOf _
1588
- * @category Functions
1589
- * @param {Function} func The function to throttle.
1590
- * @param {Number} wait The number of milliseconds to throttle executions to.
1591
- * @returns {Function} Returns the new throttled function.
1592
- * @example
1593
- *
1594
- * var throttled = _.throttle(updatePosition, 100);
1595
- * jQuery(window).on('scroll', throttled);
1596
- */
1597
- function throttle(func, wait) {
1598
- var args, more, result, thisArg, throttling, timeout,
1599
- whenDone = debounce(function() { more = throttling = false; }, wait);
1600
-
1601
- return function() {
1602
- args = arguments;
1603
- thisArg = this;
1604
-
1605
- if (!timeout) {
1606
- timeout = setTimeout(function() {
1607
- timeout = undefined;
1608
- if (more) {
1609
- func.apply(thisArg, args);
1610
- }
1611
- whenDone();
1612
- }, wait);
1613
- }
1614
- if (throttling) {
1615
- more = true;
1616
- } else {
1617
- result = func.apply(thisArg, args);
1618
- }
1619
- whenDone();
1620
- throttling = true;
1621
- return result;
1622
- };
1623
- }
1624
-
1625
- /**
1626
- * Create a new function that passes the `func` function to the `wrapper`
1627
- * function as its first argument. Additional arguments are appended to those
1628
- * passed to the `wrapper` function.
1629
- *
1630
- * @static
1631
- * @memberOf _
1632
- * @category Functions
1633
- * @param {Function} func The function to wrap.
1634
- * @param {Function} wrapper The wrapper function.
1635
- * @param {Mixed} [arg1, arg2, ...] Arguments to append to those passed to the wrapper.
1636
- * @returns {Function} Returns the new function.
1637
- * @example
1638
- *
1639
- * var hello = function(name) { return 'hello: ' + name; };
1640
- * hello = _.wrap(hello, function(func) {
1641
- * return 'before, ' + func('moe') + ', after';
1642
- * });
1643
- * hello();
1644
- * // => 'before, hello: moe, after'
1645
- */
1646
- function wrap(func, wrapper) {
1647
- return function() {
1648
- var args = [func];
1649
- push.apply(args, arguments);
1650
- return wrapper.apply(this, args);
1651
- };
1652
- }
1653
-
1654
- /*--------------------------------------------------------------------------*/
1655
-
1656
- /**
1657
- * Create a shallow clone of the `value`. Any nested objects or arrays will be
1658
- * assigned by reference and not cloned.
1659
- *
1660
- * @static
1661
- * @memberOf _
1662
- * @category Objects
1663
- * @param {Mixed} value The value to clone.
1664
- * @returns {Mixed} Returns the cloned `value`.
1665
- * @example
1666
- *
1667
- * _.clone({ 'name': 'moe' });
1668
- * // => { 'name': 'moe' };
1669
- */
1670
- function clone(value) {
1671
- if (value !== Object(value)) {
1672
- return value;
1673
- }
1674
- return isArray(value) ? value.slice() : extend({}, value);
1675
- }
1676
-
1677
- /**
1678
- * Assigns missing properties in `object` with default values from the defaults
1679
- * objects. As soon as a property is set, additional defaults of the same
1680
- * property will be ignored.
1681
- *
1682
- * @static
1683
- * @memberOf _
1684
- * @category Objects
1685
- * @param {Object} object The object to populate.
1686
- * @param {Object} [defaults1, defaults2, ..] The defaults objects to apply to `object`.
1687
- * @returns {Object} Returns `object`.
1688
- * @example
1689
- *
1690
- * var iceCream = { 'flavor': 'chocolate' };
1691
- * _.defaults(iceCream, { 'flavor': 'vanilla', 'sprinkles': 'lots' });
1692
- * // => { 'flavor': 'chocolate', 'sprinkles': 'lots' }
1693
- */
1694
- var defaults = iterationFactory(extendFactoryOptions, {
1695
- 'inLoop': 'if(object[index]==undefined)' + extendFactoryOptions.inLoop
1696
- });
1697
-
1698
- /**
1699
- * Copies enumerable properties from the source objects to the `destination` object.
1700
- * Subsequent sources will overwrite propery assignments of previous sources.
1701
- *
1702
- * @static
1703
- * @memberOf _
1704
- * @category Objects
1705
- * @param {Object} object The destination object.
1706
- * @param {Object} [source1, source2, ..] The source objects.
1707
- * @returns {Object} Returns the destination object.
1708
- * @example
1709
- *
1710
- * _.extend({ 'name': 'moe' }, { 'age': 40 });
1711
- * // => { 'name': 'moe', 'age': 40 }
1712
- */
1713
- var extend = iterationFactory(extendFactoryOptions);
1714
-
1715
- /**
1716
- * Produces a sorted array of the properties, own and inherited, of `object`
1717
- * that have function values.
1718
- *
1719
- * @static
1720
- * @memberOf _
1721
- * @alias methods
1722
- * @category Objects
1723
- * @param {Object} object The object to inspect.
1724
- * @returns {Array} Returns a new array of property names that have function values.
1725
- * @example
1726
- *
1727
- * _.functions(_);
1728
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
1729
- */
1730
- var functions = iterationFactory(keysFactoryOptions, {
1731
- 'top': '',
1732
- 'useHas': false,
1733
- 'inLoop': 'if(toString.call(object[index])==funcClass)result.push(index)',
1734
- 'returns': 'result.sort()'
1735
- });
1736
-
1737
- /**
1738
- * Checks if the specified object `property` exists and is a direct property,
1739
- * instead of an inherited property.
1740
- *
1741
- * @static
1742
- * @memberOf _
1743
- * @category Objects
1744
- * @param {Object} object The object to check.
1745
- * @param {String} property The property to check for.
1746
- * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
1747
- * @example
1748
- *
1749
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
1750
- * // => true
1751
- */
1752
- function has(object, prop) {
1753
- return hasOwnProperty.call(object, prop);
1754
- }
1755
-
1756
- /**
1757
- * Checks if a `value` is an `arguments` object.
1758
- *
1759
- * @static
1760
- * @memberOf _
1761
- * @category Objects
1762
- * @param {Mixed} value The value to check.
1763
- * @returns {Boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
1764
- * @example
1765
- *
1766
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
1767
- * // => true
1768
- *
1769
- * _.isArguments([1, 2, 3]);
1770
- * // => false
1771
- */
1772
- var isArguments = function isArguments(value) {
1773
- return toString.call(value) == '[object Arguments]';
1774
- };
1775
- // fallback for browser like IE<9 which detect `arguments` as `[object Object]`
1776
- if (!isArguments(arguments)) {
1777
- isArguments = function isArguments(value) {
1778
- return !!(value && hasOwnProperty.call(value, 'callee'));
1779
- };
1780
- }
1781
-
1782
- /**
1783
- * Checks if a `value` is a boolean (`true` or `false`) value.
1784
- *
1785
- * @static
1786
- * @memberOf _
1787
- * @category Objects
1788
- * @param {Mixed} value The value to check.
1789
- * @returns {Boolean} Returns `true` if the `value` is a boolean value, else `false`.
1790
- * @example
1791
- *
1792
- * _.isBoolean(null);
1793
- * // => false
1794
- */
1795
- function isBoolean(value) {
1796
- return value === true || value === false || toString.call(value) == boolClass;
1797
- }
1798
-
1799
- /**
1800
- * Checks if a `value` is a date.
1801
- *
1802
- * @static
1803
- * @memberOf _
1804
- * @category Objects
1805
- * @param {Mixed} value The value to check.
1806
- * @returns {Boolean} Returns `true` if the `value` is a date, else `false`.
1807
- * @example
1808
- *
1809
- * _.isDate(new Date);
1810
- * // => true
1811
- */
1812
- function isDate(value) {
1813
- return toString.call(value) == dateClass;
1814
- }
1815
-
1816
- /**
1817
- * Checks if a `value` is a DOM element.
1818
- *
1819
- * @static
1820
- * @memberOf _
1821
- * @category Objects
1822
- * @param {Mixed} value The value to check.
1823
- * @returns {Boolean} Returns `true` if the `value` is a DOM element, else `false`.
1824
- * @example
1825
- *
1826
- * _.isElement(document.body);
1827
- * // => true
1828
- */
1829
- function isElement(value) {
1830
- return !!(value && value.nodeType == 1);
1831
- }
1832
-
1833
- /**
1834
- * Performs a deep comparison between two values to determine if they are
1835
- * equivalent to each other.
1836
- *
1837
- * @static
1838
- * @memberOf _
1839
- * @category Objects
1840
- * @param {Mixed} a The value to compare.
1841
- * @param {Mixed} b The other value to compare.
1842
- * @param {Array} [stack] Internally used to keep track of "seen" objects to
1843
- * avoid circular references.
1844
- * @returns {Boolean} Returns `true` if the values are equvalent, else `false`.
1845
- * @example
1846
- *
1847
- * var moe = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] };
1848
- * var clone = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] };
1849
- *
1850
- * moe == clone;
1851
- * // => false
1852
- *
1853
- * _.isEqual(moe, clone);
1854
- * // => true
1855
- */
1856
- function isEqual(a, b, stack) {
1857
- stack || (stack = []);
1858
-
1859
- // exit early for identical values
1860
- if (a === b) {
1861
- // treat `+0` vs. `-0` as not equal
1862
- return a !== 0 || (1 / a == 1 / b);
1863
- }
1864
- // a strict comparison is necessary because `null == undefined`
1865
- if (a == undefined || b == undefined) {
1866
- return a === b;
1867
- }
1868
- // unwrap any wrapped objects
1869
- if (a._chain) {
1870
- a = a._wrapped;
1871
- }
1872
- if (b._chain) {
1873
- b = b._wrapped;
1874
- }
1875
- // invoke a custom `isEqual` method if one is provided
1876
- if (a.isEqual && isFunction(a.isEqual)) {
1877
- return a.isEqual(b);
1878
- }
1879
- if (b.isEqual && isFunction(b.isEqual)) {
1880
- return b.isEqual(a);
1881
- }
1882
- // compare [[Class]] names
1883
- var className = toString.call(a);
1884
- if (className != toString.call(b)) {
1885
- return false;
1886
- }
1887
- switch (className) {
1888
- // strings, numbers, dates, and booleans are compared by value
1889
- case stringClass:
1890
- // primitives and their corresponding object instances are equivalent;
1891
- // thus, `'5'` is quivalent to `new String('5')`
1892
- return a == String(b);
1893
-
1894
- case numberClass:
1895
- // treat `NaN` vs. `NaN` as equal
1896
- return a != +a
1897
- ? b != +b
1898
- // but treat `+0` vs. `-0` as not equal
1899
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
1900
-
1901
- case boolClass:
1902
- case dateClass:
1903
- // coerce dates and booleans to numeric values, dates to milliseconds and booleans to 1 or 0;
1904
- // treat invalid dates coerced to `NaN` as not equal
1905
- return +a == +b;
1906
-
1907
- // regexps are compared by their source and flags
1908
- case regexpClass:
1909
- return a.source == b.source &&
1910
- a.global == b.global &&
1911
- a.multiline == b.multiline &&
1912
- a.ignoreCase == b.ignoreCase;
1913
- }
1914
- if (typeof a != 'object' || typeof b != 'object') {
1915
- return false;
1916
- }
1917
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
1918
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1919
- var length = stack.length;
1920
- while (length--) {
1921
- // Linear search. Performance is inversely proportional to the number of
1922
- // unique nested structures.
1923
- if (stack[length] == a) {
1924
- return true;
1925
- }
1926
- }
1927
-
1928
- var result = true,
1929
- size = 0;
1930
-
1931
- // add the first collection to the stack of traversed objects
1932
- stack.push(a);
1933
-
1934
- // recursively compare objects and arrays
1935
- if (className == arrayClass) {
1936
- // compare array lengths to determine if a deep comparison is necessary
1937
- size = a.length;
1938
- result = size == b.length;
1939
-
1940
- if (result) {
1941
- // deep compare the contents, ignoring non-numeric properties
1942
- while (size--) {
1943
- // ensure commutative equality for sparse arrays
1944
- if (!(result = size in a == size in b && isEqual(a[size], b[size], stack))) {
1945
- break;
1946
- }
1947
- }
1948
- }
1949
- } else {
1950
- // objects with different constructors are not equivalent
1951
- if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) {
1952
- return false;
1953
- }
1954
- // deep compare objects
1955
- for (var prop in a) {
1956
- if (hasOwnProperty.call(a, prop)) {
1957
- // count the expected number of properties
1958
- size++;
1959
- // deep compare each member
1960
- if (!(result = hasOwnProperty.call(b, prop) && isEqual(a[prop], b[prop], stack))) {
1961
- break;
1962
- }
1963
- }
1964
- }
1965
- // ensure that both objects contain the same number of properties
1966
- if (result) {
1967
- for (prop in b) {
1968
- if (hasOwnProperty.call(b, prop) && !(size--)) {
1969
- break;
1970
- }
1971
- }
1972
- result = !size;
1973
- }
1974
- }
1975
- // remove the first collection from the stack of traversed objects
1976
- stack.pop();
1977
- return result;
1978
- }
1979
-
1980
- /**
1981
- * Checks if a `value` is a finite number.
1982
- *
1983
- * @static
1984
- * @memberOf _
1985
- * @category Objects
1986
- * @param {Mixed} value The value to check.
1987
- * @returns {Boolean} Returns `true` if the `value` is a finite number, else `false`.
1988
- * @example
1989
- *
1990
- * _.isFinite(-101);
1991
- * // => true
1992
- *
1993
- * _.isFinite('10');
1994
- * // => false
1995
- *
1996
- * _.isFinite(Infinity);
1997
- * // => false
1998
- */
1999
- function isFinite(value) {
2000
- return nativeIsFinite(value) && toString.call(value) == numberClass;
2001
- }
2002
-
2003
- /**
2004
- * Checks if a `value` is a function.
2005
- *
2006
- * @static
2007
- * @memberOf _
2008
- * @category Objects
2009
- * @param {Mixed} value The value to check.
2010
- * @returns {Boolean} Returns `true` if the `value` is a function, else `false`.
2011
- * @example
2012
- *
2013
- * _.isFunction(''.concat);
2014
- * // => true
2015
- */
2016
- function isFunction(value) {
2017
- return toString.call(value) == funcClass;
2018
- }
2019
-
2020
- /**
2021
- * Checks if a `value` is an object.
2022
- *
2023
- * @static
2024
- * @memberOf _
2025
- * @category Objects
2026
- * @param {Mixed} value The value to check.
2027
- * @returns {Boolean} Returns `true` if the `value` is an object, else `false`.
2028
- * @example
2029
- *
2030
- * _.isObject({});
2031
- * // => true
2032
- *
2033
- * _.isObject(1);
2034
- * // => false
2035
- */
2036
- function isObject(value) {
2037
- return value === Object(value);
2038
- }
2039
-
2040
- /**
2041
- * Checks if a `value` is `NaN`.
2042
- * Note: this is not the same as native `isNaN`, which will return true for
2043
- * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
2044
- *
2045
- * @static
2046
- * @memberOf _
2047
- * @category Objects
2048
- * @param {Mixed} value The value to check.
2049
- * @returns {Boolean} Returns `true` if the `value` is `NaN`, else `false`.
2050
- * @example
2051
- *
2052
- * _.isNaN(NaN);
2053
- * // => true
2054
- *
2055
- * _.isNaN(new Number(NaN));
2056
- * // => true
2057
- *
2058
- * isNaN(undefined);
2059
- * // => true
2060
- *
2061
- * _.isNaN(undefined);
2062
- * // => false
2063
- */
2064
- function isNaN(value) {
2065
- // `NaN` as a primitive is the only value that is not equal to itself
2066
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
2067
- return toString.call(value) == numberClass && value != +value
2068
- }
2069
-
2070
- /**
2071
- * Checks if a `value` is `null`.
2072
- *
2073
- * @static
2074
- * @memberOf _
2075
- * @category Objects
2076
- * @param {Mixed} value The value to check.
2077
- * @returns {Boolean} Returns `true` if the `value` is `null`, else `false`.
2078
- * @example
2079
- *
2080
- * _.isNull(null);
2081
- * // => true
2082
- *
2083
- * _.isNull(undefined);
2084
- * // => false
2085
- */
2086
- function isNull(value) {
2087
- return value === null;
2088
- }
2089
-
2090
- /**
2091
- * Checks if a `value` is a number.
2092
- *
2093
- * @static
2094
- * @memberOf _
2095
- * @category Objects
2096
- * @param {Mixed} value The value to check.
2097
- * @returns {Boolean} Returns `true` if the `value` is a number, else `false`.
2098
- * @example
2099
- *
2100
- * _.isNumber(8.4 * 5;
2101
- * // => true
2102
- */
2103
- function isNumber(value) {
2104
- return toString.call(value) == numberClass;
2105
- }
2106
-
2107
- /**
2108
- * Checks if a `value` is a regular expression.
2109
- *
2110
- * @static
2111
- * @memberOf _
2112
- * @category Objects
2113
- * @param {Mixed} value The value to check.
2114
- * @returns {Boolean} Returns `true` if the `value` is a regular expression, else `false`.
2115
- * @example
2116
- *
2117
- * _.isRegExp(/moe/);
2118
- * // => true
2119
- */
2120
- function isRegExp(value) {
2121
- return toString.call(value) == regexpClass;
2122
- }
2123
-
2124
- /**
2125
- * Checks if a `value` is a string.
2126
- *
2127
- * @static
2128
- * @memberOf _
2129
- * @category Objects
2130
- * @param {Mixed} value The value to check.
2131
- * @returns {Boolean} Returns `true` if the `value` is a string, else `false`.
2132
- * @example
2133
- *
2134
- * _.isString('moe');
2135
- * // => true
2136
- */
2137
- function isString(value) {
2138
- return toString.call(value) == stringClass;
2139
- }
2140
-
2141
- /**
2142
- * Checks if a `value` is `undefined`.
2143
- *
2144
- * @static
2145
- * @memberOf _
2146
- * @category Objects
2147
- * @param {Mixed} value The value to check.
2148
- * @returns {Boolean} Returns `true` if the `value` is `undefined`, else `false`.
2149
- * @example
2150
- *
2151
- * _.isUndefined(void 0);
2152
- * // => true
2153
- */
2154
- function isUndefined(value) {
2155
- return value === undefined;
2156
- }
2157
-
2158
- /**
2159
- * Produces an array of the `object`'s enumerable own property names.
2160
- *
2161
- * @static
2162
- * @memberOf _
2163
- * @category Objects
2164
- * @param {Object} object The object to inspect.
2165
- * @returns {Array} Returns a new array of property names.
2166
- * @example
2167
- *
2168
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
2169
- * // => ['one', 'two', 'three']
2170
- */
2171
- var keys = nativeKeys || iterationFactory(keysFactoryOptions);
2172
-
2173
- /**
2174
- * Creates an object composed of the specified properties. Property names may
2175
- * be specified as individual arguments or as arrays of property names.
2176
- *
2177
- * @static
2178
- * @memberOf _
2179
- * @category Objects
2180
- * @param {Object} object The object to pluck.
2181
- * @param {Object} [prop1, prop2, ..] The properties to pick.
2182
- * @returns {Object} Returns an object composed of the picked properties.
2183
- * @example
2184
- *
2185
- * _.pick({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'name', 'age');
2186
- * // => { 'name': 'moe', 'age': 40 }
2187
- */
2188
- function pick(object) {
2189
- var prop,
2190
- index = -1,
2191
- props = flatten(slice.call(arguments, 1)),
2192
- length = props.length,
2193
- result = {};
2194
-
2195
- while (++index < length) {
2196
- prop = props[index];
2197
- if (prop in object) {
2198
- result[prop] = object[prop];
2199
- }
2200
- }
2201
- return result;
2202
- }
2203
-
2204
- /**
2205
- * Invokes `interceptor` with the `value` as the first argument, and then returns
2206
- * `value`. The primary purpose of this method is to "tap into" a method chain,
2207
- * in order to performoperations on intermediate results within the chain.
2208
- *
2209
- * @static
2210
- * @memberOf _
2211
- * @category Objects
2212
- * @param {Mixed} value The value to pass to `callback`.
2213
- * @param {Function} interceptor The function to invoke.
2214
- * @returns {Mixed} Returns `value`.
2215
- * @example
2216
- *
2217
- * _.chain([1,2,3,200])
2218
- * .filter(function(num) { return num % 2 == 0; })
2219
- * .tap(alert)
2220
- * .map(function(num) { return num * num })
2221
- * .value();
2222
- * // => // [2, 200] (alerted)
2223
- * // => [4, 40000]
2224
- */
2225
- function tap(value, interceptor) {
2226
- interceptor(value);
2227
- return value;
2228
- }
2229
-
2230
- /*--------------------------------------------------------------------------*/
2231
-
2232
- /**
2233
- * Escapes a string for insertion into HTML, replacing `&`, `<`, `>`, `"`, `'`,
2234
- * and `/` characters.
2235
- *
2236
- * @static
2237
- * @memberOf _
2238
- * @category Utilities
2239
- * @param {String} string The string to escape.
2240
- * @returns {String} Returns the escaped string.
2241
- * @example
2242
- *
2243
- * _.escape('Curly, Larry & Moe');
2244
- * // => "Curly, Larry &amp; Moe"
2245
- */
2246
- function escape(string) {
2247
- return (string + '')
2248
- .replace(/&/g, '&amp;')
2249
- .replace(/</g, '&lt;')
2250
- .replace(/>/g, '&gt;')
2251
- .replace(/"/g, '&quot;')
2252
- .replace(/'/g, '&#x27;')
2253
- .replace(/\//g,'&#x2F;');
2254
- }
2255
-
2256
- /**
2257
- * This function simply returns the first argument passed to it.
2258
- * Note: It is used throughout Lo-Dash as a default callback.
2259
- *
2260
- * @static
2261
- * @memberOf _
2262
- * @category Utilities
2263
- * @param {Mixed} value Any value.
2264
- * @returns {Mixed} Returns `value`.
2265
- * @example
2266
- *
2267
- * var moe = { 'name': 'moe' };
2268
- * moe === _.identity(moe);
2269
- * // => true
2270
- */
2271
- function identity(value) {
2272
- return value;
2273
- }
2274
-
2275
- /**
2276
- * Adds functions properties of `object` to the `lodash` function and chainable
2277
- * wrapper.
2278
- *
2279
- * @static
2280
- * @memberOf _
2281
- * @category Utilities
2282
- * @param {Object} object The object of function properties to add to `lodash`.
2283
- * @example
2284
- *
2285
- * _.mixin({
2286
- * 'capitalize': function(string) {
2287
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
2288
- * }
2289
- * });
2290
- *
2291
- * _.capitalize('curly');
2292
- * // => 'Curly'
2293
- *
2294
- * _('larry').capitalize();
2295
- * // => 'Larry'
2296
- */
2297
- function mixin(object) {
2298
- forEach(functions(object), function(methodName) {
2299
- var func = lodash[methodName] = object[methodName];
2300
-
2301
- lodash.prototype[methodName] = function() {
2302
- // In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()`
2303
- // generically to augment the `arguments` object will pave the value at
2304
- // index `0` without incrimenting the other values's indexes.
2305
- // https://github.com/documentcloud/underscore/issues/9
2306
- var args = slice.call(arguments);
2307
- unshift.call(args, this._wrapped);
2308
-
2309
- var result = func.apply(lodash, args);
2310
- return this._chain ? new Lodash(result).chain() : result;
2311
- };
2312
- });
2313
- }
2314
-
2315
- /**
2316
- * Reverts the '_' variable to its previous value and returns a reference to
2317
- * the `lodash` function.
2318
- *
2319
- * @static
2320
- * @memberOf _
2321
- * @category Utilities
2322
- * @returns {Function} Returns the `lodash` function.
2323
- * @example
2324
- *
2325
- * var lodash = _.noConflict();
2326
- */
2327
- function noConflict() {
2328
- window._ = oldDash;
2329
- return this;
2330
- }
2331
-
2332
- /**
2333
- * Resolves the value of `property` on `object`. If the property is a function
2334
- * it will be invoked and its result returned, else the property value is returned.
2335
- *
2336
- * @static
2337
- * @memberOf _
2338
- * @category Utilities
2339
- * @param {Object} object The object to inspect.
2340
- * @param {String} property The property to get the result of.
2341
- * @returns {Mixed} Returns the resolved.
2342
- * @example
2343
- *
2344
- * var object = {
2345
- * 'cheese': 'crumpets',
2346
- * 'stuff': function() {
2347
- * return 'nonsense';
2348
- * }
2349
- * };
2350
- *
2351
- * _.result(object, 'cheese');
2352
- * // => 'crumpets'
2353
- *
2354
- * _.result(object, 'stuff');
2355
- * // => 'nonsense'
2356
- */
2357
- function result(object, property) {
2358
- if (object == undefined) {
2359
- return null;
2360
- }
2361
- var value = object[property];
2362
- return isFunction(value) ? object[property]() : value;
2363
- }
2364
-
2365
- /**
2366
- * Executes the `callback` function `n` times.
2367
- *
2368
- * @static
2369
- * @memberOf _
2370
- * @category Utilities
2371
- * @param {Number} n The number of times to execute the callback.
2372
- * @param {Function} callback The function called per iteration.
2373
- * @param {Mixed} [thisArg] The `this` binding for the callback.
2374
- * @example
2375
- *
2376
- * _.times(3, function() { genie.grantWish(); });
2377
- */
2378
- function times(n, callback, thisArg) {
2379
- if (thisArg) {
2380
- callback = bind(callback, thisArg);
2381
- }
2382
- for (var index = 0; index < n; index++) {
2383
- callback(index);
2384
- }
2385
- }
2386
-
2387
- /**
2388
- * Generates a unique id. If `prefix` is passed, the id will be appended to it.
2389
- *
2390
- * @static
2391
- * @memberOf _
2392
- * @category Utilities
2393
- * @param {String} [prefix] The value to prefix the id with.
2394
- * @returns {Number|String} Returns a numeric id if no prefix is passed, else
2395
- * a string id may be returned.
2396
- * @example
2397
- *
2398
- * _.uniqueId('contact_');
2399
- * // => 'contact_104'
2400
- */
2401
- function uniqueId(prefix) {
2402
- var id = idCounter++;
2403
- return prefix ? prefix + id : id;
2404
- }
2405
-
2406
- /*--------------------------------------------------------------------------*/
2407
-
2408
- /**
2409
- * A JavaScript micro-templating method, similar to John Resig's implementation.
2410
- * Lo-Dash templating handles arbitrary delimiters, preserves whitespace, and
2411
- * correctly escapes quotes within interpolated code.
2412
- *
2413
- * @static
2414
- * @memberOf _
2415
- * @category Utilities
2416
- * @param {String} text The template text.
2417
- * @param {Obect} data The data object used to populate the text.
2418
- * @param {Object} options The options object.
2419
- * @returns {Function|String} Returns a compiled function when no `data` object
2420
- * is given, else it returns the interpolated text.
2421
- * @example
2422
- *
2423
- * // using compiled template
2424
- * var compiled = _.template('hello: <%= name %>');
2425
- * compiled({ 'name': 'moe' });
2426
- * // => 'hello: moe'
2427
- *
2428
- * var list = '% _.forEach(people, function(name) { %> <li><%= name %></li> <% }); %>';
2429
- * _.template(list, { 'people': ['moe', 'curly', 'larry'] });
2430
- * // => '<li>moe</li><li>curly</li><li>larry</li>'
2431
- *
2432
- * var template = _.template('<b><%- value %></b>');
2433
- * template({ 'value': '<script>' });
2434
- * // => '<b>&lt;script&gt;</b>'
2435
- *
2436
- * // using `print`
2437
- * var compiled = _.template('<% print("Hello " + epithet); %>');
2438
- * compiled({ 'epithet': 'stooge' });
2439
- * // => 'Hello stooge.'
2440
- *
2441
- * // using custom template settings
2442
- * _.templateSettings = {
2443
- * 'interpolate': /\{\{(.+?)\}\}/g
2444
- * };
2445
- *
2446
- * var template = _.template('Hello {{ name }}!');
2447
- * template({ 'name': 'Mustache' });
2448
- * // => 'Hello Mustache!'
2449
- *
2450
- *
2451
- * // using the `variable` option
2452
- * _.template('<%= data.hasWith %>', { 'hasWith': 'no' }, { 'variable': 'data' });
2453
- * // => 'no'
2454
- *
2455
- * // using the `source` property
2456
- * <script>
2457
- * JST.project = <%= _.template(jstText).source %>;
2458
- * </script>
2459
- */
2460
- function template(text, data, options) {
2461
- options = defaults(options || {}, lodash.templateSettings);
2462
-
2463
- // Compile the template source, taking care to escape characters that
2464
- // cannot be included in string literals and then unescape them in code
2465
- // blocks.
2466
- var source = "__p+='" + text
2467
- .replace(reEscaper, function(match) {
2468
- return '\\' + escapes[match];
2469
- })
2470
- .replace(options.escape || reNoMatch, function(match, code) {
2471
- return "'+\n((__t=(" + unescape(code) + "))==null?'':_.escape(__t))+\n'";
2472
- })
2473
- .replace(options.interpolate || reNoMatch, function(match, code) {
2474
- return "'+\n((__t=(" + unescape(code) + "))==null?'':__t)+\n'";
2475
- })
2476
- .replace(options.evaluate || reNoMatch, function(match, code) {
2477
- return "';\n" + unescape(code) + ";\n__p+='";
2478
- }) + "';\n";
2479
-
2480
- // if a variable is not specified, place data values in local scope
2481
- if (!options.variable) {
2482
- source = 'with(object||{}){\n' + source + '\n}\n';
2483
- }
2484
-
2485
- source = 'var __t,__j=Array.prototype.join,__p="";' +
2486
- 'function print(){__p+=__j.call(arguments,"")}\n' +
2487
- source + 'return __p';
2488
-
2489
- var render = Function(options.variable || 'object', '_', source);
2490
- if (data) {
2491
- return render(data, lodash);
2492
- }
2493
-
2494
- var template = function(data) {
2495
- return render.call(this, data, lodash);
2496
- };
2497
-
2498
- // provide the compiled function source as a convenience for build time precompilation
2499
- template.source = 'function(' + (options.variable || 'object') + '){\n' + source + '\n}';
2500
-
2501
- return template;
2502
- }
2503
-
2504
- /*--------------------------------------------------------------------------*/
2505
-
2506
- /**
2507
- * Wraps the value in a `lodash` chainable object.
2508
- *
2509
- * @static
2510
- * @memberOf _
2511
- * @category Chaining
2512
- * @param {Mixed} value The value to wrap.
2513
- * @returns {Object} Returns the `lodash` chainable object.
2514
- * @example
2515
- *
2516
- * var stooges = [
2517
- * { 'name': 'moe', 'age': 40 },
2518
- * { 'name': 'larry', 'age': 50 },
2519
- * { 'name': 'curly', 'age': 60 }
2520
- * ];
2521
- *
2522
- * var youngest = _.chain(stooges)
2523
- * .sortBy(function(stooge) { return stooge.age; })
2524
- * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
2525
- * .first()
2526
- * .value();
2527
- * // => 'moe is 40'
2528
- */
2529
- function chain(value) {
2530
- return new Lodash(value).chain();
2531
- }
2532
-
2533
- /**
2534
- * Extracts the value from a wrapped chainable object.
2535
- *
2536
- * @name chain
2537
- * @memberOf _
2538
- * @category Chaining
2539
- * @returns {Mixed} Returns the wrapped object.
2540
- * @example
2541
- *
2542
- * _([1, 2, 3]).value();
2543
- * // => [1, 2, 3]
2544
- */
2545
- function chainWrapper() {
2546
- this._chain = true;
2547
- return this;
2548
- }
2549
-
2550
- /**
2551
- * Extracts the value from a wrapped chainable object.
2552
- *
2553
- * @memberOf _
2554
- * @category Chaining
2555
- * @returns {Mixed} Returns the wrapped object.
2556
- * @example
2557
- *
2558
- * _([1, 2, 3]).value();
2559
- * // => [1, 2, 3]
2560
- */
2561
- function value() {
2562
- return this._wrapped;
2563
- }
2564
-
2565
- /*--------------------------------------------------------------------------*/
2566
-
2567
- extend(lodash, {
2568
-
2569
- /**
2570
- * The semantic version number.
2571
- *
2572
- * @static
2573
- * @memberOf _
2574
- * @type String
2575
- */
2576
- 'VERSION': '0.1.0',
2577
-
2578
- /**
2579
- * By default, Lo-Dash uses ERB-style template delimiters, change the
2580
- * following template settings to use alternative delimiters.
2581
- *
2582
- * @static
2583
- * @memberOf _
2584
- * @type Object
2585
- */
2586
- 'templateSettings': {
2587
-
2588
- /**
2589
- * Used to detect `data` property values to be HTML-escaped.
2590
- *
2591
- * @static
2592
- * @memberOf _.templateSettings
2593
- * @type RegExp
2594
- */
2595
- 'escape': /<%-([\s\S]+?)%>/g,
2596
-
2597
- /**
2598
- * Used to detect code to be evaluated.
2599
- *
2600
- * @static
2601
- * @memberOf _.templateSettings
2602
- * @type RegExp
2603
- */
2604
- 'evaluate': /<%([\s\S]+?)%>/g,
2605
-
2606
- /**
2607
- * Used to detect `data` property values to inject.
2608
- *
2609
- * @static
2610
- * @memberOf _.templateSettings
2611
- * @type RegExp
2612
- */
2613
- 'interpolate': /<%=([\s\S]+?)%>/g
2614
- },
2615
-
2616
- // assign static methods
2617
- 'after': after,
2618
- 'bind': bind,
2619
- 'bindAll': bindAll,
2620
- 'chain': chain,
2621
- 'clone': clone,
2622
- 'compact': compact,
2623
- 'compose': compose,
2624
- 'contains': contains,
2625
- 'debounce': debounce,
2626
- 'defaults': defaults,
2627
- 'defer': defer,
2628
- 'delay': delay,
2629
- 'difference': difference,
2630
- 'escape': escape,
2631
- 'every': every,
2632
- 'extend': extend,
2633
- 'filter': filter,
2634
- 'find': find,
2635
- 'first': first,
2636
- 'flatten': flatten,
2637
- 'forEach': forEach,
2638
- 'functions': functions,
2639
- 'groupBy': groupBy,
2640
- 'has': has,
2641
- 'identity': identity,
2642
- 'indexOf': indexOf,
2643
- 'initial': initial,
2644
- 'intersection': intersection,
2645
- 'invoke': invoke,
2646
- 'isArguments': isArguments,
2647
- 'isArray': isArray,
2648
- 'isBoolean': isBoolean,
2649
- 'isDate': isDate,
2650
- 'isElement': isElement,
2651
- 'isEmpty': isEmpty,
2652
- 'isEqual': isEqual,
2653
- 'isFinite': isFinite,
2654
- 'isFunction': isFunction,
2655
- 'isNaN': isNaN,
2656
- 'isNull': isNull,
2657
- 'isNumber': isNumber,
2658
- 'isObject': isObject,
2659
- 'isRegExp': isRegExp,
2660
- 'isString': isString,
2661
- 'isUndefined': isUndefined,
2662
- 'keys': keys,
2663
- 'last': last,
2664
- 'lastIndexOf': lastIndexOf,
2665
- 'map': map,
2666
- 'max': max,
2667
- 'memoize': memoize,
2668
- 'min': min,
2669
- 'mixin': mixin,
2670
- 'noConflict': noConflict,
2671
- 'once': once,
2672
- 'pick': pick,
2673
- 'pluck': pluck,
2674
- 'range': range,
2675
- 'reduce': reduce,
2676
- 'reduceRight': reduceRight,
2677
- 'reject': reject,
2678
- 'rest': rest,
2679
- 'result': result,
2680
- 'shuffle': shuffle,
2681
- 'size': size,
2682
- 'some': some,
2683
- 'sortBy': sortBy,
2684
- 'sortedIndex': sortedIndex,
2685
- 'tap': tap,
2686
- 'template': template,
2687
- 'throttle': throttle,
2688
- 'times': times,
2689
- 'toArray': toArray,
2690
- 'union': union,
2691
- 'uniq': uniq,
2692
- 'uniqueId': uniqueId,
2693
- 'values': values,
2694
- 'without': without,
2695
- 'wrap': wrap,
2696
- 'zip': zip,
2697
-
2698
- // assign aliases
2699
- 'all': every,
2700
- 'any': some,
2701
- 'collect': map,
2702
- 'detect': find,
2703
- 'each': forEach,
2704
- 'foldl': reduce,
2705
- 'foldr': reduceRight,
2706
- 'head': first,
2707
- 'include': contains,
2708
- 'inject': reduce,
2709
- 'intersect': intersection,
2710
- 'methods': functions,
2711
- 'select': filter,
2712
- 'tail': rest,
2713
- 'take': first,
2714
- 'unique': uniq
2715
- });
2716
-
2717
- /*--------------------------------------------------------------------------*/
2718
-
2719
- // assign private `Lodash` constructor's prototype
2720
- Lodash.prototype = lodash.prototype;
2721
-
2722
- // add all of the static functions to `Lodash.prototype`
2723
- mixin(lodash);
2724
-
2725
- // add all mutator Array functions to the wrapper.
2726
- forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
2727
- var func = ArrayProto[methodName];
2728
-
2729
- lodash.prototype[methodName] = function() {
2730
- var value = this._wrapped;
2731
- func.apply(value, arguments);
2732
-
2733
- // IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()`
2734
- // functions that fail to remove the last element, `object[0]`, of
2735
- // array-like-objects even though the `length` property is set to `0`.
2736
- // The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
2737
- // is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
2738
- if (value.length === 0) {
2739
- delete value[0];
2740
- }
2741
- return this._chain ? new Lodash(value).chain() : value;
2742
- };
2743
- });
2744
-
2745
- // add all accessor Array functions to the wrapper.
2746
- forEach(['concat', 'join', 'slice'], function(methodName) {
2747
- var func = ArrayProto[methodName];
2748
- Lodash.prototype[methodName] = function() {
2749
- var result = func.apply(this._wrapped, arguments);
2750
- return this._chain ? new Lodash(result).chain() : result;
2751
- };
2752
- });
2753
-
2754
- // add `chain` and `value` after calling to `mixin()` to avoid getting wrapped
2755
- extend(Lodash.prototype, {
2756
- 'chain': chainWrapper,
2757
- 'value': value
2758
- });
2759
-
2760
- /*--------------------------------------------------------------------------*/
2761
-
2762
- // expose Lo-Dash
2763
- if (freeExports) {
2764
- // in Node.js or RingoJS v0.8.0+
2765
- if (typeof module == 'object' && module && module.exports == freeExports) {
2766
- (module.exports = lodash)._ = lodash;
2767
- }
2768
- // in Narwhal or RingoJS v0.7.0-
2769
- else {
2770
- freeExports._ = lodash;
2771
- }
2772
- } else {
2773
- // in a browser or Rhino
2774
- window._ = lodash;
2775
-
2776
- // Expose Lo-Dash as an AMD module, but only for AMD loaders that understand
2777
- // the issues with loading multiple versions of Lo-Dash in a page that all
2778
- // might call `define()`. The loader will indicate they have special
2779
- // allowances for multiple Lo-Dash versions by specifying
2780
- // `define.amd.lodash=true`. Register as a named module, since Lo-Dash can
2781
- // be concatenated with other files that may use `define()`, but not use a
2782
- // proper concatenation script that understands anonymous AMD modules.
2783
- // Lowercase `lodash` is used because AMD module names are derived from
2784
- // file names, and Lo-Dash is normally delivered in a lowercase file name.
2785
- // Do this after assigning Lo-Dash the global so that if an AMD module wants
2786
- // to call `noConflict()` to hide this version of Lo-Dash, it will work.
2787
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd && define.amd.lodash) {
2788
- define('lodash', function() {
2789
- return lodash;
2790
- });
2791
- }
2792
- }
2793
- }(this));