PluginProbe
WebTotem Security / 2.3.42
WebTotem Security v2.3.42
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / node_modules / underscore / underscore.js

underscore.js in WebTotem Security 2.3.42, at node_modules/underscore/underscore.js

1,344 lines 44.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // Underscore.js 1.6.0
2 // http://underscorejs.org
3 // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4 // Underscore may be freely distributed under the MIT license.
5
6 (function() {
7
8 // Baseline setup
9 // --------------
10
11 // Establish the root object, `window` in the browser, or `exports` on the server.
12 var root = this;
13
14 // Save the previous value of the `_` variable.
15 var previousUnderscore = root._;
16
17 // Establish the object that gets returned to break out of a loop iteration.
18 var breaker = {};
19
20 // Save bytes in the minified (but not gzipped) version:
21 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
22
23 // Create quick reference variables for speed access to core prototypes.
24 var
25 push = ArrayProto.push,
26 slice = ArrayProto.slice,
27 concat = ArrayProto.concat,
28 toString = ObjProto.toString,
29 hasOwnProperty = ObjProto.hasOwnProperty;
30
31 // All **ECMAScript 5** native function implementations that we hope to use
32 // are declared here.
33 var
34 nativeForEach = ArrayProto.forEach,
35 nativeMap = ArrayProto.map,
36 nativeReduce = ArrayProto.reduce,
37 nativeReduceRight = ArrayProto.reduceRight,
38 nativeFilter = ArrayProto.filter,
39 nativeEvery = ArrayProto.every,
40 nativeSome = ArrayProto.some,
41 nativeIndexOf = ArrayProto.indexOf,
42 nativeLastIndexOf = ArrayProto.lastIndexOf,
43 nativeIsArray = Array.isArray,
44 nativeKeys = Object.keys,
45 nativeBind = FuncProto.bind;
46
47 // Create a safe reference to the Underscore object for use below.
48 var _ = function(obj) {
49 if (obj instanceof _) return obj;
50 if (!(this instanceof _)) return new _(obj);
51 this._wrapped = obj;
52 };
53
54 // Export the Underscore object for **Node.js**, with
55 // backwards-compatibility for the old `require()` API. If we're in
56 // the browser, add `_` as a global object via a string identifier,
57 // for Closure Compiler "advanced" mode.
58 if (typeof exports !== 'undefined') {
59 if (typeof module !== 'undefined' && module.exports) {
60 exports = module.exports = _;
61 }
62 exports._ = _;
63 } else {
64 root._ = _;
65 }
66
67 // Current version.
68 _.VERSION = '1.6.0';
69
70 // Collection Functions
71 // --------------------
72
73 // The cornerstone, an `each` implementation, aka `forEach`.
74 // Handles objects with the built-in `forEach`, arrays, and raw objects.
75 // Delegates to **ECMAScript 5**'s native `forEach` if available.
76 var each = _.each = _.forEach = function(obj, iterator, context) {
77 if (obj == null) return obj;
78 if (nativeForEach && obj.forEach === nativeForEach) {
79 obj.forEach(iterator, context);
80 } else if (obj.length === +obj.length) {
81 for (var i = 0, length = obj.length; i < length; i++) {
82 if (iterator.call(context, obj[i], i, obj) === breaker) return;
83 }
84 } else {
85 var keys = _.keys(obj);
86 for (var i = 0, length = keys.length; i < length; i++) {
87 if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
88 }
89 }
90 return obj;
91 };
92
93 // Return the results of applying the iterator to each element.
94 // Delegates to **ECMAScript 5**'s native `map` if available.
95 _.map = _.collect = function(obj, iterator, context) {
96 var results = [];
97 if (obj == null) return results;
98 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
99 each(obj, function(value, index, list) {
100 results.push(iterator.call(context, value, index, list));
101 });
102 return results;
103 };
104
105 var reduceError = 'Reduce of empty array with no initial value';
106
107 // **Reduce** builds up a single result from a list of values, aka `inject`,
108 // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
109 _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
110 var initial = arguments.length > 2;
111 if (obj == null) obj = [];
112 if (nativeReduce && obj.reduce === nativeReduce) {
113 if (context) iterator = _.bind(iterator, context);
114 return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
115 }
116 each(obj, function(value, index, list) {
117 if (!initial) {
118 memo = value;
119 initial = true;
120 } else {
121 memo = iterator.call(context, memo, value, index, list);
122 }
123 });
124 if (!initial) throw new TypeError(reduceError);
125 return memo;
126 };
127
128 // The right-associative version of reduce, also known as `foldr`.
129 // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
130 _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
131 var initial = arguments.length > 2;
132 if (obj == null) obj = [];
133 if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
134 if (context) iterator = _.bind(iterator, context);
135 return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
136 }
137 var length = obj.length;
138 if (length !== +length) {
139 var keys = _.keys(obj);
140 length = keys.length;
141 }
142 each(obj, function(value, index, list) {
143 index = keys ? keys[--length] : --length;
144 if (!initial) {
145 memo = obj[index];
146 initial = true;
147 } else {
148 memo = iterator.call(context, memo, obj[index], index, list);
149 }
150 });
151 if (!initial) throw new TypeError(reduceError);
152 return memo;
153 };
154
155 // Return the first value which passes a truth test. Aliased as `detect`.
156 _.find = _.detect = function(obj, predicate, context) {
157 var result;
158 any(obj, function(value, index, list) {
159 if (predicate.call(context, value, index, list)) {
160 result = value;
161 return true;
162 }
163 });
164 return result;
165 };
166
167 // Return all the elements that pass a truth test.
168 // Delegates to **ECMAScript 5**'s native `filter` if available.
169 // Aliased as `select`.
170 _.filter = _.select = function(obj, predicate, context) {
171 var results = [];
172 if (obj == null) return results;
173 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
174 each(obj, function(value, index, list) {
175 if (predicate.call(context, value, index, list)) results.push(value);
176 });
177 return results;
178 };
179
180 // Return all the elements for which a truth test fails.
181 _.reject = function(obj, predicate, context) {
182 return _.filter(obj, function(value, index, list) {
183 return !predicate.call(context, value, index, list);
184 }, context);
185 };
186
187 // Determine whether all of the elements match a truth test.
188 // Delegates to **ECMAScript 5**'s native `every` if available.
189 // Aliased as `all`.
190 _.every = _.all = function(obj, predicate, context) {
191 predicate || (predicate = _.identity);
192 var result = true;
193 if (obj == null) return result;
194 if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
195 each(obj, function(value, index, list) {
196 if (!(result = result && predicate.call(context, value, index, list))) return breaker;
197 });
198 return !!result;
199 };
200
201 // Determine if at least one element in the object matches a truth test.
202 // Delegates to **ECMAScript 5**'s native `some` if available.
203 // Aliased as `any`.
204 var any = _.some = _.any = function(obj, predicate, context) {
205 predicate || (predicate = _.identity);
206 var result = false;
207 if (obj == null) return result;
208 if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
209 each(obj, function(value, index, list) {
210 if (result || (result = predicate.call(context, value, index, list))) return breaker;
211 });
212 return !!result;
213 };
214
215 // Determine if the array or object contains a given value (using `===`).
216 // Aliased as `include`.
217 _.contains = _.include = function(obj, target) {
218 if (obj == null) return false;
219 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
220 return any(obj, function(value) {
221 return value === target;
222 });
223 };
224
225 // Invoke a method (with arguments) on every item in a collection.
226 _.invoke = function(obj, method) {
227 var args = slice.call(arguments, 2);
228 var isFunc = _.isFunction(method);
229 return _.map(obj, function(value) {
230 return (isFunc ? method : value[method]).apply(value, args);
231 });
232 };
233
234 // Convenience version of a common use case of `map`: fetching a property.
235 _.pluck = function(obj, key) {
236 return _.map(obj, _.property(key));
237 };
238
239 // Convenience version of a common use case of `filter`: selecting only objects
240 // containing specific `key:value` pairs.
241 _.where = function(obj, attrs) {
242 return _.filter(obj, _.matches(attrs));
243 };
244
245 // Convenience version of a common use case of `find`: getting the first object
246 // containing specific `key:value` pairs.
247 _.findWhere = function(obj, attrs) {
248 return _.find(obj, _.matches(attrs));
249 };
250
251 // Return the maximum element or (element-based computation).
252 // Can't optimize arrays of integers longer than 65,535 elements.
253 // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
254 _.max = function(obj, iterator, context) {
255 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
256 return Math.max.apply(Math, obj);
257 }
258 var result = -Infinity, lastComputed = -Infinity;
259 each(obj, function(value, index, list) {
260 var computed = iterator ? iterator.call(context, value, index, list) : value;
261 if (computed > lastComputed) {
262 result = value;
263 lastComputed = computed;
264 }
265 });
266 return result;
267 };
268
269 // Return the minimum element (or element-based computation).
270 _.min = function(obj, iterator, context) {
271 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
272 return Math.min.apply(Math, obj);
273 }
274 var result = Infinity, lastComputed = Infinity;
275 each(obj, function(value, index, list) {
276 var computed = iterator ? iterator.call(context, value, index, list) : value;
277 if (computed < lastComputed) {
278 result = value;
279 lastComputed = computed;
280 }
281 });
282 return result;
283 };
284
285 // Shuffle an array, using the modern version of the
286 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
287 _.shuffle = function(obj) {
288 var rand;
289 var index = 0;
290 var shuffled = [];
291 each(obj, function(value) {
292 rand = _.random(index++);
293 shuffled[index - 1] = shuffled[rand];
294 shuffled[rand] = value;
295 });
296 return shuffled;
297 };
298
299 // Sample **n** random values from a collection.
300 // If **n** is not specified, returns a single random element.
301 // The internal `guard` argument allows it to work with `map`.
302 _.sample = function(obj, n, guard) {
303 if (n == null || guard) {
304 if (obj.length !== +obj.length) obj = _.values(obj);
305 return obj[_.random(obj.length - 1)];
306 }
307 return _.shuffle(obj).slice(0, Math.max(0, n));
308 };
309
310 // An internal function to generate lookup iterators.
311 var lookupIterator = function(value) {
312 if (value == null) return _.identity;
313 if (_.isFunction(value)) return value;
314 return _.property(value);
315 };
316
317 // Sort the object's values by a criterion produced by an iterator.
318 _.sortBy = function(obj, iterator, context) {
319 iterator = lookupIterator(iterator);
320 return _.pluck(_.map(obj, function(value, index, list) {
321 return {
322 value: value,
323 index: index,
324 criteria: iterator.call(context, value, index, list)
325 };
326 }).sort(function(left, right) {
327 var a = left.criteria;
328 var b = right.criteria;
329 if (a !== b) {
330 if (a > b || a === void 0) return 1;
331 if (a < b || b === void 0) return -1;
332 }
333 return left.index - right.index;
334 }), 'value');
335 };
336
337 // An internal function used for aggregate "group by" operations.
338 var group = function(behavior) {
339 return function(obj, iterator, context) {
340 var result = {};
341 iterator = lookupIterator(iterator);
342 each(obj, function(value, index) {
343 var key = iterator.call(context, value, index, obj);
344 behavior(result, key, value);
345 });
346 return result;
347 };
348 };
349
350 // Groups the object's values by a criterion. Pass either a string attribute
351 // to group by, or a function that returns the criterion.
352 _.groupBy = group(function(result, key, value) {
353 _.has(result, key) ? result[key].push(value) : result[key] = [value];
354 });
355
356 // Indexes the object's values by a criterion, similar to `groupBy`, but for
357 // when you know that your index values will be unique.
358 _.indexBy = group(function(result, key, value) {
359 result[key] = value;
360 });
361
362 // Counts instances of an object that group by a certain criterion. Pass
363 // either a string attribute to count by, or a function that returns the
364 // criterion.
365 _.countBy = group(function(result, key) {
366 _.has(result, key) ? result[key]++ : result[key] = 1;
367 });
368
369 // Use a comparator function to figure out the smallest index at which
370 // an object should be inserted so as to maintain order. Uses binary search.
371 _.sortedIndex = function(array, obj, iterator, context) {
372 iterator = lookupIterator(iterator);
373 var value = iterator.call(context, obj);
374 var low = 0, high = array.length;
375 while (low < high) {
376 var mid = (low + high) >>> 1;
377 iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
378 }
379 return low;
380 };
381
382 // Safely create a real, live array from anything iterable.
383 _.toArray = function(obj) {
384 if (!obj) return [];
385 if (_.isArray(obj)) return slice.call(obj);
386 if (obj.length === +obj.length) return _.map(obj, _.identity);
387 return _.values(obj);
388 };
389
390 // Return the number of elements in an object.
391 _.size = function(obj) {
392 if (obj == null) return 0;
393 return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
394 };
395
396 // Array Functions
397 // ---------------
398
399 // Get the first element of an array. Passing **n** will return the first N
400 // values in the array. Aliased as `head` and `take`. The **guard** check
401 // allows it to work with `_.map`.
402 _.first = _.head = _.take = function(array, n, guard) {
403 if (array == null) return void 0;
404 if ((n == null) || guard) return array[0];
405 if (n < 0) return [];
406 return slice.call(array, 0, n);
407 };
408
409 // Returns everything but the last entry of the array. Especially useful on
410 // the arguments object. Passing **n** will return all the values in
411 // the array, excluding the last N. The **guard** check allows it to work with
412 // `_.map`.
413 _.initial = function(array, n, guard) {
414 return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
415 };
416
417 // Get the last element of an array. Passing **n** will return the last N
418 // values in the array. The **guard** check allows it to work with `_.map`.
419 _.last = function(array, n, guard) {
420 if (array == null) return void 0;
421 if ((n == null) || guard) return array[array.length - 1];
422 return slice.call(array, Math.max(array.length - n, 0));
423 };
424
425 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
426 // Especially useful on the arguments object. Passing an **n** will return
427 // the rest N values in the array. The **guard**
428 // check allows it to work with `_.map`.
429 _.rest = _.tail = _.drop = function(array, n, guard) {
430 return slice.call(array, (n == null) || guard ? 1 : n);
431 };
432
433 // Trim out all falsy values from an array.
434 _.compact = function(array) {
435 return _.filter(array, _.identity);
436 };
437
438 // Internal implementation of a recursive `flatten` function.
439 var flatten = function(input, shallow, output) {
440 if (shallow && _.every(input, _.isArray)) {
441 return concat.apply(output, input);
442 }
443 each(input, function(value) {
444 if (_.isArray(value) || _.isArguments(value)) {
445 shallow ? push.apply(output, value) : flatten(value, shallow, output);
446 } else {
447 output.push(value);
448 }
449 });
450 return output;
451 };
452
453 // Flatten out an array, either recursively (by default), or just one level.
454 _.flatten = function(array, shallow) {
455 return flatten(array, shallow, []);
456 };
457
458 // Return a version of the array that does not contain the specified value(s).
459 _.without = function(array) {
460 return _.difference(array, slice.call(arguments, 1));
461 };
462
463 // Split an array into two arrays: one whose elements all satisfy the given
464 // predicate, and one whose elements all do not satisfy the predicate.
465 _.partition = function(array, predicate) {
466 var pass = [], fail = [];
467 each(array, function(elem) {
468 (predicate(elem) ? pass : fail).push(elem);
469 });
470 return [pass, fail];
471 };
472
473 // Produce a duplicate-free version of the array. If the array has already
474 // been sorted, you have the option of using a faster algorithm.
475 // Aliased as `unique`.
476 _.uniq = _.unique = function(array, isSorted, iterator, context) {
477 if (_.isFunction(isSorted)) {
478 context = iterator;
479 iterator = isSorted;
480 isSorted = false;
481 }
482 var initial = iterator ? _.map(array, iterator, context) : array;
483 var results = [];
484 var seen = [];
485 each(initial, function(value, index) {
486 if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
487 seen.push(value);
488 results.push(array[index]);
489 }
490 });
491 return results;
492 };
493
494 // Produce an array that contains the union: each distinct element from all of
495 // the passed-in arrays.
496 _.union = function() {
497 return _.uniq(_.flatten(arguments, true));
498 };
499
500 // Produce an array that contains every item shared between all the
501 // passed-in arrays.
502 _.intersection = function(array) {
503 var rest = slice.call(arguments, 1);
504 return _.filter(_.uniq(array), function(item) {
505 return _.every(rest, function(other) {
506 return _.contains(other, item);
507 });
508 });
509 };
510
511 // Take the difference between one array and a number of other arrays.
512 // Only the elements present in just the first array will remain.
513 _.difference = function(array) {
514 var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
515 return _.filter(array, function(value){ return !_.contains(rest, value); });
516 };
517
518 // Zip together multiple lists into a single array -- elements that share
519 // an index go together.
520 _.zip = function() {
521 var length = _.max(_.pluck(arguments, 'length').concat(0));
522 var results = new Array(length);
523 for (var i = 0; i < length; i++) {
524 results[i] = _.pluck(arguments, '' + i);
525 }
526 return results;
527 };
528
529 // Converts lists into objects. Pass either a single array of `[key, value]`
530 // pairs, or two parallel arrays of the same length -- one of keys, and one of
531 // the corresponding values.
532 _.object = function(list, values) {
533 if (list == null) return {};
534 var result = {};
535 for (var i = 0, length = list.length; i < length; i++) {
536 if (values) {
537 result[list[i]] = values[i];
538 } else {
539 result[list[i][0]] = list[i][1];
540 }
541 }
542 return result;
543 };
544
545 // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
546 // we need this function. Return the position of the first occurrence of an
547 // item in an array, or -1 if the item is not included in the array.
548 // Delegates to **ECMAScript 5**'s native `indexOf` if available.
549 // If the array is large and already in sort order, pass `true`
550 // for **isSorted** to use binary search.
551 _.indexOf = function(array, item, isSorted) {
552 if (array == null) return -1;
553 var i = 0, length = array.length;
554 if (isSorted) {
555 if (typeof isSorted == 'number') {
556 i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
557 } else {
558 i = _.sortedIndex(array, item);
559 return array[i] === item ? i : -1;
560 }
561 }
562 if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
563 for (; i < length; i++) if (array[i] === item) return i;
564 return -1;
565 };
566
567 // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
568 _.lastIndexOf = function(array, item, from) {
569 if (array == null) return -1;
570 var hasIndex = from != null;
571 if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
572 return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
573 }
574 var i = (hasIndex ? from : array.length);
575 while (i--) if (array[i] === item) return i;
576 return -1;
577 };
578
579 // Generate an integer Array containing an arithmetic progression. A port of
580 // the native Python `range()` function. See
581 // [the Python documentation](http://docs.python.org/library/functions.html#range).
582 _.range = function(start, stop, step) {
583 if (arguments.length <= 1) {
584 stop = start || 0;
585 start = 0;
586 }
587 step = arguments[2] || 1;
588
589 var length = Math.max(Math.ceil((stop - start) / step), 0);
590 var idx = 0;
591 var range = new Array(length);
592
593 while(idx < length) {
594 range[idx++] = start;
595 start += step;
596 }
597
598 return range;
599 };
600
601 // Function (ahem) Functions
602 // ------------------
603
604 // Reusable constructor function for prototype setting.
605 var ctor = function(){};
606
607 // Create a function bound to a given object (assigning `this`, and arguments,
608 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
609 // available.
610 _.bind = function(func, context) {
611 var args, bound;
612 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
613 if (!_.isFunction(func)) throw new TypeError;
614 args = slice.call(arguments, 2);
615 return bound = function() {
616 if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
617 ctor.prototype = func.prototype;
618 var self = new ctor;
619 ctor.prototype = null;
620 var result = func.apply(self, args.concat(slice.call(arguments)));
621 if (Object(result) === result) return result;
622 return self;
623 };
624 };
625
626 // Partially apply a function by creating a version that has had some of its
627 // arguments pre-filled, without changing its dynamic `this` context. _ acts
628 // as a placeholder, allowing any combination of arguments to be pre-filled.
629 _.partial = function(func) {
630 var boundArgs = slice.call(arguments, 1);
631 return function() {
632 var position = 0;
633 var args = boundArgs.slice();
634 for (var i = 0, length = args.length; i < length; i++) {
635 if (args[i] === _) args[i] = arguments[position++];
636 }
637 while (position < arguments.length) args.push(arguments[position++]);
638 return func.apply(this, args);
639 };
640 };
641
642 // Bind a number of an object's methods to that object. Remaining arguments
643 // are the method names to be bound. Useful for ensuring that all callbacks
644 // defined on an object belong to it.
645 _.bindAll = function(obj) {
646 var funcs = slice.call(arguments, 1);
647 if (funcs.length === 0) throw new Error('bindAll must be passed function names');
648 each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
649 return obj;
650 };
651
652 // Memoize an expensive function by storing its results.
653 _.memoize = function(func, hasher) {
654 var memo = {};
655 hasher || (hasher = _.identity);
656 return function() {
657 var key = hasher.apply(this, arguments);
658 return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
659 };
660 };
661
662 // Delays a function for the given number of milliseconds, and then calls
663 // it with the arguments supplied.
664 _.delay = function(func, wait) {
665 var args = slice.call(arguments, 2);
666 return setTimeout(function(){ return func.apply(null, args); }, wait);
667 };
668
669 // Defers a function, scheduling it to run after the current call stack has
670 // cleared.
671 _.defer = function(func) {
672 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
673 };
674
675 // Returns a function, that, when invoked, will only be triggered at most once
676 // during a given window of time. Normally, the throttled function will run
677 // as much as it can, without ever going more than once per `wait` duration;
678 // but if you'd like to disable the execution on the leading edge, pass
679 // `{leading: false}`. To disable execution on the trailing edge, ditto.
680 _.throttle = function(func, wait, options) {
681 var context, args, result;
682 var timeout = null;
683 var previous = 0;
684 options || (options = {});
685 var later = function() {
686 previous = options.leading === false ? 0 : _.now();
687 timeout = null;
688 result = func.apply(context, args);
689 context = args = null;
690 };
691 return function() {
692 var now = _.now();
693 if (!previous && options.leading === false) previous = now;
694 var remaining = wait - (now - previous);
695 context = this;
696 args = arguments;
697 if (remaining <= 0) {
698 clearTimeout(timeout);
699 timeout = null;
700 previous = now;
701 result = func.apply(context, args);
702 context = args = null;
703 } else if (!timeout && options.trailing !== false) {
704 timeout = setTimeout(later, remaining);
705 }
706 return result;
707 };
708 };
709
710 // Returns a function, that, as long as it continues to be invoked, will not
711 // be triggered. The function will be called after it stops being called for
712 // N milliseconds. If `immediate` is passed, trigger the function on the
713 // leading edge, instead of the trailing.
714 _.debounce = function(func, wait, immediate) {
715 var timeout, args, context, timestamp, result;
716
717 var later = function() {
718 var last = _.now() - timestamp;
719 if (last < wait) {
720 timeout = setTimeout(later, wait - last);
721 } else {
722 timeout = null;
723 if (!immediate) {
724 result = func.apply(context, args);
725 context = args = null;
726 }
727 }
728 };
729
730 return function() {
731 context = this;
732 args = arguments;
733 timestamp = _.now();
734 var callNow = immediate && !timeout;
735 if (!timeout) {
736 timeout = setTimeout(later, wait);
737 }
738 if (callNow) {
739 result = func.apply(context, args);
740 context = args = null;
741 }
742
743 return result;
744 };
745 };
746
747 // Returns a function that will be executed at most one time, no matter how
748 // often you call it. Useful for lazy initialization.
749 _.once = function(func) {
750 var ran = false, memo;
751 return function() {
752 if (ran) return memo;
753 ran = true;
754 memo = func.apply(this, arguments);
755 func = null;
756 return memo;
757 };
758 };
759
760 // Returns the first function passed as an argument to the second,
761 // allowing you to adjust arguments, run code before and after, and
762 // conditionally execute the original function.
763 _.wrap = function(func, wrapper) {
764 return _.partial(wrapper, func);
765 };
766
767 // Returns a function that is the composition of a list of functions, each
768 // consuming the return value of the function that follows.
769 _.compose = function() {
770 var funcs = arguments;
771 return function() {
772 var args = arguments;
773 for (var i = funcs.length - 1; i >= 0; i--) {
774 args = [funcs[i].apply(this, args)];
775 }
776 return args[0];
777 };
778 };
779
780 // Returns a function that will only be executed after being called N times.
781 _.after = function(times, func) {
782 return function() {
783 if (--times < 1) {
784 return func.apply(this, arguments);
785 }
786 };
787 };
788
789 // Object Functions
790 // ----------------
791
792 // Retrieve the names of an object's properties.
793 // Delegates to **ECMAScript 5**'s native `Object.keys`
794 _.keys = function(obj) {
795 if (!_.isObject(obj)) return [];
796 if (nativeKeys) return nativeKeys(obj);
797 var keys = [];
798 for (var key in obj) if (_.has(obj, key)) keys.push(key);
799 return keys;
800 };
801
802 // Retrieve the values of an object's properties.
803 _.values = function(obj) {
804 var keys = _.keys(obj);
805 var length = keys.length;
806 var values = new Array(length);
807 for (var i = 0; i < length; i++) {
808 values[i] = obj[keys[i]];
809 }
810 return values;
811 };
812
813 // Convert an object into a list of `[key, value]` pairs.
814 _.pairs = function(obj) {
815 var keys = _.keys(obj);
816 var length = keys.length;
817 var pairs = new Array(length);
818 for (var i = 0; i < length; i++) {
819 pairs[i] = [keys[i], obj[keys[i]]];
820 }
821 return pairs;
822 };
823
824 // Invert the keys and values of an object. The values must be serializable.
825 _.invert = function(obj) {
826 var result = {};
827 var keys = _.keys(obj);
828 for (var i = 0, length = keys.length; i < length; i++) {
829 result[obj[keys[i]]] = keys[i];
830 }
831 return result;
832 };
833
834 // Return a sorted list of the function names available on the object.
835 // Aliased as `methods`
836 _.functions = _.methods = function(obj) {
837 var names = [];
838 for (var key in obj) {
839 if (_.isFunction(obj[key])) names.push(key);
840 }
841 return names.sort();
842 };
843
844 // Extend a given object with all the properties in passed-in object(s).
845 _.extend = function(obj) {
846 each(slice.call(arguments, 1), function(source) {
847 if (source) {
848 for (var prop in source) {
849 obj[prop] = source[prop];
850 }
851 }
852 });
853 return obj;
854 };
855
856 // Return a copy of the object only containing the whitelisted properties.
857 _.pick = function(obj) {
858 var copy = {};
859 var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
860 each(keys, function(key) {
861 if (key in obj) copy[key] = obj[key];
862 });
863 return copy;
864 };
865
866 // Return a copy of the object without the blacklisted properties.
867 _.omit = function(obj) {
868 var copy = {};
869 var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
870 for (var key in obj) {
871 if (!_.contains(keys, key)) copy[key] = obj[key];
872 }
873 return copy;
874 };
875
876 // Fill in a given object with default properties.
877 _.defaults = function(obj) {
878 each(slice.call(arguments, 1), function(source) {
879 if (source) {
880 for (var prop in source) {
881 if (obj[prop] === void 0) obj[prop] = source[prop];
882 }
883 }
884 });
885 return obj;
886 };
887
888 // Create a (shallow-cloned) duplicate of an object.
889 _.clone = function(obj) {
890 if (!_.isObject(obj)) return obj;
891 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
892 };
893
894 // Invokes interceptor with the obj, and then returns obj.
895 // The primary purpose of this method is to "tap into" a method chain, in
896 // order to perform operations on intermediate results within the chain.
897 _.tap = function(obj, interceptor) {
898 interceptor(obj);
899 return obj;
900 };
901
902 // Internal recursive comparison function for `isEqual`.
903 var eq = function(a, b, aStack, bStack) {
904 // Identical objects are equal. `0 === -0`, but they aren't identical.
905 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
906 if (a === b) return a !== 0 || 1 / a == 1 / b;
907 // A strict comparison is necessary because `null == undefined`.
908 if (a == null || b == null) return a === b;
909 // Unwrap any wrapped objects.
910 if (a instanceof _) a = a._wrapped;
911 if (b instanceof _) b = b._wrapped;
912 // Compare `[[Class]]` names.
913 var className = toString.call(a);
914 if (className != toString.call(b)) return false;
915 switch (className) {
916 // Strings, numbers, dates, and booleans are compared by value.
917 case '[object String]':
918 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
919 // equivalent to `new String("5")`.
920 return a == String(b);
921 case '[object Number]':
922 // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
923 // other numeric values.
924 return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
925 case '[object Date]':
926 case '[object Boolean]':
927 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
928 // millisecond representations. Note that invalid dates with millisecond representations
929 // of `NaN` are not equivalent.
930 return +a == +b;
931 // RegExps are compared by their source patterns and flags.
932 case '[object RegExp]':
933 return a.source == b.source &&
934 a.global == b.global &&
935 a.multiline == b.multiline &&
936 a.ignoreCase == b.ignoreCase;
937 }
938 if (typeof a != 'object' || typeof b != 'object') return false;
939 // Assume equality for cyclic structures. The algorithm for detecting cyclic
940 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
941 var length = aStack.length;
942 while (length--) {
943 // Linear search. Performance is inversely proportional to the number of
944 // unique nested structures.
945 if (aStack[length] == a) return bStack[length] == b;
946 }
947 // Objects with different constructors are not equivalent, but `Object`s
948 // from different frames are.
949 var aCtor = a.constructor, bCtor = b.constructor;
950 if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
951 _.isFunction(bCtor) && (bCtor instanceof bCtor))
952 && ('constructor' in a && 'constructor' in b)) {
953 return false;
954 }
955 // Add the first object to the stack of traversed objects.
956 aStack.push(a);
957 bStack.push(b);
958 var size = 0, result = true;
959 // Recursively compare objects and arrays.
960 if (className == '[object Array]') {
961 // Compare array lengths to determine if a deep comparison is necessary.
962 size = a.length;
963 result = size == b.length;
964 if (result) {
965 // Deep compare the contents, ignoring non-numeric properties.
966 while (size--) {
967 if (!(result = eq(a[size], b[size], aStack, bStack))) break;
968 }
969 }
970 } else {
971 // Deep compare objects.
972 for (var key in a) {
973 if (_.has(a, key)) {
974 // Count the expected number of properties.
975 size++;
976 // Deep compare each member.
977 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
978 }
979 }
980 // Ensure that both objects contain the same number of properties.
981 if (result) {
982 for (key in b) {
983 if (_.has(b, key) && !(size--)) break;
984 }
985 result = !size;
986 }
987 }
988 // Remove the first object from the stack of traversed objects.
989 aStack.pop();
990 bStack.pop();
991 return result;
992 };
993
994 // Perform a deep comparison to check if two objects are equal.
995 _.isEqual = function(a, b) {
996 return eq(a, b, [], []);
997 };
998
999 // Is a given array, string, or object empty?
1000 // An "empty" object has no enumerable own-properties.
1001 _.isEmpty = function(obj) {
1002 if (obj == null) return true;
1003 if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
1004 for (var key in obj) if (_.has(obj, key)) return false;
1005 return true;
1006 };
1007
1008 // Is a given value a DOM element?
1009 _.isElement = function(obj) {
1010 return !!(obj && obj.nodeType === 1);
1011 };
1012
1013 // Is a given value an array?
1014 // Delegates to ECMA5's native Array.isArray
1015 _.isArray = nativeIsArray || function(obj) {
1016 return toString.call(obj) == '[object Array]';
1017 };
1018
1019 // Is a given variable an object?
1020 _.isObject = function(obj) {
1021 return obj === Object(obj);
1022 };
1023
1024 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
1025 each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
1026 _['is' + name] = function(obj) {
1027 return toString.call(obj) == '[object ' + name + ']';
1028 };
1029 });
1030
1031 // Define a fallback version of the method in browsers (ahem, IE), where
1032 // there isn't any inspectable "Arguments" type.
1033 if (!_.isArguments(arguments)) {
1034 _.isArguments = function(obj) {
1035 return !!(obj && _.has(obj, 'callee'));
1036 };
1037 }
1038
1039 // Optimize `isFunction` if appropriate.
1040 if (typeof (/./) !== 'function') {
1041 _.isFunction = function(obj) {
1042 return typeof obj === 'function';
1043 };
1044 }
1045
1046 // Is a given object a finite number?
1047 _.isFinite = function(obj) {
1048 return isFinite(obj) && !isNaN(parseFloat(obj));
1049 };
1050
1051 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1052 _.isNaN = function(obj) {
1053 return _.isNumber(obj) && obj != +obj;
1054 };
1055
1056 // Is a given value a boolean?
1057 _.isBoolean = function(obj) {
1058 return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
1059 };
1060
1061 // Is a given value equal to null?
1062 _.isNull = function(obj) {
1063 return obj === null;
1064 };
1065
1066 // Is a given variable undefined?
1067 _.isUndefined = function(obj) {
1068 return obj === void 0;
1069 };
1070
1071 // Shortcut function for checking if an object has a given property directly
1072 // on itself (in other words, not on a prototype).
1073 _.has = function(obj, key) {
1074 return hasOwnProperty.call(obj, key);
1075 };
1076
1077 // Utility Functions
1078 // -----------------
1079
1080 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1081 // previous owner. Returns a reference to the Underscore object.
1082 _.noConflict = function() {
1083 root._ = previousUnderscore;
1084 return this;
1085 };
1086
1087 // Keep the identity function around for default iterators.
1088 _.identity = function(value) {
1089 return value;
1090 };
1091
1092 _.constant = function(value) {
1093 return function () {
1094 return value;
1095 };
1096 };
1097
1098 _.property = function(key) {
1099 return function(obj) {
1100 return obj[key];
1101 };
1102 };
1103
1104 // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
1105 _.matches = function(attrs) {
1106 return function(obj) {
1107 if (obj === attrs) return true; //avoid comparing an object to itself.
1108 for (var key in attrs) {
1109 if (attrs[key] !== obj[key])
1110 return false;
1111 }
1112 return true;
1113 }
1114 };
1115
1116 // Run a function **n** times.
1117 _.times = function(n, iterator, context) {
1118 var accum = Array(Math.max(0, n));
1119 for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
1120 return accum;
1121 };
1122
1123 // Return a random integer between min and max (inclusive).
1124 _.random = function(min, max) {
1125 if (max == null) {
1126 max = min;
1127 min = 0;
1128 }
1129 return min + Math.floor(Math.random() * (max - min + 1));
1130 };
1131
1132 // A (possibly faster) way to get the current timestamp as an integer.
1133 _.now = Date.now || function() { return new Date().getTime(); };
1134
1135 // List of HTML entities for escaping.
1136 var entityMap = {
1137 escape: {
1138 '&': '&amp;',
1139 '<': '&lt;',
1140 '>': '&gt;',
1141 '"': '&quot;',
1142 "'": '&#x27;'
1143 }
1144 };
1145 entityMap.unescape = _.invert(entityMap.escape);
1146
1147 // Regexes containing the keys and values listed immediately above.
1148 var entityRegexes = {
1149 escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
1150 unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
1151 };
1152
1153 // Functions for escaping and unescaping strings to/from HTML interpolation.
1154 _.each(['escape', 'unescape'], function(method) {
1155 _[method] = function(string) {
1156 if (string == null) return '';
1157 return ('' + string).replace(entityRegexes[method], function(match) {
1158 return entityMap[method][match];
1159 });
1160 };
1161 });
1162
1163 // If the value of the named `property` is a function then invoke it with the
1164 // `object` as context; otherwise, return it.
1165 _.result = function(object, property) {
1166 if (object == null) return void 0;
1167 var value = object[property];
1168 return _.isFunction(value) ? value.call(object) : value;
1169 };
1170
1171 // Add your own custom functions to the Underscore object.
1172 _.mixin = function(obj) {
1173 each(_.functions(obj), function(name) {
1174 var func = _[name] = obj[name];
1175 _.prototype[name] = function() {
1176 var args = [this._wrapped];
1177 push.apply(args, arguments);
1178 return result.call(this, func.apply(_, args));
1179 };
1180 });
1181 };
1182
1183 // Generate a unique integer id (unique within the entire client session).
1184 // Useful for temporary DOM ids.
1185 var idCounter = 0;
1186 _.uniqueId = function(prefix) {
1187 var id = ++idCounter + '';
1188 return prefix ? prefix + id : id;
1189 };
1190
1191 // By default, Underscore uses ERB-style template delimiters, change the
1192 // following template settings to use alternative delimiters.
1193 _.templateSettings = {
1194 evaluate : /<%([\s\S]+?)%>/g,
1195 interpolate : /<%=([\s\S]+?)%>/g,
1196 escape : /<%-([\s\S]+?)%>/g
1197 };
1198
1199 // When customizing `templateSettings`, if you don't want to define an
1200 // interpolation, evaluation or escaping regex, we need one that is
1201 // guaranteed not to match.
1202 var noMatch = /(.)^/;
1203
1204 // Certain characters need to be escaped so that they can be put into a
1205 // string literal.
1206 var escapes = {
1207 "'": "'",
1208 '\\': '\\',
1209 '\r': 'r',
1210 '\n': 'n',
1211 '\t': 't',
1212 '\u2028': 'u2028',
1213 '\u2029': 'u2029'
1214 };
1215
1216 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
1217
1218 // JavaScript micro-templating, similar to John Resig's implementation.
1219 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1220 // and correctly escapes quotes within interpolated code.
1221 _.template = function(text, data, settings) {
1222 var render;
1223 settings = _.defaults({}, settings, _.templateSettings);
1224
1225 // Combine delimiters into one regular expression via alternation.
1226 var matcher = new RegExp([
1227 (settings.escape || noMatch).source,
1228 (settings.interpolate || noMatch).source,
1229 (settings.evaluate || noMatch).source
1230 ].join('|') + '|$', 'g');
1231
1232 // Compile the template source, escaping string literals appropriately.
1233 var index = 0;
1234 var source = "__p+='";
1235 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1236 source += text.slice(index, offset)
1237 .replace(escaper, function(match) { return '\\' + escapes[match]; });
1238
1239 if (escape) {
1240 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1241 }
1242 if (interpolate) {
1243 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1244 }
1245 if (evaluate) {
1246 source += "';\n" + evaluate + "\n__p+='";
1247 }
1248 index = offset + match.length;
1249 return match;
1250 });
1251 source += "';\n";
1252
1253 // If a variable is not specified, place data values in local scope.
1254 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1255
1256 source = "var __t,__p='',__j=Array.prototype.join," +
1257 "print=function(){__p+=__j.call(arguments,'');};\n" +
1258 source + "return __p;\n";
1259
1260 try {
1261 render = new Function(settings.variable || 'obj', '_', source);
1262 } catch (e) {
1263 e.source = source;
1264 throw e;
1265 }
1266
1267 if (data) return render(data, _);
1268 var template = function(data) {
1269 return render.call(this, data, _);
1270 };
1271
1272 // Provide the compiled function source as a convenience for precompilation.
1273 template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
1274
1275 return template;
1276 };
1277
1278 // Add a "chain" function, which will delegate to the wrapper.
1279 _.chain = function(obj) {
1280 return _(obj).chain();
1281 };
1282
1283 // OOP
1284 // ---------------
1285 // If Underscore is called as a function, it returns a wrapped object that
1286 // can be used OO-style. This wrapper holds altered versions of all the
1287 // underscore functions. Wrapped objects may be chained.
1288
1289 // Helper function to continue chaining intermediate results.
1290 var result = function(obj) {
1291 return this._chain ? _(obj).chain() : obj;
1292 };
1293
1294 // Add all of the Underscore functions to the wrapper object.
1295 _.mixin(_);
1296
1297 // Add all mutator Array functions to the wrapper.
1298 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1299 var method = ArrayProto[name];
1300 _.prototype[name] = function() {
1301 var obj = this._wrapped;
1302 method.apply(obj, arguments);
1303 if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
1304 return result.call(this, obj);
1305 };
1306 });
1307
1308 // Add all accessor Array functions to the wrapper.
1309 each(['concat', 'join', 'slice'], function(name) {
1310 var method = ArrayProto[name];
1311 _.prototype[name] = function() {
1312 return result.call(this, method.apply(this._wrapped, arguments));
1313 };
1314 });
1315
1316 _.extend(_.prototype, {
1317
1318 // Start chaining a wrapped Underscore object.
1319 chain: function() {
1320 this._chain = true;
1321 return this;
1322 },
1323
1324 // Extracts the result from a wrapped and chained object.
1325 value: function() {
1326 return this._wrapped;
1327 }
1328
1329 });
1330
1331 // AMD registration happens at the end for compatibility with AMD loaders
1332 // that may not enforce next-turn semantics on modules. Even though general
1333 // practice for AMD registration is to be anonymous, underscore registers
1334 // as a named module because, like jQuery, it is a base library that is
1335 // popular enough to be bundled in a third party lib, but not be part of
1336 // an AMD load request. Those cases could generate an error when an
1337 // anonymous define() is called outside of a loader request.
1338 if (typeof define === 'function' && define.amd) {
1339 define('underscore', [], function() {
1340 return _;
1341 });
1342 }
1343 }).call(this);
1344