PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/files/underscorejs/1.7.0/underscore.js

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