frank-cucumber 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/frank-skeleton/libFrank.a +0 -0
  2. data/lib/frank-cucumber/core_frank_steps.rb +8 -35
  3. data/lib/frank-cucumber/version.rb +1 -1
  4. metadata +4 -43
  5. data/Frank/features/my_first.feature +0 -12
  6. data/Frank/features/step_definitions/launch_steps.rb +0 -41
  7. data/Frank/features/support/env.rb +0 -1
  8. data/Frank/frank_static_resources.bundle/images/ajax-loader.gif +0 -0
  9. data/Frank/frank_static_resources.bundle/images/file.gif +0 -0
  10. data/Frank/frank_static_resources.bundle/images/folder-closed.gif +0 -0
  11. data/Frank/frank_static_resources.bundle/images/folder.gif +0 -0
  12. data/Frank/frank_static_resources.bundle/images/minus.gif +0 -0
  13. data/Frank/frank_static_resources.bundle/images/plus.gif +0 -0
  14. data/Frank/frank_static_resources.bundle/images/treeview-black-line.gif +0 -0
  15. data/Frank/frank_static_resources.bundle/images/treeview-black.gif +0 -0
  16. data/Frank/frank_static_resources.bundle/images/treeview-default-line.gif +0 -0
  17. data/Frank/frank_static_resources.bundle/images/treeview-default.gif +0 -0
  18. data/Frank/frank_static_resources.bundle/images/treeview-famfamfam-line.gif +0 -0
  19. data/Frank/frank_static_resources.bundle/images/treeview-famfamfam.gif +0 -0
  20. data/Frank/frank_static_resources.bundle/images/treeview-gray-line.gif +0 -0
  21. data/Frank/frank_static_resources.bundle/images/treeview-gray.gif +0 -0
  22. data/Frank/frank_static_resources.bundle/images/treeview-red-line.gif +0 -0
  23. data/Frank/frank_static_resources.bundle/images/treeview-red.gif +0 -0
  24. data/Frank/frank_static_resources.bundle/index.haml +0 -64
  25. data/Frank/frank_static_resources.bundle/index.html +0 -89
  26. data/Frank/frank_static_resources.bundle/jquery-ui.css +0 -571
  27. data/Frank/frank_static_resources.bundle/jquery-ui.min.js +0 -405
  28. data/Frank/frank_static_resources.bundle/jquery.min.js +0 -19
  29. data/Frank/frank_static_resources.bundle/jquery.treeview.css +0 -68
  30. data/Frank/frank_static_resources.bundle/jquery.treeview.js +0 -251
  31. data/Frank/frank_static_resources.bundle/json2.js +0 -481
  32. data/Frank/frank_static_resources.bundle/raphael-min.js +0 -7
  33. data/Frank/frank_static_resources.bundle/symbiote.css +0 -127
  34. data/Frank/frank_static_resources.bundle/symbiote.js +0 -512
  35. data/Frank/frank_static_resources.bundle/underscore.js +0 -770
  36. data/Frank/libFrank.a +0 -0
