cornerstone-source 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +20 -0
  5. data/Rakefile +8 -0
  6. data/config.rb +79 -0
  7. data/config.ru +4 -0
  8. data/cornerstone.gemspec +22 -0
  9. data/doc_scraper.rb +51 -0
  10. data/game.js +4293 -0
  11. data/lib/assets/javascripts/cornerstone.js +4719 -0
  12. data/lib/cornerstone.rb +11 -0
  13. data/lib/cornerstone/rails.rb +5 -0
  14. data/lib/cornerstone/sprockets.rb +2 -0
  15. data/lib/cornerstone/version.rb +3 -0
  16. data/manifest.json +15 -0
  17. data/pixie.json +12 -0
  18. data/source/javascripts/_cornerstone/_object_extensions.js.coffee +108 -0
  19. data/source/javascripts/_cornerstone/array_extensions.js.coffee +570 -0
  20. data/source/javascripts/_cornerstone/bindable.js.coffee +125 -0
  21. data/source/javascripts/_cornerstone/command_stack.js.coffee +36 -0
  22. data/source/javascripts/_cornerstone/core_object.js.coffee +183 -0
  23. data/source/javascripts/_cornerstone/function_extensions.js.coffee +60 -0
  24. data/source/javascripts/_cornerstone/logging.js.coffee +19 -0
  25. data/source/javascripts/_cornerstone/matrix.js.coffee +337 -0
  26. data/source/javascripts/_cornerstone/number_extensions.js.coffee +491 -0
  27. data/source/javascripts/_cornerstone/point.js.coffee +641 -0
  28. data/source/javascripts/_cornerstone/random.js.coffee +86 -0
  29. data/source/javascripts/_cornerstone/rectangle.js.coffee +35 -0
  30. data/source/javascripts/_cornerstone/string_extensions.js.coffee +232 -0
  31. data/source/javascripts/_cornerstone/stubs.js.coffee +1042 -0
  32. data/source/javascripts/_cornerstone/uuid.js +96 -0
  33. data/source/javascripts/_test/array_extensions.coffee +173 -0
  34. data/source/javascripts/_test/bindable.coffee +68 -0
  35. data/source/javascripts/_test/command_stack.coffee +99 -0
  36. data/source/javascripts/_test/core_object.coffee +95 -0
  37. data/source/javascripts/_test/function_extensions.coffee +50 -0
  38. data/source/javascripts/_test/logging.coffee +7 -0
  39. data/source/javascripts/_test/matrix.coffee +174 -0
  40. data/source/javascripts/_test/number_extensions.coffee +138 -0
  41. data/source/javascripts/_test/object_extensions.coffee +53 -0
  42. data/source/javascripts/_test/point.coffee +196 -0
  43. data/source/javascripts/_test/random.coffee +22 -0
  44. data/source/javascripts/_test/rectangle.coffee +70 -0
  45. data/source/javascripts/_test/string_extensions.coffee +59 -0
  46. data/source/javascripts/cornerstone.js.coffee +1 -0
  47. data/source/javascripts/cornerstone_tests.js.coffee +2 -0
  48. data/source/test.html.haml +13 -0
  49. data/vendor/javascripts/qunit.js +1275 -0
  50. data/vendor/stylesheets/qunit.css.sass +115 -0
  51. metadata +141 -0
