frontend-helpers 0.0.9 → 0.0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +0,0 @@
1
- //= require ./underscore
2
- //= require ./backbone
3
- //= require ./authtoken
@@ -1,839 +0,0 @@
1
- // Underscore.js 1.1.7
2
- // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
3
- // Underscore is freely distributable under the MIT license.
4
- // Portions of Underscore are inspired or borrowed from Prototype,
5
- // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
- // For all details and documentation:
7
- // http://documentcloud.github.com/underscore
8
-
9
- (function() {
10
-
11
- // Baseline setup
12
- // --------------
13
-
14
- // Establish the root object, `window` in the browser, or `global` on the server.
15
- var root = this;
16
-
17
- // Save the previous value of the `_` variable.
18
- var previousUnderscore = root._;
19
-
20
- // Establish the object that gets returned to break out of a loop iteration.
21
- var breaker = {};
22
-
23
- // Save bytes in the minified (but not gzipped) version:
24
- var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
25
-
26
- // Create quick reference variables for speed access to core prototypes.
27
- var slice = ArrayProto.slice,
28
- unshift = ArrayProto.unshift,
29
- toString = ObjProto.toString,
30
- hasOwnProperty = ObjProto.hasOwnProperty;
31
-
32
- // All **ECMAScript 5** native function implementations that we hope to use
33
- // are declared here.
34
- var
35
- nativeForEach = ArrayProto.forEach,
36
- nativeMap = ArrayProto.map,
37
- nativeReduce = ArrayProto.reduce,
38
- nativeReduceRight = ArrayProto.reduceRight,
39
- nativeFilter = ArrayProto.filter,
40
- nativeEvery = ArrayProto.every,
41
- nativeSome = ArrayProto.some,
42
- nativeIndexOf = ArrayProto.indexOf,
43
- nativeLastIndexOf = ArrayProto.lastIndexOf,
44
- nativeIsArray = Array.isArray,
45
- nativeKeys = Object.keys,
46
- nativeBind = FuncProto.bind;
47
-
48
- // Create a safe reference to the Underscore object for use below.
49
- var _ = function(obj) { return new wrapper(obj); };
50
-
51
- // Export the Underscore object for **CommonJS**, with backwards-compatibility
52
- // for the old `require()` API. If we're not in CommonJS, add `_` to the
53
- // global object.
54
- if (typeof module !== 'undefined' && module.exports) {
55
- module.exports = _;
56
- _._ = _;
57
- } else {
58
- // Exported as a string, for Closure Compiler "advanced" mode.
59
- root['_'] = _;
60
- }
61
-
62
- // Current version.
63
- _.VERSION = '1.1.7';
64
-
65
- // Collection Functions
66
- // --------------------
67
-
68
- // The cornerstone, an `each` implementation, aka `forEach`.
69
- // Handles objects with the built-in `forEach`, arrays, and raw objects.
70
- // Delegates to **ECMAScript 5**'s native `forEach` if available.
71
- var each = _.each = _.forEach = function(obj, iterator, context) {
72
- if (obj == null) return;
73
- if (nativeForEach && obj.forEach === nativeForEach) {
74
- obj.forEach(iterator, context);
75
- } else if (obj.length === +obj.length) {
76
- for (var i = 0, l = obj.length; i < l; i++) {
77
- if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
78
- }
79
- } else {
80
- for (var key in obj) {
81
- if (hasOwnProperty.call(obj, key)) {
82
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
83
- }
84
- }
85
- }
86
- };
87
-
88
- // Return the results of applying the iterator to each element.
89
- // Delegates to **ECMAScript 5**'s native `map` if available.
90
- _.map = function(obj, iterator, context) {
91
- var results = [];
92
- if (obj == null) return results;
93
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
94
- each(obj, function(value, index, list) {
95
- results[results.length] = iterator.call(context, value, index, list);
96
- });
97
- return results;
98
- };
99
-
100
- // **Reduce** builds up a single result from a list of values, aka `inject`,
101
- // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
102
- _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
103
- var initial = memo !== void 0;
104
- if (obj == null) obj = [];
105
- if (nativeReduce && obj.reduce === nativeReduce) {
106
- if (context) iterator = _.bind(iterator, context);
107
- return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
108
- }
109
- each(obj, function(value, index, list) {
110
- if (!initial) {
111
- memo = value;
112
- initial = true;
113
- } else {
114
- memo = iterator.call(context, memo, value, index, list);
115
- }
116
- });
117
- if (!initial) throw new TypeError("Reduce of empty array with no initial value");
118
- return memo;
119
- };
120
-
121
- // The right-associative version of reduce, also known as `foldr`.
122
- // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
123
- _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
124
- if (obj == null) obj = [];
125
- if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
126
- if (context) iterator = _.bind(iterator, context);
127
- return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
128
- }
129
- var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
130
- return _.reduce(reversed, iterator, memo, context);
131
- };
132
-
133
- // Return the first value which passes a truth test. Aliased as `detect`.
134
- _.find = _.detect = function(obj, iterator, context) {
135
- var result;
136
- any(obj, function(value, index, list) {
137
- if (iterator.call(context, value, index, list)) {
138
- result = value;
139
- return true;
140
- }
141
- });
142
- return result;
143
- };
144
-
145
- // Return all the elements that pass a truth test.
146
- // Delegates to **ECMAScript 5**'s native `filter` if available.
147
- // Aliased as `select`.
148
- _.filter = _.select = function(obj, iterator, context) {
149
- var results = [];
150
- if (obj == null) return results;
151
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
152
- each(obj, function(value, index, list) {
153
- if (iterator.call(context, value, index, list)) results[results.length] = value;
154
- });
155
- return results;
156
- };
157
-
158
- // Return all the elements for which a truth test fails.
159
- _.reject = function(obj, iterator, context) {
160
- var results = [];
161
- if (obj == null) return results;
162
- each(obj, function(value, index, list) {
163
- if (!iterator.call(context, value, index, list)) results[results.length] = value;
164
- });
165
- return results;
166
- };
167
-
168
- // Determine whether all of the elements match a truth test.
169
- // Delegates to **ECMAScript 5**'s native `every` if available.
170
- // Aliased as `all`.
171
- _.every = _.all = function(obj, iterator, context) {
172
- var result = true;
173
- if (obj == null) return result;
174
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
175
- each(obj, function(value, index, list) {
176
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
177
- });
178
- return result;
179
- };
180
-
181
- // Determine if at least one element in the object matches a truth test.
182
- // Delegates to **ECMAScript 5**'s native `some` if available.
183
- // Aliased as `any`.
184
- var any = _.some = _.any = function(obj, iterator, context) {
185
- iterator = iterator || _.identity;
186
- var result = false;
187
- if (obj == null) return result;
188
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
189
- each(obj, function(value, index, list) {
190
- if (result |= iterator.call(context, value, index, list)) return breaker;
191
- });
192
- return !!result;
193
- };
194
-
195
- // Determine if a given value is included in the array or object using `===`.
196
- // Aliased as `contains`.
197
- _.include = _.contains = function(obj, target) {
198
- var found = false;
199
- if (obj == null) return found;
200
- if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
201
- any(obj, function(value) {
202
- if (found = value === target) return true;
203
- });
204
- return found;
205
- };
206
-
207
- // Invoke a method (with arguments) on every item in a collection.
208
- _.invoke = function(obj, method) {
209
- var args = slice.call(arguments, 2);
210
- return _.map(obj, function(value) {
211
- return (method.call ? method || value : value[method]).apply(value, args);
212
- });
213
- };
214
-
215
- // Convenience version of a common use case of `map`: fetching a property.
216
- _.pluck = function(obj, key) {
217
- return _.map(obj, function(value){ return value[key]; });
218
- };
219
-
220
- // Return the maximum element or (element-based computation).
221
- _.max = function(obj, iterator, context) {
222
- if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
223
- var result = {computed : -Infinity};
224
- each(obj, function(value, index, list) {
225
- var computed = iterator ? iterator.call(context, value, index, list) : value;
226
- computed >= result.computed && (result = {value : value, computed : computed});
227
- });
228
- return result.value;
229
- };
230
-
231
- // Return the minimum element (or element-based computation).
232
- _.min = function(obj, iterator, context) {
233
- if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
234
- var result = {computed : Infinity};
235
- each(obj, function(value, index, list) {
236
- var computed = iterator ? iterator.call(context, value, index, list) : value;
237
- computed < result.computed && (result = {value : value, computed : computed});
238
- });
239
- return result.value;
240
- };
241
-
242
- // Sort the object's values by a criterion produced by an iterator.
243
- _.sortBy = function(obj, iterator, context) {
244
- return _.pluck(_.map(obj, function(value, index, list) {
245
- return {
246
- value : value,
247
- criteria : iterator.call(context, value, index, list)
248
- };
249
- }).sort(function(left, right) {
250
- var a = left.criteria, b = right.criteria;
251
- return a < b ? -1 : a > b ? 1 : 0;
252
- }), 'value');
253
- };
254
-
255
- // Groups the object's values by a criterion produced by an iterator
256
- _.groupBy = function(obj, iterator) {
257
- var result = {};
258
- each(obj, function(value, index) {
259
- var key = iterator(value, index);
260
- (result[key] || (result[key] = [])).push(value);
261
- });
262
- return result;
263
- };
264
-
265
- // Use a comparator function to figure out at what index an object should
266
- // be inserted so as to maintain order. Uses binary search.
267
- _.sortedIndex = function(array, obj, iterator) {
268
- iterator || (iterator = _.identity);
269
- var low = 0, high = array.length;
270
- while (low < high) {
271
- var mid = (low + high) >> 1;
272
- iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
273
- }
274
- return low;
275
- };
276
-
277
- // Safely convert anything iterable into a real, live array.
278
- _.toArray = function(iterable) {
279
- if (!iterable) return [];
280
- if (iterable.toArray) return iterable.toArray();
281
- if (_.isArray(iterable)) return slice.call(iterable);
282
- if (_.isArguments(iterable)) return slice.call(iterable);
283
- return _.values(iterable);
284
- };
285
-
286
- // Return the number of elements in an object.
287
- _.size = function(obj) {
288
- return _.toArray(obj).length;
289
- };
290
-
291
- // Array Functions
292
- // ---------------
293
-
294
- // Get the first element of an array. Passing **n** will return the first N
295
- // values in the array. Aliased as `head`. The **guard** check allows it to work
296
- // with `_.map`.
297
- _.first = _.head = function(array, n, guard) {
298
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
299
- };
300
-
301
- // Returns everything but the first entry of the array. Aliased as `tail`.
302
- // Especially useful on the arguments object. Passing an **index** will return
303
- // the rest of the values in the array from that index onward. The **guard**
304
- // check allows it to work with `_.map`.
305
- _.rest = _.tail = function(array, index, guard) {
306
- return slice.call(array, (index == null) || guard ? 1 : index);
307
- };
308
-
309
- // Get the last element of an array.
310
- _.last = function(array) {
311
- return array[array.length - 1];
312
- };
313
-
314
- // Trim out all falsy values from an array.
315
- _.compact = function(array) {
316
- return _.filter(array, function(value){ return !!value; });
317
- };
318
-
319
- // Return a completely flattened version of an array.
320
- _.flatten = function(array) {
321
- return _.reduce(array, function(memo, value) {
322
- if (_.isArray(value)) return memo.concat(_.flatten(value));
323
- memo[memo.length] = value;
324
- return memo;
325
- }, []);
326
- };
327
-
328
- // Return a version of the array that does not contain the specified value(s).
329
- _.without = function(array) {
330
- return _.difference(array, slice.call(arguments, 1));
331
- };
332
-
333
- // Produce a duplicate-free version of the array. If the array has already
334
- // been sorted, you have the option of using a faster algorithm.
335
- // Aliased as `unique`.
336
- _.uniq = _.unique = function(array, isSorted) {
337
- return _.reduce(array, function(memo, el, i) {
338
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
339
- return memo;
340
- }, []);
341
- };
342
-
343
- // Produce an array that contains the union: each distinct element from all of
344
- // the passed-in arrays.
345
- _.union = function() {
346
- return _.uniq(_.flatten(arguments));
347
- };
348
-
349
- // Produce an array that contains every item shared between all the
350
- // passed-in arrays. (Aliased as "intersect" for back-compat.)
351
- _.intersection = _.intersect = function(array) {
352
- var rest = slice.call(arguments, 1);
353
- return _.filter(_.uniq(array), function(item) {
354
- return _.every(rest, function(other) {
355
- return _.indexOf(other, item) >= 0;
356
- });
357
- });
358
- };
359
-
360
- // Take the difference between one array and another.
361
- // Only the elements present in just the first array will remain.
362
- _.difference = function(array, other) {
363
- return _.filter(array, function(value){ return !_.include(other, value); });
364
- };
365
-
366
- // Zip together multiple lists into a single array -- elements that share
367
- // an index go together.
368
- _.zip = function() {
369
- var args = slice.call(arguments);
370
- var length = _.max(_.pluck(args, 'length'));
371
- var results = new Array(length);
372
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
373
- return results;
374
- };
375
-
376
- // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
377
- // we need this function. Return the position of the first occurrence of an
378
- // item in an array, or -1 if the item is not included in the array.
379
- // Delegates to **ECMAScript 5**'s native `indexOf` if available.
380
- // If the array is large and already in sort order, pass `true`
381
- // for **isSorted** to use binary search.
382
- _.indexOf = function(array, item, isSorted) {
383
- if (array == null) return -1;
384
- var i, l;
385
- if (isSorted) {
386
- i = _.sortedIndex(array, item);
387
- return array[i] === item ? i : -1;
388
- }
389
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
390
- for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
391
- return -1;
392
- };
393
-
394
-
395
- // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
396
- _.lastIndexOf = function(array, item) {
397
- if (array == null) return -1;
398
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
399
- var i = array.length;
400
- while (i--) if (array[i] === item) return i;
401
- return -1;
402
- };
403
-
404
- // Generate an integer Array containing an arithmetic progression. A port of
405
- // the native Python `range()` function. See
406
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
407
- _.range = function(start, stop, step) {
408
- if (arguments.length <= 1) {
409
- stop = start || 0;
410
- start = 0;
411
- }
412
- step = arguments[2] || 1;
413
-
414
- var len = Math.max(Math.ceil((stop - start) / step), 0);
415
- var idx = 0;
416
- var range = new Array(len);
417
-
418
- while(idx < len) {
419
- range[idx++] = start;
420
- start += step;
421
- }
422
-
423
- return range;
424
- };
425
-
426
- // Function (ahem) Functions
427
- // ------------------
428
-
429
- // Create a function bound to a given object (assigning `this`, and arguments,
430
- // optionally). Binding with arguments is also known as `curry`.
431
- // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
432
- // We check for `func.bind` first, to fail fast when `func` is undefined.
433
- _.bind = function(func, obj) {
434
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
435
- var args = slice.call(arguments, 2);
436
- return function() {
437
- return func.apply(obj, args.concat(slice.call(arguments)));
438
- };
439
- };
440
-
441
- // Bind all of an object's methods to that object. Useful for ensuring that
442
- // all callbacks defined on an object belong to it.
443
- _.bindAll = function(obj) {
444
- var funcs = slice.call(arguments, 1);
445
- if (funcs.length == 0) funcs = _.functions(obj);
446
- each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
447
- return obj;
448
- };
449
-
450
- // Memoize an expensive function by storing its results.
451
- _.memoize = function(func, hasher) {
452
- var memo = {};
453
- hasher || (hasher = _.identity);
454
- return function() {
455
- var key = hasher.apply(this, arguments);
456
- return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
457
- };
458
- };
459
-
460
- // Delays a function for the given number of milliseconds, and then calls
461
- // it with the arguments supplied.
462
- _.delay = function(func, wait) {
463
- var args = slice.call(arguments, 2);
464
- return setTimeout(function(){ return func.apply(func, args); }, wait);
465
- };
466
-
467
- // Defers a function, scheduling it to run after the current call stack has
468
- // cleared.
469
- _.defer = function(func) {
470
- return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
471
- };
472
-
473
- // Internal function used to implement `_.throttle` and `_.debounce`.
474
- var limit = function(func, wait, debounce) {
475
- var timeout;
476
- return function() {
477
- var context = this, args = arguments;
478
- var throttler = function() {
479
- timeout = null;
480
- func.apply(context, args);
481
- };
482
- if (debounce) clearTimeout(timeout);
483
- if (debounce || !timeout) timeout = setTimeout(throttler, wait);
484
- };
485
- };
486
-
487
- // Returns a function, that, when invoked, will only be triggered at most once
488
- // during a given window of time.
489
- _.throttle = function(func, wait) {
490
- return limit(func, wait, false);
491
- };
492
-
493
- // Returns a function, that, as long as it continues to be invoked, will not
494
- // be triggered. The function will be called after it stops being called for
495
- // N milliseconds.
496
- _.debounce = function(func, wait) {
497
- return limit(func, wait, true);
498
- };
499
-
500
- // Returns a function that will be executed at most one time, no matter how
501
- // often you call it. Useful for lazy initialization.
502
- _.once = function(func) {
503
- var ran = false, memo;
504
- return function() {
505
- if (ran) return memo;
506
- ran = true;
507
- return memo = func.apply(this, arguments);
508
- };
509
- };
510
-
511
- // Returns the first function passed as an argument to the second,
512
- // allowing you to adjust arguments, run code before and after, and
513
- // conditionally execute the original function.
514
- _.wrap = function(func, wrapper) {
515
- return function() {
516
- var args = [func].concat(slice.call(arguments));
517
- return wrapper.apply(this, args);
518
- };
519
- };
520
-
521
- // Returns a function that is the composition of a list of functions, each
522
- // consuming the return value of the function that follows.
523
- _.compose = function() {
524
- var funcs = slice.call(arguments);
525
- return function() {
526
- var args = slice.call(arguments);
527
- for (var i = funcs.length - 1; i >= 0; i--) {
528
- args = [funcs[i].apply(this, args)];
529
- }
530
- return args[0];
531
- };
532
- };
533
-
534
- // Returns a function that will only be executed after being called N times.
535
- _.after = function(times, func) {
536
- return function() {
537
- if (--times < 1) { return func.apply(this, arguments); }
538
- };
539
- };
540
-
541
-
542
- // Object Functions
543
- // ----------------
544
-
545
- // Retrieve the names of an object's properties.
546
- // Delegates to **ECMAScript 5**'s native `Object.keys`
547
- _.keys = nativeKeys || function(obj) {
548
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
549
- var keys = [];
550
- for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
551
- return keys;
552
- };
553
-
554
- // Retrieve the values of an object's properties.
555
- _.values = function(obj) {
556
- return _.map(obj, _.identity);
557
- };
558
-
559
- // Return a sorted list of the function names available on the object.
560
- // Aliased as `methods`
561
- _.functions = _.methods = function(obj) {
562
- var names = [];
563
- for (var key in obj) {
564
- if (_.isFunction(obj[key])) names.push(key);
565
- }
566
- return names.sort();
567
- };
568
-
569
- // Extend a given object with all the properties in passed-in object(s).
570
- _.extend = function(obj) {
571
- each(slice.call(arguments, 1), function(source) {
572
- for (var prop in source) {
573
- if (source[prop] !== void 0) obj[prop] = source[prop];
574
- }
575
- });
576
- return obj;
577
- };
578
-
579
- // Fill in a given object with default properties.
580
- _.defaults = function(obj) {
581
- each(slice.call(arguments, 1), function(source) {
582
- for (var prop in source) {
583
- if (obj[prop] == null) obj[prop] = source[prop];
584
- }
585
- });
586
- return obj;
587
- };
588
-
589
- // Create a (shallow-cloned) duplicate of an object.
590
- _.clone = function(obj) {
591
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
592
- };
593
-
594
- // Invokes interceptor with the obj, and then returns obj.
595
- // The primary purpose of this method is to "tap into" a method chain, in
596
- // order to perform operations on intermediate results within the chain.
597
- _.tap = function(obj, interceptor) {
598
- interceptor(obj);
599
- return obj;
600
- };
601
-
602
- // Perform a deep comparison to check if two objects are equal.
603
- _.isEqual = function(a, b) {
604
- // Check object identity.
605
- if (a === b) return true;
606
- // Different types?
607
- var atype = typeof(a), btype = typeof(b);
608
- if (atype != btype) return false;
609
- // Basic equality test (watch out for coercions).
610
- if (a == b) return true;
611
- // One is falsy and the other truthy.
612
- if ((!a && b) || (a && !b)) return false;
613
- // Unwrap any wrapped objects.
614
- if (a._chain) a = a._wrapped;
615
- if (b._chain) b = b._wrapped;
616
- // One of them implements an isEqual()?
617
- if (a.isEqual) return a.isEqual(b);
618
- if (b.isEqual) return b.isEqual(a);
619
- // Check dates' integer values.
620
- if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
621
- // Both are NaN?
622
- if (_.isNaN(a) && _.isNaN(b)) return false;
623
- // Compare regular expressions.
624
- if (_.isRegExp(a) && _.isRegExp(b))
625
- return a.source === b.source &&
626
- a.global === b.global &&
627
- a.ignoreCase === b.ignoreCase &&
628
- a.multiline === b.multiline;
629
- // If a is not an object by this point, we can't handle it.
630
- if (atype !== 'object') return false;
631
- // Check for different array lengths before comparing contents.
632
- if (a.length && (a.length !== b.length)) return false;
633
- // Nothing else worked, deep compare the contents.
634
- var aKeys = _.keys(a), bKeys = _.keys(b);
635
- // Different object sizes?
636
- if (aKeys.length != bKeys.length) return false;
637
- // Recursive comparison of contents.
638
- for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
639
- return true;
640
- };
641
-
642
- // Is a given array or object empty?
643
- _.isEmpty = function(obj) {
644
- if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
645
- for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
646
- return true;
647
- };
648
-
649
- // Is a given value a DOM element?
650
- _.isElement = function(obj) {
651
- return !!(obj && obj.nodeType == 1);
652
- };
653
-
654
- // Is a given value an array?
655
- // Delegates to ECMA5's native Array.isArray
656
- _.isArray = nativeIsArray || function(obj) {
657
- return toString.call(obj) === '[object Array]';
658
- };
659
-
660
- // Is a given variable an object?
661
- _.isObject = function(obj) {
662
- return obj === Object(obj);
663
- };
664
-
665
- // Is a given variable an arguments object?
666
- _.isArguments = function(obj) {
667
- return !!(obj && hasOwnProperty.call(obj, 'callee'));
668
- };
669
-
670
- // Is a given value a function?
671
- _.isFunction = function(obj) {
672
- return !!(obj && obj.constructor && obj.call && obj.apply);
673
- };
674
-
675
- // Is a given value a string?
676
- _.isString = function(obj) {
677
- return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
678
- };
679
-
680
- // Is a given value a number?
681
- _.isNumber = function(obj) {
682
- return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
683
- };
684
-
685
- // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
686
- // that does not equal itself.
687
- _.isNaN = function(obj) {
688
- return obj !== obj;
689
- };
690
-
691
- // Is a given value a boolean?
692
- _.isBoolean = function(obj) {
693
- return obj === true || obj === false;
694
- };
695
-
696
- // Is a given value a date?
697
- _.isDate = function(obj) {
698
- return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
699
- };
700
-
701
- // Is the given value a regular expression?
702
- _.isRegExp = function(obj) {
703
- return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
704
- };
705
-
706
- // Is a given value equal to null?
707
- _.isNull = function(obj) {
708
- return obj === null;
709
- };
710
-
711
- // Is a given variable undefined?
712
- _.isUndefined = function(obj) {
713
- return obj === void 0;
714
- };
715
-
716
- // Utility Functions
717
- // -----------------
718
-
719
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
720
- // previous owner. Returns a reference to the Underscore object.
721
- _.noConflict = function() {
722
- root._ = previousUnderscore;
723
- return this;
724
- };
725
-
726
- // Keep the identity function around for default iterators.
727
- _.identity = function(value) {
728
- return value;
729
- };
730
-
731
- // Run a function **n** times.
732
- _.times = function (n, iterator, context) {
733
- for (var i = 0; i < n; i++) iterator.call(context, i);
734
- };
735
-
736
- // Add your own custom functions to the Underscore object, ensuring that
737
- // they're correctly added to the OOP wrapper as well.
738
- _.mixin = function(obj) {
739
- each(_.functions(obj), function(name){
740
- addToWrapper(name, _[name] = obj[name]);
741
- });
742
- };
743
-
744
- // Generate a unique integer id (unique within the entire client session).
745
- // Useful for temporary DOM ids.
746
- var idCounter = 0;
747
- _.uniqueId = function(prefix) {
748
- var id = idCounter++;
749
- return prefix ? prefix + id : id;
750
- };
751
-
752
- // By default, Underscore uses ERB-style template delimiters, change the
753
- // following template settings to use alternative delimiters.
754
- _.templateSettings = {
755
- evaluate : /<%([\s\S]+?)%>/g,
756
- interpolate : /<%=([\s\S]+?)%>/g
757
- };
758
-
759
- // JavaScript micro-templating, similar to John Resig's implementation.
760
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
761
- // and correctly escapes quotes within interpolated code.
762
- _.template = function(str, data) {
763
- var c = _.templateSettings;
764
- var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
765
- 'with(obj||{}){__p.push(\'' +
766
- str.replace(/\\/g, '\\\\')
767
- .replace(/'/g, "\\'")
768
- .replace(c.interpolate, function(match, code) {
769
- return "'," + code.replace(/\\'/g, "'") + ",'";
770
- })
771
- .replace(c.evaluate || null, function(match, code) {
772
- return "');" + code.replace(/\\'/g, "'")
773
- .replace(/[\r\n\t]/g, ' ') + "__p.push('";
774
- })
775
- .replace(/\r/g, '\\r')
776
- .replace(/\n/g, '\\n')
777
- .replace(/\t/g, '\\t')
778
- + "');}return __p.join('');";
779
- var func = new Function('obj', tmpl);
780
- return data ? func(data) : func;
781
- };
782
-
783
- // The OOP Wrapper
784
- // ---------------
785
-
786
- // If Underscore is called as a function, it returns a wrapped object that
787
- // can be used OO-style. This wrapper holds altered versions of all the
788
- // underscore functions. Wrapped objects may be chained.
789
- var wrapper = function(obj) { this._wrapped = obj; };
790
-
791
- // Expose `wrapper.prototype` as `_.prototype`
792
- _.prototype = wrapper.prototype;
793
-
794
- // Helper function to continue chaining intermediate results.
795
- var result = function(obj, chain) {
796
- return chain ? _(obj).chain() : obj;
797
- };
798
-
799
- // A method to easily add functions to the OOP wrapper.
800
- var addToWrapper = function(name, func) {
801
- wrapper.prototype[name] = function() {
802
- var args = slice.call(arguments);
803
- unshift.call(args, this._wrapped);
804
- return result(func.apply(_, args), this._chain);
805
- };
806
- };
807
-
808
- // Add all of the Underscore functions to the wrapper object.
809
- _.mixin(_);
810
-
811
- // Add all mutator Array functions to the wrapper.
812
- each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
813
- var method = ArrayProto[name];
814
- wrapper.prototype[name] = function() {
815
- method.apply(this._wrapped, arguments);
816
- return result(this._wrapped, this._chain);
817
- };
818
- });
819
-
820
- // Add all accessor Array functions to the wrapper.
821
- each(['concat', 'join', 'slice'], function(name) {
822
- var method = ArrayProto[name];
823
- wrapper.prototype[name] = function() {
824
- return result(method.apply(this._wrapped, arguments), this._chain);
825
- };
826
- });
827
-
828
- // Start chaining a wrapped Underscore object.
829
- wrapper.prototype.chain = function() {
830
- this._chain = true;
831
- return this;
832
- };
833
-
834
- // Extracts the result from a wrapped and chained object.
835
- wrapper.prototype.value = function() {
836
- return this._wrapped;
837
- };
838
-
839
- })();