coffee-script 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ # Identifiers run together:
2
+ # a b c
3
+
4
+ # Trailing comma in array:
5
+ # array: [1, 2, 3, 4, 5,]
6
+
7
+ # Unterminated object literal:
8
+ # obj: { one: 1, two: 2
9
+
10
+ # Numbers run together:
11
+ # 101 202
12
+
13
+ # Strings run together:
14
+ # str: "broken" "words"
15
+
16
+ # Forgot to terminate a function:
17
+ # obj: {
18
+ # first: a => a[0].
19
+ # last: a => a[a.length-1]
20
+ # }
@@ -0,0 +1,597 @@
1
+ # Underscore.js
2
+ # (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
3
+ # Underscore is freely distributable under the terms of the MIT license.
4
+ # Portions of Underscore are inspired by or borrowed from Prototype.js,
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
+ # ------------------------- Baseline setup ---------------------------------
10
+
11
+ # Establish the root object, "window" in the browser, or "global" on the server.
12
+ root: this
13
+
14
+ # Save the previous value of the "_" variable.
15
+ previousUnderscore: root._
16
+
17
+ # If Underscore is called as a function, it returns a wrapped object that
18
+ # can be used OO-style. This wrapper holds altered versions of all the
19
+ # underscore functions. Wrapped objects may be chained.
20
+ wrapper: obj => this._wrapped: obj.
21
+
22
+ # Establish the object that gets thrown to break out of a loop iteration.
23
+ breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration.
24
+
25
+ # Create a safe reference to the Underscore object for reference below.
26
+ _: root._: obj => new wrapper(obj).
27
+
28
+ # Export the Underscore object for CommonJS.
29
+ if typeof(exports) != 'undefined' then exports._: _.
30
+
31
+ # Create quick reference variables for speed access to core prototypes.
32
+ slice: Array.prototype.slice
33
+ unshift: Array.prototype.unshift
34
+ toString: Object.prototype.toString
35
+ hasOwnProperty: Object.prototype.hasOwnProperty
36
+ propertyIsEnumerable: Object.prototype.propertyIsEnumerable
37
+
38
+ # Current version.
39
+ _.VERSION: '0.5.1'
40
+
41
+ # ------------------------ Collection Functions: ---------------------------
42
+
43
+ # The cornerstone, an each implementation.
44
+ # Handles objects implementing forEach, arrays, and raw objects.
45
+ _.each: obj, iterator, context =>
46
+ index: 0
47
+ try
48
+ return obj.forEach(iterator, context) if obj.forEach
49
+ return iterator.call(context, item, i, obj) for item, i in obj. if _.isArray(obj) or _.isArguments(obj)
50
+ iterator.call(context, obj[key], key, obj) for key in _.keys(obj).
51
+ catch e
52
+ throw e if e aint breaker.
53
+ obj.
54
+
55
+ # Return the results of applying the iterator to each element. Use JavaScript
56
+ # 1.6's version of map, if possible.
57
+ _.map: obj, iterator, context =>
58
+ return obj.map(iterator, context) if (obj and _.isFunction(obj.map))
59
+ results: []
60
+ mapper: value, index, list => results.push(iterator.call(context, value, index, list)).
61
+ _.each(obj, mapper)
62
+ results.
63
+
64
+ # Reduce builds up a single result from a list of values. Also known as
65
+ # inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
66
+ _.reduce: obj, memo, iterator, context =>
67
+ return obj.reduce(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduce))
68
+ reducer: value, index, list => memo: iterator.call(context, memo, value, index, list).
69
+ _.each(obj, reducer)
70
+ memo.
71
+
72
+ # The right-associative version of reduce, also known as foldr. Uses
73
+ # JavaScript 1.8's version of reduceRight, if available.
74
+ _.reduceRight: obj, memo, iterator, context =>
75
+ return obj.reduceRight(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduceRight))
76
+ reversed: _.clone(_.toArray(obj)).reverse()
77
+ reverser: value, index => memo: iterator.call(context, memo, value, index, obj).
78
+ _.each(reversed, reverser)
79
+ memo.
80
+
81
+ # Return the first value which passes a truth test.
82
+ _.detect: obj, iterator, context =>
83
+ result: null
84
+ _.each(obj, (value, index, list =>
85
+ if iterator.call(context, value, index, list)
86
+ result: value
87
+ _.breakLoop()..))
88
+ result.
89
+
90
+ # Return all the elements that pass a truth test. Use JavaScript 1.6's
91
+ # filter(), if it exists.
92
+ _.select: obj, iterator, context =>
93
+ if obj and _.isFunction(obj.filter) then return obj.filter(iterator, context).
94
+ results: []
95
+ _.each(obj, (value, index, list =>
96
+ iterator.call(context, value, index, list) and results.push(value).))
97
+ results.
98
+
99
+ #
100
+ # # Return all the elements for which a truth test fails.
101
+ # _.reject = function(obj, iterator, context) {
102
+ # var results = [];
103
+ # _.each(obj, function(value, index, list) {
104
+ # !iterator.call(context, value, index, list) && results.push(value);
105
+ # });
106
+ # return results;
107
+ # };
108
+ #
109
+ # # Determine whether all of the elements match a truth test. Delegate to
110
+ # # JavaScript 1.6's every(), if it is present.
111
+ # _.all = function(obj, iterator, context) {
112
+ # iterator = iterator || _.identity;
113
+ # if (obj && _.isFunction(obj.every)) return obj.every(iterator, context);
114
+ # var result = true;
115
+ # _.each(obj, function(value, index, list) {
116
+ # if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop();
117
+ # });
118
+ # return result;
119
+ # };
120
+ #
121
+ # # Determine if at least one element in the object matches a truth test. Use
122
+ # # JavaScript 1.6's some(), if it exists.
123
+ # _.any = function(obj, iterator, context) {
124
+ # iterator = iterator || _.identity;
125
+ # if (obj && _.isFunction(obj.some)) return obj.some(iterator, context);
126
+ # var result = false;
127
+ # _.each(obj, function(value, index, list) {
128
+ # if (result = iterator.call(context, value, index, list)) _.breakLoop();
129
+ # });
130
+ # return result;
131
+ # };
132
+ #
133
+ # # Determine if a given value is included in the array or object,
134
+ # # based on '==='.
135
+ # _.include = function(obj, target) {
136
+ # if (_.isArray(obj)) return _.indexOf(obj, target) != -1;
137
+ # var found = false;
138
+ # _.each(obj, function(value) {
139
+ # if (found = value === target) _.breakLoop();
140
+ # });
141
+ # return found;
142
+ # };
143
+ #
144
+ # # Invoke a method with arguments on every item in a collection.
145
+ # _.invoke = function(obj, method) {
146
+ # var args = _.rest(arguments, 2);
147
+ # return _.map(obj, function(value) {
148
+ # return (method ? value[method] : value).apply(value, args);
149
+ # });
150
+ # };
151
+ #
152
+ # # Convenience version of a common use case of map: fetching a property.
153
+ # _.pluck = function(obj, key) {
154
+ # return _.map(obj, function(value){ return value[key]; });
155
+ # };
156
+ #
157
+ # # Return the maximum item or (item-based computation).
158
+ # _.max = function(obj, iterator, context) {
159
+ # if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
160
+ # var result = {computed : -Infinity};
161
+ # _.each(obj, function(value, index, list) {
162
+ # var computed = iterator ? iterator.call(context, value, index, list) : value;
163
+ # computed >= result.computed && (result = {value : value, computed : computed});
164
+ # });
165
+ # return result.value;
166
+ # };
167
+ #
168
+ # # Return the minimum element (or element-based computation).
169
+ # _.min = function(obj, iterator, context) {
170
+ # if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
171
+ # var result = {computed : Infinity};
172
+ # _.each(obj, function(value, index, list) {
173
+ # var computed = iterator ? iterator.call(context, value, index, list) : value;
174
+ # computed < result.computed && (result = {value : value, computed : computed});
175
+ # });
176
+ # return result.value;
177
+ # };
178
+ #
179
+ # # Sort the object's values by a criteria produced by an iterator.
180
+ # _.sortBy = function(obj, iterator, context) {
181
+ # return _.pluck(_.map(obj, function(value, index, list) {
182
+ # return {
183
+ # value : value,
184
+ # criteria : iterator.call(context, value, index, list)
185
+ # };
186
+ # }).sort(function(left, right) {
187
+ # var a = left.criteria, b = right.criteria;
188
+ # return a < b ? -1 : a > b ? 1 : 0;
189
+ # }), 'value');
190
+ # };
191
+ #
192
+ # # Use a comparator function to figure out at what index an object should
193
+ # # be inserted so as to maintain order. Uses binary search.
194
+ # _.sortedIndex = function(array, obj, iterator) {
195
+ # iterator = iterator || _.identity;
196
+ # var low = 0, high = array.length;
197
+ # while (low < high) {
198
+ # var mid = (low + high) >> 1;
199
+ # iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
200
+ # }
201
+ # return low;
202
+ # };
203
+ #
204
+ # # Convert anything iterable into a real, live array.
205
+ # _.toArray = function(iterable) {
206
+ # if (!iterable) return [];
207
+ # if (iterable.toArray) return iterable.toArray();
208
+ # if (_.isArray(iterable)) return iterable;
209
+ # if (_.isArguments(iterable)) return slice.call(iterable);
210
+ # return _.map(iterable, function(val){ return val; });
211
+ # };
212
+ #
213
+ # # Return the number of elements in an object.
214
+ # _.size = function(obj) {
215
+ # return _.toArray(obj).length;
216
+ # };
217
+ #
218
+ # /*-------------------------- Array Functions: ------------------------------*/
219
+ #
220
+ # # Get the first element of an array. Passing "n" will return the first N
221
+ # # values in the array. Aliased as "head". The "guard" check allows it to work
222
+ # # with _.map.
223
+ # _.first = function(array, n, guard) {
224
+ # return n && !guard ? slice.call(array, 0, n) : array[0];
225
+ # };
226
+ #
227
+ # # Returns everything but the first entry of the array. Aliased as "tail".
228
+ # # Especially useful on the arguments object. Passing an "index" will return
229
+ # # the rest of the values in the array from that index onward. The "guard"
230
+ # //check allows it to work with _.map.
231
+ # _.rest = function(array, index, guard) {
232
+ # return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
233
+ # };
234
+ #
235
+ # # Get the last element of an array.
236
+ # _.last = function(array) {
237
+ # return array[array.length - 1];
238
+ # };
239
+ #
240
+ # # Trim out all falsy values from an array.
241
+ # _.compact = function(array) {
242
+ # return _.select(array, function(value){ return !!value; });
243
+ # };
244
+ #
245
+ # # Return a completely flattened version of an array.
246
+ # _.flatten = function(array) {
247
+ # return _.reduce(array, [], function(memo, value) {
248
+ # if (_.isArray(value)) return memo.concat(_.flatten(value));
249
+ # memo.push(value);
250
+ # return memo;
251
+ # });
252
+ # };
253
+ #
254
+ # # Return a version of the array that does not contain the specified value(s).
255
+ # _.without = function(array) {
256
+ # var values = _.rest(arguments);
257
+ # return _.select(array, function(value){ return !_.include(values, value); });
258
+ # };
259
+ #
260
+ # # Produce a duplicate-free version of the array. If the array has already
261
+ # # been sorted, you have the option of using a faster algorithm.
262
+ # _.uniq = function(array, isSorted) {
263
+ # return _.reduce(array, [], function(memo, el, i) {
264
+ # if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
265
+ # return memo;
266
+ # });
267
+ # };
268
+ #
269
+ # # Produce an array that contains every item shared between all the
270
+ # # passed-in arrays.
271
+ # _.intersect = function(array) {
272
+ # var rest = _.rest(arguments);
273
+ # return _.select(_.uniq(array), function(item) {
274
+ # return _.all(rest, function(other) {
275
+ # return _.indexOf(other, item) >= 0;
276
+ # });
277
+ # });
278
+ # };
279
+ #
280
+ # # Zip together multiple lists into a single array -- elements that share
281
+ # # an index go together.
282
+ # _.zip = function() {
283
+ # var args = _.toArray(arguments);
284
+ # var length = _.max(_.pluck(args, 'length'));
285
+ # var results = new Array(length);
286
+ # for (var i=0; i<length; i++) results[i] = _.pluck(args, String(i));
287
+ # return results;
288
+ # };
289
+ #
290
+ # # If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
291
+ # # we need this function. Return the position of the first occurence of an
292
+ # # item in an array, or -1 if the item is not included in the array.
293
+ # _.indexOf = function(array, item) {
294
+ # if (array.indexOf) return array.indexOf(item);
295
+ # for (var i=0, l=array.length; i<l; i++) if (array[i] === item) return i;
296
+ # return -1;
297
+ # };
298
+ #
299
+ # # Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
300
+ # # if possible.
301
+ # _.lastIndexOf = function(array, item) {
302
+ # if (array.lastIndexOf) return array.lastIndexOf(item);
303
+ # var i = array.length;
304
+ # while (i--) if (array[i] === item) return i;
305
+ # return -1;
306
+ # };
307
+ #
308
+ # # Generate an integer Array containing an arithmetic progression. A port of
309
+ # # the native Python range() function. See:
310
+ # # http://docs.python.org/library/functions.html#range
311
+ # _.range = function(start, stop, step) {
312
+ # var a = _.toArray(arguments);
313
+ # var solo = a.length <= 1;
314
+ # var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
315
+ # var len = Math.ceil((stop - start) / step);
316
+ # if (len <= 0) return [];
317
+ # var range = new Array(len);
318
+ # for (var i = start, idx = 0; true; i += step) {
319
+ # if ((step > 0 ? i - stop : stop - i) >= 0) return range;
320
+ # range[idx++] = i;
321
+ # }
322
+ # };
323
+ #
324
+ # /* ----------------------- Function Functions: -----------------------------*/
325
+ #
326
+ # # Create a function bound to a given object (assigning 'this', and arguments,
327
+ # # optionally). Binding with arguments is also known as 'curry'.
328
+ # _.bind = function(func, obj) {
329
+ # var args = _.rest(arguments, 2);
330
+ # return function() {
331
+ # return func.apply(obj || root, args.concat(_.toArray(arguments)));
332
+ # };
333
+ # };
334
+ #
335
+ # # Bind all of an object's methods to that object. Useful for ensuring that
336
+ # # all callbacks defined on an object belong to it.
337
+ # _.bindAll = function(obj) {
338
+ # var funcs = _.rest(arguments);
339
+ # if (funcs.length == 0) funcs = _.functions(obj);
340
+ # _.each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
341
+ # return obj;
342
+ # };
343
+ #
344
+ # # Delays a function for the given number of milliseconds, and then calls
345
+ # # it with the arguments supplied.
346
+ # _.delay = function(func, wait) {
347
+ # var args = _.rest(arguments, 2);
348
+ # return setTimeout(function(){ return func.apply(func, args); }, wait);
349
+ # };
350
+ #
351
+ # # Defers a function, scheduling it to run after the current call stack has
352
+ # # cleared.
353
+ # _.defer = function(func) {
354
+ # return _.delay.apply(_, [func, 1].concat(_.rest(arguments)));
355
+ # };
356
+ #
357
+ # # Returns the first function passed as an argument to the second,
358
+ # # allowing you to adjust arguments, run code before and after, and
359
+ # # conditionally execute the original function.
360
+ # _.wrap = function(func, wrapper) {
361
+ # return function() {
362
+ # var args = [func].concat(_.toArray(arguments));
363
+ # return wrapper.apply(wrapper, args);
364
+ # };
365
+ # };
366
+ #
367
+ # # Returns a function that is the composition of a list of functions, each
368
+ # # consuming the return value of the function that follows.
369
+ # _.compose = function() {
370
+ # var funcs = _.toArray(arguments);
371
+ # return function() {
372
+ # var args = _.toArray(arguments);
373
+ # for (var i=funcs.length-1; i >= 0; i--) {
374
+ # args = [funcs[i].apply(this, args)];
375
+ # }
376
+ # return args[0];
377
+ # };
378
+ # };
379
+ #
380
+ # /* ------------------------- Object Functions: ---------------------------- */
381
+ #
382
+ # # Retrieve the names of an object's properties.
383
+ # _.keys = function(obj) {
384
+ # if(_.isArray(obj)) return _.range(0, obj.length);
385
+ # var keys = [];
386
+ # for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
387
+ # return keys;
388
+ # };
389
+ #
390
+ # # Retrieve the values of an object's properties.
391
+ # _.values = function(obj) {
392
+ # return _.map(obj, _.identity);
393
+ # };
394
+ #
395
+ # # Return a sorted list of the function names available in Underscore.
396
+ # _.functions = function(obj) {
397
+ # return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
398
+ # };
399
+ #
400
+ # # Extend a given object with all of the properties in a source object.
401
+ # _.extend = function(destination, source) {
402
+ # for (var property in source) destination[property] = source[property];
403
+ # return destination;
404
+ # };
405
+ #
406
+ # # Create a (shallow-cloned) duplicate of an object.
407
+ # _.clone = function(obj) {
408
+ # if (_.isArray(obj)) return obj.slice(0);
409
+ # return _.extend({}, obj);
410
+ # };
411
+ #
412
+ # # Perform a deep comparison to check if two objects are equal.
413
+ # _.isEqual = function(a, b) {
414
+ # # Check object identity.
415
+ # if (a === b) return true;
416
+ # # Different types?
417
+ # var atype = typeof(a), btype = typeof(b);
418
+ # if (atype != btype) return false;
419
+ # # Basic equality test (watch out for coercions).
420
+ # if (a == b) return true;
421
+ # # One is falsy and the other truthy.
422
+ # if ((!a && b) || (a && !b)) return false;
423
+ # # One of them implements an isEqual()?
424
+ # if (a.isEqual) return a.isEqual(b);
425
+ # # Check dates' integer values.
426
+ # if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
427
+ # # Both are NaN?
428
+ # if (_.isNaN(a) && _.isNaN(b)) return true;
429
+ # # Compare regular expressions.
430
+ # if (_.isRegExp(a) && _.isRegExp(b))
431
+ # return a.source === b.source &&
432
+ # a.global === b.global &&
433
+ # a.ignoreCase === b.ignoreCase &&
434
+ # a.multiline === b.multiline;
435
+ # # If a is not an object by this point, we can't handle it.
436
+ # if (atype !== 'object') return false;
437
+ # # Check for different array lengths before comparing contents.
438
+ # if (a.length && (a.length !== b.length)) return false;
439
+ # # Nothing else worked, deep compare the contents.
440
+ # var aKeys = _.keys(a), bKeys = _.keys(b);
441
+ # # Different object sizes?
442
+ # if (aKeys.length != bKeys.length) return false;
443
+ # # Recursive comparison of contents.
444
+ # for (var key in a) if (!_.isEqual(a[key], b[key])) return false;
445
+ # return true;
446
+ # };
447
+ #
448
+ # # Is a given array or object empty?
449
+ # _.isEmpty = function(obj) {
450
+ # return _.keys(obj).length == 0;
451
+ # };
452
+ #
453
+ # # Is a given value a DOM element?
454
+ # _.isElement = function(obj) {
455
+ # return !!(obj && obj.nodeType == 1);
456
+ # };
457
+ #
458
+ # # Is a given variable an arguments object?
459
+ # _.isArguments = function(obj) {
460
+ # return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length');
461
+ # };
462
+ #
463
+ # # Is the given value NaN -- this one is interesting. NaN != NaN, and
464
+ # # isNaN(undefined) == true, so we make sure it's a number first.
465
+ # _.isNaN = function(obj) {
466
+ # return _.isNumber(obj) && isNaN(obj);
467
+ # };
468
+ #
469
+ # # Is a given value equal to null?
470
+ # _.isNull = function(obj) {
471
+ # return obj === null;
472
+ # };
473
+ #
474
+ # # Is a given variable undefined?
475
+ # _.isUndefined = function(obj) {
476
+ # return typeof obj == 'undefined';
477
+ # };
478
+ #
479
+ # # Invokes interceptor with the obj, and then returns obj.
480
+ # # The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
481
+ # _.tap = function(obj, interceptor) {
482
+ # interceptor(obj);
483
+ # return obj;
484
+ # }
485
+ #
486
+ # # Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString
487
+ # # functions based on their toString identifiers.
488
+ # var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'];
489
+ # for (var i=0, l=types.length; i<l; i++) {
490
+ # (function() {
491
+ # var identifier = '[object ' + types[i] + ']';
492
+ # _['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; };
493
+ # })();
494
+ # }
495
+ #
496
+ # /* -------------------------- Utility Functions: -------------------------- */
497
+ #
498
+ # # Run Underscore.js in noConflict mode, returning the '_' variable to its
499
+ # # previous owner. Returns a reference to the Underscore object.
500
+ # _.noConflict = function() {
501
+ # root._ = previousUnderscore;
502
+ # return this;
503
+ # };
504
+ #
505
+ # # Keep the identity function around for default iterators.
506
+ # _.identity = function(value) {
507
+ # return value;
508
+ # };
509
+ #
510
+ # # Break out of the middle of an iteration.
511
+ # _.breakLoop = function() {
512
+ # throw breaker;
513
+ # };
514
+ #
515
+ # # Generate a unique integer id (unique within the entire client session).
516
+ # # Useful for temporary DOM ids.
517
+ # var idCounter = 0;
518
+ # _.uniqueId = function(prefix) {
519
+ # var id = idCounter++;
520
+ # return prefix ? prefix + id : id;
521
+ # };
522
+ #
523
+ # # JavaScript templating a-la ERB, pilfered from John Resig's
524
+ # # "Secrets of the JavaScript Ninja", page 83.
525
+ # _.template = function(str, data) {
526
+ # var fn = new Function('obj',
527
+ # 'var p=[],print=function(){p.push.apply(p,arguments);};' +
528
+ # 'with(obj){p.push(\'' +
529
+ # str
530
+ # .replace(/[\r\t\n]/g, " ")
531
+ # .split("<%").join("\t")
532
+ # .replace(/((^|%>)[^\t]*)'/g, "$1\r")
533
+ # .replace(/\t=(.*?)%>/g, "',$1,'")
534
+ # .split("\t").join("');")
535
+ # .split("%>").join("p.push('")
536
+ # .split("\r").join("\\'")
537
+ # + "');}return p.join('');");
538
+ # return data ? fn(data) : fn;
539
+ # };
540
+ #
541
+ # /*------------------------------- Aliases ----------------------------------*/
542
+ #
543
+ # _.forEach = _.each;
544
+ # _.foldl = _.inject = _.reduce;
545
+ # _.foldr = _.reduceRight;
546
+ # _.filter = _.select;
547
+ # _.every = _.all;
548
+ # _.some = _.any;
549
+ # _.head = _.first;
550
+ # _.tail = _.rest;
551
+ # _.methods = _.functions;
552
+ #
553
+ # /*------------------------ Setup the OOP Wrapper: --------------------------*/
554
+ #
555
+ # # Helper function to continue chaining intermediate results.
556
+ # var result = function(obj, chain) {
557
+ # return chain ? _(obj).chain() : obj;
558
+ # };
559
+ #
560
+ # # Add all of the Underscore functions to the wrapper object.
561
+ # _.each(_.functions(_), function(name) {
562
+ # var method = _[name];
563
+ # wrapper.prototype[name] = function() {
564
+ # unshift.call(arguments, this._wrapped);
565
+ # return result(method.apply(_, arguments), this._chain);
566
+ # };
567
+ # });
568
+ #
569
+ # # Add all mutator Array functions to the wrapper.
570
+ # _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
571
+ # var method = Array.prototype[name];
572
+ # wrapper.prototype[name] = function() {
573
+ # method.apply(this._wrapped, arguments);
574
+ # return result(this._wrapped, this._chain);
575
+ # };
576
+ # });
577
+ #
578
+ # # Add all accessor Array functions to the wrapper.
579
+ # _.each(['concat', 'join', 'slice'], function(name) {
580
+ # var method = Array.prototype[name];
581
+ # wrapper.prototype[name] = function() {
582
+ # return result(method.apply(this._wrapped, arguments), this._chain);
583
+ # };
584
+ # });
585
+ #
586
+ # # Start chaining a wrapped Underscore object.
587
+ # wrapper.prototype.chain = function() {
588
+ # this._chain = true;
589
+ # return this;
590
+ # };
591
+ #
592
+ # # Extracts the result from a wrapped and chained object.
593
+ # wrapper.prototype.value = function() {
594
+ # return this._wrapped;
595
+ # };
596
+ #
597
+ # ()