@@ -0,0 +1,11 @@
1
+ require "cornerstone/version"
2
+
3
+ # Sneaky require for Rails engine environment
4
+ if defined? ::Rails::Engine
5
+ require "cornerstone/rails"
6
+ elsif defined? ::Sprockets
7
+ require "cornerstone/sprockets"
8
+ end
9
+
10
+ module Cornerstone
11
+ end
@@ -0,0 +1,5 @@
1
+ module Cornerstone
2
+ class Rails < Rails::Engine
3
+ # auto wire assets
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ root_dir = File.expand_path(File.dirname(File.dirname(File.dirname(__FILE__))))
2
+ Sprockets.paths << File.join(root_dir, "lib", "assets")
@@ -0,0 +1,3 @@
1
+ module Cornerstone
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "corelib",
3
+ "description": "Extending JavaScript in all the right ways.",
4
+ "app": {
5
+ "launch": {
6
+ "local_path": "webstore/main.html"
7
+ }
8
+ },
9
+ "version": "0.0.1",
10
+ "icons": {
11
+ "128": "webstore/images/icon_128.png",
12
+ "96": "webstore/images/icon_96.png",
13
+ "16": "webstore/images/icon_16.png"
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "author": "PixieEngine",
3
+ "main": null,
4
+ "name": "Cornerstone",
5
+ "library": true,
6
+ "directories": {
7
+ "lib": "vendor/assets/javascripts",
8
+ "source": "_cornerstone",
9
+ "test": "_test"
10
+ },
11
+ "autosave": true
12
+ }
@@ -0,0 +1,108 @@
1
+ ###*
2
+ Checks whether an object is an array.
3
+
4
+ Object.isArray([1, 2, 4])
5
+ # => true
6
+
7
+ Object.isArray({key: "value"})
8
+ # => false
9
+
10
+ @name isArray
11
+ @methodOf Object
12
+ @param {Object} object The object to check for array-ness.
13
+ @returns {Boolean} A boolean expressing whether the object is an instance of Array
14
+ ###
15
+ Object.isArray = (object) ->
16
+ Object::toString.call(object) == "[object Array]"
17
+
18
+ ###*
19
+ Checks whether an object is a string.
20
+
21
+ Object.isString("a string")
22
+ # => true
23
+
24
+ Object.isString([1, 2, 4])
25
+ # => false
26
+
27
+ Object.isString({key: "value"})
28
+ # => false
29
+
30
+ @name isString
31
+ @methodOf Object
32
+ @param {Object} object The object to check for string-ness.
33
+ @returns {Boolean} A boolean expressing whether the object is an instance of String
34
+ ###
35
+ Object.isString = (object) ->
36
+ Object::toString.call(object) == "[object String]"
37
+
38
+ ###*
39
+ Merges properties from objects into target without overiding.
40
+ First come, first served.
41
+
42
+ I =
43
+ a: 1
44
+ b: 2
45
+ c: 3
46
+
47
+ Object.reverseMerge I,
48
+ c: 6
49
+ d: 4
50
+
51
+ I # => {a: 1, b:2, c:3, d: 4}
52
+
53
+ @name reverseMerge
54
+ @methodOf Object
55
+ @param {Object} target The object to merge the properties into.
56
+ @returns {Object} target
57
+ ###
58
+ Object.reverseMerge = (target, objects...) ->
59
+ for object in objects
60
+ for name of object
61
+ unless target.hasOwnProperty(name)
62
+ target[name] = object[name]
63
+
64
+ return target
65
+
66
+ ###*
67
+ Merges properties from sources into target with overiding.
68
+ Last in covers earlier properties.
69
+
70
+ I =
71
+ a: 1
72
+ b: 2
73
+ c: 3
74
+
75
+ Object.extend I,
76
+ c: 6
77
+ d: 4
78
+
79
+ I # => {a: 1, b:2, c:6, d: 4}
80
+
81
+ @name extend
82
+ @methodOf Object
83
+ @param {Object} target The object to merge the properties into.
84
+ @returns {Object} target
85
+ ###
86
+ Object.extend = (target, sources...) ->
87
+ for source in sources
88
+ for name of source
89
+ target[name] = source[name]
90
+
91
+ return target
92
+
93
+ ###*
94
+ Helper method that tells you if something is an object.
95
+
96
+ object = {a: 1}
97
+
98
+ Object.isObject(object)
99
+ # => true
100
+
101
+ @name isObject
102
+ @methodOf Object
103
+ @param {Object} object Maybe this guy is an object.
104
+ @returns {Boolean} true if this guy is an object.
105
+ ###
106
+ Object.isObject = (object) ->
107
+ Object.prototype.toString.call(object) == '[object Object]'
108
+
@@ -0,0 +1,570 @@
1
+ ###*
2
+ Calculate the average value of an array. Returns undefined if some elements
3
+ are not numbers.
4
+
5
+ [1, 3, 5, 7].average()
6
+ # => 4
7
+
8
+ @name average
9
+ @methodOf Array#
10
+ @returns {Number} The average (arithmetic mean) of the list of numbers.
11
+ ###
12
+ Array::average = ->
13
+ @sum()/@length
14
+
15
+ ###*
16
+ Returns a copy of the array without null and undefined values.
17
+
18
+ [null, undefined, 3, 3, undefined, 5].compact()
19
+ # => [3, 3, 5]
20
+
21
+ @name compact
22
+ @methodOf Array#
23
+ @returns {Array} A new array that contains only the non-null values.
24
+ ###
25
+ Array::compact = ->
26
+ this.select (element) ->
27
+ element?
28
+
29
+ ###*
30
+ Creates and returns a copy of the array. The copy contains
31
+ the same objects.
32
+
33
+ a = ["a", "b", "c"]
34
+ b = a.copy()
35
+
36
+ # their elements are equal
37
+ a[0] == b[0] && a[1] == b[1] && a[2] == b[2]
38
+ # => true
39
+
40
+ # but they aren't the same object in memory
41
+ a === b
42
+ # => false
43
+
44
+ @name copy
45
+ @methodOf Array#
46
+ @returns {Array} A new array that is a copy of the array
47
+ ###
48
+ Array::copy = ->
49
+ this.concat()
50
+
51
+ ###*
52
+ Empties the array of its contents. It is modified in place.
53
+
54
+ fullArray = [1, 2, 3]
55
+ fullArray.clear()
56
+ fullArray
57
+ # => []
58
+
59
+ @name clear
60
+ @methodOf Array#
61
+ @returns {Array} this, now emptied.
62
+ ###
63
+ Array::clear = ->
64
+ this.length = 0
65
+
66
+ return this
67
+
68
+ ###*
69
+ Flatten out an array of arrays into a single array of elements.
70
+
71
+ [[1, 2], [3, 4], 5].flatten()
72
+ # => [1, 2, 3, 4, 5]
73
+
74
+ # won't flatten twice nested arrays. call
75
+ # flatten twice if that is what you want
76
+ [[1, 2], [3, [4, 5]], 6].flatten()
77
+ # => [1, 2, 3, [4, 5], 6]
78
+
79
+ @name flatten
80
+ @methodOf Array#
81
+ @returns {Array} A new array with all the sub-arrays flattened to the top.
82
+ ###
83
+ Array::flatten = ->
84
+ this.inject [], (a, b) ->
85
+ a.concat b
86
+
87
+ ###*
88
+ Invoke the named method on each element in the array
89
+ and return a new array containing the results of the invocation.
90
+
91
+ [1.1, 2.2, 3.3, 4.4].invoke("floor")
92
+ # => [1, 2, 3, 4]
93
+
94
+ ['hello', 'world', 'cool!'].invoke('substring', 0, 3)
95
+ # => ['hel', 'wor', 'coo']
96
+
97
+ @param {String} method The name of the method to invoke.
98
+ @param [arg...] Optional arguments to pass to the method being invoked.
99
+ @name invoke
100
+ @methodOf Array#
101
+ @returns {Array} A new array containing the results of invoking the named method on each element.
102
+ ###
103
+ Array::invoke = (method, args...) ->
104
+ this.map (element) ->
105
+ element[method].apply(element, args)
106
+
107
+ ###*
108
+ Randomly select an element from the array.
109
+
110
+ [1, 2, 3].rand()
111
+ # => 2
112
+
113
+ @name rand
114
+ @methodOf Array#
115
+ @returns {Object} A random element from an array
116
+ ###
117
+ Array::rand = ->
118
+ this[rand(this.length)]
119
+
120
+ ###*
121
+ Remove the first occurrence of the given object from the array if it is
122
+ present. The array is modified in place.
123
+
124
+ a = [1, 1, "a", "b"]
125
+ a.remove(1)
126
+ # => 1
127
+
128
+ a
129
+ # => [1, "a", "b"]
130
+
131
+ @name remove
132
+ @methodOf Array#
133
+ @param {Object} object The object to remove from the array if present.
134
+ @returns {Object} The removed object if present otherwise undefined.
135
+ ###
136
+ Array::remove = (object) ->
137
+ index = this.indexOf(object)
138
+
139
+ if index >= 0
140
+ this.splice(index, 1)[0]
141
+ else
142
+ undefined
143
+
144
+ ###*
145
+ Returns true if the element is present in the array.
146
+
147
+ ["a", "b", "c"].include("c")
148
+ # => true
149
+
150
+ [40, "a"].include(700)
151
+ # => false
152
+
153
+ @name include
154
+ @methodOf Array#
155
+ @param {Object} element The element to check if present.
156
+ @returns {Boolean} true if the element is in the array, false otherwise.
157
+ ###
158
+ Array::include = (element) ->
159
+ this.indexOf(element) != -1
160
+
161
+ ###*
162
+ Call the given iterator once for each element in the array,
163
+ passing in the element as the first argument, the index of
164
+ the element as the second argument, and <code>this</code> array as the
165
+ third argument.
166
+
167
+ word = ""
168
+ indices = []
169
+ ["r", "a", "d"].each (letter, index) ->
170
+ word += letter
171
+ indices.push(index)
172
+
173
+ # => ["r", "a", "d"]
174
+
175
+ word
176
+ # => "rad"
177
+
178
+ indices
179
+ # => [0, 1, 2]
180
+
181
+ @name each
182
+ @methodOf Array#
183
+ @param {Function} iterator Function to be called once for each element in the array.
184
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
185
+ @returns {Array} this to enable method chaining.
186
+ ###
187
+ Array::each = (iterator, context) ->
188
+ if this.forEach
189
+ this.forEach iterator, context
190
+ else
191
+ for element, i in this
192
+ iterator.call context, element, i, this
193
+
194
+ return this
195
+
196
+ ###*
197
+ Call the given iterator once for each element in the array,
198
+ passing in the element as the first argument, the index of
199
+ the element as the second argument, and `this` array as the
200
+ third argument.
201
+
202
+ [1, 2, 3].map (number) ->
203
+ number * number
204
+ # => [1, 4, 9]
205
+
206
+ @name map
207
+ @methodOf Array#
208
+ @param {Function} iterator Function to be called once for each element in the array.
209
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
210
+ @returns {Array} An array of the results of the iterator function being called on the original array elements.
211
+ ###
212
+ Array::map ||= (iterator, context) ->
213
+ results = []
214
+
215
+ for element, i in this
216
+ results.push iterator.call(context, element, i, this)
217
+
218
+ results
219
+
220
+ ###*
221
+ Call the given iterator once for each pair of objects in the array.
222
+
223
+ [1, 2, 3, 4].eachPair (a, b) ->
224
+ # 1, 2
225
+ # 1, 3
226
+ # 1, 4
227
+ # 2, 3
228
+ # 2, 4
229
+ # 3, 4
230
+
231
+ @name eachPair
232
+ @methodOf Array#
233
+ @param {Function} iterator Function to be called once for each pair of elements in the array.
234
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
235
+ ###
236
+ Array::eachPair = (iterator, context) ->
237
+ length = this.length
238
+ i = 0
239
+ while i < length
240
+ a = this[i]
241
+ j = i + 1
242
+ i += 1
243
+
244
+ while j < length
245
+ b = this[j]
246
+ j += 1
247
+
248
+ iterator.call context, a, b
249
+
250
+ ###*
251
+ Call the given iterator once for each element in the array,
252
+ passing in the element as the first argument and the given object
253
+ as the second argument. Additional arguments are passed similar to
254
+ <code>each</code>.
255
+
256
+ @see Array#each
257
+ @name eachWithObject
258
+ @methodOf Array#
259
+ @param {Object} object The object to pass to the iterator on each visit.
260
+ @param {Function} iterator Function to be called once for each element in the array.
261
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
262
+ @returns {Array} this
263
+ ###
264
+ Array::eachWithObject = (object, iterator, context) ->
265
+ this.each (element, i, self) ->
266
+ iterator.call context, element, object, i, self
267
+
268
+ return object
269
+
270
+ ###*
271
+ Call the given iterator once for each group of elements in the array,
272
+ passing in the elements in groups of n. Additional argumens are
273
+ passed as in each.
274
+
275
+ results = []
276
+ [1, 2, 3, 4].eachSlice 2, (slice) ->
277
+ results.push(slice)
278
+ # => [1, 2, 3, 4]
279
+
280
+ results
281
+ # => [[1, 2], [3, 4]]
282
+
283
+ @see Array#each
284
+ @name eachSlice
285
+ @methodOf Array#
286
+ @param {Number} n The number of elements in each group.
287
+ @param {Function} iterator Function to be called once for each group of elements in the array.
288
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
289
+ @returns {Array} this
290
+ ###
291
+ Array::eachSlice = (n, iterator, context) ->
292
+ if n > 0
293
+ len = (this.length / n).floor()
294
+ i = -1
295
+
296
+ while ++i < len
297
+ iterator.call(context, this.slice(i*n, (i+1)*n), i*n, this)
298
+
299
+ return this
300
+
301
+ ###*
302
+ Pipe the input through each function in the array in turn. For example, if you have a
303
+ list of objects you can perform a series of selection, sorting, and other processing
304
+ methods and then receive the processed list. This array must contain functions that
305
+ accept a single input and return the processed input. The output of the first function
306
+ is fed to the input of the second and so on until the final processed output is returned.
307
+
308
+ @name pipeline
309
+ @methodOf Array#
310
+
311
+ @param {Object} input The initial input to pass to the first function in the pipeline.
312
+ @returns {Object} The result of processing the input by each function in the array.
313
+ ###
314
+ Array::pipeline = (input) ->
315
+ for fn in this
316
+ input = fn(input)
317
+
318
+ return input
319
+
320
+ ###*
321
+ Returns a new array with the elements all shuffled up.
322
+
323
+ a = [1, 2, 3]
324
+
325
+ a.shuffle()
326
+ # => [2, 3, 1]
327
+
328
+ a # => [1, 2, 3]
329
+
330
+ @name shuffle
331
+ @methodOf Array#
332
+ @returns {Array} A new array that is randomly shuffled.
333
+ ###
334
+ Array::shuffle = ->
335
+ shuffledArray = []
336
+
337
+ this.each (element) ->
338
+ shuffledArray.splice(rand(shuffledArray.length + 1), 0, element)
339
+
340
+ return shuffledArray
341
+
342
+ ###*
343
+ Returns the first element of the array, undefined if the array is empty.
344
+
345
+ ["first", "second", "third"].first()
346
+ # => "first"
347
+
348
+ @name first
349
+ @methodOf Array#
350
+ @returns {Object} The first element, or undefined if the array is empty.
351
+ ###
352
+ Array::first = ->
353
+ this[0]
354
+
355
+ ###*
356
+ Returns the last element of the array, undefined if the array is empty.
357
+
358
+ ["first", "second", "third"].last()
359
+ # => "third"
360
+
361
+ @name last
362
+ @methodOf Array#
363
+ @returns {Object} The last element, or undefined if the array is empty.
364
+ ###
365
+ Array::last = ->
366
+ this[this.length - 1]
367
+
368
+ ###*
369
+ Returns an object containing the extremes of this array.
370
+
371
+ [-1, 3, 0].extremes()
372
+ # => {min: -1, max: 3}
373
+
374
+ @name extremes
375
+ @methodOf Array#
376
+ @param {Function} [fn] An optional funtion used to evaluate each element to calculate its value for determining extremes.
377
+ @returns {Object} {min: minElement, max: maxElement}
378
+ ###
379
+ Array::extremes = (fn) ->
380
+ fn ||= (n) -> n
381
+
382
+ min = max = undefined
383
+ minResult = maxResult = undefined
384
+
385
+ this.each (object) ->
386
+ result = fn(object)
387
+
388
+ if min?
389
+ if result < minResult
390
+ min = object
391
+ minResult = result
392
+ else
393
+ min = object
394
+ minResult = result
395
+
396
+ if max?
397
+ if result > maxResult
398
+ max = object
399
+ maxResult = result
400
+ else
401
+ max = object
402
+ maxResult = result
403
+
404
+ min: min
405
+ max: max
406
+
407
+ ###*
408
+ Pretend the array is a circle and grab a new array containing length elements.
409
+ If length is not given return the element at start, again assuming the array
410
+ is a circle.
411
+
412
+ [1, 2, 3].wrap(-1)
413
+ # => 3
414
+
415
+ [1, 2, 3].wrap(6)
416
+ # => 1
417
+
418
+ ["l", "o", "o", "p"].wrap(0, 16)
419
+ # => ["l", "o", "o", "p", "l", "o", "o", "p", "l", "o", "o", "p", "l", "o", "o", "p"]
420
+
421
+ @name wrap
422
+ @methodOf Array#
423
+ @param {Number} start The index to start wrapping at, or the index of the sole element to return if no length is given.
424
+ @param {Number} [length] Optional length determines how long result array should be.
425
+ @returns {Object} or {Array} The element at start mod array.length, or an array of length elements, starting from start and wrapping.
426
+ ###
427
+ Array::wrap = (start, length) ->
428
+ if length?
429
+ end = start + length
430
+ i = start
431
+ result = []
432
+
433
+ result.push(this[i.mod(this.length)]) while i++ < end
434
+
435
+ return result
436
+ else
437
+ return this[start.mod(this.length)]
438
+
439
+ ###*
440
+ Partitions the elements into two groups: those for which the iterator returns
441
+ true, and those for which it returns false.
442
+
443
+ [evens, odds] = [1, 2, 3, 4].partition (n) ->
444
+ n.even()
445
+
446
+ evens
447
+ # => [2, 4]
448
+
449
+ odds
450
+ # => [1, 3]
451
+
452
+ @name partition
453
+ @methodOf Array#
454
+ @param {Function} iterator
455
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
456
+ @returns {Array} An array in the form of [trueCollection, falseCollection]
457
+ ###
458
+ Array::partition = (iterator, context) ->
459
+ trueCollection = []
460
+ falseCollection = []
461
+
462
+ this.each (element) ->
463
+ if iterator.call(context, element)
464
+ trueCollection.push element
465
+ else
466
+ falseCollection.push element
467
+
468
+ return [trueCollection, falseCollection]
469
+
470
+ ###*
471
+ Return the group of elements for which the return value of the iterator is true.
472
+
473
+ @name select
474
+ @methodOf Array#
475
+ @param {Function} iterator The iterator receives each element in turn as the first agument.
476
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
477
+ @returns {Array} An array containing the elements for which the iterator returned true.
478
+ ###
479
+ Array::select = (iterator, context) ->
480
+ return this.partition(iterator, context)[0]
481
+
482
+ ###*
483
+ Return the group of elements that are not in the passed in set.
484
+
485
+ [1, 2, 3, 4].without ([2, 3])
486
+ # => [1, 4]
487
+
488
+ @name without
489
+ @methodOf Array#
490
+ @param {Array} values List of elements to exclude.
491
+ @returns {Array} An array containing the elements that are not passed in.
492
+ ###
493
+ Array::without = (values) ->
494
+ this.reject (element) ->
495
+ values.include(element)
496
+
497
+ ###*
498
+ Return the group of elements for which the return value of the iterator is false.
499
+
500
+ @name reject
501
+ @methodOf Array#
502
+ @param {Function} iterator The iterator receives each element in turn as the first agument.
503
+ @param {Object} [context] Optional context parameter to be used as `this` when calling the iterator function.
504
+ @returns {Array} An array containing the elements for which the iterator returned false.
505
+ ###
506
+ Array::reject = (iterator, context) ->
507
+ this.partition(iterator, context)[1]
508
+
509
+ ###*
510
+ Combines all elements of the array by applying a binary operation.
511
+ for each element in the arra the iterator is passed an accumulator
512
+ value (memo) and the element.
513
+
514
+ @name inject
515
+ @methodOf Array#
516
+ @returns {Object} The result of a
517
+ ###
518
+ Array::inject = (initial, iterator) ->
519
+ this.each (element) ->
520
+ initial = iterator(initial, element)
521
+
522
+ return initial
523
+
524
+ ###*
525
+ Add all the elements in the array.
526
+
527
+ [1, 2, 3, 4].sum()
528
+ # => 10
529
+
530
+ @name sum
531
+ @methodOf Array#
532
+ @returns {Number} The sum of the elements in the array.
533
+ ###
534
+ Array::sum = ->
535
+ this.inject 0, (sum, n) ->
536
+ sum + n
537
+
538
+ ###*
539
+ Multiply all the elements in the array.
540
+
541
+ [1, 2, 3, 4].product()
542
+ # => 24
543
+
544
+ @name product
545
+ @methodOf Array#
546
+ @returns {Number} The product of the elements in the array.
547
+ ###
548
+ Array::product = ->
549
+ this.inject 1, (product, n) ->
550
+ product * n
551
+
552
+ ###*
553
+ Merges together the values of each of the arrays with the values at the corresponding position.
554
+
555
+ ['a', 'b', 'c'].zip([1, 2, 3])
556
+ # => [['a', 1], ['b', 2], ['c', 3]]
557
+
558
+ @name zip
559
+ @methodOf Array#
560
+ @returns {Array} Array groupings whose values are arranged by their positions in the original input arrays.
561
+ ###
562
+ Array::zip = (args...) ->
563
+ this.map (element, index) ->
564
+ output = args.map (arr) ->
565
+ arr[index]
566
+
567
+ output.unshift(element)
568
+
569
+ return output
570
+