@@ -1,770 +0,0 @@
1
- // Underscore.js 1.1.4
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;
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
-
47
- // Create a safe reference to the Underscore object for use below.
48
- var _ = function(obj) { return new wrapper(obj); };
49
-
50
- // Export the Underscore object for **CommonJS**, with backwards-compatibility
51
- // for the old `require()` API. If we're not in CommonJS, add `_` to the
52
- // global object.
53
- if (typeof module !== 'undefined' && module.exports) {
54
- module.exports = _;
55
- _._ = _;
56
- } else {
57
- root._ = _;
58
- }
59
-
60
- // Current version.
61
- _.VERSION = '1.1.4';
62
-
63
- // Collection Functions
64
- // --------------------
65
-
66
- // The cornerstone, an `each` implementation, aka `forEach`.
67
- // Handles objects implementing `forEach`, arrays, and raw objects.
68
- // Delegates to **ECMAScript 5**'s native `forEach` if available.
69
- var each = _.each = _.forEach = function(obj, iterator, context) {
70
- var value;
71
- if (obj == null) return;
72
- if (nativeForEach && obj.forEach === nativeForEach) {
73
- obj.forEach(iterator, context);
74
- } else if (_.isNumber(obj.length)) {
75
- for (var i = 0, l = obj.length; i < l; i++) {
76
- if (iterator.call(context, obj[i], i, obj) === breaker) return;
77
- }
78
- } else {
79
- for (var key in obj) {
80
- if (hasOwnProperty.call(obj, key)) {
81
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
82
- }
83
- }
84
- }
85
- };
86
-
87
- // Return the results of applying the iterator to each element.
88
- // Delegates to **ECMAScript 5**'s native `map` if available.
89
- _.map = function(obj, iterator, context) {
90
- var results = [];
91
- if (obj == null) return results;
92
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
93
- each(obj, function(value, index, list) {
94
- results[results.length] = iterator.call(context, value, index, list);
95
- });
96
- return results;
97
- };
98
-
99
- // **Reduce** builds up a single result from a list of values, aka `inject`,
100
- // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
101
- _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
102
- var initial = memo !== void 0;
103
- if (obj == null) obj = [];
104
- if (nativeReduce && obj.reduce === nativeReduce) {
105
- if (context) iterator = _.bind(iterator, context);
106
- return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
107
- }
108
- each(obj, function(value, index, list) {
109
- if (!initial && index === 0) {
110
- memo = value;
111
- initial = true;
112
- } else {
113
- memo = iterator.call(context, memo, value, index, list);
114
- }
115
- });
116
- if (!initial) throw new TypeError("Reduce of empty array with no initial value");
117
- return memo;
118
- };
119
-
120
- // The right-associative version of reduce, also known as `foldr`.
121
- // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
122
- _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
123
- if (obj == null) obj = [];
124
- if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
125
- if (context) iterator = _.bind(iterator, context);
126
- return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
127
- }
128
- var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
129
- return _.reduce(reversed, iterator, memo, context);
130
- };
131
-
132
- // Return the first value which passes a truth test. Aliased as `detect`.
133
- _.find = _.detect = function(obj, iterator, context) {
134
- var result;
135
- any(obj, function(value, index, list) {
136
- if (iterator.call(context, value, index, list)) {
137
- result = value;
138
- return true;
139
- }
140
- });
141
- return result;
142
- };
143
-
144
- // Return all the elements that pass a truth test.
145
- // Delegates to **ECMAScript 5**'s native `filter` if available.
146
- // Aliased as `select`.
147
- _.filter = _.select = function(obj, iterator, context) {
148
- var results = [];
149
- if (obj == null) return results;
150
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
151
- each(obj, function(value, index, list) {
152
- if (iterator.call(context, value, index, list)) results[results.length] = value;
153
- });
154
- return results;
155
- };
156
-
157
- // Return all the elements for which a truth test fails.
158
- _.reject = function(obj, iterator, context) {
159
- var results = [];
160
- if (obj == null) return results;
161
- each(obj, function(value, index, list) {
162
- if (!iterator.call(context, value, index, list)) results[results.length] = value;
163
- });
164
- return results;
165
- };
166
-
167
- // Determine whether all of the elements match a truth test.
168
- // Delegates to **ECMAScript 5**'s native `every` if available.
169
- // Aliased as `all`.
170
- _.every = _.all = function(obj, iterator, context) {
171
- iterator = iterator || _.identity;
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 ? value[method] : value).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
- // Use a comparator function to figure out at what index an object should
256
- // be inserted so as to maintain order. Uses binary search.
257
- _.sortedIndex = function(array, obj, iterator) {
258
- iterator = iterator || _.identity;
259
- var low = 0, high = array.length;
260
- while (low < high) {
261
- var mid = (low + high) >> 1;
262
- iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
263
- }
264
- return low;
265
- };
266
-
267
- // Safely convert anything iterable into a real, live array.
268
- _.toArray = function(iterable) {
269
- if (!iterable) return [];
270
- if (iterable.toArray) return iterable.toArray();
271
- if (_.isArray(iterable)) return iterable;
272
- if (_.isArguments(iterable)) return slice.call(iterable);
273
- return _.values(iterable);
274
- };
275
-
276
- // Return the number of elements in an object.
277
- _.size = function(obj) {
278
- return _.toArray(obj).length;
279
- };
280
-
281
- // Array Functions
282
- // ---------------
283
-
284
- // Get the first element of an array. Passing **n** will return the first N
285
- // values in the array. Aliased as `head`. The **guard** check allows it to work
286
- // with `_.map`.
287
- _.first = _.head = function(array, n, guard) {
288
- return n && !guard ? slice.call(array, 0, n) : array[0];
289
- };
290
-
291
- // Returns everything but the first entry of the array. Aliased as `tail`.
292
- // Especially useful on the arguments object. Passing an **index** will return
293
- // the rest of the values in the array from that index onward. The **guard**
294
- // check allows it to work with `_.map`.
295
- _.rest = _.tail = function(array, index, guard) {
296
- return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
297
- };
298
-
299
- // Get the last element of an array.
300
- _.last = function(array) {
301
- return array[array.length - 1];
302
- };
303
-
304
- // Trim out all falsy values from an array.
305
- _.compact = function(array) {
306
- return _.filter(array, function(value){ return !!value; });
307
- };
308
-
309
- // Return a completely flattened version of an array.
310
- _.flatten = function(array) {
311
- return _.reduce(array, function(memo, value) {
312
- if (_.isArray(value)) return memo.concat(_.flatten(value));
313
- memo[memo.length] = value;
314
- return memo;
315
- }, []);
316
- };
317
-
318
- // Return a version of the array that does not contain the specified value(s).
319
- _.without = function(array) {
320
- var values = slice.call(arguments, 1);
321
- return _.filter(array, function(value){ return !_.include(values, value); });
322
- };
323
-
324
- // Produce a duplicate-free version of the array. If the array has already
325
- // been sorted, you have the option of using a faster algorithm.
326
- // Aliased as `unique`.
327
- _.uniq = _.unique = function(array, isSorted) {
328
- return _.reduce(array, function(memo, el, i) {
329
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
330
- return memo;
331
- }, []);
332
- };
333
-
334
- // Produce an array that contains every item shared between all the
335
- // passed-in arrays.
336
- _.intersect = function(array) {
337
- var rest = slice.call(arguments, 1);
338
- return _.filter(_.uniq(array), function(item) {
339
- return _.every(rest, function(other) {
340
- return _.indexOf(other, item) >= 0;
341
- });
342
- });
343
- };
344
-
345
- // Zip together multiple lists into a single array -- elements that share
346
- // an index go together.
347
- _.zip = function() {
348
- var args = slice.call(arguments);
349
- var length = _.max(_.pluck(args, 'length'));
350
- var results = new Array(length);
351
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
352
- return results;
353
- };
354
-
355
- // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
356
- // we need this function. Return the position of the first occurrence of an
357
- // item in an array, or -1 if the item is not included in the array.
358
- // Delegates to **ECMAScript 5**'s native `indexOf` if available.
359
- // If the array is large and already in sort order, pass `true`
360
- // for **isSorted** to use binary search.
361
- _.indexOf = function(array, item, isSorted) {
362
- if (array == null) return -1;
363
- if (isSorted) {
364
- var i = _.sortedIndex(array, item);
365
- return array[i] === item ? i : -1;
366
- }
367
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
368
- for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
369
- return -1;
370
- };
371
-
372
-
373
- // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
374
- _.lastIndexOf = function(array, item) {
375
- if (array == null) return -1;
376
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
377
- var i = array.length;
378
- while (i--) if (array[i] === item) return i;
379
- return -1;
380
- };
381
-
382
- // Generate an integer Array containing an arithmetic progression. A port of
383
- // the native Python `range()` function. See
384
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
385
- _.range = function(start, stop, step) {
386
- var args = slice.call(arguments),
387
- solo = args.length <= 1,
388
- start = solo ? 0 : args[0],
389
- stop = solo ? args[0] : args[1],
390
- step = args[2] || 1,
391
- len = Math.max(Math.ceil((stop - start) / step), 0),
392
- idx = 0,
393
- range = new Array(len);
394
- while (idx < len) {
395
- range[idx++] = start;
396
- start += step;
397
- }
398
- return range;
399
- };
400
-
401
- // Function (ahem) Functions
402
- // ------------------
403
-
404
- // Create a function bound to a given object (assigning `this`, and arguments,
405
- // optionally). Binding with arguments is also known as `curry`.
406
- _.bind = function(func, obj) {
407
- var args = slice.call(arguments, 2);
408
- return function() {
409
- return func.apply(obj || {}, args.concat(slice.call(arguments)));
410
- };
411
- };
412
-
413
- // Bind all of an object's methods to that object. Useful for ensuring that
414
- // all callbacks defined on an object belong to it.
415
- _.bindAll = function(obj) {
416
- var funcs = slice.call(arguments, 1);
417
- if (funcs.length == 0) funcs = _.functions(obj);
418
- each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
419
- return obj;
420
- };
421
-
422
- // Memoize an expensive function by storing its results.
423
- _.memoize = function(func, hasher) {
424
- var memo = {};
425
- hasher = hasher || _.identity;
426
- return function() {
427
- var key = hasher.apply(this, arguments);
428
- return key in memo ? memo[key] : (memo[key] = func.apply(this, arguments));
429
- };
430
- };
431
-
432
- // Delays a function for the given number of milliseconds, and then calls
433
- // it with the arguments supplied.
434
- _.delay = function(func, wait) {
435
- var args = slice.call(arguments, 2);
436
- return setTimeout(function(){ return func.apply(func, args); }, wait);
437
- };
438
-
439
- // Defers a function, scheduling it to run after the current call stack has
440
- // cleared.
441
- _.defer = function(func) {
442
- return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
443
- };
444
-
445
- // Internal function used to implement `_.throttle` and `_.debounce`.
446
- var limit = function(func, wait, debounce) {
447
- var timeout;
448
- return function() {
449
- var context = this, args = arguments;
450
- var throttler = function() {
451
- timeout = null;
452
- func.apply(context, args);
453
- };
454
- if (debounce) clearTimeout(timeout);
455
- if (debounce || !timeout) timeout = setTimeout(throttler, wait);
456
- };
457
- };
458
-
459
- // Returns a function, that, when invoked, will only be triggered at most once
460
- // during a given window of time.
461
- _.throttle = function(func, wait) {
462
- return limit(func, wait, false);
463
- };
464
-
465
- // Returns a function, that, as long as it continues to be invoked, will not
466
- // be triggered. The function will be called after it stops being called for
467
- // N milliseconds.
468
- _.debounce = function(func, wait) {
469
- return limit(func, wait, true);
470
- };
471
-
472
- // Returns the first function passed as an argument to the second,
473
- // allowing you to adjust arguments, run code before and after, and
474
- // conditionally execute the original function.
475
- _.wrap = function(func, wrapper) {
476
- return function() {
477
- var args = [func].concat(slice.call(arguments));
478
- return wrapper.apply(this, args);
479
- };
480
- };
481
-
482
- // Returns a function that is the composition of a list of functions, each
483
- // consuming the return value of the function that follows.
484
- _.compose = function() {
485
- var funcs = slice.call(arguments);
486
- return function() {
487
- var args = slice.call(arguments);
488
- for (var i=funcs.length-1; i >= 0; i--) {
489
- args = [funcs[i].apply(this, args)];
490
- }
491
- return args[0];
492
- };
493
- };
494
-
495
- // Object Functions
496
- // ----------------
497
-
498
- // Retrieve the names of an object's properties.
499
- // Delegates to **ECMAScript 5**'s native `Object.keys`
500
- _.keys = nativeKeys || function(obj) {
501
- if (_.isArray(obj)) return _.range(0, obj.length);
502
- var keys = [];
503
- for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
504
- return keys;
505
- };
506
-
507
- // Retrieve the values of an object's properties.
508
- _.values = function(obj) {
509
- return _.map(obj, _.identity);
510
- };
511
-
512
- // Return a sorted list of the function names available on the object.
513
- // Aliased as `methods`
514
- _.functions = _.methods = function(obj) {
515
- return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
516
- };
517
-
518
- // Extend a given object with all the properties in passed-in object(s).
519
- _.extend = function(obj) {
520
- each(slice.call(arguments, 1), function(source) {
521
- for (var prop in source) obj[prop] = source[prop];
522
- });
523
- return obj;
524
- };
525
-
526
- // Create a (shallow-cloned) duplicate of an object.
527
- _.clone = function(obj) {
528
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
529
- };
530
-
531
- // Invokes interceptor with the obj, and then returns obj.
532
- // The primary purpose of this method is to "tap into" a method chain, in
533
- // order to perform operations on intermediate results within the chain.
534
- _.tap = function(obj, interceptor) {
535
- interceptor(obj);
536
- return obj;
537
- };
538
-
539
- // Perform a deep comparison to check if two objects are equal.
540
- _.isEqual = function(a, b) {
541
- // Check object identity.
542
- if (a === b) return true;
543
- // Different types?
544
- var atype = typeof(a), btype = typeof(b);
545
- if (atype != btype) return false;
546
- // Basic equality test (watch out for coercions).
547
- if (a == b) return true;
548
- // One is falsy and the other truthy.
549
- if ((!a && b) || (a && !b)) return false;
550
- // Unwrap any wrapped objects.
551
- if (a._chain) a = a._wrapped;
552
- if (b._chain) b = b._wrapped;
553
- // One of them implements an isEqual()?
554
- if (a.isEqual) return a.isEqual(b);
555
- // Check dates' integer values.
556
- if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
557
- // Both are NaN?
558
- if (_.isNaN(a) && _.isNaN(b)) return false;
559
- // Compare regular expressions.
560
- if (_.isRegExp(a) && _.isRegExp(b))
561
- return a.source === b.source &&
562
- a.global === b.global &&
563
- a.ignoreCase === b.ignoreCase &&
564
- a.multiline === b.multiline;
565
- // If a is not an object by this point, we can't handle it.
566
- if (atype !== 'object') return false;
567
- // Check for different array lengths before comparing contents.
568
- if (a.length && (a.length !== b.length)) return false;
569
- // Nothing else worked, deep compare the contents.
570
- var aKeys = _.keys(a), bKeys = _.keys(b);
571
- // Different object sizes?
572
- if (aKeys.length != bKeys.length) return false;
573
- // Recursive comparison of contents.
574
- for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
575
- return true;
576
- };
577
-
578
- // Is a given array or object empty?
579
- _.isEmpty = function(obj) {
580
- if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
581
- for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
582
- return true;
583
- };
584
-
585
- // Is a given value a DOM element?
586
- _.isElement = function(obj) {
587
- return !!(obj && obj.nodeType == 1);
588
- };
589
-
590
- // Is a given value an array?
591
- // Delegates to ECMA5's native Array.isArray
592
- _.isArray = nativeIsArray || function(obj) {
593
- return toString.call(obj) === '[object Array]';
594
- };
595
-
596
- // Is a given variable an arguments object?
597
- _.isArguments = function(obj) {
598
- return !!(obj && hasOwnProperty.call(obj, 'callee'));
599
- };
600
-
601
- // Is a given value a function?
602
- _.isFunction = function(obj) {
603
- return !!(obj && obj.constructor && obj.call && obj.apply);
604
- };
605
-
606
- // Is a given value a string?
607
- _.isString = function(obj) {
608
- return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
609
- };
610
-
611
- // Is a given value a number?
612
- _.isNumber = function(obj) {
613
- return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
614
- };
615
-
616
- // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
617
- // that does not equal itself.
618
- _.isNaN = function(obj) {
619
- return obj !== obj;
620
- };
621
-
622
- // Is a given value a boolean?
623
- _.isBoolean = function(obj) {
624
- return obj === true || obj === false;
625
- };
626
-
627
- // Is a given value a date?
628
- _.isDate = function(obj) {
629
- return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
630
- };
631
-
632
- // Is the given value a regular expression?
633
- _.isRegExp = function(obj) {
634
- return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
635
- };
636
-
637
- // Is a given value equal to null?
638
- _.isNull = function(obj) {
639
- return obj === null;
640
- };
641
-
642
- // Is a given variable undefined?
643
- _.isUndefined = function(obj) {
644
- return obj === void 0;
645
- };
646
-
647
- // Utility Functions
648
- // -----------------
649
-
650
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
651
- // previous owner. Returns a reference to the Underscore object.
652
- _.noConflict = function() {
653
- root._ = previousUnderscore;
654
- return this;
655
- };
656
-
657
- // Keep the identity function around for default iterators.
658
- _.identity = function(value) {
659
- return value;
660
- };
661
-
662
- // Run a function **n** times.
663
- _.times = function (n, iterator, context) {
664
- for (var i = 0; i < n; i++) iterator.call(context, i);
665
- };
666
-
667
- // Add your own custom functions to the Underscore object, ensuring that
668
- // they're correctly added to the OOP wrapper as well.
669
- _.mixin = function(obj) {
670
- each(_.functions(obj), function(name){
671
- addToWrapper(name, _[name] = obj[name]);
672
- });
673
- };
674
-
675
- // Generate a unique integer id (unique within the entire client session).
676
- // Useful for temporary DOM ids.
677
- var idCounter = 0;
678
- _.uniqueId = function(prefix) {
679
- var id = idCounter++;
680
- return prefix ? prefix + id : id;
681
- };
682
-
683
- // By default, Underscore uses ERB-style template delimiters, change the
684
- // following template settings to use alternative delimiters.
685
- _.templateSettings = {
686
- evaluate : /<%([\s\S]+?)%>/g,
687
- interpolate : /<%=([\s\S]+?)%>/g
688
- };
689
-
690
- // JavaScript micro-templating, similar to John Resig's implementation.
691
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
692
- // and correctly escapes quotes within interpolated code.
693
- _.template = function(str, data) {
694
- var c = _.templateSettings;
695
- var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
696
- 'with(obj||{}){__p.push(\'' +
697
- str.replace(/\\/g, '\\\\')
698
- .replace(/'/g, "\\'")
699
- .replace(c.interpolate, function(match, code) {
700
- return "'," + code.replace(/\\'/g, "'") + ",'";
701
- })
702
- .replace(c.evaluate || null, function(match, code) {
703
- return "');" + code.replace(/\\'/g, "'")
704
- .replace(/[\r\n\t]/g, ' ') + "__p.push('";
705
- })
706
- .replace(/\r/g, '\\r')
707
- .replace(/\n/g, '\\n')
708
- .replace(/\t/g, '\\t')
709
- + "');}return __p.join('');";
710
- var func = new Function('obj', tmpl);
711
- return data ? func(data) : func;
712
- };
713
-
714
- // The OOP Wrapper
715
- // ---------------
716
-
717
- // If Underscore is called as a function, it returns a wrapped object that
718
- // can be used OO-style. This wrapper holds altered versions of all the
719
- // underscore functions. Wrapped objects may be chained.
720
- var wrapper = function(obj) { this._wrapped = obj; };
721
-
722
- // Expose `wrapper.prototype` as `_.prototype`
723
- _.prototype = wrapper.prototype;
724
-
725
- // Helper function to continue chaining intermediate results.
726
- var result = function(obj, chain) {
727
- return chain ? _(obj).chain() : obj;
728
- };
729
-
730
- // A method to easily add functions to the OOP wrapper.
731
- var addToWrapper = function(name, func) {
732
- wrapper.prototype[name] = function() {
733
- var args = slice.call(arguments);
734
- unshift.call(args, this._wrapped);
735
- return result(func.apply(_, args), this._chain);
736
- };
737
- };
738
-
739
- // Add all of the Underscore functions to the wrapper object.
740
- _.mixin(_);
741
-
742
- // Add all mutator Array functions to the wrapper.
743
- each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
744
- var method = ArrayProto[name];
745
- wrapper.prototype[name] = function() {
746
- method.apply(this._wrapped, arguments);
747
- return result(this._wrapped, this._chain);
748
- };
749
- });
750
-
751
- // Add all accessor Array functions to the wrapper.
752
- each(['concat', 'join', 'slice'], function(name) {
753
- var method = ArrayProto[name];
754
- wrapper.prototype[name] = function() {
755
- return result(method.apply(this._wrapped, arguments), this._chain);
756
- };
757
- });
758
-
759
- // Start chaining a wrapped Underscore object.
760
- wrapper.prototype.chain = function() {
761
- this._chain = true;
762
- return this;
763
- };
764
-
765
- // Extracts the result from a wrapped and chained object.
766
- wrapper.prototype.value = function() {
767
- return this._wrapped;
768
- };
769
-
770
- })();