underscore-rails 1.7.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/underscore-rails/version.rb +1 -1
- data/vendor/assets/javascripts/underscore.js +406 -286
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce8085a066bdc1f92a0f5acb443d499285a8e00f
|
4
|
+
data.tar.gz: 0d019d9874583f7394925d972d1e1c7da5397af8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5982f54fb6ff4e9a100186bfeae138868314c39c29fef3a3e3ce6aaba3c80375fc984d30923119316af15bfde9e1a497adf3a303cc3f4f29d9a9151a922152ad
|
7
|
+
data.tar.gz: 32b31f13a3ae31573a74df38c63e143940caadea355102f486d418953a8dff4a0b0afb688e25d07f5851de318ee90bf3beb2c9d38d31551af7a1c874d7bad7f7
|
@@ -1,6 +1,6 @@
|
|
1
|
-
// Underscore.js 1.
|
1
|
+
// Underscore.js 1.8.2
|
2
2
|
// http://underscorejs.org
|
3
|
-
// (c) 2009-
|
3
|
+
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
4
4
|
// Underscore may be freely distributed under the MIT license.
|
5
5
|
|
6
6
|
(function() {
|
@@ -21,7 +21,6 @@
|
|
21
21
|
var
|
22
22
|
push = ArrayProto.push,
|
23
23
|
slice = ArrayProto.slice,
|
24
|
-
concat = ArrayProto.concat,
|
25
24
|
toString = ObjProto.toString,
|
26
25
|
hasOwnProperty = ObjProto.hasOwnProperty;
|
27
26
|
|
@@ -30,7 +29,11 @@
|
|
30
29
|
var
|
31
30
|
nativeIsArray = Array.isArray,
|
32
31
|
nativeKeys = Object.keys,
|
33
|
-
nativeBind = FuncProto.bind
|
32
|
+
nativeBind = FuncProto.bind,
|
33
|
+
nativeCreate = Object.create;
|
34
|
+
|
35
|
+
// Naked function reference for surrogate-prototype-swapping.
|
36
|
+
var Ctor = function(){};
|
34
37
|
|
35
38
|
// Create a safe reference to the Underscore object for use below.
|
36
39
|
var _ = function(obj) {
|
@@ -52,12 +55,12 @@
|
|
52
55
|
}
|
53
56
|
|
54
57
|
// Current version.
|
55
|
-
_.VERSION = '1.
|
58
|
+
_.VERSION = '1.8.2';
|
56
59
|
|
57
60
|
// Internal function that returns an efficient (for current engines) version
|
58
61
|
// of the passed-in callback, to be repeatedly applied in other Underscore
|
59
62
|
// functions.
|
60
|
-
var
|
63
|
+
var optimizeCb = function(func, context, argCount) {
|
61
64
|
if (context === void 0) return func;
|
62
65
|
switch (argCount == null ? 3 : argCount) {
|
63
66
|
case 1: return function(value) {
|
@@ -81,12 +84,52 @@
|
|
81
84
|
// A mostly-internal function to generate callbacks that can be applied
|
82
85
|
// to each element in a collection, returning the desired result — either
|
83
86
|
// identity, an arbitrary callback, a property matcher, or a property accessor.
|
84
|
-
|
87
|
+
var cb = function(value, context, argCount) {
|
85
88
|
if (value == null) return _.identity;
|
86
|
-
if (_.isFunction(value)) return
|
87
|
-
if (_.isObject(value)) return _.
|
89
|
+
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
|
90
|
+
if (_.isObject(value)) return _.matcher(value);
|
88
91
|
return _.property(value);
|
89
92
|
};
|
93
|
+
_.iteratee = function(value, context) {
|
94
|
+
return cb(value, context, Infinity);
|
95
|
+
};
|
96
|
+
|
97
|
+
// An internal function for creating assigner functions.
|
98
|
+
var createAssigner = function(keysFunc, undefinedOnly) {
|
99
|
+
return function(obj) {
|
100
|
+
var length = arguments.length;
|
101
|
+
if (length < 2 || obj == null) return obj;
|
102
|
+
for (var index = 1; index < length; index++) {
|
103
|
+
var source = arguments[index],
|
104
|
+
keys = keysFunc(source),
|
105
|
+
l = keys.length;
|
106
|
+
for (var i = 0; i < l; i++) {
|
107
|
+
var key = keys[i];
|
108
|
+
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
|
109
|
+
}
|
110
|
+
}
|
111
|
+
return obj;
|
112
|
+
};
|
113
|
+
};
|
114
|
+
|
115
|
+
// An internal function for creating a new object that inherits from another.
|
116
|
+
var baseCreate = function(prototype) {
|
117
|
+
if (!_.isObject(prototype)) return {};
|
118
|
+
if (nativeCreate) return nativeCreate(prototype);
|
119
|
+
Ctor.prototype = prototype;
|
120
|
+
var result = new Ctor;
|
121
|
+
Ctor.prototype = null;
|
122
|
+
return result;
|
123
|
+
};
|
124
|
+
|
125
|
+
// Helper for collection methods to determine whether a collection
|
126
|
+
// should be iterated as an array or as an object
|
127
|
+
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
|
128
|
+
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
|
129
|
+
var isArrayLike = function(collection) {
|
130
|
+
var length = collection && collection.length;
|
131
|
+
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
|
132
|
+
};
|
90
133
|
|
91
134
|
// Collection Functions
|
92
135
|
// --------------------
|
@@ -95,11 +138,10 @@
|
|
95
138
|
// Handles raw objects in addition to array-likes. Treats all
|
96
139
|
// sparse array-likes as if they were dense.
|
97
140
|
_.each = _.forEach = function(obj, iteratee, context) {
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
for (i = 0; i < length; i++) {
|
141
|
+
iteratee = optimizeCb(iteratee, context);
|
142
|
+
var i, length;
|
143
|
+
if (isArrayLike(obj)) {
|
144
|
+
for (i = 0, length = obj.length; i < length; i++) {
|
103
145
|
iteratee(obj[i], i, obj);
|
104
146
|
}
|
105
147
|
} else {
|
@@ -113,77 +155,66 @@
|
|
113
155
|
|
114
156
|
// Return the results of applying the iteratee to each element.
|
115
157
|
_.map = _.collect = function(obj, iteratee, context) {
|
116
|
-
|
117
|
-
|
118
|
-
var keys = obj.length !== +obj.length && _.keys(obj),
|
158
|
+
iteratee = cb(iteratee, context);
|
159
|
+
var keys = !isArrayLike(obj) && _.keys(obj),
|
119
160
|
length = (keys || obj).length,
|
120
|
-
results = Array(length)
|
121
|
-
currentKey;
|
161
|
+
results = Array(length);
|
122
162
|
for (var index = 0; index < length; index++) {
|
123
|
-
currentKey = keys ? keys[index] : index;
|
163
|
+
var currentKey = keys ? keys[index] : index;
|
124
164
|
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
125
165
|
}
|
126
166
|
return results;
|
127
167
|
};
|
128
168
|
|
129
|
-
|
169
|
+
// Create a reducing function iterating left or right.
|
170
|
+
function createReduce(dir) {
|
171
|
+
// Optimized iterator function as using arguments.length
|
172
|
+
// in the main function will deoptimize the, see #1991.
|
173
|
+
function iterator(obj, iteratee, memo, keys, index, length) {
|
174
|
+
for (; index >= 0 && index < length; index += dir) {
|
175
|
+
var currentKey = keys ? keys[index] : index;
|
176
|
+
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
177
|
+
}
|
178
|
+
return memo;
|
179
|
+
}
|
180
|
+
|
181
|
+
return function(obj, iteratee, memo, context) {
|
182
|
+
iteratee = optimizeCb(iteratee, context, 4);
|
183
|
+
var keys = !isArrayLike(obj) && _.keys(obj),
|
184
|
+
length = (keys || obj).length,
|
185
|
+
index = dir > 0 ? 0 : length - 1;
|
186
|
+
// Determine the initial value if none is provided.
|
187
|
+
if (arguments.length < 3) {
|
188
|
+
memo = obj[keys ? keys[index] : index];
|
189
|
+
index += dir;
|
190
|
+
}
|
191
|
+
return iterator(obj, iteratee, memo, keys, index, length);
|
192
|
+
};
|
193
|
+
}
|
130
194
|
|
131
195
|
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
132
196
|
// or `foldl`.
|
133
|
-
_.reduce = _.foldl = _.inject =
|
134
|
-
if (obj == null) obj = [];
|
135
|
-
iteratee = createCallback(iteratee, context, 4);
|
136
|
-
var keys = obj.length !== +obj.length && _.keys(obj),
|
137
|
-
length = (keys || obj).length,
|
138
|
-
index = 0, currentKey;
|
139
|
-
if (arguments.length < 3) {
|
140
|
-
if (!length) throw new TypeError(reduceError);
|
141
|
-
memo = obj[keys ? keys[index++] : index++];
|
142
|
-
}
|
143
|
-
for (; index < length; index++) {
|
144
|
-
currentKey = keys ? keys[index] : index;
|
145
|
-
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
146
|
-
}
|
147
|
-
return memo;
|
148
|
-
};
|
197
|
+
_.reduce = _.foldl = _.inject = createReduce(1);
|
149
198
|
|
150
199
|
// The right-associative version of reduce, also known as `foldr`.
|
151
|
-
_.reduceRight = _.foldr =
|
152
|
-
if (obj == null) obj = [];
|
153
|
-
iteratee = createCallback(iteratee, context, 4);
|
154
|
-
var keys = obj.length !== + obj.length && _.keys(obj),
|
155
|
-
index = (keys || obj).length,
|
156
|
-
currentKey;
|
157
|
-
if (arguments.length < 3) {
|
158
|
-
if (!index) throw new TypeError(reduceError);
|
159
|
-
memo = obj[keys ? keys[--index] : --index];
|
160
|
-
}
|
161
|
-
while (index--) {
|
162
|
-
currentKey = keys ? keys[index] : index;
|
163
|
-
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
164
|
-
}
|
165
|
-
return memo;
|
166
|
-
};
|
200
|
+
_.reduceRight = _.foldr = createReduce(-1);
|
167
201
|
|
168
202
|
// Return the first value which passes a truth test. Aliased as `detect`.
|
169
203
|
_.find = _.detect = function(obj, predicate, context) {
|
170
|
-
var
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
});
|
178
|
-
return result;
|
204
|
+
var key;
|
205
|
+
if (isArrayLike(obj)) {
|
206
|
+
key = _.findIndex(obj, predicate, context);
|
207
|
+
} else {
|
208
|
+
key = _.findKey(obj, predicate, context);
|
209
|
+
}
|
210
|
+
if (key !== void 0 && key !== -1) return obj[key];
|
179
211
|
};
|
180
212
|
|
181
213
|
// Return all the elements that pass a truth test.
|
182
214
|
// Aliased as `select`.
|
183
215
|
_.filter = _.select = function(obj, predicate, context) {
|
184
216
|
var results = [];
|
185
|
-
|
186
|
-
predicate = _.iteratee(predicate, context);
|
217
|
+
predicate = cb(predicate, context);
|
187
218
|
_.each(obj, function(value, index, list) {
|
188
219
|
if (predicate(value, index, list)) results.push(value);
|
189
220
|
});
|
@@ -192,19 +223,17 @@
|
|
192
223
|
|
193
224
|
// Return all the elements for which a truth test fails.
|
194
225
|
_.reject = function(obj, predicate, context) {
|
195
|
-
return _.filter(obj, _.negate(
|
226
|
+
return _.filter(obj, _.negate(cb(predicate)), context);
|
196
227
|
};
|
197
228
|
|
198
229
|
// Determine whether all of the elements match a truth test.
|
199
230
|
// Aliased as `all`.
|
200
231
|
_.every = _.all = function(obj, predicate, context) {
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
for (index = 0; index < length; index++) {
|
207
|
-
currentKey = keys ? keys[index] : index;
|
232
|
+
predicate = cb(predicate, context);
|
233
|
+
var keys = !isArrayLike(obj) && _.keys(obj),
|
234
|
+
length = (keys || obj).length;
|
235
|
+
for (var index = 0; index < length; index++) {
|
236
|
+
var currentKey = keys ? keys[index] : index;
|
208
237
|
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
209
238
|
}
|
210
239
|
return true;
|
@@ -213,24 +242,21 @@
|
|
213
242
|
// Determine if at least one element in the object matches a truth test.
|
214
243
|
// Aliased as `any`.
|
215
244
|
_.some = _.any = function(obj, predicate, context) {
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
for (index = 0; index < length; index++) {
|
222
|
-
currentKey = keys ? keys[index] : index;
|
245
|
+
predicate = cb(predicate, context);
|
246
|
+
var keys = !isArrayLike(obj) && _.keys(obj),
|
247
|
+
length = (keys || obj).length;
|
248
|
+
for (var index = 0; index < length; index++) {
|
249
|
+
var currentKey = keys ? keys[index] : index;
|
223
250
|
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
224
251
|
}
|
225
252
|
return false;
|
226
253
|
};
|
227
254
|
|
228
255
|
// Determine if the array or object contains a given value (using `===`).
|
229
|
-
// Aliased as `include`.
|
230
|
-
_.contains = _.include = function(obj, target) {
|
231
|
-
if (obj
|
232
|
-
|
233
|
-
return _.indexOf(obj, target) >= 0;
|
256
|
+
// Aliased as `includes` and `include`.
|
257
|
+
_.contains = _.includes = _.include = function(obj, target, fromIndex) {
|
258
|
+
if (!isArrayLike(obj)) obj = _.values(obj);
|
259
|
+
return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
|
234
260
|
};
|
235
261
|
|
236
262
|
// Invoke a method (with arguments) on every item in a collection.
|
@@ -238,7 +264,8 @@
|
|
238
264
|
var args = slice.call(arguments, 2);
|
239
265
|
var isFunc = _.isFunction(method);
|
240
266
|
return _.map(obj, function(value) {
|
241
|
-
|
267
|
+
var func = isFunc ? method : value[method];
|
268
|
+
return func == null ? func : func.apply(value, args);
|
242
269
|
});
|
243
270
|
};
|
244
271
|
|
@@ -250,13 +277,13 @@
|
|
250
277
|
// Convenience version of a common use case of `filter`: selecting only objects
|
251
278
|
// containing specific `key:value` pairs.
|
252
279
|
_.where = function(obj, attrs) {
|
253
|
-
return _.filter(obj, _.
|
280
|
+
return _.filter(obj, _.matcher(attrs));
|
254
281
|
};
|
255
282
|
|
256
283
|
// Convenience version of a common use case of `find`: getting the first object
|
257
284
|
// containing specific `key:value` pairs.
|
258
285
|
_.findWhere = function(obj, attrs) {
|
259
|
-
return _.find(obj, _.
|
286
|
+
return _.find(obj, _.matcher(attrs));
|
260
287
|
};
|
261
288
|
|
262
289
|
// Return the maximum element (or element-based computation).
|
@@ -264,7 +291,7 @@
|
|
264
291
|
var result = -Infinity, lastComputed = -Infinity,
|
265
292
|
value, computed;
|
266
293
|
if (iteratee == null && obj != null) {
|
267
|
-
obj = obj
|
294
|
+
obj = isArrayLike(obj) ? obj : _.values(obj);
|
268
295
|
for (var i = 0, length = obj.length; i < length; i++) {
|
269
296
|
value = obj[i];
|
270
297
|
if (value > result) {
|
@@ -272,7 +299,7 @@
|
|
272
299
|
}
|
273
300
|
}
|
274
301
|
} else {
|
275
|
-
iteratee =
|
302
|
+
iteratee = cb(iteratee, context);
|
276
303
|
_.each(obj, function(value, index, list) {
|
277
304
|
computed = iteratee(value, index, list);
|
278
305
|
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
|
@@ -289,7 +316,7 @@
|
|
289
316
|
var result = Infinity, lastComputed = Infinity,
|
290
317
|
value, computed;
|
291
318
|
if (iteratee == null && obj != null) {
|
292
|
-
obj = obj
|
319
|
+
obj = isArrayLike(obj) ? obj : _.values(obj);
|
293
320
|
for (var i = 0, length = obj.length; i < length; i++) {
|
294
321
|
value = obj[i];
|
295
322
|
if (value < result) {
|
@@ -297,7 +324,7 @@
|
|
297
324
|
}
|
298
325
|
}
|
299
326
|
} else {
|
300
|
-
iteratee =
|
327
|
+
iteratee = cb(iteratee, context);
|
301
328
|
_.each(obj, function(value, index, list) {
|
302
329
|
computed = iteratee(value, index, list);
|
303
330
|
if (computed < lastComputed || computed === Infinity && result === Infinity) {
|
@@ -312,7 +339,7 @@
|
|
312
339
|
// Shuffle a collection, using the modern version of the
|
313
340
|
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
314
341
|
_.shuffle = function(obj) {
|
315
|
-
var set = obj
|
342
|
+
var set = isArrayLike(obj) ? obj : _.values(obj);
|
316
343
|
var length = set.length;
|
317
344
|
var shuffled = Array(length);
|
318
345
|
for (var index = 0, rand; index < length; index++) {
|
@@ -328,7 +355,7 @@
|
|
328
355
|
// The internal `guard` argument allows it to work with `map`.
|
329
356
|
_.sample = function(obj, n, guard) {
|
330
357
|
if (n == null || guard) {
|
331
|
-
if (obj
|
358
|
+
if (!isArrayLike(obj)) obj = _.values(obj);
|
332
359
|
return obj[_.random(obj.length - 1)];
|
333
360
|
}
|
334
361
|
return _.shuffle(obj).slice(0, Math.max(0, n));
|
@@ -336,7 +363,7 @@
|
|
336
363
|
|
337
364
|
// Sort the object's values by a criterion produced by an iteratee.
|
338
365
|
_.sortBy = function(obj, iteratee, context) {
|
339
|
-
iteratee =
|
366
|
+
iteratee = cb(iteratee, context);
|
340
367
|
return _.pluck(_.map(obj, function(value, index, list) {
|
341
368
|
return {
|
342
369
|
value: value,
|
@@ -358,7 +385,7 @@
|
|
358
385
|
var group = function(behavior) {
|
359
386
|
return function(obj, iteratee, context) {
|
360
387
|
var result = {};
|
361
|
-
iteratee =
|
388
|
+
iteratee = cb(iteratee, context);
|
362
389
|
_.each(obj, function(value, index) {
|
363
390
|
var key = iteratee(value, index, obj);
|
364
391
|
behavior(result, value, key);
|
@@ -386,37 +413,24 @@
|
|
386
413
|
if (_.has(result, key)) result[key]++; else result[key] = 1;
|
387
414
|
});
|
388
415
|
|
389
|
-
// Use a comparator function to figure out the smallest index at which
|
390
|
-
// an object should be inserted so as to maintain order. Uses binary search.
|
391
|
-
_.sortedIndex = function(array, obj, iteratee, context) {
|
392
|
-
iteratee = _.iteratee(iteratee, context, 1);
|
393
|
-
var value = iteratee(obj);
|
394
|
-
var low = 0, high = array.length;
|
395
|
-
while (low < high) {
|
396
|
-
var mid = low + high >>> 1;
|
397
|
-
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
398
|
-
}
|
399
|
-
return low;
|
400
|
-
};
|
401
|
-
|
402
416
|
// Safely create a real, live array from anything iterable.
|
403
417
|
_.toArray = function(obj) {
|
404
418
|
if (!obj) return [];
|
405
419
|
if (_.isArray(obj)) return slice.call(obj);
|
406
|
-
if (obj
|
420
|
+
if (isArrayLike(obj)) return _.map(obj, _.identity);
|
407
421
|
return _.values(obj);
|
408
422
|
};
|
409
423
|
|
410
424
|
// Return the number of elements in an object.
|
411
425
|
_.size = function(obj) {
|
412
426
|
if (obj == null) return 0;
|
413
|
-
return obj
|
427
|
+
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
|
414
428
|
};
|
415
429
|
|
416
430
|
// Split a collection into two arrays: one whose elements all satisfy the given
|
417
431
|
// predicate, and one whose elements all do not satisfy the predicate.
|
418
432
|
_.partition = function(obj, predicate, context) {
|
419
|
-
predicate =
|
433
|
+
predicate = cb(predicate, context);
|
420
434
|
var pass = [], fail = [];
|
421
435
|
_.each(obj, function(value, key, obj) {
|
422
436
|
(predicate(value, key, obj) ? pass : fail).push(value);
|
@@ -433,30 +447,27 @@
|
|
433
447
|
_.first = _.head = _.take = function(array, n, guard) {
|
434
448
|
if (array == null) return void 0;
|
435
449
|
if (n == null || guard) return array[0];
|
436
|
-
|
437
|
-
return slice.call(array, 0, n);
|
450
|
+
return _.initial(array, array.length - n);
|
438
451
|
};
|
439
452
|
|
440
453
|
// Returns everything but the last entry of the array. Especially useful on
|
441
454
|
// the arguments object. Passing **n** will return all the values in
|
442
|
-
// the array, excluding the last N.
|
443
|
-
// `_.map`.
|
455
|
+
// the array, excluding the last N.
|
444
456
|
_.initial = function(array, n, guard) {
|
445
457
|
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
|
446
458
|
};
|
447
459
|
|
448
460
|
// Get the last element of an array. Passing **n** will return the last N
|
449
|
-
// values in the array.
|
461
|
+
// values in the array.
|
450
462
|
_.last = function(array, n, guard) {
|
451
463
|
if (array == null) return void 0;
|
452
464
|
if (n == null || guard) return array[array.length - 1];
|
453
|
-
return
|
465
|
+
return _.rest(array, Math.max(0, array.length - n));
|
454
466
|
};
|
455
467
|
|
456
468
|
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
457
469
|
// Especially useful on the arguments object. Passing an **n** will return
|
458
|
-
// the rest N values in the array.
|
459
|
-
// check allows it to work with `_.map`.
|
470
|
+
// the rest N values in the array.
|
460
471
|
_.rest = _.tail = _.drop = function(array, n, guard) {
|
461
472
|
return slice.call(array, n == null || guard ? 1 : n);
|
462
473
|
};
|
@@ -467,18 +478,20 @@
|
|
467
478
|
};
|
468
479
|
|
469
480
|
// Internal implementation of a recursive `flatten` function.
|
470
|
-
var flatten = function(input, shallow, strict,
|
471
|
-
|
472
|
-
|
473
|
-
}
|
474
|
-
for (var i = 0, length = input.length; i < length; i++) {
|
481
|
+
var flatten = function(input, shallow, strict, startIndex) {
|
482
|
+
var output = [], idx = 0;
|
483
|
+
for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
|
475
484
|
var value = input[i];
|
476
|
-
if (
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
485
|
+
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
|
486
|
+
//flatten current level of array or arguments object
|
487
|
+
if (!shallow) value = flatten(value, shallow, strict);
|
488
|
+
var j = 0, len = value.length;
|
489
|
+
output.length += len;
|
490
|
+
while (j < len) {
|
491
|
+
output[idx++] = value[j++];
|
492
|
+
}
|
493
|
+
} else if (!strict) {
|
494
|
+
output[idx++] = value;
|
482
495
|
}
|
483
496
|
}
|
484
497
|
return output;
|
@@ -486,7 +499,7 @@
|
|
486
499
|
|
487
500
|
// Flatten out an array, either recursively (by default), or just one level.
|
488
501
|
_.flatten = function(array, shallow) {
|
489
|
-
return flatten(array, shallow, false
|
502
|
+
return flatten(array, shallow, false);
|
490
503
|
};
|
491
504
|
|
492
505
|
// Return a version of the array that does not contain the specified value(s).
|
@@ -504,21 +517,21 @@
|
|
504
517
|
iteratee = isSorted;
|
505
518
|
isSorted = false;
|
506
519
|
}
|
507
|
-
if (iteratee != null) iteratee =
|
520
|
+
if (iteratee != null) iteratee = cb(iteratee, context);
|
508
521
|
var result = [];
|
509
522
|
var seen = [];
|
510
523
|
for (var i = 0, length = array.length; i < length; i++) {
|
511
|
-
var value = array[i]
|
524
|
+
var value = array[i],
|
525
|
+
computed = iteratee ? iteratee(value, i, array) : value;
|
512
526
|
if (isSorted) {
|
513
|
-
if (!i || seen !==
|
514
|
-
seen =
|
527
|
+
if (!i || seen !== computed) result.push(value);
|
528
|
+
seen = computed;
|
515
529
|
} else if (iteratee) {
|
516
|
-
|
517
|
-
if (_.indexOf(seen, computed) < 0) {
|
530
|
+
if (!_.contains(seen, computed)) {
|
518
531
|
seen.push(computed);
|
519
532
|
result.push(value);
|
520
533
|
}
|
521
|
-
} else if (_.
|
534
|
+
} else if (!_.contains(result, value)) {
|
522
535
|
result.push(value);
|
523
536
|
}
|
524
537
|
}
|
@@ -528,7 +541,7 @@
|
|
528
541
|
// Produce an array that contains the union: each distinct element from all of
|
529
542
|
// the passed-in arrays.
|
530
543
|
_.union = function() {
|
531
|
-
return _.uniq(flatten(arguments, true, true
|
544
|
+
return _.uniq(flatten(arguments, true, true));
|
532
545
|
};
|
533
546
|
|
534
547
|
// Produce an array that contains every item shared between all the
|
@@ -551,7 +564,7 @@
|
|
551
564
|
// Take the difference between one array and a number of other arrays.
|
552
565
|
// Only the elements present in just the first array will remain.
|
553
566
|
_.difference = function(array) {
|
554
|
-
var rest = flatten(
|
567
|
+
var rest = flatten(arguments, true, true, 1);
|
555
568
|
return _.filter(array, function(value){
|
556
569
|
return !_.contains(rest, value);
|
557
570
|
});
|
@@ -559,23 +572,28 @@
|
|
559
572
|
|
560
573
|
// Zip together multiple lists into a single array -- elements that share
|
561
574
|
// an index go together.
|
562
|
-
_.zip = function(
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
575
|
+
_.zip = function() {
|
576
|
+
return _.unzip(arguments);
|
577
|
+
};
|
578
|
+
|
579
|
+
// Complement of _.zip. Unzip accepts an array of arrays and groups
|
580
|
+
// each array's elements on shared indices
|
581
|
+
_.unzip = function(array) {
|
582
|
+
var length = array && _.max(array, 'length').length || 0;
|
583
|
+
var result = Array(length);
|
584
|
+
|
585
|
+
for (var index = 0; index < length; index++) {
|
586
|
+
result[index] = _.pluck(array, index);
|
568
587
|
}
|
569
|
-
return
|
588
|
+
return result;
|
570
589
|
};
|
571
590
|
|
572
591
|
// Converts lists into objects. Pass either a single array of `[key, value]`
|
573
592
|
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
574
593
|
// the corresponding values.
|
575
594
|
_.object = function(list, values) {
|
576
|
-
if (list == null) return {};
|
577
595
|
var result = {};
|
578
|
-
for (var i = 0, length = list.length; i < length; i++) {
|
596
|
+
for (var i = 0, length = list && list.length; i < length; i++) {
|
579
597
|
if (values) {
|
580
598
|
result[list[i]] = values[i];
|
581
599
|
} else {
|
@@ -590,30 +608,63 @@
|
|
590
608
|
// If the array is large and already in sort order, pass `true`
|
591
609
|
// for **isSorted** to use binary search.
|
592
610
|
_.indexOf = function(array, item, isSorted) {
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
611
|
+
var i = 0, length = array && array.length;
|
612
|
+
if (typeof isSorted == 'number') {
|
613
|
+
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
|
614
|
+
} else if (isSorted && length) {
|
615
|
+
i = _.sortedIndex(array, item);
|
616
|
+
return array[i] === item ? i : -1;
|
617
|
+
}
|
618
|
+
if (item !== item) {
|
619
|
+
return _.findIndex(slice.call(array, i), _.isNaN);
|
602
620
|
}
|
603
621
|
for (; i < length; i++) if (array[i] === item) return i;
|
604
622
|
return -1;
|
605
623
|
};
|
606
624
|
|
607
625
|
_.lastIndexOf = function(array, item, from) {
|
608
|
-
|
609
|
-
var idx = array.length;
|
626
|
+
var idx = array ? array.length : 0;
|
610
627
|
if (typeof from == 'number') {
|
611
628
|
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
|
612
629
|
}
|
630
|
+
if (item !== item) {
|
631
|
+
return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
|
632
|
+
}
|
613
633
|
while (--idx >= 0) if (array[idx] === item) return idx;
|
614
634
|
return -1;
|
615
635
|
};
|
616
636
|
|
637
|
+
// Generator function to create the findIndex and findLastIndex functions
|
638
|
+
function createIndexFinder(dir) {
|
639
|
+
return function(array, predicate, context) {
|
640
|
+
predicate = cb(predicate, context);
|
641
|
+
var length = array != null && array.length;
|
642
|
+
var index = dir > 0 ? 0 : length - 1;
|
643
|
+
for (; index >= 0 && index < length; index += dir) {
|
644
|
+
if (predicate(array[index], index, array)) return index;
|
645
|
+
}
|
646
|
+
return -1;
|
647
|
+
};
|
648
|
+
}
|
649
|
+
|
650
|
+
// Returns the first index on an array-like that passes a predicate test
|
651
|
+
_.findIndex = createIndexFinder(1);
|
652
|
+
|
653
|
+
_.findLastIndex = createIndexFinder(-1);
|
654
|
+
|
655
|
+
// Use a comparator function to figure out the smallest index at which
|
656
|
+
// an object should be inserted so as to maintain order. Uses binary search.
|
657
|
+
_.sortedIndex = function(array, obj, iteratee, context) {
|
658
|
+
iteratee = cb(iteratee, context, 1);
|
659
|
+
var value = iteratee(obj);
|
660
|
+
var low = 0, high = array.length;
|
661
|
+
while (low < high) {
|
662
|
+
var mid = Math.floor((low + high) / 2);
|
663
|
+
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
664
|
+
}
|
665
|
+
return low;
|
666
|
+
};
|
667
|
+
|
617
668
|
// Generate an integer Array containing an arithmetic progression. A port of
|
618
669
|
// the native Python `range()` function. See
|
619
670
|
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
@@ -637,25 +688,25 @@
|
|
637
688
|
// Function (ahem) Functions
|
638
689
|
// ------------------
|
639
690
|
|
640
|
-
//
|
641
|
-
|
691
|
+
// Determines whether to execute a function as a constructor
|
692
|
+
// or a normal function with the provided arguments
|
693
|
+
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
|
694
|
+
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
|
695
|
+
var self = baseCreate(sourceFunc.prototype);
|
696
|
+
var result = sourceFunc.apply(self, args);
|
697
|
+
if (_.isObject(result)) return result;
|
698
|
+
return self;
|
699
|
+
};
|
642
700
|
|
643
701
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
644
702
|
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
645
703
|
// available.
|
646
704
|
_.bind = function(func, context) {
|
647
|
-
var args, bound;
|
648
705
|
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
649
706
|
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
|
650
|
-
args = slice.call(arguments, 2);
|
651
|
-
bound = function() {
|
652
|
-
|
653
|
-
Ctor.prototype = func.prototype;
|
654
|
-
var self = new Ctor;
|
655
|
-
Ctor.prototype = null;
|
656
|
-
var result = func.apply(self, args.concat(slice.call(arguments)));
|
657
|
-
if (_.isObject(result)) return result;
|
658
|
-
return self;
|
707
|
+
var args = slice.call(arguments, 2);
|
708
|
+
var bound = function() {
|
709
|
+
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
|
659
710
|
};
|
660
711
|
return bound;
|
661
712
|
};
|
@@ -665,15 +716,16 @@
|
|
665
716
|
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
666
717
|
_.partial = function(func) {
|
667
718
|
var boundArgs = slice.call(arguments, 1);
|
668
|
-
|
669
|
-
var position = 0;
|
670
|
-
var args =
|
671
|
-
for (var i = 0
|
672
|
-
|
719
|
+
var bound = function() {
|
720
|
+
var position = 0, length = boundArgs.length;
|
721
|
+
var args = Array(length);
|
722
|
+
for (var i = 0; i < length; i++) {
|
723
|
+
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
|
673
724
|
}
|
674
725
|
while (position < arguments.length) args.push(arguments[position++]);
|
675
|
-
return func
|
726
|
+
return executeBound(func, bound, this, this, args);
|
676
727
|
};
|
728
|
+
return bound;
|
677
729
|
};
|
678
730
|
|
679
731
|
// Bind a number of an object's methods to that object. Remaining arguments
|
@@ -693,7 +745,7 @@
|
|
693
745
|
_.memoize = function(func, hasher) {
|
694
746
|
var memoize = function(key) {
|
695
747
|
var cache = memoize.cache;
|
696
|
-
var address = hasher ? hasher.apply(this, arguments) : key;
|
748
|
+
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
|
697
749
|
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
|
698
750
|
return cache[address];
|
699
751
|
};
|
@@ -712,9 +764,7 @@
|
|
712
764
|
|
713
765
|
// Defers a function, scheduling it to run after the current call stack has
|
714
766
|
// cleared.
|
715
|
-
_.defer =
|
716
|
-
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
717
|
-
};
|
767
|
+
_.defer = _.partial(_.delay, _, 1);
|
718
768
|
|
719
769
|
// Returns a function, that, when invoked, will only be triggered at most once
|
720
770
|
// during a given window of time. Normally, the throttled function will run
|
@@ -739,8 +789,10 @@
|
|
739
789
|
context = this;
|
740
790
|
args = arguments;
|
741
791
|
if (remaining <= 0 || remaining > wait) {
|
742
|
-
|
743
|
-
|
792
|
+
if (timeout) {
|
793
|
+
clearTimeout(timeout);
|
794
|
+
timeout = null;
|
795
|
+
}
|
744
796
|
previous = now;
|
745
797
|
result = func.apply(context, args);
|
746
798
|
if (!timeout) context = args = null;
|
@@ -761,7 +813,7 @@
|
|
761
813
|
var later = function() {
|
762
814
|
var last = _.now() - timestamp;
|
763
815
|
|
764
|
-
if (last < wait && last
|
816
|
+
if (last < wait && last >= 0) {
|
765
817
|
timeout = setTimeout(later, wait - last);
|
766
818
|
} else {
|
767
819
|
timeout = null;
|
@@ -814,7 +866,7 @@
|
|
814
866
|
};
|
815
867
|
};
|
816
868
|
|
817
|
-
// Returns a function that will only be executed after
|
869
|
+
// Returns a function that will only be executed on and after the Nth call.
|
818
870
|
_.after = function(times, func) {
|
819
871
|
return function() {
|
820
872
|
if (--times < 1) {
|
@@ -823,15 +875,14 @@
|
|
823
875
|
};
|
824
876
|
};
|
825
877
|
|
826
|
-
// Returns a function that will only be executed
|
878
|
+
// Returns a function that will only be executed up to (but not including) the Nth call.
|
827
879
|
_.before = function(times, func) {
|
828
880
|
var memo;
|
829
881
|
return function() {
|
830
882
|
if (--times > 0) {
|
831
883
|
memo = func.apply(this, arguments);
|
832
|
-
} else {
|
833
|
-
func = null;
|
834
884
|
}
|
885
|
+
if (times <= 1) func = null;
|
835
886
|
return memo;
|
836
887
|
};
|
837
888
|
};
|
@@ -843,13 +894,47 @@
|
|
843
894
|
// Object Functions
|
844
895
|
// ----------------
|
845
896
|
|
846
|
-
//
|
897
|
+
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
|
898
|
+
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
|
899
|
+
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
|
900
|
+
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
|
901
|
+
|
902
|
+
function collectNonEnumProps(obj, keys) {
|
903
|
+
var nonEnumIdx = nonEnumerableProps.length;
|
904
|
+
var constructor = obj.constructor;
|
905
|
+
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
|
906
|
+
|
907
|
+
// Constructor is a special case.
|
908
|
+
var prop = 'constructor';
|
909
|
+
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
|
910
|
+
|
911
|
+
while (nonEnumIdx--) {
|
912
|
+
prop = nonEnumerableProps[nonEnumIdx];
|
913
|
+
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
|
914
|
+
keys.push(prop);
|
915
|
+
}
|
916
|
+
}
|
917
|
+
}
|
918
|
+
|
919
|
+
// Retrieve the names of an object's own properties.
|
847
920
|
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
848
921
|
_.keys = function(obj) {
|
849
922
|
if (!_.isObject(obj)) return [];
|
850
923
|
if (nativeKeys) return nativeKeys(obj);
|
851
924
|
var keys = [];
|
852
925
|
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
926
|
+
// Ahem, IE < 9.
|
927
|
+
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
928
|
+
return keys;
|
929
|
+
};
|
930
|
+
|
931
|
+
// Retrieve all the property names of an object.
|
932
|
+
_.allKeys = function(obj) {
|
933
|
+
if (!_.isObject(obj)) return [];
|
934
|
+
var keys = [];
|
935
|
+
for (var key in obj) keys.push(key);
|
936
|
+
// Ahem, IE < 9.
|
937
|
+
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
853
938
|
return keys;
|
854
939
|
};
|
855
940
|
|
@@ -864,6 +949,21 @@
|
|
864
949
|
return values;
|
865
950
|
};
|
866
951
|
|
952
|
+
// Returns the results of applying the iteratee to each element of the object
|
953
|
+
// In contrast to _.map it returns an object
|
954
|
+
_.mapObject = function(obj, iteratee, context) {
|
955
|
+
iteratee = cb(iteratee, context);
|
956
|
+
var keys = _.keys(obj),
|
957
|
+
length = keys.length,
|
958
|
+
results = {},
|
959
|
+
currentKey;
|
960
|
+
for (var index = 0; index < length; index++) {
|
961
|
+
currentKey = keys[index];
|
962
|
+
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
|
963
|
+
}
|
964
|
+
return results;
|
965
|
+
};
|
966
|
+
|
867
967
|
// Convert an object into a list of `[key, value]` pairs.
|
868
968
|
_.pairs = function(obj) {
|
869
969
|
var keys = _.keys(obj);
|
@@ -896,37 +996,38 @@
|
|
896
996
|
};
|
897
997
|
|
898
998
|
// Extend a given object with all the properties in passed-in object(s).
|
899
|
-
_.extend =
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
999
|
+
_.extend = createAssigner(_.allKeys);
|
1000
|
+
|
1001
|
+
// Assigns a given object with all the own properties in the passed-in object(s)
|
1002
|
+
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
|
1003
|
+
_.extendOwn = _.assign = createAssigner(_.keys);
|
1004
|
+
|
1005
|
+
// Returns the first key on an object that passes a predicate test
|
1006
|
+
_.findKey = function(obj, predicate, context) {
|
1007
|
+
predicate = cb(predicate, context);
|
1008
|
+
var keys = _.keys(obj), key;
|
1009
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
1010
|
+
key = keys[i];
|
1011
|
+
if (predicate(obj[key], key, obj)) return key;
|
909
1012
|
}
|
910
|
-
return obj;
|
911
1013
|
};
|
912
1014
|
|
913
1015
|
// Return a copy of the object only containing the whitelisted properties.
|
914
|
-
_.pick = function(
|
915
|
-
var result = {},
|
1016
|
+
_.pick = function(object, oiteratee, context) {
|
1017
|
+
var result = {}, obj = object, iteratee, keys;
|
916
1018
|
if (obj == null) return result;
|
917
|
-
if (_.isFunction(
|
918
|
-
|
919
|
-
|
920
|
-
var value = obj[key];
|
921
|
-
if (iteratee(value, key, obj)) result[key] = value;
|
922
|
-
}
|
1019
|
+
if (_.isFunction(oiteratee)) {
|
1020
|
+
keys = _.allKeys(obj);
|
1021
|
+
iteratee = optimizeCb(oiteratee, context);
|
923
1022
|
} else {
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
1023
|
+
keys = flatten(arguments, false, false, 1);
|
1024
|
+
iteratee = function(value, key, obj) { return key in obj; };
|
1025
|
+
obj = Object(obj);
|
1026
|
+
}
|
1027
|
+
for (var i = 0, length = keys.length; i < length; i++) {
|
1028
|
+
var key = keys[i];
|
1029
|
+
var value = obj[key];
|
1030
|
+
if (iteratee(value, key, obj)) result[key] = value;
|
930
1031
|
}
|
931
1032
|
return result;
|
932
1033
|
};
|
@@ -936,7 +1037,7 @@
|
|
936
1037
|
if (_.isFunction(iteratee)) {
|
937
1038
|
iteratee = _.negate(iteratee);
|
938
1039
|
} else {
|
939
|
-
var keys = _.map(
|
1040
|
+
var keys = _.map(flatten(arguments, false, false, 1), String);
|
940
1041
|
iteratee = function(value, key) {
|
941
1042
|
return !_.contains(keys, key);
|
942
1043
|
};
|
@@ -945,16 +1046,7 @@
|
|
945
1046
|
};
|
946
1047
|
|
947
1048
|
// Fill in a given object with default properties.
|
948
|
-
_.defaults =
|
949
|
-
if (!_.isObject(obj)) return obj;
|
950
|
-
for (var i = 1, length = arguments.length; i < length; i++) {
|
951
|
-
var source = arguments[i];
|
952
|
-
for (var prop in source) {
|
953
|
-
if (obj[prop] === void 0) obj[prop] = source[prop];
|
954
|
-
}
|
955
|
-
}
|
956
|
-
return obj;
|
957
|
-
};
|
1049
|
+
_.defaults = createAssigner(_.allKeys, true);
|
958
1050
|
|
959
1051
|
// Create a (shallow-cloned) duplicate of an object.
|
960
1052
|
_.clone = function(obj) {
|
@@ -970,6 +1062,19 @@
|
|
970
1062
|
return obj;
|
971
1063
|
};
|
972
1064
|
|
1065
|
+
// Returns whether an object has a given set of `key:value` pairs.
|
1066
|
+
_.isMatch = function(object, attrs) {
|
1067
|
+
var keys = _.keys(attrs), length = keys.length;
|
1068
|
+
if (object == null) return !length;
|
1069
|
+
var obj = Object(object);
|
1070
|
+
for (var i = 0; i < length; i++) {
|
1071
|
+
var key = keys[i];
|
1072
|
+
if (attrs[key] !== obj[key] || !(key in obj)) return false;
|
1073
|
+
}
|
1074
|
+
return true;
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
|
973
1078
|
// Internal recursive comparison function for `isEqual`.
|
974
1079
|
var eq = function(a, b, aStack, bStack) {
|
975
1080
|
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
@@ -1004,74 +1109,76 @@
|
|
1004
1109
|
// of `NaN` are not equivalent.
|
1005
1110
|
return +a === +b;
|
1006
1111
|
}
|
1007
|
-
|
1112
|
+
|
1113
|
+
var areArrays = className === '[object Array]';
|
1114
|
+
if (!areArrays) {
|
1115
|
+
if (typeof a != 'object' || typeof b != 'object') return false;
|
1116
|
+
|
1117
|
+
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
1118
|
+
// from different frames are.
|
1119
|
+
var aCtor = a.constructor, bCtor = b.constructor;
|
1120
|
+
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
|
1121
|
+
_.isFunction(bCtor) && bCtor instanceof bCtor)
|
1122
|
+
&& ('constructor' in a && 'constructor' in b)) {
|
1123
|
+
return false;
|
1124
|
+
}
|
1125
|
+
}
|
1008
1126
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
1009
1127
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
1128
|
+
|
1129
|
+
// Initializing stack of traversed objects.
|
1130
|
+
// It's done here since we only need them for objects and arrays comparison.
|
1131
|
+
aStack = aStack || [];
|
1132
|
+
bStack = bStack || [];
|
1010
1133
|
var length = aStack.length;
|
1011
1134
|
while (length--) {
|
1012
1135
|
// Linear search. Performance is inversely proportional to the number of
|
1013
1136
|
// unique nested structures.
|
1014
1137
|
if (aStack[length] === a) return bStack[length] === b;
|
1015
1138
|
}
|
1016
|
-
|
1017
|
-
// from different frames are.
|
1018
|
-
var aCtor = a.constructor, bCtor = b.constructor;
|
1019
|
-
if (
|
1020
|
-
aCtor !== bCtor &&
|
1021
|
-
// Handle Object.create(x) cases
|
1022
|
-
'constructor' in a && 'constructor' in b &&
|
1023
|
-
!(_.isFunction(aCtor) && aCtor instanceof aCtor &&
|
1024
|
-
_.isFunction(bCtor) && bCtor instanceof bCtor)
|
1025
|
-
) {
|
1026
|
-
return false;
|
1027
|
-
}
|
1139
|
+
|
1028
1140
|
// Add the first object to the stack of traversed objects.
|
1029
1141
|
aStack.push(a);
|
1030
1142
|
bStack.push(b);
|
1031
|
-
|
1143
|
+
|
1032
1144
|
// Recursively compare objects and arrays.
|
1033
|
-
if (
|
1145
|
+
if (areArrays) {
|
1034
1146
|
// Compare array lengths to determine if a deep comparison is necessary.
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
|
1041
|
-
}
|
1147
|
+
length = a.length;
|
1148
|
+
if (length !== b.length) return false;
|
1149
|
+
// Deep compare the contents, ignoring non-numeric properties.
|
1150
|
+
while (length--) {
|
1151
|
+
if (!eq(a[length], b[length], aStack, bStack)) return false;
|
1042
1152
|
}
|
1043
1153
|
} else {
|
1044
1154
|
// Deep compare objects.
|
1045
1155
|
var keys = _.keys(a), key;
|
1046
|
-
|
1156
|
+
length = keys.length;
|
1047
1157
|
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
|
1054
|
-
}
|
1158
|
+
if (_.keys(b).length !== length) return false;
|
1159
|
+
while (length--) {
|
1160
|
+
// Deep compare each member
|
1161
|
+
key = keys[length];
|
1162
|
+
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
|
1055
1163
|
}
|
1056
1164
|
}
|
1057
1165
|
// Remove the first object from the stack of traversed objects.
|
1058
1166
|
aStack.pop();
|
1059
1167
|
bStack.pop();
|
1060
|
-
return
|
1168
|
+
return true;
|
1061
1169
|
};
|
1062
1170
|
|
1063
1171
|
// Perform a deep comparison to check if two objects are equal.
|
1064
1172
|
_.isEqual = function(a, b) {
|
1065
|
-
return eq(a, b
|
1173
|
+
return eq(a, b);
|
1066
1174
|
};
|
1067
1175
|
|
1068
1176
|
// Is a given array, string, or object empty?
|
1069
1177
|
// An "empty" object has no enumerable own-properties.
|
1070
1178
|
_.isEmpty = function(obj) {
|
1071
1179
|
if (obj == null) return true;
|
1072
|
-
if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
|
1073
|
-
|
1074
|
-
return true;
|
1180
|
+
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
|
1181
|
+
return _.keys(obj).length === 0;
|
1075
1182
|
};
|
1076
1183
|
|
1077
1184
|
// Is a given value a DOM element?
|
@@ -1091,14 +1198,14 @@
|
|
1091
1198
|
return type === 'function' || type === 'object' && !!obj;
|
1092
1199
|
};
|
1093
1200
|
|
1094
|
-
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
|
1095
|
-
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
|
1201
|
+
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
|
1202
|
+
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
|
1096
1203
|
_['is' + name] = function(obj) {
|
1097
1204
|
return toString.call(obj) === '[object ' + name + ']';
|
1098
1205
|
};
|
1099
1206
|
});
|
1100
1207
|
|
1101
|
-
// Define a fallback version of the method in browsers (ahem, IE), where
|
1208
|
+
// Define a fallback version of the method in browsers (ahem, IE < 9), where
|
1102
1209
|
// there isn't any inspectable "Arguments" type.
|
1103
1210
|
if (!_.isArguments(arguments)) {
|
1104
1211
|
_.isArguments = function(obj) {
|
@@ -1106,8 +1213,9 @@
|
|
1106
1213
|
};
|
1107
1214
|
}
|
1108
1215
|
|
1109
|
-
// Optimize `isFunction` if appropriate. Work around
|
1110
|
-
|
1216
|
+
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
|
1217
|
+
// IE 11 (#1621), and in Safari 8 (#1929).
|
1218
|
+
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
|
1111
1219
|
_.isFunction = function(obj) {
|
1112
1220
|
return typeof obj == 'function' || false;
|
1113
1221
|
};
|
@@ -1170,28 +1278,30 @@
|
|
1170
1278
|
|
1171
1279
|
_.property = function(key) {
|
1172
1280
|
return function(obj) {
|
1281
|
+
return obj == null ? void 0 : obj[key];
|
1282
|
+
};
|
1283
|
+
};
|
1284
|
+
|
1285
|
+
// Generates a function for a given object that returns a given property.
|
1286
|
+
_.propertyOf = function(obj) {
|
1287
|
+
return obj == null ? function(){} : function(key) {
|
1173
1288
|
return obj[key];
|
1174
1289
|
};
|
1175
1290
|
};
|
1176
1291
|
|
1177
|
-
// Returns a predicate for checking whether an object has a given set of
|
1178
|
-
|
1179
|
-
|
1292
|
+
// Returns a predicate for checking whether an object has a given set of
|
1293
|
+
// `key:value` pairs.
|
1294
|
+
_.matcher = _.matches = function(attrs) {
|
1295
|
+
attrs = _.extendOwn({}, attrs);
|
1180
1296
|
return function(obj) {
|
1181
|
-
|
1182
|
-
obj = new Object(obj);
|
1183
|
-
for (var i = 0; i < length; i++) {
|
1184
|
-
var pair = pairs[i], key = pair[0];
|
1185
|
-
if (pair[1] !== obj[key] || !(key in obj)) return false;
|
1186
|
-
}
|
1187
|
-
return true;
|
1297
|
+
return _.isMatch(obj, attrs);
|
1188
1298
|
};
|
1189
1299
|
};
|
1190
1300
|
|
1191
1301
|
// Run a function **n** times.
|
1192
1302
|
_.times = function(n, iteratee, context) {
|
1193
1303
|
var accum = Array(Math.max(0, n));
|
1194
|
-
iteratee =
|
1304
|
+
iteratee = optimizeCb(iteratee, context, 1);
|
1195
1305
|
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
1196
1306
|
return accum;
|
1197
1307
|
};
|
@@ -1240,10 +1350,12 @@
|
|
1240
1350
|
|
1241
1351
|
// If the value of the named `property` is a function then invoke it with the
|
1242
1352
|
// `object` as context; otherwise, return it.
|
1243
|
-
_.result = function(object, property) {
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1353
|
+
_.result = function(object, property, fallback) {
|
1354
|
+
var value = object == null ? void 0 : object[property];
|
1355
|
+
if (value === void 0) {
|
1356
|
+
value = fallback;
|
1357
|
+
}
|
1358
|
+
return _.isFunction(value) ? value.call(object) : value;
|
1247
1359
|
};
|
1248
1360
|
|
1249
1361
|
// Generate a unique integer id (unique within the entire client session).
|
@@ -1358,8 +1470,8 @@
|
|
1358
1470
|
// underscore functions. Wrapped objects may be chained.
|
1359
1471
|
|
1360
1472
|
// Helper function to continue chaining intermediate results.
|
1361
|
-
var result = function(obj) {
|
1362
|
-
return
|
1473
|
+
var result = function(instance, obj) {
|
1474
|
+
return instance._chain ? _(obj).chain() : obj;
|
1363
1475
|
};
|
1364
1476
|
|
1365
1477
|
// Add your own custom functions to the Underscore object.
|
@@ -1369,7 +1481,7 @@
|
|
1369
1481
|
_.prototype[name] = function() {
|
1370
1482
|
var args = [this._wrapped];
|
1371
1483
|
push.apply(args, arguments);
|
1372
|
-
return result
|
1484
|
+
return result(this, func.apply(_, args));
|
1373
1485
|
};
|
1374
1486
|
});
|
1375
1487
|
};
|
@@ -1384,7 +1496,7 @@
|
|
1384
1496
|
var obj = this._wrapped;
|
1385
1497
|
method.apply(obj, arguments);
|
1386
1498
|
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
|
1387
|
-
return result
|
1499
|
+
return result(this, obj);
|
1388
1500
|
};
|
1389
1501
|
});
|
1390
1502
|
|
@@ -1392,7 +1504,7 @@
|
|
1392
1504
|
_.each(['concat', 'join', 'slice'], function(name) {
|
1393
1505
|
var method = ArrayProto[name];
|
1394
1506
|
_.prototype[name] = function() {
|
1395
|
-
return result
|
1507
|
+
return result(this, method.apply(this._wrapped, arguments));
|
1396
1508
|
};
|
1397
1509
|
});
|
1398
1510
|
|
@@ -1401,6 +1513,14 @@
|
|
1401
1513
|
return this._wrapped;
|
1402
1514
|
};
|
1403
1515
|
|
1516
|
+
// Provide unwrapping proxy for some methods used in engine operations
|
1517
|
+
// such as arithmetic and JSON stringification.
|
1518
|
+
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
|
1519
|
+
|
1520
|
+
_.prototype.toString = function() {
|
1521
|
+
return '' + this._wrapped;
|
1522
|
+
};
|
1523
|
+
|
1404
1524
|
// AMD registration happens at the end for compatibility with AMD loaders
|
1405
1525
|
// that may not enforce next-turn semantics on modules. Even though general
|
1406
1526
|
// practice for AMD registration is to be anonymous, underscore registers
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: underscore-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Wenglewski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|