UNPKG

260 kBJavaScriptView Raw
1(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2(function (global){
3/**
4 * @license
5 * Copyright (c) 2014, Chris Pettitt
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its contributors
19 * may be used to endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33global.graphlib = require('./index');
34
35}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
36},{"./index":2}],2:[function(require,module,exports){
37/**
38 * Copyright (c) 2014, Chris Pettitt
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions are met:
43 *
44 * 1. Redistributions of source code must retain the above copyright notice, this
45 * list of conditions and the following disclaimer.
46 *
47 * 2. Redistributions in binary form must reproduce the above copyright notice,
48 * this list of conditions and the following disclaimer in the documentation
49 * and/or other materials provided with the distribution.
50 *
51 * 3. Neither the name of the copyright holder nor the names of its contributors
52 * may be used to endorse or promote products derived from this software without
53 * specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
61 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
62 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
63 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
64 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 */
66
67var lib = require("./lib");
68
69module.exports = {
70 Graph: lib.Graph,
71 json: require("./lib/json"),
72 alg: require("./lib/alg"),
73 version: lib.version
74};
75
76},{"./lib":18,"./lib/alg":9,"./lib/json":19}],3:[function(require,module,exports){
77var _ = require("../lodash");
78
79module.exports = components;
80
81function components(g) {
82 var visited = {},
83 cmpts = [],
84 cmpt;
85
86 function dfs(v) {
87 if (_.has(visited, v)) return;
88 visited[v] = true;
89 cmpt.push(v);
90 _.each(g.successors(v), dfs);
91 _.each(g.predecessors(v), dfs);
92 }
93
94 _.each(g.nodes(), function(v) {
95 cmpt = [];
96 dfs(v);
97 if (cmpt.length) {
98 cmpts.push(cmpt);
99 }
100 });
101
102 return cmpts;
103}
104
105},{"../lodash":20}],4:[function(require,module,exports){
106var _ = require("../lodash");
107
108module.exports = dfs;
109
110/*
111 * A helper that preforms a pre- or post-order traversal on the input graph
112 * and returns the nodes in the order they were visited. This algorithm treats
113 * the input as undirected.
114 *
115 * Order must be one of "pre" or "post".
116 */
117function dfs(g, vs, order) {
118 if (!_.isArray(vs)) {
119 vs = [vs];
120 }
121
122 var acc = [],
123 visited = {};
124 _.each(vs, function(v) {
125 if (!g.hasNode(v)) {
126 throw new Error("Graph does not have node: " + v);
127 }
128
129 doDfs(g, v, order === "post", visited, acc);
130 });
131 return acc;
132}
133
134function doDfs(g, v, postorder, visited, acc) {
135 if (!_.has(visited, v)) {
136 visited[v] = true;
137
138 if (!postorder) { acc.push(v); }
139 _.each(g.neighbors(v), function(w) {
140 doDfs(g, w, postorder, visited, acc);
141 });
142 if (postorder) { acc.push(v); }
143 }
144}
145
146},{"../lodash":20}],5:[function(require,module,exports){
147var dijkstra = require("./dijkstra"),
148 _ = require("../lodash");
149
150module.exports = dijkstraAll;
151
152function dijkstraAll(g, weightFunc, edgeFunc) {
153 return _.transform(g.nodes(), function(acc, v) {
154 acc[v] = dijkstra(g, v, weightFunc, edgeFunc);
155 }, {});
156}
157
158},{"../lodash":20,"./dijkstra":6}],6:[function(require,module,exports){
159var _ = require("../lodash"),
160 PriorityQueue = require("../data/priority-queue");
161
162module.exports = dijkstra;
163
164var DEFAULT_WEIGHT_FUNC = _.constant(1);
165
166function dijkstra(g, source, weightFn, edgeFn) {
167 return runDijkstra(g, String(source),
168 weightFn || DEFAULT_WEIGHT_FUNC,
169 edgeFn || function(v) { return g.outEdges(v); });
170}
171
172function runDijkstra(g, source, weightFn, edgeFn) {
173 var results = {},
174 pq = new PriorityQueue(),
175 v, vEntry;
176
177 var updateNeighbors = function(edge) {
178 var w = edge.v !== v ? edge.v : edge.w,
179 wEntry = results[w],
180 weight = weightFn(edge),
181 distance = vEntry.distance + weight;
182
183 if (weight < 0) {
184 throw new Error("dijkstra does not allow negative edge weights. " +
185 "Bad edge: " + edge + " Weight: " + weight);
186 }
187
188 if (distance < wEntry.distance) {
189 wEntry.distance = distance;
190 wEntry.predecessor = v;
191 pq.decrease(w, distance);
192 }
193 };
194
195 g.nodes().forEach(function(v) {
196 var distance = v === source ? 0 : Number.POSITIVE_INFINITY;
197 results[v] = { distance: distance };
198 pq.add(v, distance);
199 });
200
201 while (pq.size() > 0) {
202 v = pq.removeMin();
203 vEntry = results[v];
204 if (vEntry.distance === Number.POSITIVE_INFINITY) {
205 break;
206 }
207
208 edgeFn(v).forEach(updateNeighbors);
209 }
210
211 return results;
212}
213
214},{"../data/priority-queue":16,"../lodash":20}],7:[function(require,module,exports){
215var _ = require("../lodash"),
216 tarjan = require("./tarjan");
217
218module.exports = findCycles;
219
220function findCycles(g) {
221 return _.filter(tarjan(g), function(cmpt) { return cmpt.length > 1; });
222}
223
224},{"../lodash":20,"./tarjan":14}],8:[function(require,module,exports){
225var _ = require("../lodash");
226
227module.exports = floydWarshall;
228
229var DEFAULT_WEIGHT_FUNC = _.constant(1);
230
231function floydWarshall(g, weightFn, edgeFn) {
232 return runFloydWarshall(g,
233 weightFn || DEFAULT_WEIGHT_FUNC,
234 edgeFn || function(v) { return g.outEdges(v); });
235}
236
237function runFloydWarshall(g, weightFn, edgeFn) {
238 var results = {},
239 nodes = g.nodes();
240
241 nodes.forEach(function(v) {
242 results[v] = {};
243 results[v][v] = { distance: 0 };
244 nodes.forEach(function(w) {
245 if (v !== w) {
246 results[v][w] = { distance: Number.POSITIVE_INFINITY };
247 }
248 });
249 edgeFn(v).forEach(function(edge) {
250 var w = edge.v === v ? edge.w : edge.v,
251 d = weightFn(edge);
252 results[v][w] = { distance: d, predecessor: v };
253 });
254 });
255
256 nodes.forEach(function(k) {
257 var rowK = results[k];
258 nodes.forEach(function(i) {
259 var rowI = results[i];
260 nodes.forEach(function(j) {
261 var ik = rowI[k];
262 var kj = rowK[j];
263 var ij = rowI[j];
264 var altDistance = ik.distance + kj.distance;
265 if (altDistance < ij.distance) {
266 ij.distance = altDistance;
267 ij.predecessor = kj.predecessor;
268 }
269 });
270 });
271 });
272
273 return results;
274}
275
276},{"../lodash":20}],9:[function(require,module,exports){
277module.exports = {
278 components: require("./components"),
279 dijkstra: require("./dijkstra"),
280 dijkstraAll: require("./dijkstra-all"),
281 findCycles: require("./find-cycles"),
282 floydWarshall: require("./floyd-warshall"),
283 isAcyclic: require("./is-acyclic"),
284 postorder: require("./postorder"),
285 preorder: require("./preorder"),
286 prim: require("./prim"),
287 tarjan: require("./tarjan"),
288 topsort: require("./topsort")
289};
290
291},{"./components":3,"./dijkstra":6,"./dijkstra-all":5,"./find-cycles":7,"./floyd-warshall":8,"./is-acyclic":10,"./postorder":11,"./preorder":12,"./prim":13,"./tarjan":14,"./topsort":15}],10:[function(require,module,exports){
292var topsort = require("./topsort");
293
294module.exports = isAcyclic;
295
296function isAcyclic(g) {
297 try {
298 topsort(g);
299 } catch (e) {
300 if (e instanceof topsort.CycleException) {
301 return false;
302 }
303 throw e;
304 }
305 return true;
306}
307
308},{"./topsort":15}],11:[function(require,module,exports){
309var dfs = require("./dfs");
310
311module.exports = postorder;
312
313function postorder(g, vs) {
314 return dfs(g, vs, "post");
315}
316
317},{"./dfs":4}],12:[function(require,module,exports){
318var dfs = require("./dfs");
319
320module.exports = preorder;
321
322function preorder(g, vs) {
323 return dfs(g, vs, "pre");
324}
325
326},{"./dfs":4}],13:[function(require,module,exports){
327var _ = require("../lodash"),
328 Graph = require("../graph"),
329 PriorityQueue = require("../data/priority-queue");
330
331module.exports = prim;
332
333function prim(g, weightFunc) {
334 var result = new Graph(),
335 parents = {},
336 pq = new PriorityQueue(),
337 v;
338
339 function updateNeighbors(edge) {
340 var w = edge.v === v ? edge.w : edge.v,
341 pri = pq.priority(w);
342 if (pri !== undefined) {
343 var edgeWeight = weightFunc(edge);
344 if (edgeWeight < pri) {
345 parents[w] = v;
346 pq.decrease(w, edgeWeight);
347 }
348 }
349 }
350
351 if (g.nodeCount() === 0) {
352 return result;
353 }
354
355 _.each(g.nodes(), function(v) {
356 pq.add(v, Number.POSITIVE_INFINITY);
357 result.setNode(v);
358 });
359
360 // Start from an arbitrary node
361 pq.decrease(g.nodes()[0], 0);
362
363 var init = false;
364 while (pq.size() > 0) {
365 v = pq.removeMin();
366 if (_.has(parents, v)) {
367 result.setEdge(v, parents[v]);
368 } else if (init) {
369 throw new Error("Input graph is not connected: " + g);
370 } else {
371 init = true;
372 }
373
374 g.nodeEdges(v).forEach(updateNeighbors);
375 }
376
377 return result;
378}
379
380},{"../data/priority-queue":16,"../graph":17,"../lodash":20}],14:[function(require,module,exports){
381var _ = require("../lodash");
382
383module.exports = tarjan;
384
385function tarjan(g) {
386 var index = 0,
387 stack = [],
388 visited = {}, // node id -> { onStack, lowlink, index }
389 results = [];
390
391 function dfs(v) {
392 var entry = visited[v] = {
393 onStack: true,
394 lowlink: index,
395 index: index++
396 };
397 stack.push(v);
398
399 g.successors(v).forEach(function(w) {
400 if (!_.has(visited, w)) {
401 dfs(w);
402 entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink);
403 } else if (visited[w].onStack) {
404 entry.lowlink = Math.min(entry.lowlink, visited[w].index);
405 }
406 });
407
408 if (entry.lowlink === entry.index) {
409 var cmpt = [],
410 w;
411 do {
412 w = stack.pop();
413 visited[w].onStack = false;
414 cmpt.push(w);
415 } while (v !== w);
416 results.push(cmpt);
417 }
418 }
419
420 g.nodes().forEach(function(v) {
421 if (!_.has(visited, v)) {
422 dfs(v);
423 }
424 });
425
426 return results;
427}
428
429},{"../lodash":20}],15:[function(require,module,exports){
430var _ = require("../lodash");
431
432module.exports = topsort;
433topsort.CycleException = CycleException;
434
435function topsort(g) {
436 var visited = {},
437 stack = {},
438 results = [];
439
440 function visit(node) {
441 if (_.has(stack, node)) {
442 throw new CycleException();
443 }
444
445 if (!_.has(visited, node)) {
446 stack[node] = true;
447 visited[node] = true;
448 _.each(g.predecessors(node), visit);
449 delete stack[node];
450 results.push(node);
451 }
452 }
453
454 _.each(g.sinks(), visit);
455
456 if (_.size(visited) !== g.nodeCount()) {
457 throw new CycleException();
458 }
459
460 return results;
461}
462
463function CycleException() {}
464
465},{"../lodash":20}],16:[function(require,module,exports){
466var _ = require("../lodash");
467
468module.exports = PriorityQueue;
469
470/**
471 * A min-priority queue data structure. This algorithm is derived from Cormen,
472 * et al., "Introduction to Algorithms". The basic idea of a min-priority
473 * queue is that you can efficiently (in O(1) time) get the smallest key in
474 * the queue. Adding and removing elements takes O(log n) time. A key can
475 * have its priority decreased in O(log n) time.
476 */
477function PriorityQueue() {
478 this._arr = [];
479 this._keyIndices = {};
480}
481
482/**
483 * Returns the number of elements in the queue. Takes `O(1)` time.
484 */
485PriorityQueue.prototype.size = function() {
486 return this._arr.length;
487};
488
489/**
490 * Returns the keys that are in the queue. Takes `O(n)` time.
491 */
492PriorityQueue.prototype.keys = function() {
493 return this._arr.map(function(x) { return x.key; });
494};
495
496/**
497 * Returns `true` if **key** is in the queue and `false` if not.
498 */
499PriorityQueue.prototype.has = function(key) {
500 return _.has(this._keyIndices, key);
501};
502
503/**
504 * Returns the priority for **key**. If **key** is not present in the queue
505 * then this function returns `undefined`. Takes `O(1)` time.
506 *
507 * @param {Object} key
508 */
509PriorityQueue.prototype.priority = function(key) {
510 var index = this._keyIndices[key];
511 if (index !== undefined) {
512 return this._arr[index].priority;
513 }
514};
515
516/**
517 * Returns the key for the minimum element in this queue. If the queue is
518 * empty this function throws an Error. Takes `O(1)` time.
519 */
520PriorityQueue.prototype.min = function() {
521 if (this.size() === 0) {
522 throw new Error("Queue underflow");
523 }
524 return this._arr[0].key;
525};
526
527/**
528 * Inserts a new key into the priority queue. If the key already exists in
529 * the queue this function returns `false`; otherwise it will return `true`.
530 * Takes `O(n)` time.
531 *
532 * @param {Object} key the key to add
533 * @param {Number} priority the initial priority for the key
534 */
535PriorityQueue.prototype.add = function(key, priority) {
536 var keyIndices = this._keyIndices;
537 key = String(key);
538 if (!_.has(keyIndices, key)) {
539 var arr = this._arr;
540 var index = arr.length;
541 keyIndices[key] = index;
542 arr.push({key: key, priority: priority});
543 this._decrease(index);
544 return true;
545 }
546 return false;
547};
548
549/**
550 * Removes and returns the smallest key in the queue. Takes `O(log n)` time.
551 */
552PriorityQueue.prototype.removeMin = function() {
553 this._swap(0, this._arr.length - 1);
554 var min = this._arr.pop();
555 delete this._keyIndices[min.key];
556 this._heapify(0);
557 return min.key;
558};
559
560/**
561 * Decreases the priority for **key** to **priority**. If the new priority is
562 * greater than the previous priority, this function will throw an Error.
563 *
564 * @param {Object} key the key for which to raise priority
565 * @param {Number} priority the new priority for the key
566 */
567PriorityQueue.prototype.decrease = function(key, priority) {
568 var index = this._keyIndices[key];
569 if (priority > this._arr[index].priority) {
570 throw new Error("New priority is greater than current priority. " +
571 "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority);
572 }
573 this._arr[index].priority = priority;
574 this._decrease(index);
575};
576
577PriorityQueue.prototype._heapify = function(i) {
578 var arr = this._arr;
579 var l = 2 * i,
580 r = l + 1,
581 largest = i;
582 if (l < arr.length) {
583 largest = arr[l].priority < arr[largest].priority ? l : largest;
584 if (r < arr.length) {
585 largest = arr[r].priority < arr[largest].priority ? r : largest;
586 }
587 if (largest !== i) {
588 this._swap(i, largest);
589 this._heapify(largest);
590 }
591 }
592};
593
594PriorityQueue.prototype._decrease = function(index) {
595 var arr = this._arr;
596 var priority = arr[index].priority;
597 var parent;
598 while (index !== 0) {
599 parent = index >> 1;
600 if (arr[parent].priority < priority) {
601 break;
602 }
603 this._swap(index, parent);
604 index = parent;
605 }
606};
607
608PriorityQueue.prototype._swap = function(i, j) {
609 var arr = this._arr;
610 var keyIndices = this._keyIndices;
611 var origArrI = arr[i];
612 var origArrJ = arr[j];
613 arr[i] = origArrJ;
614 arr[j] = origArrI;
615 keyIndices[origArrJ.key] = i;
616 keyIndices[origArrI.key] = j;
617};
618
619},{"../lodash":20}],17:[function(require,module,exports){
620"use strict";
621
622var _ = require("./lodash");
623
624module.exports = Graph;
625
626var DEFAULT_EDGE_NAME = "\x00",
627 GRAPH_NODE = "\x00",
628 EDGE_KEY_DELIM = "\x01";
629
630// Implementation notes:
631//
632// * Node id query functions should return string ids for the nodes
633// * Edge id query functions should return an "edgeObj", edge object, that is
634// composed of enough information to uniquely identify an edge: {v, w, name}.
635// * Internally we use an "edgeId", a stringified form of the edgeObj, to
636// reference edges. This is because we need a performant way to look these
637// edges up and, object properties, which have string keys, are the closest
638// we're going to get to a performant hashtable in JavaScript.
639
640function Graph(opts) {
641 this._isDirected = _.has(opts, "directed") ? opts.directed : true;
642 this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false;
643 this._isCompound = _.has(opts, "compound") ? opts.compound : false;
644
645 // Label for the graph itself
646 this._label = undefined;
647
648 // Defaults to be set when creating a new node
649 this._defaultNodeLabelFn = _.constant(undefined);
650
651 // Defaults to be set when creating a new edge
652 this._defaultEdgeLabelFn = _.constant(undefined);
653
654 // v -> label
655 this._nodes = {};
656
657 if (this._isCompound) {
658 // v -> parent
659 this._parent = {};
660
661 // v -> children
662 this._children = {};
663 this._children[GRAPH_NODE] = {};
664 }
665
666 // v -> edgeObj
667 this._in = {};
668
669 // u -> v -> Number
670 this._preds = {};
671
672 // v -> edgeObj
673 this._out = {};
674
675 // v -> w -> Number
676 this._sucs = {};
677
678 // e -> edgeObj
679 this._edgeObjs = {};
680
681 // e -> label
682 this._edgeLabels = {};
683}
684
685/* Number of nodes in the graph. Should only be changed by the implementation. */
686Graph.prototype._nodeCount = 0;
687
688/* Number of edges in the graph. Should only be changed by the implementation. */
689Graph.prototype._edgeCount = 0;
690
691
692/* === Graph functions ========= */
693
694Graph.prototype.isDirected = function() {
695 return this._isDirected;
696};
697
698Graph.prototype.isMultigraph = function() {
699 return this._isMultigraph;
700};
701
702Graph.prototype.isCompound = function() {
703 return this._isCompound;
704};
705
706Graph.prototype.setGraph = function(label) {
707 this._label = label;
708 return this;
709};
710
711Graph.prototype.graph = function() {
712 return this._label;
713};
714
715
716/* === Node functions ========== */
717
718Graph.prototype.setDefaultNodeLabel = function(newDefault) {
719 if (!_.isFunction(newDefault)) {
720 newDefault = _.constant(newDefault);
721 }
722 this._defaultNodeLabelFn = newDefault;
723 return this;
724};
725
726Graph.prototype.nodeCount = function() {
727 return this._nodeCount;
728};
729
730Graph.prototype.nodes = function() {
731 return _.keys(this._nodes);
732};
733
734Graph.prototype.sources = function() {
735 return _.filter(this.nodes(), function(v) {
736 return _.isEmpty(this._in[v]);
737 }, this);
738};
739
740Graph.prototype.sinks = function() {
741 return _.filter(this.nodes(), function(v) {
742 return _.isEmpty(this._out[v]);
743 }, this);
744};
745
746Graph.prototype.setNodes = function(vs, value) {
747 var args = arguments;
748 _.each(vs, function(v) {
749 if (args.length > 1) {
750 this.setNode(v, value);
751 } else {
752 this.setNode(v);
753 }
754 }, this);
755 return this;
756};
757
758Graph.prototype.setNode = function(v, value) {
759 if (_.has(this._nodes, v)) {
760 if (arguments.length > 1) {
761 this._nodes[v] = value;
762 }
763 return this;
764 }
765
766 this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v);
767 if (this._isCompound) {
768 this._parent[v] = GRAPH_NODE;
769 this._children[v] = {};
770 this._children[GRAPH_NODE][v] = true;
771 }
772 this._in[v] = {};
773 this._preds[v] = {};
774 this._out[v] = {};
775 this._sucs[v] = {};
776 ++this._nodeCount;
777 return this;
778};
779
780Graph.prototype.node = function(v) {
781 return this._nodes[v];
782};
783
784Graph.prototype.hasNode = function(v) {
785 return _.has(this._nodes, v);
786};
787
788Graph.prototype.removeNode = function(v) {
789 var self = this;
790 if (_.has(this._nodes, v)) {
791 var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); };
792 delete this._nodes[v];
793 if (this._isCompound) {
794 this._removeFromParentsChildList(v);
795 delete this._parent[v];
796 _.each(this.children(v), function(child) {
797 this.setParent(child);
798 }, this);
799 delete this._children[v];
800 }
801 _.each(_.keys(this._in[v]), removeEdge);
802 delete this._in[v];
803 delete this._preds[v];
804 _.each(_.keys(this._out[v]), removeEdge);
805 delete this._out[v];
806 delete this._sucs[v];
807 --this._nodeCount;
808 }
809 return this;
810};
811
812Graph.prototype.setParent = function(v, parent) {
813 if (!this._isCompound) {
814 throw new Error("Cannot set parent in a non-compound graph");
815 }
816
817 if (_.isUndefined(parent)) {
818 parent = GRAPH_NODE;
819 } else {
820 // Coerce parent to string
821 parent += "";
822 for (var ancestor = parent;
823 !_.isUndefined(ancestor);
824 ancestor = this.parent(ancestor)) {
825 if (ancestor === v) {
826 throw new Error("Setting " + parent+ " as parent of " + v +
827 " would create create a cycle");
828 }
829 }
830
831 this.setNode(parent);
832 }
833
834 this.setNode(v);
835 this._removeFromParentsChildList(v);
836 this._parent[v] = parent;
837 this._children[parent][v] = true;
838 return this;
839};
840
841Graph.prototype._removeFromParentsChildList = function(v) {
842 delete this._children[this._parent[v]][v];
843};
844
845Graph.prototype.parent = function(v) {
846 if (this._isCompound) {
847 var parent = this._parent[v];
848 if (parent !== GRAPH_NODE) {
849 return parent;
850 }
851 }
852};
853
854Graph.prototype.children = function(v) {
855 if (_.isUndefined(v)) {
856 v = GRAPH_NODE;
857 }
858
859 if (this._isCompound) {
860 var children = this._children[v];
861 if (children) {
862 return _.keys(children);
863 }
864 } else if (v === GRAPH_NODE) {
865 return this.nodes();
866 } else if (this.hasNode(v)) {
867 return [];
868 }
869};
870
871Graph.prototype.predecessors = function(v) {
872 var predsV = this._preds[v];
873 if (predsV) {
874 return _.keys(predsV);
875 }
876};
877
878Graph.prototype.successors = function(v) {
879 var sucsV = this._sucs[v];
880 if (sucsV) {
881 return _.keys(sucsV);
882 }
883};
884
885Graph.prototype.neighbors = function(v) {
886 var preds = this.predecessors(v);
887 if (preds) {
888 return _.union(preds, this.successors(v));
889 }
890};
891
892/* === Edge functions ========== */
893
894Graph.prototype.setDefaultEdgeLabel = function(newDefault) {
895 if (!_.isFunction(newDefault)) {
896 newDefault = _.constant(newDefault);
897 }
898 this._defaultEdgeLabelFn = newDefault;
899 return this;
900};
901
902Graph.prototype.edgeCount = function() {
903 return this._edgeCount;
904};
905
906Graph.prototype.edges = function() {
907 return _.values(this._edgeObjs);
908};
909
910Graph.prototype.setPath = function(vs, value) {
911 var self = this,
912 args = arguments;
913 _.reduce(vs, function(v, w) {
914 if (args.length > 1) {
915 self.setEdge(v, w, value);
916 } else {
917 self.setEdge(v, w);
918 }
919 return w;
920 });
921 return this;
922};
923
924/*
925 * setEdge(v, w, [value, [name]])
926 * setEdge({ v, w, [name] }, [value])
927 */
928Graph.prototype.setEdge = function() {
929 var v, w, name, value,
930 valueSpecified = false;
931
932 if (_.isPlainObject(arguments[0])) {
933 v = arguments[0].v;
934 w = arguments[0].w;
935 name = arguments[0].name;
936 if (arguments.length === 2) {
937 value = arguments[1];
938 valueSpecified = true;
939 }
940 } else {
941 v = arguments[0];
942 w = arguments[1];
943 name = arguments[3];
944 if (arguments.length > 2) {
945 value = arguments[2];
946 valueSpecified = true;
947 }
948 }
949
950 v = "" + v;
951 w = "" + w;
952 if (!_.isUndefined(name)) {
953 name = "" + name;
954 }
955
956 var e = edgeArgsToId(this._isDirected, v, w, name);
957 if (_.has(this._edgeLabels, e)) {
958 if (valueSpecified) {
959 this._edgeLabels[e] = value;
960 }
961 return this;
962 }
963
964 if (!_.isUndefined(name) && !this._isMultigraph) {
965 throw new Error("Cannot set a named edge when isMultigraph = false");
966 }
967
968 // It didn't exist, so we need to create it.
969 // First ensure the nodes exist.
970 this.setNode(v);
971 this.setNode(w);
972
973 this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name);
974
975 var edgeObj = edgeArgsToObj(this._isDirected, v, w, name);
976 // Ensure we add undirected edges in a consistent way.
977 v = edgeObj.v;
978 w = edgeObj.w;
979
980 Object.freeze(edgeObj);
981 this._edgeObjs[e] = edgeObj;
982 incrementOrInitEntry(this._preds[w], v);
983 incrementOrInitEntry(this._sucs[v], w);
984 this._in[w][e] = edgeObj;
985 this._out[v][e] = edgeObj;
986 this._edgeCount++;
987 return this;
988};
989
990Graph.prototype.edge = function(v, w, name) {
991 var e = (arguments.length === 1
992 ? edgeObjToId(this._isDirected, arguments[0])
993 : edgeArgsToId(this._isDirected, v, w, name));
994 return this._edgeLabels[e];
995};
996
997Graph.prototype.hasEdge = function(v, w, name) {
998 var e = (arguments.length === 1
999 ? edgeObjToId(this._isDirected, arguments[0])
1000 : edgeArgsToId(this._isDirected, v, w, name));
1001 return _.has(this._edgeLabels, e);
1002};
1003
1004Graph.prototype.removeEdge = function(v, w, name) {
1005 var e = (arguments.length === 1
1006 ? edgeObjToId(this._isDirected, arguments[0])
1007 : edgeArgsToId(this._isDirected, v, w, name)),
1008 edge = this._edgeObjs[e];
1009 if (edge) {
1010 v = edge.v;
1011 w = edge.w;
1012 delete this._edgeLabels[e];
1013 delete this._edgeObjs[e];
1014 decrementOrRemoveEntry(this._preds[w], v);
1015 decrementOrRemoveEntry(this._sucs[v], w);
1016 delete this._in[w][e];
1017 delete this._out[v][e];
1018 this._edgeCount--;
1019 }
1020 return this;
1021};
1022
1023Graph.prototype.inEdges = function(v, u) {
1024 var inV = this._in[v];
1025 if (inV) {
1026 var edges = _.values(inV);
1027 if (!u) {
1028 return edges;
1029 }
1030 return _.filter(edges, function(edge) { return edge.v === u; });
1031 }
1032};
1033
1034Graph.prototype.outEdges = function(v, w) {
1035 var outV = this._out[v];
1036 if (outV) {
1037 var edges = _.values(outV);
1038 if (!w) {
1039 return edges;
1040 }
1041 return _.filter(edges, function(edge) { return edge.w === w; });
1042 }
1043};
1044
1045Graph.prototype.nodeEdges = function(v, w) {
1046 var inEdges = this.inEdges(v, w);
1047 if (inEdges) {
1048 return inEdges.concat(this.outEdges(v, w));
1049 }
1050};
1051
1052function incrementOrInitEntry(map, k) {
1053 if (_.has(map, k)) {
1054 map[k]++;
1055 } else {
1056 map[k] = 1;
1057 }
1058}
1059
1060function decrementOrRemoveEntry(map, k) {
1061 if (!--map[k]) { delete map[k]; }
1062}
1063
1064function edgeArgsToId(isDirected, v, w, name) {
1065 if (!isDirected && v > w) {
1066 var tmp = v;
1067 v = w;
1068 w = tmp;
1069 }
1070 return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM +
1071 (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name);
1072}
1073
1074function edgeArgsToObj(isDirected, v, w, name) {
1075 if (!isDirected && v > w) {
1076 var tmp = v;
1077 v = w;
1078 w = tmp;
1079 }
1080 var edgeObj = { v: v, w: w };
1081 if (name) {
1082 edgeObj.name = name;
1083 }
1084 return edgeObj;
1085}
1086
1087function edgeObjToId(isDirected, edgeObj) {
1088 return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);
1089}
1090
1091},{"./lodash":20}],18:[function(require,module,exports){
1092// Includes only the "core" of graphlib
1093module.exports = {
1094 Graph: require("./graph"),
1095 version: require("./version")
1096};
1097
1098},{"./graph":17,"./version":21}],19:[function(require,module,exports){
1099var _ = require("./lodash"),
1100 Graph = require("./graph");
1101
1102module.exports = {
1103 write: write,
1104 read: read
1105};
1106
1107function write(g) {
1108 var json = {
1109 options: {
1110 directed: g.isDirected(),
1111 multigraph: g.isMultigraph(),
1112 compound: g.isCompound()
1113 },
1114 nodes: writeNodes(g),
1115 edges: writeEdges(g)
1116 };
1117 if (!_.isUndefined(g.graph())) {
1118 json.value = _.clone(g.graph());
1119 }
1120 return json;
1121}
1122
1123function writeNodes(g) {
1124 return _.map(g.nodes(), function(v) {
1125 var nodeValue = g.node(v),
1126 parent = g.parent(v),
1127 node = { v: v };
1128 if (!_.isUndefined(nodeValue)) {
1129 node.value = nodeValue;
1130 }
1131 if (!_.isUndefined(parent)) {
1132 node.parent = parent;
1133 }
1134 return node;
1135 });
1136}
1137
1138function writeEdges(g) {
1139 return _.map(g.edges(), function(e) {
1140 var edgeValue = g.edge(e),
1141 edge = { v: e.v, w: e.w };
1142 if (!_.isUndefined(e.name)) {
1143 edge.name = e.name;
1144 }
1145 if (!_.isUndefined(edgeValue)) {
1146 edge.value = edgeValue;
1147 }
1148 return edge;
1149 });
1150}
1151
1152function read(json) {
1153 var g = new Graph(json.options).setGraph(json.value);
1154 _.each(json.nodes, function(entry) {
1155 g.setNode(entry.v, entry.value);
1156 if (entry.parent) {
1157 g.setParent(entry.v, entry.parent);
1158 }
1159 });
1160 _.each(json.edges, function(entry) {
1161 g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value);
1162 });
1163 return g;
1164}
1165
1166},{"./graph":17,"./lodash":20}],20:[function(require,module,exports){
1167/* global window */
1168
1169var lodash;
1170
1171if (typeof require === "function") {
1172 try {
1173 lodash = require("lodash");
1174 } catch (e) {}
1175}
1176
1177if (!lodash) {
1178 lodash = window._;
1179}
1180
1181module.exports = lodash;
1182
1183},{"lodash":22}],21:[function(require,module,exports){
1184module.exports = '1.0.2';
1185
1186},{}],22:[function(require,module,exports){
1187(function (global){
1188/**
1189 * @license
1190 * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
1191 * Build: `lodash modern -o ./dist/lodash.js`
1192 * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
1193 * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
1194 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
1195 * Available under MIT license <http://lodash.com/license>
1196 */
1197;(function() {
1198
1199 /** Used as a safe reference for `undefined` in pre ES5 environments */
1200 var undefined;
1201
1202 /** Used to pool arrays and objects used internally */
1203 var arrayPool = [],
1204 objectPool = [];
1205
1206 /** Used to generate unique IDs */
1207 var idCounter = 0;
1208
1209 /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
1210 var keyPrefix = +new Date + '';
1211
1212 /** Used as the size when optimizations are enabled for large arrays */
1213 var largeArraySize = 75;
1214
1215 /** Used as the max size of the `arrayPool` and `objectPool` */
1216 var maxPoolSize = 40;
1217
1218 /** Used to detect and test whitespace */
1219 var whitespace = (
1220 // whitespace
1221 ' \t\x0B\f\xA0\ufeff' +
1222
1223 // line terminators
1224 '\n\r\u2028\u2029' +
1225
1226 // unicode category "Zs" space separators
1227 '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
1228 );
1229
1230 /** Used to match empty string literals in compiled template source */
1231 var reEmptyStringLeading = /\b__p \+= '';/g,
1232 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
1233 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
1234
1235 /**
1236 * Used to match ES6 template delimiters
1237 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
1238 */
1239 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
1240
1241 /** Used to match regexp flags from their coerced string values */
1242 var reFlags = /\w*$/;
1243
1244 /** Used to detected named functions */
1245 var reFuncName = /^\s*function[ \n\r\t]+\w/;
1246
1247 /** Used to match "interpolate" template delimiters */
1248 var reInterpolate = /<%=([\s\S]+?)%>/g;
1249
1250 /** Used to match leading whitespace and zeros to be removed */
1251 var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
1252
1253 /** Used to ensure capturing order of template delimiters */
1254 var reNoMatch = /($^)/;
1255
1256 /** Used to detect functions containing a `this` reference */
1257 var reThis = /\bthis\b/;
1258
1259 /** Used to match unescaped characters in compiled string literals */
1260 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
1261
1262 /** Used to assign default `context` object properties */
1263 var contextProps = [
1264 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
1265 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
1266 'parseInt', 'setTimeout'
1267 ];
1268
1269 /** Used to make template sourceURLs easier to identify */
1270 var templateCounter = 0;
1271
1272 /** `Object#toString` result shortcuts */
1273 var argsClass = '[object Arguments]',
1274 arrayClass = '[object Array]',
1275 boolClass = '[object Boolean]',
1276 dateClass = '[object Date]',
1277 funcClass = '[object Function]',
1278 numberClass = '[object Number]',
1279 objectClass = '[object Object]',
1280 regexpClass = '[object RegExp]',
1281 stringClass = '[object String]';
1282
1283 /** Used to identify object classifications that `_.clone` supports */
1284 var cloneableClasses = {};
1285 cloneableClasses[funcClass] = false;
1286 cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
1287 cloneableClasses[boolClass] = cloneableClasses[dateClass] =
1288 cloneableClasses[numberClass] = cloneableClasses[objectClass] =
1289 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
1290
1291 /** Used as an internal `_.debounce` options object */
1292 var debounceOptions = {
1293 'leading': false,
1294 'maxWait': 0,
1295 'trailing': false
1296 };
1297
1298 /** Used as the property descriptor for `__bindData__` */
1299 var descriptor = {
1300 'configurable': false,
1301 'enumerable': false,
1302 'value': null,
1303 'writable': false
1304 };
1305
1306 /** Used to determine if values are of the language type Object */
1307 var objectTypes = {
1308 'boolean': false,
1309 'function': true,
1310 'object': true,
1311 'number': false,
1312 'string': false,
1313 'undefined': false
1314 };
1315
1316 /** Used to escape characters for inclusion in compiled string literals */
1317 var stringEscapes = {
1318 '\\': '\\',
1319 "'": "'",
1320 '\n': 'n',
1321 '\r': 'r',
1322 '\t': 't',
1323 '\u2028': 'u2028',
1324 '\u2029': 'u2029'
1325 };
1326
1327 /** Used as a reference to the global object */
1328 var root = (objectTypes[typeof window] && window) || this;
1329
1330 /** Detect free variable `exports` */
1331 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
1332
1333 /** Detect free variable `module` */
1334 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
1335
1336 /** Detect the popular CommonJS extension `module.exports` */
1337 var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
1338
1339 /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
1340 var freeGlobal = objectTypes[typeof global] && global;
1341 if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
1342 root = freeGlobal;
1343 }
1344
1345 /*--------------------------------------------------------------------------*/
1346
1347 /**
1348 * The base implementation of `_.indexOf` without support for binary searches
1349 * or `fromIndex` constraints.
1350 *
1351 * @private
1352 * @param {Array} array The array to search.
1353 * @param {*} value The value to search for.
1354 * @param {number} [fromIndex=0] The index to search from.
1355 * @returns {number} Returns the index of the matched value or `-1`.
1356 */
1357 function baseIndexOf(array, value, fromIndex) {
1358 var index = (fromIndex || 0) - 1,
1359 length = array ? array.length : 0;
1360
1361 while (++index < length) {
1362 if (array[index] === value) {
1363 return index;
1364 }
1365 }
1366 return -1;
1367 }
1368
1369 /**
1370 * An implementation of `_.contains` for cache objects that mimics the return
1371 * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
1372 *
1373 * @private
1374 * @param {Object} cache The cache object to inspect.
1375 * @param {*} value The value to search for.
1376 * @returns {number} Returns `0` if `value` is found, else `-1`.
1377 */
1378 function cacheIndexOf(cache, value) {
1379 var type = typeof value;
1380 cache = cache.cache;
1381
1382 if (type == 'boolean' || value == null) {
1383 return cache[value] ? 0 : -1;
1384 }
1385 if (type != 'number' && type != 'string') {
1386 type = 'object';
1387 }
1388 var key = type == 'number' ? value : keyPrefix + value;
1389 cache = (cache = cache[type]) && cache[key];
1390
1391 return type == 'object'
1392 ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
1393 : (cache ? 0 : -1);
1394 }
1395
1396 /**
1397 * Adds a given value to the corresponding cache object.
1398 *
1399 * @private
1400 * @param {*} value The value to add to the cache.
1401 */
1402 function cachePush(value) {
1403 var cache = this.cache,
1404 type = typeof value;
1405
1406 if (type == 'boolean' || value == null) {
1407 cache[value] = true;
1408 } else {
1409 if (type != 'number' && type != 'string') {
1410 type = 'object';
1411 }
1412 var key = type == 'number' ? value : keyPrefix + value,
1413 typeCache = cache[type] || (cache[type] = {});
1414
1415 if (type == 'object') {
1416 (typeCache[key] || (typeCache[key] = [])).push(value);
1417 } else {
1418 typeCache[key] = true;
1419 }
1420 }
1421 }
1422
1423 /**
1424 * Used by `_.max` and `_.min` as the default callback when a given
1425 * collection is a string value.
1426 *
1427 * @private
1428 * @param {string} value The character to inspect.
1429 * @returns {number} Returns the code unit of given character.
1430 */
1431 function charAtCallback(value) {
1432 return value.charCodeAt(0);
1433 }
1434
1435 /**
1436 * Used by `sortBy` to compare transformed `collection` elements, stable sorting
1437 * them in ascending order.
1438 *
1439 * @private
1440 * @param {Object} a The object to compare to `b`.
1441 * @param {Object} b The object to compare to `a`.
1442 * @returns {number} Returns the sort order indicator of `1` or `-1`.
1443 */
1444 function compareAscending(a, b) {
1445 var ac = a.criteria,
1446 bc = b.criteria,
1447 index = -1,
1448 length = ac.length;
1449
1450 while (++index < length) {
1451 var value = ac[index],
1452 other = bc[index];
1453
1454 if (value !== other) {
1455 if (value > other || typeof value == 'undefined') {
1456 return 1;
1457 }
1458 if (value < other || typeof other == 'undefined') {
1459 return -1;
1460 }
1461 }
1462 }
1463 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
1464 // that causes it, under certain circumstances, to return the same value for
1465 // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
1466 //
1467 // This also ensures a stable sort in V8 and other engines.
1468 // See http://code.google.com/p/v8/issues/detail?id=90
1469 return a.index - b.index;
1470 }
1471
1472 /**
1473 * Creates a cache object to optimize linear searches of large arrays.
1474 *
1475 * @private
1476 * @param {Array} [array=[]] The array to search.
1477 * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
1478 */
1479 function createCache(array) {
1480 var index = -1,
1481 length = array.length,
1482 first = array[0],
1483 mid = array[(length / 2) | 0],
1484 last = array[length - 1];
1485
1486 if (first && typeof first == 'object' &&
1487 mid && typeof mid == 'object' && last && typeof last == 'object') {
1488 return false;
1489 }
1490 var cache = getObject();
1491 cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
1492
1493 var result = getObject();
1494 result.array = array;
1495 result.cache = cache;
1496 result.push = cachePush;
1497
1498 while (++index < length) {
1499 result.push(array[index]);
1500 }
1501 return result;
1502 }
1503
1504 /**
1505 * Used by `template` to escape characters for inclusion in compiled
1506 * string literals.
1507 *
1508 * @private
1509 * @param {string} match The matched character to escape.
1510 * @returns {string} Returns the escaped character.
1511 */
1512 function escapeStringChar(match) {
1513 return '\\' + stringEscapes[match];
1514 }
1515
1516 /**
1517 * Gets an array from the array pool or creates a new one if the pool is empty.
1518 *
1519 * @private
1520 * @returns {Array} The array from the pool.
1521 */
1522 function getArray() {
1523 return arrayPool.pop() || [];
1524 }
1525
1526 /**
1527 * Gets an object from the object pool or creates a new one if the pool is empty.
1528 *
1529 * @private
1530 * @returns {Object} The object from the pool.
1531 */
1532 function getObject() {
1533 return objectPool.pop() || {
1534 'array': null,
1535 'cache': null,
1536 'criteria': null,
1537 'false': false,
1538 'index': 0,
1539 'null': false,
1540 'number': null,
1541 'object': null,
1542 'push': null,
1543 'string': null,
1544 'true': false,
1545 'undefined': false,
1546 'value': null
1547 };
1548 }
1549
1550 /**
1551 * Releases the given array back to the array pool.
1552 *
1553 * @private
1554 * @param {Array} [array] The array to release.
1555 */
1556 function releaseArray(array) {
1557 array.length = 0;
1558 if (arrayPool.length < maxPoolSize) {
1559 arrayPool.push(array);
1560 }
1561 }
1562
1563 /**
1564 * Releases the given object back to the object pool.
1565 *
1566 * @private
1567 * @param {Object} [object] The object to release.
1568 */
1569 function releaseObject(object) {
1570 var cache = object.cache;
1571 if (cache) {
1572 releaseObject(cache);
1573 }
1574 object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
1575 if (objectPool.length < maxPoolSize) {
1576 objectPool.push(object);
1577 }
1578 }
1579
1580 /**
1581 * Slices the `collection` from the `start` index up to, but not including,
1582 * the `end` index.
1583 *
1584 * Note: This function is used instead of `Array#slice` to support node lists
1585 * in IE < 9 and to ensure dense arrays are returned.
1586 *
1587 * @private
1588 * @param {Array|Object|string} collection The collection to slice.
1589 * @param {number} start The start index.
1590 * @param {number} end The end index.
1591 * @returns {Array} Returns the new array.
1592 */
1593 function slice(array, start, end) {
1594 start || (start = 0);
1595 if (typeof end == 'undefined') {
1596 end = array ? array.length : 0;
1597 }
1598 var index = -1,
1599 length = end - start || 0,
1600 result = Array(length < 0 ? 0 : length);
1601
1602 while (++index < length) {
1603 result[index] = array[start + index];
1604 }
1605 return result;
1606 }
1607
1608 /*--------------------------------------------------------------------------*/
1609
1610 /**
1611 * Create a new `lodash` function using the given context object.
1612 *
1613 * @static
1614 * @memberOf _
1615 * @category Utilities
1616 * @param {Object} [context=root] The context object.
1617 * @returns {Function} Returns the `lodash` function.
1618 */
1619 function runInContext(context) {
1620 // Avoid issues with some ES3 environments that attempt to use values, named
1621 // after built-in constructors like `Object`, for the creation of literals.
1622 // ES5 clears this up by stating that literals must use built-in constructors.
1623 // See http://es5.github.io/#x11.1.5.
1624 context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
1625
1626 /** Native constructor references */
1627 var Array = context.Array,
1628 Boolean = context.Boolean,
1629 Date = context.Date,
1630 Function = context.Function,
1631 Math = context.Math,
1632 Number = context.Number,
1633 Object = context.Object,
1634 RegExp = context.RegExp,
1635 String = context.String,
1636 TypeError = context.TypeError;
1637
1638 /**
1639 * Used for `Array` method references.
1640 *
1641 * Normally `Array.prototype` would suffice, however, using an array literal
1642 * avoids issues in Narwhal.
1643 */
1644 var arrayRef = [];
1645
1646 /** Used for native method references */
1647 var objectProto = Object.prototype;
1648
1649 /** Used to restore the original `_` reference in `noConflict` */
1650 var oldDash = context._;
1651
1652 /** Used to resolve the internal [[Class]] of values */
1653 var toString = objectProto.toString;
1654
1655 /** Used to detect if a method is native */
1656 var reNative = RegExp('^' +
1657 String(toString)
1658 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
1659 .replace(/toString| for [^\]]+/g, '.*?') + '$'
1660 );
1661
1662 /** Native method shortcuts */
1663 var ceil = Math.ceil,
1664 clearTimeout = context.clearTimeout,
1665 floor = Math.floor,
1666 fnToString = Function.prototype.toString,
1667 getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
1668 hasOwnProperty = objectProto.hasOwnProperty,
1669 push = arrayRef.push,
1670 setTimeout = context.setTimeout,
1671 splice = arrayRef.splice,
1672 unshift = arrayRef.unshift;
1673
1674 /** Used to set meta data on functions */
1675 var defineProperty = (function() {
1676 // IE 8 only accepts DOM elements
1677 try {
1678 var o = {},
1679 func = isNative(func = Object.defineProperty) && func,
1680 result = func(o, o, o) && func;
1681 } catch(e) { }
1682 return result;
1683 }());
1684
1685 /* Native method shortcuts for methods with the same name as other `lodash` methods */
1686 var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
1687 nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
1688 nativeIsFinite = context.isFinite,
1689 nativeIsNaN = context.isNaN,
1690 nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
1691 nativeMax = Math.max,
1692 nativeMin = Math.min,
1693 nativeParseInt = context.parseInt,
1694 nativeRandom = Math.random;
1695
1696 /** Used to lookup a built-in constructor by [[Class]] */
1697 var ctorByClass = {};
1698 ctorByClass[arrayClass] = Array;
1699 ctorByClass[boolClass] = Boolean;
1700 ctorByClass[dateClass] = Date;
1701 ctorByClass[funcClass] = Function;
1702 ctorByClass[objectClass] = Object;
1703 ctorByClass[numberClass] = Number;
1704 ctorByClass[regexpClass] = RegExp;
1705 ctorByClass[stringClass] = String;
1706
1707 /*--------------------------------------------------------------------------*/
1708
1709 /**
1710 * Creates a `lodash` object which wraps the given value to enable intuitive
1711 * method chaining.
1712 *
1713 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
1714 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
1715 * and `unshift`
1716 *
1717 * Chaining is supported in custom builds as long as the `value` method is
1718 * implicitly or explicitly included in the build.
1719 *
1720 * The chainable wrapper functions are:
1721 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
1722 * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
1723 * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
1724 * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
1725 * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
1726 * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
1727 * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
1728 * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
1729 * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
1730 * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
1731 * and `zip`
1732 *
1733 * The non-chainable wrapper functions are:
1734 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
1735 * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
1736 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
1737 * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
1738 * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
1739 * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
1740 * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
1741 * `template`, `unescape`, `uniqueId`, and `value`
1742 *
1743 * The wrapper functions `first` and `last` return wrapped values when `n` is
1744 * provided, otherwise they return unwrapped values.
1745 *
1746 * Explicit chaining can be enabled by using the `_.chain` method.
1747 *
1748 * @name _
1749 * @constructor
1750 * @category Chaining
1751 * @param {*} value The value to wrap in a `lodash` instance.
1752 * @returns {Object} Returns a `lodash` instance.
1753 * @example
1754 *
1755 * var wrapped = _([1, 2, 3]);
1756 *
1757 * // returns an unwrapped value
1758 * wrapped.reduce(function(sum, num) {
1759 * return sum + num;
1760 * });
1761 * // => 6
1762 *
1763 * // returns a wrapped value
1764 * var squares = wrapped.map(function(num) {
1765 * return num * num;
1766 * });
1767 *
1768 * _.isArray(squares);
1769 * // => false
1770 *
1771 * _.isArray(squares.value());
1772 * // => true
1773 */
1774 function lodash(value) {
1775 // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
1776 return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
1777 ? value
1778 : new lodashWrapper(value);
1779 }
1780
1781 /**
1782 * A fast path for creating `lodash` wrapper objects.
1783 *
1784 * @private
1785 * @param {*} value The value to wrap in a `lodash` instance.
1786 * @param {boolean} chainAll A flag to enable chaining for all methods
1787 * @returns {Object} Returns a `lodash` instance.
1788 */
1789 function lodashWrapper(value, chainAll) {
1790 this.__chain__ = !!chainAll;
1791 this.__wrapped__ = value;
1792 }
1793 // ensure `new lodashWrapper` is an instance of `lodash`
1794 lodashWrapper.prototype = lodash.prototype;
1795
1796 /**
1797 * An object used to flag environments features.
1798 *
1799 * @static
1800 * @memberOf _
1801 * @type Object
1802 */
1803 var support = lodash.support = {};
1804
1805 /**
1806 * Detect if functions can be decompiled by `Function#toString`
1807 * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
1808 *
1809 * @memberOf _.support
1810 * @type boolean
1811 */
1812 support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
1813
1814 /**
1815 * Detect if `Function#name` is supported (all but IE).
1816 *
1817 * @memberOf _.support
1818 * @type boolean
1819 */
1820 support.funcNames = typeof Function.name == 'string';
1821
1822 /**
1823 * By default, the template delimiters used by Lo-Dash are similar to those in
1824 * embedded Ruby (ERB). Change the following template settings to use alternative
1825 * delimiters.
1826 *
1827 * @static
1828 * @memberOf _
1829 * @type Object
1830 */
1831 lodash.templateSettings = {
1832
1833 /**
1834 * Used to detect `data` property values to be HTML-escaped.
1835 *
1836 * @memberOf _.templateSettings
1837 * @type RegExp
1838 */
1839 'escape': /<%-([\s\S]+?)%>/g,
1840
1841 /**
1842 * Used to detect code to be evaluated.
1843 *
1844 * @memberOf _.templateSettings
1845 * @type RegExp
1846 */
1847 'evaluate': /<%([\s\S]+?)%>/g,
1848
1849 /**
1850 * Used to detect `data` property values to inject.
1851 *
1852 * @memberOf _.templateSettings
1853 * @type RegExp
1854 */
1855 'interpolate': reInterpolate,
1856
1857 /**
1858 * Used to reference the data object in the template text.
1859 *
1860 * @memberOf _.templateSettings
1861 * @type string
1862 */
1863 'variable': '',
1864
1865 /**
1866 * Used to import variables into the compiled template.
1867 *
1868 * @memberOf _.templateSettings
1869 * @type Object
1870 */
1871 'imports': {
1872
1873 /**
1874 * A reference to the `lodash` function.
1875 *
1876 * @memberOf _.templateSettings.imports
1877 * @type Function
1878 */
1879 '_': lodash
1880 }
1881 };
1882
1883 /*--------------------------------------------------------------------------*/
1884
1885 /**
1886 * The base implementation of `_.bind` that creates the bound function and
1887 * sets its meta data.
1888 *
1889 * @private
1890 * @param {Array} bindData The bind data array.
1891 * @returns {Function} Returns the new bound function.
1892 */
1893 function baseBind(bindData) {
1894 var func = bindData[0],
1895 partialArgs = bindData[2],
1896 thisArg = bindData[4];
1897
1898 function bound() {
1899 // `Function#bind` spec
1900 // http://es5.github.io/#x15.3.4.5
1901 if (partialArgs) {
1902 // avoid `arguments` object deoptimizations by using `slice` instead
1903 // of `Array.prototype.slice.call` and not assigning `arguments` to a
1904 // variable as a ternary expression
1905 var args = slice(partialArgs);
1906 push.apply(args, arguments);
1907 }
1908 // mimic the constructor's `return` behavior
1909 // http://es5.github.io/#x13.2.2
1910 if (this instanceof bound) {
1911 // ensure `new bound` is an instance of `func`
1912 var thisBinding = baseCreate(func.prototype),
1913 result = func.apply(thisBinding, args || arguments);
1914 return isObject(result) ? result : thisBinding;
1915 }
1916 return func.apply(thisArg, args || arguments);
1917 }
1918 setBindData(bound, bindData);
1919 return bound;
1920 }
1921
1922 /**
1923 * The base implementation of `_.clone` without argument juggling or support
1924 * for `thisArg` binding.
1925 *
1926 * @private
1927 * @param {*} value The value to clone.
1928 * @param {boolean} [isDeep=false] Specify a deep clone.
1929 * @param {Function} [callback] The function to customize cloning values.
1930 * @param {Array} [stackA=[]] Tracks traversed source objects.
1931 * @param {Array} [stackB=[]] Associates clones with source counterparts.
1932 * @returns {*} Returns the cloned value.
1933 */
1934 function baseClone(value, isDeep, callback, stackA, stackB) {
1935 if (callback) {
1936 var result = callback(value);
1937 if (typeof result != 'undefined') {
1938 return result;
1939 }
1940 }
1941 // inspect [[Class]]
1942 var isObj = isObject(value);
1943 if (isObj) {
1944 var className = toString.call(value);
1945 if (!cloneableClasses[className]) {
1946 return value;
1947 }
1948 var ctor = ctorByClass[className];
1949 switch (className) {
1950 case boolClass:
1951 case dateClass:
1952 return new ctor(+value);
1953
1954 case numberClass:
1955 case stringClass:
1956 return new ctor(value);
1957
1958 case regexpClass:
1959 result = ctor(value.source, reFlags.exec(value));
1960 result.lastIndex = value.lastIndex;
1961 return result;
1962 }
1963 } else {
1964 return value;
1965 }
1966 var isArr = isArray(value);
1967 if (isDeep) {
1968 // check for circular references and return corresponding clone
1969 var initedStack = !stackA;
1970 stackA || (stackA = getArray());
1971 stackB || (stackB = getArray());
1972
1973 var length = stackA.length;
1974 while (length--) {
1975 if (stackA[length] == value) {
1976 return stackB[length];
1977 }
1978 }
1979 result = isArr ? ctor(value.length) : {};
1980 }
1981 else {
1982 result = isArr ? slice(value) : assign({}, value);
1983 }
1984 // add array properties assigned by `RegExp#exec`
1985 if (isArr) {
1986 if (hasOwnProperty.call(value, 'index')) {
1987 result.index = value.index;
1988 }
1989 if (hasOwnProperty.call(value, 'input')) {
1990 result.input = value.input;
1991 }
1992 }
1993 // exit for shallow clone
1994 if (!isDeep) {
1995 return result;
1996 }
1997 // add the source value to the stack of traversed objects
1998 // and associate it with its clone
1999 stackA.push(value);
2000 stackB.push(result);
2001
2002 // recursively populate clone (susceptible to call stack limits)
2003 (isArr ? forEach : forOwn)(value, function(objValue, key) {
2004 result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
2005 });
2006
2007 if (initedStack) {
2008 releaseArray(stackA);
2009 releaseArray(stackB);
2010 }
2011 return result;
2012 }
2013
2014 /**
2015 * The base implementation of `_.create` without support for assigning
2016 * properties to the created object.
2017 *
2018 * @private
2019 * @param {Object} prototype The object to inherit from.
2020 * @returns {Object} Returns the new object.
2021 */
2022 function baseCreate(prototype, properties) {
2023 return isObject(prototype) ? nativeCreate(prototype) : {};
2024 }
2025 // fallback for browsers without `Object.create`
2026 if (!nativeCreate) {
2027 baseCreate = (function() {
2028 function Object() {}
2029 return function(prototype) {
2030 if (isObject(prototype)) {
2031 Object.prototype = prototype;
2032 var result = new Object;
2033 Object.prototype = null;
2034 }
2035 return result || context.Object();
2036 };
2037 }());
2038 }
2039
2040 /**
2041 * The base implementation of `_.createCallback` without support for creating
2042 * "_.pluck" or "_.where" style callbacks.
2043 *
2044 * @private
2045 * @param {*} [func=identity] The value to convert to a callback.
2046 * @param {*} [thisArg] The `this` binding of the created callback.
2047 * @param {number} [argCount] The number of arguments the callback accepts.
2048 * @returns {Function} Returns a callback function.
2049 */
2050 function baseCreateCallback(func, thisArg, argCount) {
2051 if (typeof func != 'function') {
2052 return identity;
2053 }
2054 // exit early for no `thisArg` or already bound by `Function#bind`
2055 if (typeof thisArg == 'undefined' || !('prototype' in func)) {
2056 return func;
2057 }
2058 var bindData = func.__bindData__;
2059 if (typeof bindData == 'undefined') {
2060 if (support.funcNames) {
2061 bindData = !func.name;
2062 }
2063 bindData = bindData || !support.funcDecomp;
2064 if (!bindData) {
2065 var source = fnToString.call(func);
2066 if (!support.funcNames) {
2067 bindData = !reFuncName.test(source);
2068 }
2069 if (!bindData) {
2070 // checks if `func` references the `this` keyword and stores the result
2071 bindData = reThis.test(source);
2072 setBindData(func, bindData);
2073 }
2074 }
2075 }
2076 // exit early if there are no `this` references or `func` is bound
2077 if (bindData === false || (bindData !== true && bindData[1] & 1)) {
2078 return func;
2079 }
2080 switch (argCount) {
2081 case 1: return function(value) {
2082 return func.call(thisArg, value);
2083 };
2084 case 2: return function(a, b) {
2085 return func.call(thisArg, a, b);
2086 };
2087 case 3: return function(value, index, collection) {
2088 return func.call(thisArg, value, index, collection);
2089 };
2090 case 4: return function(accumulator, value, index, collection) {
2091 return func.call(thisArg, accumulator, value, index, collection);
2092 };
2093 }
2094 return bind(func, thisArg);
2095 }
2096
2097 /**
2098 * The base implementation of `createWrapper` that creates the wrapper and
2099 * sets its meta data.
2100 *
2101 * @private
2102 * @param {Array} bindData The bind data array.
2103 * @returns {Function} Returns the new function.
2104 */
2105 function baseCreateWrapper(bindData) {
2106 var func = bindData[0],
2107 bitmask = bindData[1],
2108 partialArgs = bindData[2],
2109 partialRightArgs = bindData[3],
2110 thisArg = bindData[4],
2111 arity = bindData[5];
2112
2113 var isBind = bitmask & 1,
2114 isBindKey = bitmask & 2,
2115 isCurry = bitmask & 4,
2116 isCurryBound = bitmask & 8,
2117 key = func;
2118
2119 function bound() {
2120 var thisBinding = isBind ? thisArg : this;
2121 if (partialArgs) {
2122 var args = slice(partialArgs);
2123 push.apply(args, arguments);
2124 }
2125 if (partialRightArgs || isCurry) {
2126 args || (args = slice(arguments));
2127 if (partialRightArgs) {
2128 push.apply(args, partialRightArgs);
2129 }
2130 if (isCurry && args.length < arity) {
2131 bitmask |= 16 & ~32;
2132 return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
2133 }
2134 }
2135 args || (args = arguments);
2136 if (isBindKey) {
2137 func = thisBinding[key];
2138 }
2139 if (this instanceof bound) {
2140 thisBinding = baseCreate(func.prototype);
2141 var result = func.apply(thisBinding, args);
2142 return isObject(result) ? result : thisBinding;
2143 }
2144 return func.apply(thisBinding, args);
2145 }
2146 setBindData(bound, bindData);
2147 return bound;
2148 }
2149
2150 /**
2151 * The base implementation of `_.difference` that accepts a single array
2152 * of values to exclude.
2153 *
2154 * @private
2155 * @param {Array} array The array to process.
2156 * @param {Array} [values] The array of values to exclude.
2157 * @returns {Array} Returns a new array of filtered values.
2158 */
2159 function baseDifference(array, values) {
2160 var index = -1,
2161 indexOf = getIndexOf(),
2162 length = array ? array.length : 0,
2163 isLarge = length >= largeArraySize && indexOf === baseIndexOf,
2164 result = [];
2165
2166 if (isLarge) {
2167 var cache = createCache(values);
2168 if (cache) {
2169 indexOf = cacheIndexOf;
2170 values = cache;
2171 } else {
2172 isLarge = false;
2173 }
2174 }
2175 while (++index < length) {
2176 var value = array[index];
2177 if (indexOf(values, value) < 0) {
2178 result.push(value);
2179 }
2180 }
2181 if (isLarge) {
2182 releaseObject(values);
2183 }
2184 return result;
2185 }
2186
2187 /**
2188 * The base implementation of `_.flatten` without support for callback
2189 * shorthands or `thisArg` binding.
2190 *
2191 * @private
2192 * @param {Array} array The array to flatten.
2193 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
2194 * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
2195 * @param {number} [fromIndex=0] The index to start from.
2196 * @returns {Array} Returns a new flattened array.
2197 */
2198 function baseFlatten(array, isShallow, isStrict, fromIndex) {
2199 var index = (fromIndex || 0) - 1,
2200 length = array ? array.length : 0,
2201 result = [];
2202
2203 while (++index < length) {
2204 var value = array[index];
2205
2206 if (value && typeof value == 'object' && typeof value.length == 'number'
2207 && (isArray(value) || isArguments(value))) {
2208 // recursively flatten arrays (susceptible to call stack limits)
2209 if (!isShallow) {
2210 value = baseFlatten(value, isShallow, isStrict);
2211 }
2212 var valIndex = -1,
2213 valLength = value.length,
2214 resIndex = result.length;
2215
2216 result.length += valLength;
2217 while (++valIndex < valLength) {
2218 result[resIndex++] = value[valIndex];
2219 }
2220 } else if (!isStrict) {
2221 result.push(value);
2222 }
2223 }
2224 return result;
2225 }
2226
2227 /**
2228 * The base implementation of `_.isEqual`, without support for `thisArg` binding,
2229 * that allows partial "_.where" style comparisons.
2230 *
2231 * @private
2232 * @param {*} a The value to compare.
2233 * @param {*} b The other value to compare.
2234 * @param {Function} [callback] The function to customize comparing values.
2235 * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
2236 * @param {Array} [stackA=[]] Tracks traversed `a` objects.
2237 * @param {Array} [stackB=[]] Tracks traversed `b` objects.
2238 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2239 */
2240 function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
2241 // used to indicate that when comparing objects, `a` has at least the properties of `b`
2242 if (callback) {
2243 var result = callback(a, b);
2244 if (typeof result != 'undefined') {
2245 return !!result;
2246 }
2247 }
2248 // exit early for identical values
2249 if (a === b) {
2250 // treat `+0` vs. `-0` as not equal
2251 return a !== 0 || (1 / a == 1 / b);
2252 }
2253 var type = typeof a,
2254 otherType = typeof b;
2255
2256 // exit early for unlike primitive values
2257 if (a === a &&
2258 !(a && objectTypes[type]) &&
2259 !(b && objectTypes[otherType])) {
2260 return false;
2261 }
2262 // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
2263 // http://es5.github.io/#x15.3.4.4
2264 if (a == null || b == null) {
2265 return a === b;
2266 }
2267 // compare [[Class]] names
2268 var className = toString.call(a),
2269 otherClass = toString.call(b);
2270
2271 if (className == argsClass) {
2272 className = objectClass;
2273 }
2274 if (otherClass == argsClass) {
2275 otherClass = objectClass;
2276 }
2277 if (className != otherClass) {
2278 return false;
2279 }
2280 switch (className) {
2281 case boolClass:
2282 case dateClass:
2283 // coerce dates and booleans to numbers, dates to milliseconds and booleans
2284 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
2285 return +a == +b;
2286
2287 case numberClass:
2288 // treat `NaN` vs. `NaN` as equal
2289 return (a != +a)
2290 ? b != +b
2291 // but treat `+0` vs. `-0` as not equal
2292 : (a == 0 ? (1 / a == 1 / b) : a == +b);
2293
2294 case regexpClass:
2295 case stringClass:
2296 // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
2297 // treat string primitives and their corresponding object instances as equal
2298 return a == String(b);
2299 }
2300 var isArr = className == arrayClass;
2301 if (!isArr) {
2302 // unwrap any `lodash` wrapped values
2303 var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
2304 bWrapped = hasOwnProperty.call(b, '__wrapped__');
2305
2306 if (aWrapped || bWrapped) {
2307 return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
2308 }
2309 // exit for functions and DOM nodes
2310 if (className != objectClass) {
2311 return false;
2312 }
2313 // in older versions of Opera, `arguments` objects have `Array` constructors
2314 var ctorA = a.constructor,
2315 ctorB = b.constructor;
2316
2317 // non `Object` object instances with different constructors are not equal
2318 if (ctorA != ctorB &&
2319 !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
2320 ('constructor' in a && 'constructor' in b)
2321 ) {
2322 return false;
2323 }
2324 }
2325 // assume cyclic structures are equal
2326 // the algorithm for detecting cyclic structures is adapted from ES 5.1
2327 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
2328 var initedStack = !stackA;
2329 stackA || (stackA = getArray());
2330 stackB || (stackB = getArray());
2331
2332 var length = stackA.length;
2333 while (length--) {
2334 if (stackA[length] == a) {
2335 return stackB[length] == b;
2336 }
2337 }
2338 var size = 0;
2339 result = true;
2340
2341 // add `a` and `b` to the stack of traversed objects
2342 stackA.push(a);
2343 stackB.push(b);
2344
2345 // recursively compare objects and arrays (susceptible to call stack limits)
2346 if (isArr) {
2347 // compare lengths to determine if a deep comparison is necessary
2348 length = a.length;
2349 size = b.length;
2350 result = size == length;
2351
2352 if (result || isWhere) {
2353 // deep compare the contents, ignoring non-numeric properties
2354 while (size--) {
2355 var index = length,
2356 value = b[size];
2357
2358 if (isWhere) {
2359 while (index--) {
2360 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
2361 break;
2362 }
2363 }
2364 } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
2365 break;
2366 }
2367 }
2368 }
2369 }
2370 else {
2371 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
2372 // which, in this case, is more costly
2373 forIn(b, function(value, key, b) {
2374 if (hasOwnProperty.call(b, key)) {
2375 // count the number of properties.
2376 size++;
2377 // deep compare each property value.
2378 return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
2379 }
2380 });
2381
2382 if (result && !isWhere) {
2383 // ensure both objects have the same number of properties
2384 forIn(a, function(value, key, a) {
2385 if (hasOwnProperty.call(a, key)) {
2386 // `size` will be `-1` if `a` has more properties than `b`
2387 return (result = --size > -1);
2388 }
2389 });
2390 }
2391 }
2392 stackA.pop();
2393 stackB.pop();
2394
2395 if (initedStack) {
2396 releaseArray(stackA);
2397 releaseArray(stackB);
2398 }
2399 return result;
2400 }
2401
2402 /**
2403 * The base implementation of `_.merge` without argument juggling or support
2404 * for `thisArg` binding.
2405 *
2406 * @private
2407 * @param {Object} object The destination object.
2408 * @param {Object} source The source object.
2409 * @param {Function} [callback] The function to customize merging properties.
2410 * @param {Array} [stackA=[]] Tracks traversed source objects.
2411 * @param {Array} [stackB=[]] Associates values with source counterparts.
2412 */
2413 function baseMerge(object, source, callback, stackA, stackB) {
2414 (isArray(source) ? forEach : forOwn)(source, function(source, key) {
2415 var found,
2416 isArr,
2417 result = source,
2418 value = object[key];
2419
2420 if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
2421 // avoid merging previously merged cyclic sources
2422 var stackLength = stackA.length;
2423 while (stackLength--) {
2424 if ((found = stackA[stackLength] == source)) {
2425 value = stackB[stackLength];
2426 break;
2427 }
2428 }
2429 if (!found) {
2430 var isShallow;
2431 if (callback) {
2432 result = callback(value, source);
2433 if ((isShallow = typeof result != 'undefined')) {
2434 value = result;
2435 }
2436 }
2437 if (!isShallow) {
2438 value = isArr
2439 ? (isArray(value) ? value : [])
2440 : (isPlainObject(value) ? value : {});
2441 }
2442 // add `source` and associated `value` to the stack of traversed objects
2443 stackA.push(source);
2444 stackB.push(value);
2445
2446 // recursively merge objects and arrays (susceptible to call stack limits)
2447 if (!isShallow) {
2448 baseMerge(value, source, callback, stackA, stackB);
2449 }
2450 }
2451 }
2452 else {
2453 if (callback) {
2454 result = callback(value, source);
2455 if (typeof result == 'undefined') {
2456 result = source;
2457 }
2458 }
2459 if (typeof result != 'undefined') {
2460 value = result;
2461 }
2462 }
2463 object[key] = value;
2464 });
2465 }
2466
2467 /**
2468 * The base implementation of `_.random` without argument juggling or support
2469 * for returning floating-point numbers.
2470 *
2471 * @private
2472 * @param {number} min The minimum possible value.
2473 * @param {number} max The maximum possible value.
2474 * @returns {number} Returns a random number.
2475 */
2476 function baseRandom(min, max) {
2477 return min + floor(nativeRandom() * (max - min + 1));
2478 }
2479
2480 /**
2481 * The base implementation of `_.uniq` without support for callback shorthands
2482 * or `thisArg` binding.
2483 *
2484 * @private
2485 * @param {Array} array The array to process.
2486 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
2487 * @param {Function} [callback] The function called per iteration.
2488 * @returns {Array} Returns a duplicate-value-free array.
2489 */
2490 function baseUniq(array, isSorted, callback) {
2491 var index = -1,
2492 indexOf = getIndexOf(),
2493 length = array ? array.length : 0,
2494 result = [];
2495
2496 var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
2497 seen = (callback || isLarge) ? getArray() : result;
2498
2499 if (isLarge) {
2500 var cache = createCache(seen);
2501 indexOf = cacheIndexOf;
2502 seen = cache;
2503 }
2504 while (++index < length) {
2505 var value = array[index],
2506 computed = callback ? callback(value, index, array) : value;
2507
2508 if (isSorted
2509 ? !index || seen[seen.length - 1] !== computed
2510 : indexOf(seen, computed) < 0
2511 ) {
2512 if (callback || isLarge) {
2513 seen.push(computed);
2514 }
2515 result.push(value);
2516 }
2517 }
2518 if (isLarge) {
2519 releaseArray(seen.array);
2520 releaseObject(seen);
2521 } else if (callback) {
2522 releaseArray(seen);
2523 }
2524 return result;
2525 }
2526
2527 /**
2528 * Creates a function that aggregates a collection, creating an object composed
2529 * of keys generated from the results of running each element of the collection
2530 * through a callback. The given `setter` function sets the keys and values
2531 * of the composed object.
2532 *
2533 * @private
2534 * @param {Function} setter The setter function.
2535 * @returns {Function} Returns the new aggregator function.
2536 */
2537 function createAggregator(setter) {
2538 return function(collection, callback, thisArg) {
2539 var result = {};
2540 callback = lodash.createCallback(callback, thisArg, 3);
2541
2542 var index = -1,
2543 length = collection ? collection.length : 0;
2544
2545 if (typeof length == 'number') {
2546 while (++index < length) {
2547 var value = collection[index];
2548 setter(result, value, callback(value, index, collection), collection);
2549 }
2550 } else {
2551 forOwn(collection, function(value, key, collection) {
2552 setter(result, value, callback(value, key, collection), collection);
2553 });
2554 }
2555 return result;
2556 };
2557 }
2558
2559 /**
2560 * Creates a function that, when called, either curries or invokes `func`
2561 * with an optional `this` binding and partially applied arguments.
2562 *
2563 * @private
2564 * @param {Function|string} func The function or method name to reference.
2565 * @param {number} bitmask The bitmask of method flags to compose.
2566 * The bitmask may be composed of the following flags:
2567 * 1 - `_.bind`
2568 * 2 - `_.bindKey`
2569 * 4 - `_.curry`
2570 * 8 - `_.curry` (bound)
2571 * 16 - `_.partial`
2572 * 32 - `_.partialRight`
2573 * @param {Array} [partialArgs] An array of arguments to prepend to those
2574 * provided to the new function.
2575 * @param {Array} [partialRightArgs] An array of arguments to append to those
2576 * provided to the new function.
2577 * @param {*} [thisArg] The `this` binding of `func`.
2578 * @param {number} [arity] The arity of `func`.
2579 * @returns {Function} Returns the new function.
2580 */
2581 function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
2582 var isBind = bitmask & 1,
2583 isBindKey = bitmask & 2,
2584 isCurry = bitmask & 4,
2585 isCurryBound = bitmask & 8,
2586 isPartial = bitmask & 16,
2587 isPartialRight = bitmask & 32;
2588
2589 if (!isBindKey && !isFunction(func)) {
2590 throw new TypeError;
2591 }
2592 if (isPartial && !partialArgs.length) {
2593 bitmask &= ~16;
2594 isPartial = partialArgs = false;
2595 }
2596 if (isPartialRight && !partialRightArgs.length) {
2597 bitmask &= ~32;
2598 isPartialRight = partialRightArgs = false;
2599 }
2600 var bindData = func && func.__bindData__;
2601 if (bindData && bindData !== true) {
2602 // clone `bindData`
2603 bindData = slice(bindData);
2604 if (bindData[2]) {
2605 bindData[2] = slice(bindData[2]);
2606 }
2607 if (bindData[3]) {
2608 bindData[3] = slice(bindData[3]);
2609 }
2610 // set `thisBinding` is not previously bound
2611 if (isBind && !(bindData[1] & 1)) {
2612 bindData[4] = thisArg;
2613 }
2614 // set if previously bound but not currently (subsequent curried functions)
2615 if (!isBind && bindData[1] & 1) {
2616 bitmask |= 8;
2617 }
2618 // set curried arity if not yet set
2619 if (isCurry && !(bindData[1] & 4)) {
2620 bindData[5] = arity;
2621 }
2622 // append partial left arguments
2623 if (isPartial) {
2624 push.apply(bindData[2] || (bindData[2] = []), partialArgs);
2625 }
2626 // append partial right arguments
2627 if (isPartialRight) {
2628 unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
2629 }
2630 // merge flags
2631 bindData[1] |= bitmask;
2632 return createWrapper.apply(null, bindData);
2633 }
2634 // fast path for `_.bind`
2635 var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
2636 return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
2637 }
2638
2639 /**
2640 * Used by `escape` to convert characters to HTML entities.
2641 *
2642 * @private
2643 * @param {string} match The matched character to escape.
2644 * @returns {string} Returns the escaped character.
2645 */
2646 function escapeHtmlChar(match) {
2647 return htmlEscapes[match];
2648 }
2649
2650 /**
2651 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
2652 * customized, this method returns the custom method, otherwise it returns
2653 * the `baseIndexOf` function.
2654 *
2655 * @private
2656 * @returns {Function} Returns the "indexOf" function.
2657 */
2658 function getIndexOf() {
2659 var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
2660 return result;
2661 }
2662
2663 /**
2664 * Checks if `value` is a native function.
2665 *
2666 * @private
2667 * @param {*} value The value to check.
2668 * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
2669 */
2670 function isNative(value) {
2671 return typeof value == 'function' && reNative.test(value);
2672 }
2673
2674 /**
2675 * Sets `this` binding data on a given function.
2676 *
2677 * @private
2678 * @param {Function} func The function to set data on.
2679 * @param {Array} value The data array to set.
2680 */
2681 var setBindData = !defineProperty ? noop : function(func, value) {
2682 descriptor.value = value;
2683 defineProperty(func, '__bindData__', descriptor);
2684 };
2685
2686 /**
2687 * A fallback implementation of `isPlainObject` which checks if a given value
2688 * is an object created by the `Object` constructor, assuming objects created
2689 * by the `Object` constructor have no inherited enumerable properties and that
2690 * there are no `Object.prototype` extensions.
2691 *
2692 * @private
2693 * @param {*} value The value to check.
2694 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
2695 */
2696 function shimIsPlainObject(value) {
2697 var ctor,
2698 result;
2699
2700 // avoid non Object objects, `arguments` objects, and DOM elements
2701 if (!(value && toString.call(value) == objectClass) ||
2702 (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
2703 return false;
2704 }
2705 // In most environments an object's own properties are iterated before
2706 // its inherited properties. If the last iterated property is an object's
2707 // own property then there are no inherited enumerable properties.
2708 forIn(value, function(value, key) {
2709 result = key;
2710 });
2711 return typeof result == 'undefined' || hasOwnProperty.call(value, result);
2712 }
2713
2714 /**
2715 * Used by `unescape` to convert HTML entities to characters.
2716 *
2717 * @private
2718 * @param {string} match The matched character to unescape.
2719 * @returns {string} Returns the unescaped character.
2720 */
2721 function unescapeHtmlChar(match) {
2722 return htmlUnescapes[match];
2723 }
2724
2725 /*--------------------------------------------------------------------------*/
2726
2727 /**
2728 * Checks if `value` is an `arguments` object.
2729 *
2730 * @static
2731 * @memberOf _
2732 * @category Objects
2733 * @param {*} value The value to check.
2734 * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
2735 * @example
2736 *
2737 * (function() { return _.isArguments(arguments); })(1, 2, 3);
2738 * // => true
2739 *
2740 * _.isArguments([1, 2, 3]);
2741 * // => false
2742 */
2743 function isArguments(value) {
2744 return value && typeof value == 'object' && typeof value.length == 'number' &&
2745 toString.call(value) == argsClass || false;
2746 }
2747
2748 /**
2749 * Checks if `value` is an array.
2750 *
2751 * @static
2752 * @memberOf _
2753 * @type Function
2754 * @category Objects
2755 * @param {*} value The value to check.
2756 * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
2757 * @example
2758 *
2759 * (function() { return _.isArray(arguments); })();
2760 * // => false
2761 *
2762 * _.isArray([1, 2, 3]);
2763 * // => true
2764 */
2765 var isArray = nativeIsArray || function(value) {
2766 return value && typeof value == 'object' && typeof value.length == 'number' &&
2767 toString.call(value) == arrayClass || false;
2768 };
2769
2770 /**
2771 * A fallback implementation of `Object.keys` which produces an array of the
2772 * given object's own enumerable property names.
2773 *
2774 * @private
2775 * @type Function
2776 * @param {Object} object The object to inspect.
2777 * @returns {Array} Returns an array of property names.
2778 */
2779 var shimKeys = function(object) {
2780 var index, iterable = object, result = [];
2781 if (!iterable) return result;
2782 if (!(objectTypes[typeof object])) return result;
2783 for (index in iterable) {
2784 if (hasOwnProperty.call(iterable, index)) {
2785 result.push(index);
2786 }
2787 }
2788 return result
2789 };
2790
2791 /**
2792 * Creates an array composed of the own enumerable property names of an object.
2793 *
2794 * @static
2795 * @memberOf _
2796 * @category Objects
2797 * @param {Object} object The object to inspect.
2798 * @returns {Array} Returns an array of property names.
2799 * @example
2800 *
2801 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
2802 * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
2803 */
2804 var keys = !nativeKeys ? shimKeys : function(object) {
2805 if (!isObject(object)) {
2806 return [];
2807 }
2808 return nativeKeys(object);
2809 };
2810
2811 /**
2812 * Used to convert characters to HTML entities:
2813 *
2814 * Though the `>` character is escaped for symmetry, characters like `>` and `/`
2815 * don't require escaping in HTML and have no special meaning unless they're part
2816 * of a tag or an unquoted attribute value.
2817 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
2818 */
2819 var htmlEscapes = {
2820 '&': '&amp;',
2821 '<': '&lt;',
2822 '>': '&gt;',
2823 '"': '&quot;',
2824 "'": '&#39;'
2825 };
2826
2827 /** Used to convert HTML entities to characters */
2828 var htmlUnescapes = invert(htmlEscapes);
2829
2830 /** Used to match HTML entities and HTML characters */
2831 var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
2832 reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
2833
2834 /*--------------------------------------------------------------------------*/
2835
2836 /**
2837 * Assigns own enumerable properties of source object(s) to the destination
2838 * object. Subsequent sources will overwrite property assignments of previous
2839 * sources. If a callback is provided it will be executed to produce the
2840 * assigned values. The callback is bound to `thisArg` and invoked with two
2841 * arguments; (objectValue, sourceValue).
2842 *
2843 * @static
2844 * @memberOf _
2845 * @type Function
2846 * @alias extend
2847 * @category Objects
2848 * @param {Object} object The destination object.
2849 * @param {...Object} [source] The source objects.
2850 * @param {Function} [callback] The function to customize assigning values.
2851 * @param {*} [thisArg] The `this` binding of `callback`.
2852 * @returns {Object} Returns the destination object.
2853 * @example
2854 *
2855 * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
2856 * // => { 'name': 'fred', 'employer': 'slate' }
2857 *
2858 * var defaults = _.partialRight(_.assign, function(a, b) {
2859 * return typeof a == 'undefined' ? b : a;
2860 * });
2861 *
2862 * var object = { 'name': 'barney' };
2863 * defaults(object, { 'name': 'fred', 'employer': 'slate' });
2864 * // => { 'name': 'barney', 'employer': 'slate' }
2865 */
2866 var assign = function(object, source, guard) {
2867 var index, iterable = object, result = iterable;
2868 if (!iterable) return result;
2869 var args = arguments,
2870 argsIndex = 0,
2871 argsLength = typeof guard == 'number' ? 2 : args.length;
2872 if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
2873 var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
2874 } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
2875 callback = args[--argsLength];
2876 }
2877 while (++argsIndex < argsLength) {
2878 iterable = args[argsIndex];
2879 if (iterable && objectTypes[typeof iterable]) {
2880 var ownIndex = -1,
2881 ownProps = objectTypes[typeof iterable] && keys(iterable),
2882 length = ownProps ? ownProps.length : 0;
2883
2884 while (++ownIndex < length) {
2885 index = ownProps[ownIndex];
2886 result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
2887 }
2888 }
2889 }
2890 return result
2891 };
2892
2893 /**
2894 * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
2895 * be cloned, otherwise they will be assigned by reference. If a callback
2896 * is provided it will be executed to produce the cloned values. If the
2897 * callback returns `undefined` cloning will be handled by the method instead.
2898 * The callback is bound to `thisArg` and invoked with one argument; (value).
2899 *
2900 * @static
2901 * @memberOf _
2902 * @category Objects
2903 * @param {*} value The value to clone.
2904 * @param {boolean} [isDeep=false] Specify a deep clone.
2905 * @param {Function} [callback] The function to customize cloning values.
2906 * @param {*} [thisArg] The `this` binding of `callback`.
2907 * @returns {*} Returns the cloned value.
2908 * @example
2909 *
2910 * var characters = [
2911 * { 'name': 'barney', 'age': 36 },
2912 * { 'name': 'fred', 'age': 40 }
2913 * ];
2914 *
2915 * var shallow = _.clone(characters);
2916 * shallow[0] === characters[0];
2917 * // => true
2918 *
2919 * var deep = _.clone(characters, true);
2920 * deep[0] === characters[0];
2921 * // => false
2922 *
2923 * _.mixin({
2924 * 'clone': _.partialRight(_.clone, function(value) {
2925 * return _.isElement(value) ? value.cloneNode(false) : undefined;
2926 * })
2927 * });
2928 *
2929 * var clone = _.clone(document.body);
2930 * clone.childNodes.length;
2931 * // => 0
2932 */
2933 function clone(value, isDeep, callback, thisArg) {
2934 // allows working with "Collections" methods without using their `index`
2935 // and `collection` arguments for `isDeep` and `callback`
2936 if (typeof isDeep != 'boolean' && isDeep != null) {
2937 thisArg = callback;
2938 callback = isDeep;
2939 isDeep = false;
2940 }
2941 return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
2942 }
2943
2944 /**
2945 * Creates a deep clone of `value`. If a callback is provided it will be
2946 * executed to produce the cloned values. If the callback returns `undefined`
2947 * cloning will be handled by the method instead. The callback is bound to
2948 * `thisArg` and invoked with one argument; (value).
2949 *
2950 * Note: This method is loosely based on the structured clone algorithm. Functions
2951 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
2952 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
2953 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
2954 *
2955 * @static
2956 * @memberOf _
2957 * @category Objects
2958 * @param {*} value The value to deep clone.
2959 * @param {Function} [callback] The function to customize cloning values.
2960 * @param {*} [thisArg] The `this` binding of `callback`.
2961 * @returns {*} Returns the deep cloned value.
2962 * @example
2963 *
2964 * var characters = [
2965 * { 'name': 'barney', 'age': 36 },
2966 * { 'name': 'fred', 'age': 40 }
2967 * ];
2968 *
2969 * var deep = _.cloneDeep(characters);
2970 * deep[0] === characters[0];
2971 * // => false
2972 *
2973 * var view = {
2974 * 'label': 'docs',
2975 * 'node': element
2976 * };
2977 *
2978 * var clone = _.cloneDeep(view, function(value) {
2979 * return _.isElement(value) ? value.cloneNode(true) : undefined;
2980 * });
2981 *
2982 * clone.node == view.node;
2983 * // => false
2984 */
2985 function cloneDeep(value, callback, thisArg) {
2986 return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
2987 }
2988
2989 /**
2990 * Creates an object that inherits from the given `prototype` object. If a
2991 * `properties` object is provided its own enumerable properties are assigned
2992 * to the created object.
2993 *
2994 * @static
2995 * @memberOf _
2996 * @category Objects
2997 * @param {Object} prototype The object to inherit from.
2998 * @param {Object} [properties] The properties to assign to the object.
2999 * @returns {Object} Returns the new object.
3000 * @example
3001 *
3002 * function Shape() {
3003 * this.x = 0;
3004 * this.y = 0;
3005 * }
3006 *
3007 * function Circle() {
3008 * Shape.call(this);
3009 * }
3010 *
3011 * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
3012 *
3013 * var circle = new Circle;
3014 * circle instanceof Circle;
3015 * // => true
3016 *
3017 * circle instanceof Shape;
3018 * // => true
3019 */
3020 function create(prototype, properties) {
3021 var result = baseCreate(prototype);
3022 return properties ? assign(result, properties) : result;
3023 }
3024
3025 /**
3026 * Assigns own enumerable properties of source object(s) to the destination
3027 * object for all destination properties that resolve to `undefined`. Once a
3028 * property is set, additional defaults of the same property will be ignored.
3029 *
3030 * @static
3031 * @memberOf _
3032 * @type Function
3033 * @category Objects
3034 * @param {Object} object The destination object.
3035 * @param {...Object} [source] The source objects.
3036 * @param- {Object} [guard] Allows working with `_.reduce` without using its
3037 * `key` and `object` arguments as sources.
3038 * @returns {Object} Returns the destination object.
3039 * @example
3040 *
3041 * var object = { 'name': 'barney' };
3042 * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
3043 * // => { 'name': 'barney', 'employer': 'slate' }
3044 */
3045 var defaults = function(object, source, guard) {
3046 var index, iterable = object, result = iterable;
3047 if (!iterable) return result;
3048 var args = arguments,
3049 argsIndex = 0,
3050 argsLength = typeof guard == 'number' ? 2 : args.length;
3051 while (++argsIndex < argsLength) {
3052 iterable = args[argsIndex];
3053 if (iterable && objectTypes[typeof iterable]) {
3054 var ownIndex = -1,
3055 ownProps = objectTypes[typeof iterable] && keys(iterable),
3056 length = ownProps ? ownProps.length : 0;
3057
3058 while (++ownIndex < length) {
3059 index = ownProps[ownIndex];
3060 if (typeof result[index] == 'undefined') result[index] = iterable[index];
3061 }
3062 }
3063 }
3064 return result
3065 };
3066
3067 /**
3068 * This method is like `_.findIndex` except that it returns the key of the
3069 * first element that passes the callback check, instead of the element itself.
3070 *
3071 * If a property name is provided for `callback` the created "_.pluck" style
3072 * callback will return the property value of the given element.
3073 *
3074 * If an object is provided for `callback` the created "_.where" style callback
3075 * will return `true` for elements that have the properties of the given object,
3076 * else `false`.
3077 *
3078 * @static
3079 * @memberOf _
3080 * @category Objects
3081 * @param {Object} object The object to search.
3082 * @param {Function|Object|string} [callback=identity] The function called per
3083 * iteration. If a property name or object is provided it will be used to
3084 * create a "_.pluck" or "_.where" style callback, respectively.
3085 * @param {*} [thisArg] The `this` binding of `callback`.
3086 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
3087 * @example
3088 *
3089 * var characters = {
3090 * 'barney': { 'age': 36, 'blocked': false },
3091 * 'fred': { 'age': 40, 'blocked': true },
3092 * 'pebbles': { 'age': 1, 'blocked': false }
3093 * };
3094 *
3095 * _.findKey(characters, function(chr) {
3096 * return chr.age < 40;
3097 * });
3098 * // => 'barney' (property order is not guaranteed across environments)
3099 *
3100 * // using "_.where" callback shorthand
3101 * _.findKey(characters, { 'age': 1 });
3102 * // => 'pebbles'
3103 *
3104 * // using "_.pluck" callback shorthand
3105 * _.findKey(characters, 'blocked');
3106 * // => 'fred'
3107 */
3108 function findKey(object, callback, thisArg) {
3109 var result;
3110 callback = lodash.createCallback(callback, thisArg, 3);
3111 forOwn(object, function(value, key, object) {
3112 if (callback(value, key, object)) {
3113 result = key;
3114 return false;
3115 }
3116 });
3117 return result;
3118 }
3119
3120 /**
3121 * This method is like `_.findKey` except that it iterates over elements
3122 * of a `collection` in the opposite order.
3123 *
3124 * If a property name is provided for `callback` the created "_.pluck" style
3125 * callback will return the property value of the given element.
3126 *
3127 * If an object is provided for `callback` the created "_.where" style callback
3128 * will return `true` for elements that have the properties of the given object,
3129 * else `false`.
3130 *
3131 * @static
3132 * @memberOf _
3133 * @category Objects
3134 * @param {Object} object The object to search.
3135 * @param {Function|Object|string} [callback=identity] The function called per
3136 * iteration. If a property name or object is provided it will be used to
3137 * create a "_.pluck" or "_.where" style callback, respectively.
3138 * @param {*} [thisArg] The `this` binding of `callback`.
3139 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
3140 * @example
3141 *
3142 * var characters = {
3143 * 'barney': { 'age': 36, 'blocked': true },
3144 * 'fred': { 'age': 40, 'blocked': false },
3145 * 'pebbles': { 'age': 1, 'blocked': true }
3146 * };
3147 *
3148 * _.findLastKey(characters, function(chr) {
3149 * return chr.age < 40;
3150 * });
3151 * // => returns `pebbles`, assuming `_.findKey` returns `barney`
3152 *
3153 * // using "_.where" callback shorthand
3154 * _.findLastKey(characters, { 'age': 40 });
3155 * // => 'fred'
3156 *
3157 * // using "_.pluck" callback shorthand
3158 * _.findLastKey(characters, 'blocked');
3159 * // => 'pebbles'
3160 */
3161 function findLastKey(object, callback, thisArg) {
3162 var result;
3163 callback = lodash.createCallback(callback, thisArg, 3);
3164 forOwnRight(object, function(value, key, object) {
3165 if (callback(value, key, object)) {
3166 result = key;
3167 return false;
3168 }
3169 });
3170 return result;
3171 }
3172
3173 /**
3174 * Iterates over own and inherited enumerable properties of an object,
3175 * executing the callback for each property. The callback is bound to `thisArg`
3176 * and invoked with three arguments; (value, key, object). Callbacks may exit
3177 * iteration early by explicitly returning `false`.
3178 *
3179 * @static
3180 * @memberOf _
3181 * @type Function
3182 * @category Objects
3183 * @param {Object} object The object to iterate over.
3184 * @param {Function} [callback=identity] The function called per iteration.
3185 * @param {*} [thisArg] The `this` binding of `callback`.
3186 * @returns {Object} Returns `object`.
3187 * @example
3188 *
3189 * function Shape() {
3190 * this.x = 0;
3191 * this.y = 0;
3192 * }
3193 *
3194 * Shape.prototype.move = function(x, y) {
3195 * this.x += x;
3196 * this.y += y;
3197 * };
3198 *
3199 * _.forIn(new Shape, function(value, key) {
3200 * console.log(key);
3201 * });
3202 * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
3203 */
3204 var forIn = function(collection, callback, thisArg) {
3205 var index, iterable = collection, result = iterable;
3206 if (!iterable) return result;
3207 if (!objectTypes[typeof iterable]) return result;
3208 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
3209 for (index in iterable) {
3210 if (callback(iterable[index], index, collection) === false) return result;
3211 }
3212 return result
3213 };
3214
3215 /**
3216 * This method is like `_.forIn` except that it iterates over elements
3217 * of a `collection` in the opposite order.
3218 *
3219 * @static
3220 * @memberOf _
3221 * @category Objects
3222 * @param {Object} object The object to iterate over.
3223 * @param {Function} [callback=identity] The function called per iteration.
3224 * @param {*} [thisArg] The `this` binding of `callback`.
3225 * @returns {Object} Returns `object`.
3226 * @example
3227 *
3228 * function Shape() {
3229 * this.x = 0;
3230 * this.y = 0;
3231 * }
3232 *
3233 * Shape.prototype.move = function(x, y) {
3234 * this.x += x;
3235 * this.y += y;
3236 * };
3237 *
3238 * _.forInRight(new Shape, function(value, key) {
3239 * console.log(key);
3240 * });
3241 * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
3242 */
3243 function forInRight(object, callback, thisArg) {
3244 var pairs = [];
3245
3246 forIn(object, function(value, key) {
3247 pairs.push(key, value);
3248 });
3249
3250 var length = pairs.length;
3251 callback = baseCreateCallback(callback, thisArg, 3);
3252 while (length--) {
3253 if (callback(pairs[length--], pairs[length], object) === false) {
3254 break;
3255 }
3256 }
3257 return object;
3258 }
3259
3260 /**
3261 * Iterates over own enumerable properties of an object, executing the callback
3262 * for each property. The callback is bound to `thisArg` and invoked with three
3263 * arguments; (value, key, object). Callbacks may exit iteration early by
3264 * explicitly returning `false`.
3265 *
3266 * @static
3267 * @memberOf _
3268 * @type Function
3269 * @category Objects
3270 * @param {Object} object The object to iterate over.
3271 * @param {Function} [callback=identity] The function called per iteration.
3272 * @param {*} [thisArg] The `this` binding of `callback`.
3273 * @returns {Object} Returns `object`.
3274 * @example
3275 *
3276 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
3277 * console.log(key);
3278 * });
3279 * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
3280 */
3281 var forOwn = function(collection, callback, thisArg) {
3282 var index, iterable = collection, result = iterable;
3283 if (!iterable) return result;
3284 if (!objectTypes[typeof iterable]) return result;
3285 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
3286 var ownIndex = -1,
3287 ownProps = objectTypes[typeof iterable] && keys(iterable),
3288 length = ownProps ? ownProps.length : 0;
3289
3290 while (++ownIndex < length) {
3291 index = ownProps[ownIndex];
3292 if (callback(iterable[index], index, collection) === false) return result;
3293 }
3294 return result
3295 };
3296
3297 /**
3298 * This method is like `_.forOwn` except that it iterates over elements
3299 * of a `collection` in the opposite order.
3300 *
3301 * @static
3302 * @memberOf _
3303 * @category Objects
3304 * @param {Object} object The object to iterate over.
3305 * @param {Function} [callback=identity] The function called per iteration.
3306 * @param {*} [thisArg] The `this` binding of `callback`.
3307 * @returns {Object} Returns `object`.
3308 * @example
3309 *
3310 * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
3311 * console.log(key);
3312 * });
3313 * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
3314 */
3315 function forOwnRight(object, callback, thisArg) {
3316 var props = keys(object),
3317 length = props.length;
3318
3319 callback = baseCreateCallback(callback, thisArg, 3);
3320 while (length--) {
3321 var key = props[length];
3322 if (callback(object[key], key, object) === false) {
3323 break;
3324 }
3325 }
3326 return object;
3327 }
3328
3329 /**
3330 * Creates a sorted array of property names of all enumerable properties,
3331 * own and inherited, of `object` that have function values.
3332 *
3333 * @static
3334 * @memberOf _
3335 * @alias methods
3336 * @category Objects
3337 * @param {Object} object The object to inspect.
3338 * @returns {Array} Returns an array of property names that have function values.
3339 * @example
3340 *
3341 * _.functions(_);
3342 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
3343 */
3344 function functions(object) {
3345 var result = [];
3346 forIn(object, function(value, key) {
3347 if (isFunction(value)) {
3348 result.push(key);
3349 }
3350 });
3351 return result.sort();
3352 }
3353
3354 /**
3355 * Checks if the specified property name exists as a direct property of `object`,
3356 * instead of an inherited property.
3357 *
3358 * @static
3359 * @memberOf _
3360 * @category Objects
3361 * @param {Object} object The object to inspect.
3362 * @param {string} key The name of the property to check.
3363 * @returns {boolean} Returns `true` if key is a direct property, else `false`.
3364 * @example
3365 *
3366 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
3367 * // => true
3368 */
3369 function has(object, key) {
3370 return object ? hasOwnProperty.call(object, key) : false;
3371 }
3372
3373 /**
3374 * Creates an object composed of the inverted keys and values of the given object.
3375 *
3376 * @static
3377 * @memberOf _
3378 * @category Objects
3379 * @param {Object} object The object to invert.
3380 * @returns {Object} Returns the created inverted object.
3381 * @example
3382 *
3383 * _.invert({ 'first': 'fred', 'second': 'barney' });
3384 * // => { 'fred': 'first', 'barney': 'second' }
3385 */
3386 function invert(object) {
3387 var index = -1,
3388 props = keys(object),
3389 length = props.length,
3390 result = {};
3391
3392 while (++index < length) {
3393 var key = props[index];
3394 result[object[key]] = key;
3395 }
3396 return result;
3397 }
3398
3399 /**
3400 * Checks if `value` is a boolean value.
3401 *
3402 * @static
3403 * @memberOf _
3404 * @category Objects
3405 * @param {*} value The value to check.
3406 * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
3407 * @example
3408 *
3409 * _.isBoolean(null);
3410 * // => false
3411 */
3412 function isBoolean(value) {
3413 return value === true || value === false ||
3414 value && typeof value == 'object' && toString.call(value) == boolClass || false;
3415 }
3416
3417 /**
3418 * Checks if `value` is a date.
3419 *
3420 * @static
3421 * @memberOf _
3422 * @category Objects
3423 * @param {*} value The value to check.
3424 * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
3425 * @example
3426 *
3427 * _.isDate(new Date);
3428 * // => true
3429 */
3430 function isDate(value) {
3431 return value && typeof value == 'object' && toString.call(value) == dateClass || false;
3432 }
3433
3434 /**
3435 * Checks if `value` is a DOM element.
3436 *
3437 * @static
3438 * @memberOf _
3439 * @category Objects
3440 * @param {*} value The value to check.
3441 * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
3442 * @example
3443 *
3444 * _.isElement(document.body);
3445 * // => true
3446 */
3447 function isElement(value) {
3448 return value && value.nodeType === 1 || false;
3449 }
3450
3451 /**
3452 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
3453 * length of `0` and objects with no own enumerable properties are considered
3454 * "empty".
3455 *
3456 * @static
3457 * @memberOf _
3458 * @category Objects
3459 * @param {Array|Object|string} value The value to inspect.
3460 * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
3461 * @example
3462 *
3463 * _.isEmpty([1, 2, 3]);
3464 * // => false
3465 *
3466 * _.isEmpty({});
3467 * // => true
3468 *
3469 * _.isEmpty('');
3470 * // => true
3471 */
3472 function isEmpty(value) {
3473 var result = true;
3474 if (!value) {
3475 return result;
3476 }
3477 var className = toString.call(value),
3478 length = value.length;
3479
3480 if ((className == arrayClass || className == stringClass || className == argsClass ) ||
3481 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
3482 return !length;
3483 }
3484 forOwn(value, function() {
3485 return (result = false);
3486 });
3487 return result;
3488 }
3489
3490 /**
3491 * Performs a deep comparison between two values to determine if they are
3492 * equivalent to each other. If a callback is provided it will be executed
3493 * to compare values. If the callback returns `undefined` comparisons will
3494 * be handled by the method instead. The callback is bound to `thisArg` and
3495 * invoked with two arguments; (a, b).
3496 *
3497 * @static
3498 * @memberOf _
3499 * @category Objects
3500 * @param {*} a The value to compare.
3501 * @param {*} b The other value to compare.
3502 * @param {Function} [callback] The function to customize comparing values.
3503 * @param {*} [thisArg] The `this` binding of `callback`.
3504 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3505 * @example
3506 *
3507 * var object = { 'name': 'fred' };
3508 * var copy = { 'name': 'fred' };
3509 *
3510 * object == copy;
3511 * // => false
3512 *
3513 * _.isEqual(object, copy);
3514 * // => true
3515 *
3516 * var words = ['hello', 'goodbye'];
3517 * var otherWords = ['hi', 'goodbye'];
3518 *
3519 * _.isEqual(words, otherWords, function(a, b) {
3520 * var reGreet = /^(?:hello|hi)$/i,
3521 * aGreet = _.isString(a) && reGreet.test(a),
3522 * bGreet = _.isString(b) && reGreet.test(b);
3523 *
3524 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
3525 * });
3526 * // => true
3527 */
3528 function isEqual(a, b, callback, thisArg) {
3529 return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
3530 }
3531
3532 /**
3533 * Checks if `value` is, or can be coerced to, a finite number.
3534 *
3535 * Note: This is not the same as native `isFinite` which will return true for
3536 * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
3537 *
3538 * @static
3539 * @memberOf _
3540 * @category Objects
3541 * @param {*} value The value to check.
3542 * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
3543 * @example
3544 *
3545 * _.isFinite(-101);
3546 * // => true
3547 *
3548 * _.isFinite('10');
3549 * // => true
3550 *
3551 * _.isFinite(true);
3552 * // => false
3553 *
3554 * _.isFinite('');
3555 * // => false
3556 *
3557 * _.isFinite(Infinity);
3558 * // => false
3559 */
3560 function isFinite(value) {
3561 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
3562 }
3563
3564 /**
3565 * Checks if `value` is a function.
3566 *
3567 * @static
3568 * @memberOf _
3569 * @category Objects
3570 * @param {*} value The value to check.
3571 * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
3572 * @example
3573 *
3574 * _.isFunction(_);
3575 * // => true
3576 */
3577 function isFunction(value) {
3578 return typeof value == 'function';
3579 }
3580
3581 /**
3582 * Checks if `value` is the language type of Object.
3583 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
3584 *
3585 * @static
3586 * @memberOf _
3587 * @category Objects
3588 * @param {*} value The value to check.
3589 * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
3590 * @example
3591 *
3592 * _.isObject({});
3593 * // => true
3594 *
3595 * _.isObject([1, 2, 3]);
3596 * // => true
3597 *
3598 * _.isObject(1);
3599 * // => false
3600 */
3601 function isObject(value) {
3602 // check if the value is the ECMAScript language type of Object
3603 // http://es5.github.io/#x8
3604 // and avoid a V8 bug
3605 // http://code.google.com/p/v8/issues/detail?id=2291
3606 return !!(value && objectTypes[typeof value]);
3607 }
3608
3609 /**
3610 * Checks if `value` is `NaN`.
3611 *
3612 * Note: This is not the same as native `isNaN` which will return `true` for
3613 * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
3614 *
3615 * @static
3616 * @memberOf _
3617 * @category Objects
3618 * @param {*} value The value to check.
3619 * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
3620 * @example
3621 *
3622 * _.isNaN(NaN);
3623 * // => true
3624 *
3625 * _.isNaN(new Number(NaN));
3626 * // => true
3627 *
3628 * isNaN(undefined);
3629 * // => true
3630 *
3631 * _.isNaN(undefined);
3632 * // => false
3633 */
3634 function isNaN(value) {
3635 // `NaN` as a primitive is the only value that is not equal to itself
3636 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
3637 return isNumber(value) && value != +value;
3638 }
3639
3640 /**
3641 * Checks if `value` is `null`.
3642 *
3643 * @static
3644 * @memberOf _
3645 * @category Objects
3646 * @param {*} value The value to check.
3647 * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
3648 * @example
3649 *
3650 * _.isNull(null);
3651 * // => true
3652 *
3653 * _.isNull(undefined);
3654 * // => false
3655 */
3656 function isNull(value) {
3657 return value === null;
3658 }
3659
3660 /**
3661 * Checks if `value` is a number.
3662 *
3663 * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
3664 *
3665 * @static
3666 * @memberOf _
3667 * @category Objects
3668 * @param {*} value The value to check.
3669 * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
3670 * @example
3671 *
3672 * _.isNumber(8.4 * 5);
3673 * // => true
3674 */
3675 function isNumber(value) {
3676 return typeof value == 'number' ||
3677 value && typeof value == 'object' && toString.call(value) == numberClass || false;
3678 }
3679
3680 /**
3681 * Checks if `value` is an object created by the `Object` constructor.
3682 *
3683 * @static
3684 * @memberOf _
3685 * @category Objects
3686 * @param {*} value The value to check.
3687 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
3688 * @example
3689 *
3690 * function Shape() {
3691 * this.x = 0;
3692 * this.y = 0;
3693 * }
3694 *
3695 * _.isPlainObject(new Shape);
3696 * // => false
3697 *
3698 * _.isPlainObject([1, 2, 3]);
3699 * // => false
3700 *
3701 * _.isPlainObject({ 'x': 0, 'y': 0 });
3702 * // => true
3703 */
3704 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
3705 if (!(value && toString.call(value) == objectClass)) {
3706 return false;
3707 }
3708 var valueOf = value.valueOf,
3709 objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
3710
3711 return objProto
3712 ? (value == objProto || getPrototypeOf(value) == objProto)
3713 : shimIsPlainObject(value);
3714 };
3715
3716 /**
3717 * Checks if `value` is a regular expression.
3718 *
3719 * @static
3720 * @memberOf _
3721 * @category Objects
3722 * @param {*} value The value to check.
3723 * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
3724 * @example
3725 *
3726 * _.isRegExp(/fred/);
3727 * // => true
3728 */
3729 function isRegExp(value) {
3730 return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
3731 }
3732
3733 /**
3734 * Checks if `value` is a string.
3735 *
3736 * @static
3737 * @memberOf _
3738 * @category Objects
3739 * @param {*} value The value to check.
3740 * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
3741 * @example
3742 *
3743 * _.isString('fred');
3744 * // => true
3745 */
3746 function isString(value) {
3747 return typeof value == 'string' ||
3748 value && typeof value == 'object' && toString.call(value) == stringClass || false;
3749 }
3750
3751 /**
3752 * Checks if `value` is `undefined`.
3753 *
3754 * @static
3755 * @memberOf _
3756 * @category Objects
3757 * @param {*} value The value to check.
3758 * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
3759 * @example
3760 *
3761 * _.isUndefined(void 0);
3762 * // => true
3763 */
3764 function isUndefined(value) {
3765 return typeof value == 'undefined';
3766 }
3767
3768 /**
3769 * Creates an object with the same keys as `object` and values generated by
3770 * running each own enumerable property of `object` through the callback.
3771 * The callback is bound to `thisArg` and invoked with three arguments;
3772 * (value, key, object).
3773 *
3774 * If a property name is provided for `callback` the created "_.pluck" style
3775 * callback will return the property value of the given element.
3776 *
3777 * If an object is provided for `callback` the created "_.where" style callback
3778 * will return `true` for elements that have the properties of the given object,
3779 * else `false`.
3780 *
3781 * @static
3782 * @memberOf _
3783 * @category Objects
3784 * @param {Object} object The object to iterate over.
3785 * @param {Function|Object|string} [callback=identity] The function called
3786 * per iteration. If a property name or object is provided it will be used
3787 * to create a "_.pluck" or "_.where" style callback, respectively.
3788 * @param {*} [thisArg] The `this` binding of `callback`.
3789 * @returns {Array} Returns a new object with values of the results of each `callback` execution.
3790 * @example
3791 *
3792 * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
3793 * // => { 'a': 3, 'b': 6, 'c': 9 }
3794 *
3795 * var characters = {
3796 * 'fred': { 'name': 'fred', 'age': 40 },
3797 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
3798 * };
3799 *
3800 * // using "_.pluck" callback shorthand
3801 * _.mapValues(characters, 'age');
3802 * // => { 'fred': 40, 'pebbles': 1 }
3803 */
3804 function mapValues(object, callback, thisArg) {
3805 var result = {};
3806 callback = lodash.createCallback(callback, thisArg, 3);
3807
3808 forOwn(object, function(value, key, object) {
3809 result[key] = callback(value, key, object);
3810 });
3811 return result;
3812 }
3813
3814 /**
3815 * Recursively merges own enumerable properties of the source object(s), that
3816 * don't resolve to `undefined` into the destination object. Subsequent sources
3817 * will overwrite property assignments of previous sources. If a callback is
3818 * provided it will be executed to produce the merged values of the destination
3819 * and source properties. If the callback returns `undefined` merging will
3820 * be handled by the method instead. The callback is bound to `thisArg` and
3821 * invoked with two arguments; (objectValue, sourceValue).
3822 *
3823 * @static
3824 * @memberOf _
3825 * @category Objects
3826 * @param {Object} object The destination object.
3827 * @param {...Object} [source] The source objects.
3828 * @param {Function} [callback] The function to customize merging properties.
3829 * @param {*} [thisArg] The `this` binding of `callback`.
3830 * @returns {Object} Returns the destination object.
3831 * @example
3832 *
3833 * var names = {
3834 * 'characters': [
3835 * { 'name': 'barney' },
3836 * { 'name': 'fred' }
3837 * ]
3838 * };
3839 *
3840 * var ages = {
3841 * 'characters': [
3842 * { 'age': 36 },
3843 * { 'age': 40 }
3844 * ]
3845 * };
3846 *
3847 * _.merge(names, ages);
3848 * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
3849 *
3850 * var food = {
3851 * 'fruits': ['apple'],
3852 * 'vegetables': ['beet']
3853 * };
3854 *
3855 * var otherFood = {
3856 * 'fruits': ['banana'],
3857 * 'vegetables': ['carrot']
3858 * };
3859 *
3860 * _.merge(food, otherFood, function(a, b) {
3861 * return _.isArray(a) ? a.concat(b) : undefined;
3862 * });
3863 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
3864 */
3865 function merge(object) {
3866 var args = arguments,
3867 length = 2;
3868
3869 if (!isObject(object)) {
3870 return object;
3871 }
3872 // allows working with `_.reduce` and `_.reduceRight` without using
3873 // their `index` and `collection` arguments
3874 if (typeof args[2] != 'number') {
3875 length = args.length;
3876 }
3877 if (length > 3 && typeof args[length - 2] == 'function') {
3878 var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
3879 } else if (length > 2 && typeof args[length - 1] == 'function') {
3880 callback = args[--length];
3881 }
3882 var sources = slice(arguments, 1, length),
3883 index = -1,
3884 stackA = getArray(),
3885 stackB = getArray();
3886
3887 while (++index < length) {
3888 baseMerge(object, sources[index], callback, stackA, stackB);
3889 }
3890 releaseArray(stackA);
3891 releaseArray(stackB);
3892 return object;
3893 }
3894
3895 /**
3896 * Creates a shallow clone of `object` excluding the specified properties.
3897 * Property names may be specified as individual arguments or as arrays of
3898 * property names. If a callback is provided it will be executed for each
3899 * property of `object` omitting the properties the callback returns truey
3900 * for. The callback is bound to `thisArg` and invoked with three arguments;
3901 * (value, key, object).
3902 *
3903 * @static
3904 * @memberOf _
3905 * @category Objects
3906 * @param {Object} object The source object.
3907 * @param {Function|...string|string[]} [callback] The properties to omit or the
3908 * function called per iteration.
3909 * @param {*} [thisArg] The `this` binding of `callback`.
3910 * @returns {Object} Returns an object without the omitted properties.
3911 * @example
3912 *
3913 * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
3914 * // => { 'name': 'fred' }
3915 *
3916 * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
3917 * return typeof value == 'number';
3918 * });
3919 * // => { 'name': 'fred' }
3920 */
3921 function omit(object, callback, thisArg) {
3922 var result = {};
3923 if (typeof callback != 'function') {
3924 var props = [];
3925 forIn(object, function(value, key) {
3926 props.push(key);
3927 });
3928 props = baseDifference(props, baseFlatten(arguments, true, false, 1));
3929
3930 var index = -1,
3931 length = props.length;
3932
3933 while (++index < length) {
3934 var key = props[index];
3935 result[key] = object[key];
3936 }
3937 } else {
3938 callback = lodash.createCallback(callback, thisArg, 3);
3939 forIn(object, function(value, key, object) {
3940 if (!callback(value, key, object)) {
3941 result[key] = value;
3942 }
3943 });
3944 }
3945 return result;
3946 }
3947
3948 /**
3949 * Creates a two dimensional array of an object's key-value pairs,
3950 * i.e. `[[key1, value1], [key2, value2]]`.
3951 *
3952 * @static
3953 * @memberOf _
3954 * @category Objects
3955 * @param {Object} object The object to inspect.
3956 * @returns {Array} Returns new array of key-value pairs.
3957 * @example
3958 *
3959 * _.pairs({ 'barney': 36, 'fred': 40 });
3960 * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
3961 */
3962 function pairs(object) {
3963 var index = -1,
3964 props = keys(object),
3965 length = props.length,
3966 result = Array(length);
3967
3968 while (++index < length) {
3969 var key = props[index];
3970 result[index] = [key, object[key]];
3971 }
3972 return result;
3973 }
3974
3975 /**
3976 * Creates a shallow clone of `object` composed of the specified properties.
3977 * Property names may be specified as individual arguments or as arrays of
3978 * property names. If a callback is provided it will be executed for each
3979 * property of `object` picking the properties the callback returns truey
3980 * for. The callback is bound to `thisArg` and invoked with three arguments;
3981 * (value, key, object).
3982 *
3983 * @static
3984 * @memberOf _
3985 * @category Objects
3986 * @param {Object} object The source object.
3987 * @param {Function|...string|string[]} [callback] The function called per
3988 * iteration or property names to pick, specified as individual property
3989 * names or arrays of property names.
3990 * @param {*} [thisArg] The `this` binding of `callback`.
3991 * @returns {Object} Returns an object composed of the picked properties.
3992 * @example
3993 *
3994 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
3995 * // => { 'name': 'fred' }
3996 *
3997 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
3998 * return key.charAt(0) != '_';
3999 * });
4000 * // => { 'name': 'fred' }
4001 */
4002 function pick(object, callback, thisArg) {
4003 var result = {};
4004 if (typeof callback != 'function') {
4005 var index = -1,
4006 props = baseFlatten(arguments, true, false, 1),
4007 length = isObject(object) ? props.length : 0;
4008
4009 while (++index < length) {
4010 var key = props[index];
4011 if (key in object) {
4012 result[key] = object[key];
4013 }
4014 }
4015 } else {
4016 callback = lodash.createCallback(callback, thisArg, 3);
4017 forIn(object, function(value, key, object) {
4018 if (callback(value, key, object)) {
4019 result[key] = value;
4020 }
4021 });
4022 }
4023 return result;
4024 }
4025
4026 /**
4027 * An alternative to `_.reduce` this method transforms `object` to a new
4028 * `accumulator` object which is the result of running each of its own
4029 * enumerable properties through a callback, with each callback execution
4030 * potentially mutating the `accumulator` object. The callback is bound to
4031 * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
4032 * Callbacks may exit iteration early by explicitly returning `false`.
4033 *
4034 * @static
4035 * @memberOf _
4036 * @category Objects
4037 * @param {Array|Object} object The object to iterate over.
4038 * @param {Function} [callback=identity] The function called per iteration.
4039 * @param {*} [accumulator] The custom accumulator value.
4040 * @param {*} [thisArg] The `this` binding of `callback`.
4041 * @returns {*} Returns the accumulated value.
4042 * @example
4043 *
4044 * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
4045 * num *= num;
4046 * if (num % 2) {
4047 * return result.push(num) < 3;
4048 * }
4049 * });
4050 * // => [1, 9, 25]
4051 *
4052 * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
4053 * result[key] = num * 3;
4054 * });
4055 * // => { 'a': 3, 'b': 6, 'c': 9 }
4056 */
4057 function transform(object, callback, accumulator, thisArg) {
4058 var isArr = isArray(object);
4059 if (accumulator == null) {
4060 if (isArr) {
4061 accumulator = [];
4062 } else {
4063 var ctor = object && object.constructor,
4064 proto = ctor && ctor.prototype;
4065
4066 accumulator = baseCreate(proto);
4067 }
4068 }
4069 if (callback) {
4070 callback = lodash.createCallback(callback, thisArg, 4);
4071 (isArr ? forEach : forOwn)(object, function(value, index, object) {
4072 return callback(accumulator, value, index, object);
4073 });
4074 }
4075 return accumulator;
4076 }
4077
4078 /**
4079 * Creates an array composed of the own enumerable property values of `object`.
4080 *
4081 * @static
4082 * @memberOf _
4083 * @category Objects
4084 * @param {Object} object The object to inspect.
4085 * @returns {Array} Returns an array of property values.
4086 * @example
4087 *
4088 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
4089 * // => [1, 2, 3] (property order is not guaranteed across environments)
4090 */
4091 function values(object) {
4092 var index = -1,
4093 props = keys(object),
4094 length = props.length,
4095 result = Array(length);
4096
4097 while (++index < length) {
4098 result[index] = object[props[index]];
4099 }
4100 return result;
4101 }
4102
4103 /*--------------------------------------------------------------------------*/
4104
4105 /**
4106 * Creates an array of elements from the specified indexes, or keys, of the
4107 * `collection`. Indexes may be specified as individual arguments or as arrays
4108 * of indexes.
4109 *
4110 * @static
4111 * @memberOf _
4112 * @category Collections
4113 * @param {Array|Object|string} collection The collection to iterate over.
4114 * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
4115 * to retrieve, specified as individual indexes or arrays of indexes.
4116 * @returns {Array} Returns a new array of elements corresponding to the
4117 * provided indexes.
4118 * @example
4119 *
4120 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
4121 * // => ['a', 'c', 'e']
4122 *
4123 * _.at(['fred', 'barney', 'pebbles'], 0, 2);
4124 * // => ['fred', 'pebbles']
4125 */
4126 function at(collection) {
4127 var args = arguments,
4128 index = -1,
4129 props = baseFlatten(args, true, false, 1),
4130 length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
4131 result = Array(length);
4132
4133 while(++index < length) {
4134 result[index] = collection[props[index]];
4135 }
4136 return result;
4137 }
4138
4139 /**
4140 * Checks if a given value is present in a collection using strict equality
4141 * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
4142 * offset from the end of the collection.
4143 *
4144 * @static
4145 * @memberOf _
4146 * @alias include
4147 * @category Collections
4148 * @param {Array|Object|string} collection The collection to iterate over.
4149 * @param {*} target The value to check for.
4150 * @param {number} [fromIndex=0] The index to search from.
4151 * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
4152 * @example
4153 *
4154 * _.contains([1, 2, 3], 1);
4155 * // => true
4156 *
4157 * _.contains([1, 2, 3], 1, 2);
4158 * // => false
4159 *
4160 * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
4161 * // => true
4162 *
4163 * _.contains('pebbles', 'eb');
4164 * // => true
4165 */
4166 function contains(collection, target, fromIndex) {
4167 var index = -1,
4168 indexOf = getIndexOf(),
4169 length = collection ? collection.length : 0,
4170 result = false;
4171
4172 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
4173 if (isArray(collection)) {
4174 result = indexOf(collection, target, fromIndex) > -1;
4175 } else if (typeof length == 'number') {
4176 result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
4177 } else {
4178 forOwn(collection, function(value) {
4179 if (++index >= fromIndex) {
4180 return !(result = value === target);
4181 }
4182 });
4183 }
4184 return result;
4185 }
4186
4187 /**
4188 * Creates an object composed of keys generated from the results of running
4189 * each element of `collection` through the callback. The corresponding value
4190 * of each key is the number of times the key was returned by the callback.
4191 * The callback is bound to `thisArg` and invoked with three arguments;
4192 * (value, index|key, collection).
4193 *
4194 * If a property name is provided for `callback` the created "_.pluck" style
4195 * callback will return the property value of the given element.
4196 *
4197 * If an object is provided for `callback` the created "_.where" style callback
4198 * will return `true` for elements that have the properties of the given object,
4199 * else `false`.
4200 *
4201 * @static
4202 * @memberOf _
4203 * @category Collections
4204 * @param {Array|Object|string} collection The collection to iterate over.
4205 * @param {Function|Object|string} [callback=identity] The function called
4206 * per iteration. If a property name or object is provided it will be used
4207 * to create a "_.pluck" or "_.where" style callback, respectively.
4208 * @param {*} [thisArg] The `this` binding of `callback`.
4209 * @returns {Object} Returns the composed aggregate object.
4210 * @example
4211 *
4212 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
4213 * // => { '4': 1, '6': 2 }
4214 *
4215 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
4216 * // => { '4': 1, '6': 2 }
4217 *
4218 * _.countBy(['one', 'two', 'three'], 'length');
4219 * // => { '3': 2, '5': 1 }
4220 */
4221 var countBy = createAggregator(function(result, value, key) {
4222 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
4223 });
4224
4225 /**
4226 * Checks if the given callback returns truey value for **all** elements of
4227 * a collection. The callback is bound to `thisArg` and invoked with three
4228 * arguments; (value, index|key, collection).
4229 *
4230 * If a property name is provided for `callback` the created "_.pluck" style
4231 * callback will return the property value of the given element.
4232 *
4233 * If an object is provided for `callback` the created "_.where" style callback
4234 * will return `true` for elements that have the properties of the given object,
4235 * else `false`.
4236 *
4237 * @static
4238 * @memberOf _
4239 * @alias all
4240 * @category Collections
4241 * @param {Array|Object|string} collection The collection to iterate over.
4242 * @param {Function|Object|string} [callback=identity] The function called
4243 * per iteration. If a property name or object is provided it will be used
4244 * to create a "_.pluck" or "_.where" style callback, respectively.
4245 * @param {*} [thisArg] The `this` binding of `callback`.
4246 * @returns {boolean} Returns `true` if all elements passed the callback check,
4247 * else `false`.
4248 * @example
4249 *
4250 * _.every([true, 1, null, 'yes']);
4251 * // => false
4252 *
4253 * var characters = [
4254 * { 'name': 'barney', 'age': 36 },
4255 * { 'name': 'fred', 'age': 40 }
4256 * ];
4257 *
4258 * // using "_.pluck" callback shorthand
4259 * _.every(characters, 'age');
4260 * // => true
4261 *
4262 * // using "_.where" callback shorthand
4263 * _.every(characters, { 'age': 36 });
4264 * // => false
4265 */
4266 function every(collection, callback, thisArg) {
4267 var result = true;
4268 callback = lodash.createCallback(callback, thisArg, 3);
4269
4270 var index = -1,
4271 length = collection ? collection.length : 0;
4272
4273 if (typeof length == 'number') {
4274 while (++index < length) {
4275 if (!(result = !!callback(collection[index], index, collection))) {
4276 break;
4277 }
4278 }
4279 } else {
4280 forOwn(collection, function(value, index, collection) {
4281 return (result = !!callback(value, index, collection));
4282 });
4283 }
4284 return result;
4285 }
4286
4287 /**
4288 * Iterates over elements of a collection, returning an array of all elements
4289 * the callback returns truey for. The callback is bound to `thisArg` and
4290 * invoked with three arguments; (value, index|key, collection).
4291 *
4292 * If a property name is provided for `callback` the created "_.pluck" style
4293 * callback will return the property value of the given element.
4294 *
4295 * If an object is provided for `callback` the created "_.where" style callback
4296 * will return `true` for elements that have the properties of the given object,
4297 * else `false`.
4298 *
4299 * @static
4300 * @memberOf _
4301 * @alias select
4302 * @category Collections
4303 * @param {Array|Object|string} collection The collection to iterate over.
4304 * @param {Function|Object|string} [callback=identity] The function called
4305 * per iteration. If a property name or object is provided it will be used
4306 * to create a "_.pluck" or "_.where" style callback, respectively.
4307 * @param {*} [thisArg] The `this` binding of `callback`.
4308 * @returns {Array} Returns a new array of elements that passed the callback check.
4309 * @example
4310 *
4311 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
4312 * // => [2, 4, 6]
4313 *
4314 * var characters = [
4315 * { 'name': 'barney', 'age': 36, 'blocked': false },
4316 * { 'name': 'fred', 'age': 40, 'blocked': true }
4317 * ];
4318 *
4319 * // using "_.pluck" callback shorthand
4320 * _.filter(characters, 'blocked');
4321 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
4322 *
4323 * // using "_.where" callback shorthand
4324 * _.filter(characters, { 'age': 36 });
4325 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
4326 */
4327 function filter(collection, callback, thisArg) {
4328 var result = [];
4329 callback = lodash.createCallback(callback, thisArg, 3);
4330
4331 var index = -1,
4332 length = collection ? collection.length : 0;
4333
4334 if (typeof length == 'number') {
4335 while (++index < length) {
4336 var value = collection[index];
4337 if (callback(value, index, collection)) {
4338 result.push(value);
4339 }
4340 }
4341 } else {
4342 forOwn(collection, function(value, index, collection) {
4343 if (callback(value, index, collection)) {
4344 result.push(value);
4345 }
4346 });
4347 }
4348 return result;
4349 }
4350
4351 /**
4352 * Iterates over elements of a collection, returning the first element that
4353 * the callback returns truey for. The callback is bound to `thisArg` and
4354 * invoked with three arguments; (value, index|key, collection).
4355 *
4356 * If a property name is provided for `callback` the created "_.pluck" style
4357 * callback will return the property value of the given element.
4358 *
4359 * If an object is provided for `callback` the created "_.where" style callback
4360 * will return `true` for elements that have the properties of the given object,
4361 * else `false`.
4362 *
4363 * @static
4364 * @memberOf _
4365 * @alias detect, findWhere
4366 * @category Collections
4367 * @param {Array|Object|string} collection The collection to iterate over.
4368 * @param {Function|Object|string} [callback=identity] The function called
4369 * per iteration. If a property name or object is provided it will be used
4370 * to create a "_.pluck" or "_.where" style callback, respectively.
4371 * @param {*} [thisArg] The `this` binding of `callback`.
4372 * @returns {*} Returns the found element, else `undefined`.
4373 * @example
4374 *
4375 * var characters = [
4376 * { 'name': 'barney', 'age': 36, 'blocked': false },
4377 * { 'name': 'fred', 'age': 40, 'blocked': true },
4378 * { 'name': 'pebbles', 'age': 1, 'blocked': false }
4379 * ];
4380 *
4381 * _.find(characters, function(chr) {
4382 * return chr.age < 40;
4383 * });
4384 * // => { 'name': 'barney', 'age': 36, 'blocked': false }
4385 *
4386 * // using "_.where" callback shorthand
4387 * _.find(characters, { 'age': 1 });
4388 * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
4389 *
4390 * // using "_.pluck" callback shorthand
4391 * _.find(characters, 'blocked');
4392 * // => { 'name': 'fred', 'age': 40, 'blocked': true }
4393 */
4394 function find(collection, callback, thisArg) {
4395 callback = lodash.createCallback(callback, thisArg, 3);
4396
4397 var index = -1,
4398 length = collection ? collection.length : 0;
4399
4400 if (typeof length == 'number') {
4401 while (++index < length) {
4402 var value = collection[index];
4403 if (callback(value, index, collection)) {
4404 return value;
4405 }
4406 }
4407 } else {
4408 var result;
4409 forOwn(collection, function(value, index, collection) {
4410 if (callback(value, index, collection)) {
4411 result = value;
4412 return false;
4413 }
4414 });
4415 return result;
4416 }
4417 }
4418
4419 /**
4420 * This method is like `_.find` except that it iterates over elements
4421 * of a `collection` from right to left.
4422 *
4423 * @static
4424 * @memberOf _
4425 * @category Collections
4426 * @param {Array|Object|string} collection The collection to iterate over.
4427 * @param {Function|Object|string} [callback=identity] The function called
4428 * per iteration. If a property name or object is provided it will be used
4429 * to create a "_.pluck" or "_.where" style callback, respectively.
4430 * @param {*} [thisArg] The `this` binding of `callback`.
4431 * @returns {*} Returns the found element, else `undefined`.
4432 * @example
4433 *
4434 * _.findLast([1, 2, 3, 4], function(num) {
4435 * return num % 2 == 1;
4436 * });
4437 * // => 3
4438 */
4439 function findLast(collection, callback, thisArg) {
4440 var result;
4441 callback = lodash.createCallback(callback, thisArg, 3);
4442 forEachRight(collection, function(value, index, collection) {
4443 if (callback(value, index, collection)) {
4444 result = value;
4445 return false;
4446 }
4447 });
4448 return result;
4449 }
4450
4451 /**
4452 * Iterates over elements of a collection, executing the callback for each
4453 * element. The callback is bound to `thisArg` and invoked with three arguments;
4454 * (value, index|key, collection). Callbacks may exit iteration early by
4455 * explicitly returning `false`.
4456 *
4457 * Note: As with other "Collections" methods, objects with a `length` property
4458 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
4459 * may be used for object iteration.
4460 *
4461 * @static
4462 * @memberOf _
4463 * @alias each
4464 * @category Collections
4465 * @param {Array|Object|string} collection The collection to iterate over.
4466 * @param {Function} [callback=identity] The function called per iteration.
4467 * @param {*} [thisArg] The `this` binding of `callback`.
4468 * @returns {Array|Object|string} Returns `collection`.
4469 * @example
4470 *
4471 * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
4472 * // => logs each number and returns '1,2,3'
4473 *
4474 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
4475 * // => logs each number and returns the object (property order is not guaranteed across environments)
4476 */
4477 function forEach(collection, callback, thisArg) {
4478 var index = -1,
4479 length = collection ? collection.length : 0;
4480
4481 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
4482 if (typeof length == 'number') {
4483 while (++index < length) {
4484 if (callback(collection[index], index, collection) === false) {
4485 break;
4486 }
4487 }
4488 } else {
4489 forOwn(collection, callback);
4490 }
4491 return collection;
4492 }
4493
4494 /**
4495 * This method is like `_.forEach` except that it iterates over elements
4496 * of a `collection` from right to left.
4497 *
4498 * @static
4499 * @memberOf _
4500 * @alias eachRight
4501 * @category Collections
4502 * @param {Array|Object|string} collection The collection to iterate over.
4503 * @param {Function} [callback=identity] The function called per iteration.
4504 * @param {*} [thisArg] The `this` binding of `callback`.
4505 * @returns {Array|Object|string} Returns `collection`.
4506 * @example
4507 *
4508 * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
4509 * // => logs each number from right to left and returns '3,2,1'
4510 */
4511 function forEachRight(collection, callback, thisArg) {
4512 var length = collection ? collection.length : 0;
4513 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
4514 if (typeof length == 'number') {
4515 while (length--) {
4516 if (callback(collection[length], length, collection) === false) {
4517 break;
4518 }
4519 }
4520 } else {
4521 var props = keys(collection);
4522 length = props.length;
4523 forOwn(collection, function(value, key, collection) {
4524 key = props ? props[--length] : --length;
4525 return callback(collection[key], key, collection);
4526 });
4527 }
4528 return collection;
4529 }
4530
4531 /**
4532 * Creates an object composed of keys generated from the results of running
4533 * each element of a collection through the callback. The corresponding value
4534 * of each key is an array of the elements responsible for generating the key.
4535 * The callback is bound to `thisArg` and invoked with three arguments;
4536 * (value, index|key, collection).
4537 *
4538 * If a property name is provided for `callback` the created "_.pluck" style
4539 * callback will return the property value of the given element.
4540 *
4541 * If an object is provided for `callback` the created "_.where" style callback
4542 * will return `true` for elements that have the properties of the given object,
4543 * else `false`
4544 *
4545 * @static
4546 * @memberOf _
4547 * @category Collections
4548 * @param {Array|Object|string} collection The collection to iterate over.
4549 * @param {Function|Object|string} [callback=identity] The function called
4550 * per iteration. If a property name or object is provided it will be used
4551 * to create a "_.pluck" or "_.where" style callback, respectively.
4552 * @param {*} [thisArg] The `this` binding of `callback`.
4553 * @returns {Object} Returns the composed aggregate object.
4554 * @example
4555 *
4556 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
4557 * // => { '4': [4.2], '6': [6.1, 6.4] }
4558 *
4559 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
4560 * // => { '4': [4.2], '6': [6.1, 6.4] }
4561 *
4562 * // using "_.pluck" callback shorthand
4563 * _.groupBy(['one', 'two', 'three'], 'length');
4564 * // => { '3': ['one', 'two'], '5': ['three'] }
4565 */
4566 var groupBy = createAggregator(function(result, value, key) {
4567 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
4568 });
4569
4570 /**
4571 * Creates an object composed of keys generated from the results of running
4572 * each element of the collection through the given callback. The corresponding
4573 * value of each key is the last element responsible for generating the key.
4574 * The callback is bound to `thisArg` and invoked with three arguments;
4575 * (value, index|key, collection).
4576 *
4577 * If a property name is provided for `callback` the created "_.pluck" style
4578 * callback will return the property value of the given element.
4579 *
4580 * If an object is provided for `callback` the created "_.where" style callback
4581 * will return `true` for elements that have the properties of the given object,
4582 * else `false`.
4583 *
4584 * @static
4585 * @memberOf _
4586 * @category Collections
4587 * @param {Array|Object|string} collection The collection to iterate over.
4588 * @param {Function|Object|string} [callback=identity] The function called
4589 * per iteration. If a property name or object is provided it will be used
4590 * to create a "_.pluck" or "_.where" style callback, respectively.
4591 * @param {*} [thisArg] The `this` binding of `callback`.
4592 * @returns {Object} Returns the composed aggregate object.
4593 * @example
4594 *
4595 * var keys = [
4596 * { 'dir': 'left', 'code': 97 },
4597 * { 'dir': 'right', 'code': 100 }
4598 * ];
4599 *
4600 * _.indexBy(keys, 'dir');
4601 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
4602 *
4603 * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
4604 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
4605 *
4606 * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
4607 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
4608 */
4609 var indexBy = createAggregator(function(result, value, key) {
4610 result[key] = value;
4611 });
4612
4613 /**
4614 * Invokes the method named by `methodName` on each element in the `collection`
4615 * returning an array of the results of each invoked method. Additional arguments
4616 * will be provided to each invoked method. If `methodName` is a function it
4617 * will be invoked for, and `this` bound to, each element in the `collection`.
4618 *
4619 * @static
4620 * @memberOf _
4621 * @category Collections
4622 * @param {Array|Object|string} collection The collection to iterate over.
4623 * @param {Function|string} methodName The name of the method to invoke or
4624 * the function invoked per iteration.
4625 * @param {...*} [arg] Arguments to invoke the method with.
4626 * @returns {Array} Returns a new array of the results of each invoked method.
4627 * @example
4628 *
4629 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
4630 * // => [[1, 5, 7], [1, 2, 3]]
4631 *
4632 * _.invoke([123, 456], String.prototype.split, '');
4633 * // => [['1', '2', '3'], ['4', '5', '6']]
4634 */
4635 function invoke(collection, methodName) {
4636 var args = slice(arguments, 2),
4637 index = -1,
4638 isFunc = typeof methodName == 'function',
4639 length = collection ? collection.length : 0,
4640 result = Array(typeof length == 'number' ? length : 0);
4641
4642 forEach(collection, function(value) {
4643 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
4644 });
4645 return result;
4646 }
4647
4648 /**
4649 * Creates an array of values by running each element in the collection
4650 * through the callback. The callback is bound to `thisArg` and invoked with
4651 * three arguments; (value, index|key, collection).
4652 *
4653 * If a property name is provided for `callback` the created "_.pluck" style
4654 * callback will return the property value of the given element.
4655 *
4656 * If an object is provided for `callback` the created "_.where" style callback
4657 * will return `true` for elements that have the properties of the given object,
4658 * else `false`.
4659 *
4660 * @static
4661 * @memberOf _
4662 * @alias collect
4663 * @category Collections
4664 * @param {Array|Object|string} collection The collection to iterate over.
4665 * @param {Function|Object|string} [callback=identity] The function called
4666 * per iteration. If a property name or object is provided it will be used
4667 * to create a "_.pluck" or "_.where" style callback, respectively.
4668 * @param {*} [thisArg] The `this` binding of `callback`.
4669 * @returns {Array} Returns a new array of the results of each `callback` execution.
4670 * @example
4671 *
4672 * _.map([1, 2, 3], function(num) { return num * 3; });
4673 * // => [3, 6, 9]
4674 *
4675 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
4676 * // => [3, 6, 9] (property order is not guaranteed across environments)
4677 *
4678 * var characters = [
4679 * { 'name': 'barney', 'age': 36 },
4680 * { 'name': 'fred', 'age': 40 }
4681 * ];
4682 *
4683 * // using "_.pluck" callback shorthand
4684 * _.map(characters, 'name');
4685 * // => ['barney', 'fred']
4686 */
4687 function map(collection, callback, thisArg) {
4688 var index = -1,
4689 length = collection ? collection.length : 0;
4690
4691 callback = lodash.createCallback(callback, thisArg, 3);
4692 if (typeof length == 'number') {
4693 var result = Array(length);
4694 while (++index < length) {
4695 result[index] = callback(collection[index], index, collection);
4696 }
4697 } else {
4698 result = [];
4699 forOwn(collection, function(value, key, collection) {
4700 result[++index] = callback(value, key, collection);
4701 });
4702 }
4703 return result;
4704 }
4705
4706 /**
4707 * Retrieves the maximum value of a collection. If the collection is empty or
4708 * falsey `-Infinity` is returned. If a callback is provided it will be executed
4709 * for each value in the collection to generate the criterion by which the value
4710 * is ranked. The callback is bound to `thisArg` and invoked with three
4711 * arguments; (value, index, collection).
4712 *
4713 * If a property name is provided for `callback` the created "_.pluck" style
4714 * callback will return the property value of the given element.
4715 *
4716 * If an object is provided for `callback` the created "_.where" style callback
4717 * will return `true` for elements that have the properties of the given object,
4718 * else `false`.
4719 *
4720 * @static
4721 * @memberOf _
4722 * @category Collections
4723 * @param {Array|Object|string} collection The collection to iterate over.
4724 * @param {Function|Object|string} [callback=identity] The function called
4725 * per iteration. If a property name or object is provided it will be used
4726 * to create a "_.pluck" or "_.where" style callback, respectively.
4727 * @param {*} [thisArg] The `this` binding of `callback`.
4728 * @returns {*} Returns the maximum value.
4729 * @example
4730 *
4731 * _.max([4, 2, 8, 6]);
4732 * // => 8
4733 *
4734 * var characters = [
4735 * { 'name': 'barney', 'age': 36 },
4736 * { 'name': 'fred', 'age': 40 }
4737 * ];
4738 *
4739 * _.max(characters, function(chr) { return chr.age; });
4740 * // => { 'name': 'fred', 'age': 40 };
4741 *
4742 * // using "_.pluck" callback shorthand
4743 * _.max(characters, 'age');
4744 * // => { 'name': 'fred', 'age': 40 };
4745 */
4746 function max(collection, callback, thisArg) {
4747 var computed = -Infinity,
4748 result = computed;
4749
4750 // allows working with functions like `_.map` without using
4751 // their `index` argument as a callback
4752 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
4753 callback = null;
4754 }
4755 if (callback == null && isArray(collection)) {
4756 var index = -1,
4757 length = collection.length;
4758
4759 while (++index < length) {
4760 var value = collection[index];
4761 if (value > result) {
4762 result = value;
4763 }
4764 }
4765 } else {
4766 callback = (callback == null && isString(collection))
4767 ? charAtCallback
4768 : lodash.createCallback(callback, thisArg, 3);
4769
4770 forEach(collection, function(value, index, collection) {
4771 var current = callback(value, index, collection);
4772 if (current > computed) {
4773 computed = current;
4774 result = value;
4775 }
4776 });
4777 }
4778 return result;
4779 }
4780
4781 /**
4782 * Retrieves the minimum value of a collection. If the collection is empty or
4783 * falsey `Infinity` is returned. If a callback is provided it will be executed
4784 * for each value in the collection to generate the criterion by which the value
4785 * is ranked. The callback is bound to `thisArg` and invoked with three
4786 * arguments; (value, index, collection).
4787 *
4788 * If a property name is provided for `callback` the created "_.pluck" style
4789 * callback will return the property value of the given element.
4790 *
4791 * If an object is provided for `callback` the created "_.where" style callback
4792 * will return `true` for elements that have the properties of the given object,
4793 * else `false`.
4794 *
4795 * @static
4796 * @memberOf _
4797 * @category Collections
4798 * @param {Array|Object|string} collection The collection to iterate over.
4799 * @param {Function|Object|string} [callback=identity] The function called
4800 * per iteration. If a property name or object is provided it will be used
4801 * to create a "_.pluck" or "_.where" style callback, respectively.
4802 * @param {*} [thisArg] The `this` binding of `callback`.
4803 * @returns {*} Returns the minimum value.
4804 * @example
4805 *
4806 * _.min([4, 2, 8, 6]);
4807 * // => 2
4808 *
4809 * var characters = [
4810 * { 'name': 'barney', 'age': 36 },
4811 * { 'name': 'fred', 'age': 40 }
4812 * ];
4813 *
4814 * _.min(characters, function(chr) { return chr.age; });
4815 * // => { 'name': 'barney', 'age': 36 };
4816 *
4817 * // using "_.pluck" callback shorthand
4818 * _.min(characters, 'age');
4819 * // => { 'name': 'barney', 'age': 36 };
4820 */
4821 function min(collection, callback, thisArg) {
4822 var computed = Infinity,
4823 result = computed;
4824
4825 // allows working with functions like `_.map` without using
4826 // their `index` argument as a callback
4827 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
4828 callback = null;
4829 }
4830 if (callback == null && isArray(collection)) {
4831 var index = -1,
4832 length = collection.length;
4833
4834 while (++index < length) {
4835 var value = collection[index];
4836 if (value < result) {
4837 result = value;
4838 }
4839 }
4840 } else {
4841 callback = (callback == null && isString(collection))
4842 ? charAtCallback
4843 : lodash.createCallback(callback, thisArg, 3);
4844
4845 forEach(collection, function(value, index, collection) {
4846 var current = callback(value, index, collection);
4847 if (current < computed) {
4848 computed = current;
4849 result = value;
4850 }
4851 });
4852 }
4853 return result;
4854 }
4855
4856 /**
4857 * Retrieves the value of a specified property from all elements in the collection.
4858 *
4859 * @static
4860 * @memberOf _
4861 * @type Function
4862 * @category Collections
4863 * @param {Array|Object|string} collection The collection to iterate over.
4864 * @param {string} property The name of the property to pluck.
4865 * @returns {Array} Returns a new array of property values.
4866 * @example
4867 *
4868 * var characters = [
4869 * { 'name': 'barney', 'age': 36 },
4870 * { 'name': 'fred', 'age': 40 }
4871 * ];
4872 *
4873 * _.pluck(characters, 'name');
4874 * // => ['barney', 'fred']
4875 */
4876 var pluck = map;
4877
4878 /**
4879 * Reduces a collection to a value which is the accumulated result of running
4880 * each element in the collection through the callback, where each successive
4881 * callback execution consumes the return value of the previous execution. If
4882 * `accumulator` is not provided the first element of the collection will be
4883 * used as the initial `accumulator` value. The callback is bound to `thisArg`
4884 * and invoked with four arguments; (accumulator, value, index|key, collection).
4885 *
4886 * @static
4887 * @memberOf _
4888 * @alias foldl, inject
4889 * @category Collections
4890 * @param {Array|Object|string} collection The collection to iterate over.
4891 * @param {Function} [callback=identity] The function called per iteration.
4892 * @param {*} [accumulator] Initial value of the accumulator.
4893 * @param {*} [thisArg] The `this` binding of `callback`.
4894 * @returns {*} Returns the accumulated value.
4895 * @example
4896 *
4897 * var sum = _.reduce([1, 2, 3], function(sum, num) {
4898 * return sum + num;
4899 * });
4900 * // => 6
4901 *
4902 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
4903 * result[key] = num * 3;
4904 * return result;
4905 * }, {});
4906 * // => { 'a': 3, 'b': 6, 'c': 9 }
4907 */
4908 function reduce(collection, callback, accumulator, thisArg) {
4909 if (!collection) return accumulator;
4910 var noaccum = arguments.length < 3;
4911 callback = lodash.createCallback(callback, thisArg, 4);
4912
4913 var index = -1,
4914 length = collection.length;
4915
4916 if (typeof length == 'number') {
4917 if (noaccum) {
4918 accumulator = collection[++index];
4919 }
4920 while (++index < length) {
4921 accumulator = callback(accumulator, collection[index], index, collection);
4922 }
4923 } else {
4924 forOwn(collection, function(value, index, collection) {
4925 accumulator = noaccum
4926 ? (noaccum = false, value)
4927 : callback(accumulator, value, index, collection)
4928 });
4929 }
4930 return accumulator;
4931 }
4932
4933 /**
4934 * This method is like `_.reduce` except that it iterates over elements
4935 * of a `collection` from right to left.
4936 *
4937 * @static
4938 * @memberOf _
4939 * @alias foldr
4940 * @category Collections
4941 * @param {Array|Object|string} collection The collection to iterate over.
4942 * @param {Function} [callback=identity] The function called per iteration.
4943 * @param {*} [accumulator] Initial value of the accumulator.
4944 * @param {*} [thisArg] The `this` binding of `callback`.
4945 * @returns {*} Returns the accumulated value.
4946 * @example
4947 *
4948 * var list = [[0, 1], [2, 3], [4, 5]];
4949 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
4950 * // => [4, 5, 2, 3, 0, 1]
4951 */
4952 function reduceRight(collection, callback, accumulator, thisArg) {
4953 var noaccum = arguments.length < 3;
4954 callback = lodash.createCallback(callback, thisArg, 4);
4955 forEachRight(collection, function(value, index, collection) {
4956 accumulator = noaccum
4957 ? (noaccum = false, value)
4958 : callback(accumulator, value, index, collection);
4959 });
4960 return accumulator;
4961 }
4962
4963 /**
4964 * The opposite of `_.filter` this method returns the elements of a
4965 * collection that the callback does **not** return truey for.
4966 *
4967 * If a property name is provided for `callback` the created "_.pluck" style
4968 * callback will return the property value of the given element.
4969 *
4970 * If an object is provided for `callback` the created "_.where" style callback
4971 * will return `true` for elements that have the properties of the given object,
4972 * else `false`.
4973 *
4974 * @static
4975 * @memberOf _
4976 * @category Collections
4977 * @param {Array|Object|string} collection The collection to iterate over.
4978 * @param {Function|Object|string} [callback=identity] The function called
4979 * per iteration. If a property name or object is provided it will be used
4980 * to create a "_.pluck" or "_.where" style callback, respectively.
4981 * @param {*} [thisArg] The `this` binding of `callback`.
4982 * @returns {Array} Returns a new array of elements that failed the callback check.
4983 * @example
4984 *
4985 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
4986 * // => [1, 3, 5]
4987 *
4988 * var characters = [
4989 * { 'name': 'barney', 'age': 36, 'blocked': false },
4990 * { 'name': 'fred', 'age': 40, 'blocked': true }
4991 * ];
4992 *
4993 * // using "_.pluck" callback shorthand
4994 * _.reject(characters, 'blocked');
4995 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
4996 *
4997 * // using "_.where" callback shorthand
4998 * _.reject(characters, { 'age': 36 });
4999 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
5000 */
5001 function reject(collection, callback, thisArg) {
5002 callback = lodash.createCallback(callback, thisArg, 3);
5003 return filter(collection, function(value, index, collection) {
5004 return !callback(value, index, collection);
5005 });
5006 }
5007
5008 /**
5009 * Retrieves a random element or `n` random elements from a collection.
5010 *
5011 * @static
5012 * @memberOf _
5013 * @category Collections
5014 * @param {Array|Object|string} collection The collection to sample.
5015 * @param {number} [n] The number of elements to sample.
5016 * @param- {Object} [guard] Allows working with functions like `_.map`
5017 * without using their `index` arguments as `n`.
5018 * @returns {Array} Returns the random sample(s) of `collection`.
5019 * @example
5020 *
5021 * _.sample([1, 2, 3, 4]);
5022 * // => 2
5023 *
5024 * _.sample([1, 2, 3, 4], 2);
5025 * // => [3, 1]
5026 */
5027 function sample(collection, n, guard) {
5028 if (collection && typeof collection.length != 'number') {
5029 collection = values(collection);
5030 }
5031 if (n == null || guard) {
5032 return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
5033 }
5034 var result = shuffle(collection);
5035 result.length = nativeMin(nativeMax(0, n), result.length);
5036 return result;
5037 }
5038
5039 /**
5040 * Creates an array of shuffled values, using a version of the Fisher-Yates
5041 * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
5042 *
5043 * @static
5044 * @memberOf _
5045 * @category Collections
5046 * @param {Array|Object|string} collection The collection to shuffle.
5047 * @returns {Array} Returns a new shuffled collection.
5048 * @example
5049 *
5050 * _.shuffle([1, 2, 3, 4, 5, 6]);
5051 * // => [4, 1, 6, 3, 5, 2]
5052 */
5053 function shuffle(collection) {
5054 var index = -1,
5055 length = collection ? collection.length : 0,
5056 result = Array(typeof length == 'number' ? length : 0);
5057
5058 forEach(collection, function(value) {
5059 var rand = baseRandom(0, ++index);
5060 result[index] = result[rand];
5061 result[rand] = value;
5062 });
5063 return result;
5064 }
5065
5066 /**
5067 * Gets the size of the `collection` by returning `collection.length` for arrays
5068 * and array-like objects or the number of own enumerable properties for objects.
5069 *
5070 * @static
5071 * @memberOf _
5072 * @category Collections
5073 * @param {Array|Object|string} collection The collection to inspect.
5074 * @returns {number} Returns `collection.length` or number of own enumerable properties.
5075 * @example
5076 *
5077 * _.size([1, 2]);
5078 * // => 2
5079 *
5080 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
5081 * // => 3
5082 *
5083 * _.size('pebbles');
5084 * // => 7
5085 */
5086 function size(collection) {
5087 var length = collection ? collection.length : 0;
5088 return typeof length == 'number' ? length : keys(collection).length;
5089 }
5090
5091 /**
5092 * Checks if the callback returns a truey value for **any** element of a
5093 * collection. The function returns as soon as it finds a passing value and
5094 * does not iterate over the entire collection. The callback is bound to
5095 * `thisArg` and invoked with three arguments; (value, index|key, collection).
5096 *
5097 * If a property name is provided for `callback` the created "_.pluck" style
5098 * callback will return the property value of the given element.
5099 *
5100 * If an object is provided for `callback` the created "_.where" style callback
5101 * will return `true` for elements that have the properties of the given object,
5102 * else `false`.
5103 *
5104 * @static
5105 * @memberOf _
5106 * @alias any
5107 * @category Collections
5108 * @param {Array|Object|string} collection The collection to iterate over.
5109 * @param {Function|Object|string} [callback=identity] The function called
5110 * per iteration. If a property name or object is provided it will be used
5111 * to create a "_.pluck" or "_.where" style callback, respectively.
5112 * @param {*} [thisArg] The `this` binding of `callback`.
5113 * @returns {boolean} Returns `true` if any element passed the callback check,
5114 * else `false`.
5115 * @example
5116 *
5117 * _.some([null, 0, 'yes', false], Boolean);
5118 * // => true
5119 *
5120 * var characters = [
5121 * { 'name': 'barney', 'age': 36, 'blocked': false },
5122 * { 'name': 'fred', 'age': 40, 'blocked': true }
5123 * ];
5124 *
5125 * // using "_.pluck" callback shorthand
5126 * _.some(characters, 'blocked');
5127 * // => true
5128 *
5129 * // using "_.where" callback shorthand
5130 * _.some(characters, { 'age': 1 });
5131 * // => false
5132 */
5133 function some(collection, callback, thisArg) {
5134 var result;
5135 callback = lodash.createCallback(callback, thisArg, 3);
5136
5137 var index = -1,
5138 length = collection ? collection.length : 0;
5139
5140 if (typeof length == 'number') {
5141 while (++index < length) {
5142 if ((result = callback(collection[index], index, collection))) {
5143 break;
5144 }
5145 }
5146 } else {
5147 forOwn(collection, function(value, index, collection) {
5148 return !(result = callback(value, index, collection));
5149 });
5150 }
5151 return !!result;
5152 }
5153
5154 /**
5155 * Creates an array of elements, sorted in ascending order by the results of
5156 * running each element in a collection through the callback. This method
5157 * performs a stable sort, that is, it will preserve the original sort order
5158 * of equal elements. The callback is bound to `thisArg` and invoked with
5159 * three arguments; (value, index|key, collection).
5160 *
5161 * If a property name is provided for `callback` the created "_.pluck" style
5162 * callback will return the property value of the given element.
5163 *
5164 * If an array of property names is provided for `callback` the collection
5165 * will be sorted by each property value.
5166 *
5167 * If an object is provided for `callback` the created "_.where" style callback
5168 * will return `true` for elements that have the properties of the given object,
5169 * else `false`.
5170 *
5171 * @static
5172 * @memberOf _
5173 * @category Collections
5174 * @param {Array|Object|string} collection The collection to iterate over.
5175 * @param {Array|Function|Object|string} [callback=identity] The function called
5176 * per iteration. If a property name or object is provided it will be used
5177 * to create a "_.pluck" or "_.where" style callback, respectively.
5178 * @param {*} [thisArg] The `this` binding of `callback`.
5179 * @returns {Array} Returns a new array of sorted elements.
5180 * @example
5181 *
5182 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
5183 * // => [3, 1, 2]
5184 *
5185 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
5186 * // => [3, 1, 2]
5187 *
5188 * var characters = [
5189 * { 'name': 'barney', 'age': 36 },
5190 * { 'name': 'fred', 'age': 40 },
5191 * { 'name': 'barney', 'age': 26 },
5192 * { 'name': 'fred', 'age': 30 }
5193 * ];
5194 *
5195 * // using "_.pluck" callback shorthand
5196 * _.map(_.sortBy(characters, 'age'), _.values);
5197 * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
5198 *
5199 * // sorting by multiple properties
5200 * _.map(_.sortBy(characters, ['name', 'age']), _.values);
5201 * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
5202 */
5203 function sortBy(collection, callback, thisArg) {
5204 var index = -1,
5205 isArr = isArray(callback),
5206 length = collection ? collection.length : 0,
5207 result = Array(typeof length == 'number' ? length : 0);
5208
5209 if (!isArr) {
5210 callback = lodash.createCallback(callback, thisArg, 3);
5211 }
5212 forEach(collection, function(value, key, collection) {
5213 var object = result[++index] = getObject();
5214 if (isArr) {
5215 object.criteria = map(callback, function(key) { return value[key]; });
5216 } else {
5217 (object.criteria = getArray())[0] = callback(value, key, collection);
5218 }
5219 object.index = index;
5220 object.value = value;
5221 });
5222
5223 length = result.length;
5224 result.sort(compareAscending);
5225 while (length--) {
5226 var object = result[length];
5227 result[length] = object.value;
5228 if (!isArr) {
5229 releaseArray(object.criteria);
5230 }
5231 releaseObject(object);
5232 }
5233 return result;
5234 }
5235
5236 /**
5237 * Converts the `collection` to an array.
5238 *
5239 * @static
5240 * @memberOf _
5241 * @category Collections
5242 * @param {Array|Object|string} collection The collection to convert.
5243 * @returns {Array} Returns the new converted array.
5244 * @example
5245 *
5246 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
5247 * // => [2, 3, 4]
5248 */
5249 function toArray(collection) {
5250 if (collection && typeof collection.length == 'number') {
5251 return slice(collection);
5252 }
5253 return values(collection);
5254 }
5255
5256 /**
5257 * Performs a deep comparison of each element in a `collection` to the given
5258 * `properties` object, returning an array of all elements that have equivalent
5259 * property values.
5260 *
5261 * @static
5262 * @memberOf _
5263 * @type Function
5264 * @category Collections
5265 * @param {Array|Object|string} collection The collection to iterate over.
5266 * @param {Object} props The object of property values to filter by.
5267 * @returns {Array} Returns a new array of elements that have the given properties.
5268 * @example
5269 *
5270 * var characters = [
5271 * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
5272 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
5273 * ];
5274 *
5275 * _.where(characters, { 'age': 36 });
5276 * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
5277 *
5278 * _.where(characters, { 'pets': ['dino'] });
5279 * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
5280 */
5281 var where = filter;
5282
5283 /*--------------------------------------------------------------------------*/
5284
5285 /**
5286 * Creates an array with all falsey values removed. The values `false`, `null`,
5287 * `0`, `""`, `undefined`, and `NaN` are all falsey.
5288 *
5289 * @static
5290 * @memberOf _
5291 * @category Arrays
5292 * @param {Array} array The array to compact.
5293 * @returns {Array} Returns a new array of filtered values.
5294 * @example
5295 *
5296 * _.compact([0, 1, false, 2, '', 3]);
5297 * // => [1, 2, 3]
5298 */
5299 function compact(array) {
5300 var index = -1,
5301 length = array ? array.length : 0,
5302 result = [];
5303
5304 while (++index < length) {
5305 var value = array[index];
5306 if (value) {
5307 result.push(value);
5308 }
5309 }
5310 return result;
5311 }
5312
5313 /**
5314 * Creates an array excluding all values of the provided arrays using strict
5315 * equality for comparisons, i.e. `===`.
5316 *
5317 * @static
5318 * @memberOf _
5319 * @category Arrays
5320 * @param {Array} array The array to process.
5321 * @param {...Array} [values] The arrays of values to exclude.
5322 * @returns {Array} Returns a new array of filtered values.
5323 * @example
5324 *
5325 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
5326 * // => [1, 3, 4]
5327 */
5328 function difference(array) {
5329 return baseDifference(array, baseFlatten(arguments, true, true, 1));
5330 }
5331
5332 /**
5333 * This method is like `_.find` except that it returns the index of the first
5334 * element that passes the callback check, instead of the element itself.
5335 *
5336 * If a property name is provided for `callback` the created "_.pluck" style
5337 * callback will return the property value of the given element.
5338 *
5339 * If an object is provided for `callback` the created "_.where" style callback
5340 * will return `true` for elements that have the properties of the given object,
5341 * else `false`.
5342 *
5343 * @static
5344 * @memberOf _
5345 * @category Arrays
5346 * @param {Array} array The array to search.
5347 * @param {Function|Object|string} [callback=identity] The function called
5348 * per iteration. If a property name or object is provided it will be used
5349 * to create a "_.pluck" or "_.where" style callback, respectively.
5350 * @param {*} [thisArg] The `this` binding of `callback`.
5351 * @returns {number} Returns the index of the found element, else `-1`.
5352 * @example
5353 *
5354 * var characters = [
5355 * { 'name': 'barney', 'age': 36, 'blocked': false },
5356 * { 'name': 'fred', 'age': 40, 'blocked': true },
5357 * { 'name': 'pebbles', 'age': 1, 'blocked': false }
5358 * ];
5359 *
5360 * _.findIndex(characters, function(chr) {
5361 * return chr.age < 20;
5362 * });
5363 * // => 2
5364 *
5365 * // using "_.where" callback shorthand
5366 * _.findIndex(characters, { 'age': 36 });
5367 * // => 0
5368 *
5369 * // using "_.pluck" callback shorthand
5370 * _.findIndex(characters, 'blocked');
5371 * // => 1
5372 */
5373 function findIndex(array, callback, thisArg) {
5374 var index = -1,
5375 length = array ? array.length : 0;
5376
5377 callback = lodash.createCallback(callback, thisArg, 3);
5378 while (++index < length) {
5379 if (callback(array[index], index, array)) {
5380 return index;
5381 }
5382 }
5383 return -1;
5384 }
5385
5386 /**
5387 * This method is like `_.findIndex` except that it iterates over elements
5388 * of a `collection` from right to left.
5389 *
5390 * If a property name is provided for `callback` the created "_.pluck" style
5391 * callback will return the property value of the given element.
5392 *
5393 * If an object is provided for `callback` the created "_.where" style callback
5394 * will return `true` for elements that have the properties of the given object,
5395 * else `false`.
5396 *
5397 * @static
5398 * @memberOf _
5399 * @category Arrays
5400 * @param {Array} array The array to search.
5401 * @param {Function|Object|string} [callback=identity] The function called
5402 * per iteration. If a property name or object is provided it will be used
5403 * to create a "_.pluck" or "_.where" style callback, respectively.
5404 * @param {*} [thisArg] The `this` binding of `callback`.
5405 * @returns {number} Returns the index of the found element, else `-1`.
5406 * @example
5407 *
5408 * var characters = [
5409 * { 'name': 'barney', 'age': 36, 'blocked': true },
5410 * { 'name': 'fred', 'age': 40, 'blocked': false },
5411 * { 'name': 'pebbles', 'age': 1, 'blocked': true }
5412 * ];
5413 *
5414 * _.findLastIndex(characters, function(chr) {
5415 * return chr.age > 30;
5416 * });
5417 * // => 1
5418 *
5419 * // using "_.where" callback shorthand
5420 * _.findLastIndex(characters, { 'age': 36 });
5421 * // => 0
5422 *
5423 * // using "_.pluck" callback shorthand
5424 * _.findLastIndex(characters, 'blocked');
5425 * // => 2
5426 */
5427 function findLastIndex(array, callback, thisArg) {
5428 var length = array ? array.length : 0;
5429 callback = lodash.createCallback(callback, thisArg, 3);
5430 while (length--) {
5431 if (callback(array[length], length, array)) {
5432 return length;
5433 }
5434 }
5435 return -1;
5436 }
5437
5438 /**
5439 * Gets the first element or first `n` elements of an array. If a callback
5440 * is provided elements at the beginning of the array are returned as long
5441 * as the callback returns truey. The callback is bound to `thisArg` and
5442 * invoked with three arguments; (value, index, array).
5443 *
5444 * If a property name is provided for `callback` the created "_.pluck" style
5445 * callback will return the property value of the given element.
5446 *
5447 * If an object is provided for `callback` the created "_.where" style callback
5448 * will return `true` for elements that have the properties of the given object,
5449 * else `false`.
5450 *
5451 * @static
5452 * @memberOf _
5453 * @alias head, take
5454 * @category Arrays
5455 * @param {Array} array The array to query.
5456 * @param {Function|Object|number|string} [callback] The function called
5457 * per element or the number of elements to return. If a property name or
5458 * object is provided it will be used to create a "_.pluck" or "_.where"
5459 * style callback, respectively.
5460 * @param {*} [thisArg] The `this` binding of `callback`.
5461 * @returns {*} Returns the first element(s) of `array`.
5462 * @example
5463 *
5464 * _.first([1, 2, 3]);
5465 * // => 1
5466 *
5467 * _.first([1, 2, 3], 2);
5468 * // => [1, 2]
5469 *
5470 * _.first([1, 2, 3], function(num) {
5471 * return num < 3;
5472 * });
5473 * // => [1, 2]
5474 *
5475 * var characters = [
5476 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
5477 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
5478 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
5479 * ];
5480 *
5481 * // using "_.pluck" callback shorthand
5482 * _.first(characters, 'blocked');
5483 * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
5484 *
5485 * // using "_.where" callback shorthand
5486 * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
5487 * // => ['barney', 'fred']
5488 */
5489 function first(array, callback, thisArg) {
5490 var n = 0,
5491 length = array ? array.length : 0;
5492
5493 if (typeof callback != 'number' && callback != null) {
5494 var index = -1;
5495 callback = lodash.createCallback(callback, thisArg, 3);
5496 while (++index < length && callback(array[index], index, array)) {
5497 n++;
5498 }
5499 } else {
5500 n = callback;
5501 if (n == null || thisArg) {
5502 return array ? array[0] : undefined;
5503 }
5504 }
5505 return slice(array, 0, nativeMin(nativeMax(0, n), length));
5506 }
5507
5508 /**
5509 * Flattens a nested array (the nesting can be to any depth). If `isShallow`
5510 * is truey, the array will only be flattened a single level. If a callback
5511 * is provided each element of the array is passed through the callback before
5512 * flattening. The callback is bound to `thisArg` and invoked with three
5513 * arguments; (value, index, array).
5514 *
5515 * If a property name is provided for `callback` the created "_.pluck" style
5516 * callback will return the property value of the given element.
5517 *
5518 * If an object is provided for `callback` the created "_.where" style callback
5519 * will return `true` for elements that have the properties of the given object,
5520 * else `false`.
5521 *
5522 * @static
5523 * @memberOf _
5524 * @category Arrays
5525 * @param {Array} array The array to flatten.
5526 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
5527 * @param {Function|Object|string} [callback=identity] The function called
5528 * per iteration. If a property name or object is provided it will be used
5529 * to create a "_.pluck" or "_.where" style callback, respectively.
5530 * @param {*} [thisArg] The `this` binding of `callback`.
5531 * @returns {Array} Returns a new flattened array.
5532 * @example
5533 *
5534 * _.flatten([1, [2], [3, [[4]]]]);
5535 * // => [1, 2, 3, 4];
5536 *
5537 * _.flatten([1, [2], [3, [[4]]]], true);
5538 * // => [1, 2, 3, [[4]]];
5539 *
5540 * var characters = [
5541 * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
5542 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
5543 * ];
5544 *
5545 * // using "_.pluck" callback shorthand
5546 * _.flatten(characters, 'pets');
5547 * // => ['hoppy', 'baby puss', 'dino']
5548 */
5549 function flatten(array, isShallow, callback, thisArg) {
5550 // juggle arguments
5551 if (typeof isShallow != 'boolean' && isShallow != null) {
5552 thisArg = callback;
5553 callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
5554 isShallow = false;
5555 }
5556 if (callback != null) {
5557 array = map(array, callback, thisArg);
5558 }
5559 return baseFlatten(array, isShallow);
5560 }
5561
5562 /**
5563 * Gets the index at which the first occurrence of `value` is found using
5564 * strict equality for comparisons, i.e. `===`. If the array is already sorted
5565 * providing `true` for `fromIndex` will run a faster binary search.
5566 *
5567 * @static
5568 * @memberOf _
5569 * @category Arrays
5570 * @param {Array} array The array to search.
5571 * @param {*} value The value to search for.
5572 * @param {boolean|number} [fromIndex=0] The index to search from or `true`
5573 * to perform a binary search on a sorted array.
5574 * @returns {number} Returns the index of the matched value or `-1`.
5575 * @example
5576 *
5577 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
5578 * // => 1
5579 *
5580 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
5581 * // => 4
5582 *
5583 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
5584 * // => 2
5585 */
5586 function indexOf(array, value, fromIndex) {
5587 if (typeof fromIndex == 'number') {
5588 var length = array ? array.length : 0;
5589 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
5590 } else if (fromIndex) {
5591 var index = sortedIndex(array, value);
5592 return array[index] === value ? index : -1;
5593 }
5594 return baseIndexOf(array, value, fromIndex);
5595 }
5596
5597 /**
5598 * Gets all but the last element or last `n` elements of an array. If a
5599 * callback is provided elements at the end of the array are excluded from
5600 * the result as long as the callback returns truey. The callback is bound
5601 * to `thisArg` and invoked with three arguments; (value, index, array).
5602 *
5603 * If a property name is provided for `callback` the created "_.pluck" style
5604 * callback will return the property value of the given element.
5605 *
5606 * If an object is provided for `callback` the created "_.where" style callback
5607 * will return `true` for elements that have the properties of the given object,
5608 * else `false`.
5609 *
5610 * @static
5611 * @memberOf _
5612 * @category Arrays
5613 * @param {Array} array The array to query.
5614 * @param {Function|Object|number|string} [callback=1] The function called
5615 * per element or the number of elements to exclude. If a property name or
5616 * object is provided it will be used to create a "_.pluck" or "_.where"
5617 * style callback, respectively.
5618 * @param {*} [thisArg] The `this` binding of `callback`.
5619 * @returns {Array} Returns a slice of `array`.
5620 * @example
5621 *
5622 * _.initial([1, 2, 3]);
5623 * // => [1, 2]
5624 *
5625 * _.initial([1, 2, 3], 2);
5626 * // => [1]
5627 *
5628 * _.initial([1, 2, 3], function(num) {
5629 * return num > 1;
5630 * });
5631 * // => [1]
5632 *
5633 * var characters = [
5634 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
5635 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
5636 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
5637 * ];
5638 *
5639 * // using "_.pluck" callback shorthand
5640 * _.initial(characters, 'blocked');
5641 * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
5642 *
5643 * // using "_.where" callback shorthand
5644 * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
5645 * // => ['barney', 'fred']
5646 */
5647 function initial(array, callback, thisArg) {
5648 var n = 0,
5649 length = array ? array.length : 0;
5650
5651 if (typeof callback != 'number' && callback != null) {
5652 var index = length;
5653 callback = lodash.createCallback(callback, thisArg, 3);
5654 while (index-- && callback(array[index], index, array)) {
5655 n++;
5656 }
5657 } else {
5658 n = (callback == null || thisArg) ? 1 : callback || n;
5659 }
5660 return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
5661 }
5662
5663 /**
5664 * Creates an array of unique values present in all provided arrays using
5665 * strict equality for comparisons, i.e. `===`.
5666 *
5667 * @static
5668 * @memberOf _
5669 * @category Arrays
5670 * @param {...Array} [array] The arrays to inspect.
5671 * @returns {Array} Returns an array of shared values.
5672 * @example
5673 *
5674 * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
5675 * // => [1, 2]
5676 */
5677 function intersection() {
5678 var args = [],
5679 argsIndex = -1,
5680 argsLength = arguments.length,
5681 caches = getArray(),
5682 indexOf = getIndexOf(),
5683 trustIndexOf = indexOf === baseIndexOf,
5684 seen = getArray();
5685
5686 while (++argsIndex < argsLength) {
5687 var value = arguments[argsIndex];
5688 if (isArray(value) || isArguments(value)) {
5689 args.push(value);
5690 caches.push(trustIndexOf && value.length >= largeArraySize &&
5691 createCache(argsIndex ? args[argsIndex] : seen));
5692 }
5693 }
5694 var array = args[0],
5695 index = -1,
5696 length = array ? array.length : 0,
5697 result = [];
5698
5699 outer:
5700 while (++index < length) {
5701 var cache = caches[0];
5702 value = array[index];
5703
5704 if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
5705 argsIndex = argsLength;
5706 (cache || seen).push(value);
5707 while (--argsIndex) {
5708 cache = caches[argsIndex];
5709 if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
5710 continue outer;
5711 }
5712 }
5713 result.push(value);
5714 }
5715 }
5716 while (argsLength--) {
5717 cache = caches[argsLength];
5718 if (cache) {
5719 releaseObject(cache);
5720 }
5721 }
5722 releaseArray(caches);
5723 releaseArray(seen);
5724 return result;
5725 }
5726
5727 /**
5728 * Gets the last element or last `n` elements of an array. If a callback is
5729 * provided elements at the end of the array are returned as long as the
5730 * callback returns truey. The callback is bound to `thisArg` and invoked
5731 * with three arguments; (value, index, array).
5732 *
5733 * If a property name is provided for `callback` the created "_.pluck" style
5734 * callback will return the property value of the given element.
5735 *
5736 * If an object is provided for `callback` the created "_.where" style callback
5737 * will return `true` for elements that have the properties of the given object,
5738 * else `false`.
5739 *
5740 * @static
5741 * @memberOf _
5742 * @category Arrays
5743 * @param {Array} array The array to query.
5744 * @param {Function|Object|number|string} [callback] The function called
5745 * per element or the number of elements to return. If a property name or
5746 * object is provided it will be used to create a "_.pluck" or "_.where"
5747 * style callback, respectively.
5748 * @param {*} [thisArg] The `this` binding of `callback`.
5749 * @returns {*} Returns the last element(s) of `array`.
5750 * @example
5751 *
5752 * _.last([1, 2, 3]);
5753 * // => 3
5754 *
5755 * _.last([1, 2, 3], 2);
5756 * // => [2, 3]
5757 *
5758 * _.last([1, 2, 3], function(num) {
5759 * return num > 1;
5760 * });
5761 * // => [2, 3]
5762 *
5763 * var characters = [
5764 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
5765 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
5766 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
5767 * ];
5768 *
5769 * // using "_.pluck" callback shorthand
5770 * _.pluck(_.last(characters, 'blocked'), 'name');
5771 * // => ['fred', 'pebbles']
5772 *
5773 * // using "_.where" callback shorthand
5774 * _.last(characters, { 'employer': 'na' });
5775 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
5776 */
5777 function last(array, callback, thisArg) {
5778 var n = 0,
5779 length = array ? array.length : 0;
5780
5781 if (typeof callback != 'number' && callback != null) {
5782 var index = length;
5783 callback = lodash.createCallback(callback, thisArg, 3);
5784 while (index-- && callback(array[index], index, array)) {
5785 n++;
5786 }
5787 } else {
5788 n = callback;
5789 if (n == null || thisArg) {
5790 return array ? array[length - 1] : undefined;
5791 }
5792 }
5793 return slice(array, nativeMax(0, length - n));
5794 }
5795
5796 /**
5797 * Gets the index at which the last occurrence of `value` is found using strict
5798 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
5799 * as the offset from the end of the collection.
5800 *
5801 * If a property name is provided for `callback` the created "_.pluck" style
5802 * callback will return the property value of the given element.
5803 *
5804 * If an object is provided for `callback` the created "_.where" style callback
5805 * will return `true` for elements that have the properties of the given object,
5806 * else `false`.
5807 *
5808 * @static
5809 * @memberOf _
5810 * @category Arrays
5811 * @param {Array} array The array to search.
5812 * @param {*} value The value to search for.
5813 * @param {number} [fromIndex=array.length-1] The index to search from.
5814 * @returns {number} Returns the index of the matched value or `-1`.
5815 * @example
5816 *
5817 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
5818 * // => 4
5819 *
5820 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
5821 * // => 1
5822 */
5823 function lastIndexOf(array, value, fromIndex) {
5824 var index = array ? array.length : 0;
5825 if (typeof fromIndex == 'number') {
5826 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
5827 }
5828 while (index--) {
5829 if (array[index] === value) {
5830 return index;
5831 }
5832 }
5833 return -1;
5834 }
5835
5836 /**
5837 * Removes all provided values from the given array using strict equality for
5838 * comparisons, i.e. `===`.
5839 *
5840 * @static
5841 * @memberOf _
5842 * @category Arrays
5843 * @param {Array} array The array to modify.
5844 * @param {...*} [value] The values to remove.
5845 * @returns {Array} Returns `array`.
5846 * @example
5847 *
5848 * var array = [1, 2, 3, 1, 2, 3];
5849 * _.pull(array, 2, 3);
5850 * console.log(array);
5851 * // => [1, 1]
5852 */
5853 function pull(array) {
5854 var args = arguments,
5855 argsIndex = 0,
5856 argsLength = args.length,
5857 length = array ? array.length : 0;
5858
5859 while (++argsIndex < argsLength) {
5860 var index = -1,
5861 value = args[argsIndex];
5862 while (++index < length) {
5863 if (array[index] === value) {
5864 splice.call(array, index--, 1);
5865 length--;
5866 }
5867 }
5868 }
5869 return array;
5870 }
5871
5872 /**
5873 * Creates an array of numbers (positive and/or negative) progressing from
5874 * `start` up to but not including `end`. If `start` is less than `stop` a
5875 * zero-length range is created unless a negative `step` is specified.
5876 *
5877 * @static
5878 * @memberOf _
5879 * @category Arrays
5880 * @param {number} [start=0] The start of the range.
5881 * @param {number} end The end of the range.
5882 * @param {number} [step=1] The value to increment or decrement by.
5883 * @returns {Array} Returns a new range array.
5884 * @example
5885 *
5886 * _.range(4);
5887 * // => [0, 1, 2, 3]
5888 *
5889 * _.range(1, 5);
5890 * // => [1, 2, 3, 4]
5891 *
5892 * _.range(0, 20, 5);
5893 * // => [0, 5, 10, 15]
5894 *
5895 * _.range(0, -4, -1);
5896 * // => [0, -1, -2, -3]
5897 *
5898 * _.range(1, 4, 0);
5899 * // => [1, 1, 1]
5900 *
5901 * _.range(0);
5902 * // => []
5903 */
5904 function range(start, end, step) {
5905 start = +start || 0;
5906 step = typeof step == 'number' ? step : (+step || 1);
5907
5908 if (end == null) {
5909 end = start;
5910 start = 0;
5911 }
5912 // use `Array(length)` so engines like Chakra and V8 avoid slower modes
5913 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
5914 var index = -1,
5915 length = nativeMax(0, ceil((end - start) / (step || 1))),
5916 result = Array(length);
5917
5918 while (++index < length) {
5919 result[index] = start;
5920 start += step;
5921 }
5922 return result;
5923 }
5924
5925 /**
5926 * Removes all elements from an array that the callback returns truey for
5927 * and returns an array of removed elements. The callback is bound to `thisArg`
5928 * and invoked with three arguments; (value, index, array).
5929 *
5930 * If a property name is provided for `callback` the created "_.pluck" style
5931 * callback will return the property value of the given element.
5932 *
5933 * If an object is provided for `callback` the created "_.where" style callback
5934 * will return `true` for elements that have the properties of the given object,
5935 * else `false`.
5936 *
5937 * @static
5938 * @memberOf _
5939 * @category Arrays
5940 * @param {Array} array The array to modify.
5941 * @param {Function|Object|string} [callback=identity] The function called
5942 * per iteration. If a property name or object is provided it will be used
5943 * to create a "_.pluck" or "_.where" style callback, respectively.
5944 * @param {*} [thisArg] The `this` binding of `callback`.
5945 * @returns {Array} Returns a new array of removed elements.
5946 * @example
5947 *
5948 * var array = [1, 2, 3, 4, 5, 6];
5949 * var evens = _.remove(array, function(num) { return num % 2 == 0; });
5950 *
5951 * console.log(array);
5952 * // => [1, 3, 5]
5953 *
5954 * console.log(evens);
5955 * // => [2, 4, 6]
5956 */
5957 function remove(array, callback, thisArg) {
5958 var index = -1,
5959 length = array ? array.length : 0,
5960 result = [];
5961
5962 callback = lodash.createCallback(callback, thisArg, 3);
5963 while (++index < length) {
5964 var value = array[index];
5965 if (callback(value, index, array)) {
5966 result.push(value);
5967 splice.call(array, index--, 1);
5968 length--;
5969 }
5970 }
5971 return result;
5972 }
5973
5974 /**
5975 * The opposite of `_.initial` this method gets all but the first element or
5976 * first `n` elements of an array. If a callback function is provided elements
5977 * at the beginning of the array are excluded from the result as long as the
5978 * callback returns truey. The callback is bound to `thisArg` and invoked
5979 * with three arguments; (value, index, array).
5980 *
5981 * If a property name is provided for `callback` the created "_.pluck" style
5982 * callback will return the property value of the given element.
5983 *
5984 * If an object is provided for `callback` the created "_.where" style callback
5985 * will return `true` for elements that have the properties of the given object,
5986 * else `false`.
5987 *
5988 * @static
5989 * @memberOf _
5990 * @alias drop, tail
5991 * @category Arrays
5992 * @param {Array} array The array to query.
5993 * @param {Function|Object|number|string} [callback=1] The function called
5994 * per element or the number of elements to exclude. If a property name or
5995 * object is provided it will be used to create a "_.pluck" or "_.where"
5996 * style callback, respectively.
5997 * @param {*} [thisArg] The `this` binding of `callback`.
5998 * @returns {Array} Returns a slice of `array`.
5999 * @example
6000 *
6001 * _.rest([1, 2, 3]);
6002 * // => [2, 3]
6003 *
6004 * _.rest([1, 2, 3], 2);
6005 * // => [3]
6006 *
6007 * _.rest([1, 2, 3], function(num) {
6008 * return num < 3;
6009 * });
6010 * // => [3]
6011 *
6012 * var characters = [
6013 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
6014 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
6015 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
6016 * ];
6017 *
6018 * // using "_.pluck" callback shorthand
6019 * _.pluck(_.rest(characters, 'blocked'), 'name');
6020 * // => ['fred', 'pebbles']
6021 *
6022 * // using "_.where" callback shorthand
6023 * _.rest(characters, { 'employer': 'slate' });
6024 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
6025 */
6026 function rest(array, callback, thisArg) {
6027 if (typeof callback != 'number' && callback != null) {
6028 var n = 0,
6029 index = -1,
6030 length = array ? array.length : 0;
6031
6032 callback = lodash.createCallback(callback, thisArg, 3);
6033 while (++index < length && callback(array[index], index, array)) {
6034 n++;
6035 }
6036 } else {
6037 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
6038 }
6039 return slice(array, n);
6040 }
6041
6042 /**
6043 * Uses a binary search to determine the smallest index at which a value
6044 * should be inserted into a given sorted array in order to maintain the sort
6045 * order of the array. If a callback is provided it will be executed for
6046 * `value` and each element of `array` to compute their sort ranking. The
6047 * callback is bound to `thisArg` and invoked with one argument; (value).
6048 *
6049 * If a property name is provided for `callback` the created "_.pluck" style
6050 * callback will return the property value of the given element.
6051 *
6052 * If an object is provided for `callback` the created "_.where" style callback
6053 * will return `true` for elements that have the properties of the given object,
6054 * else `false`.
6055 *
6056 * @static
6057 * @memberOf _
6058 * @category Arrays
6059 * @param {Array} array The array to inspect.
6060 * @param {*} value The value to evaluate.
6061 * @param {Function|Object|string} [callback=identity] The function called
6062 * per iteration. If a property name or object is provided it will be used
6063 * to create a "_.pluck" or "_.where" style callback, respectively.
6064 * @param {*} [thisArg] The `this` binding of `callback`.
6065 * @returns {number} Returns the index at which `value` should be inserted
6066 * into `array`.
6067 * @example
6068 *
6069 * _.sortedIndex([20, 30, 50], 40);
6070 * // => 2
6071 *
6072 * // using "_.pluck" callback shorthand
6073 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
6074 * // => 2
6075 *
6076 * var dict = {
6077 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
6078 * };
6079 *
6080 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
6081 * return dict.wordToNumber[word];
6082 * });
6083 * // => 2
6084 *
6085 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
6086 * return this.wordToNumber[word];
6087 * }, dict);
6088 * // => 2
6089 */
6090 function sortedIndex(array, value, callback, thisArg) {
6091 var low = 0,
6092 high = array ? array.length : low;
6093
6094 // explicitly reference `identity` for better inlining in Firefox
6095 callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
6096 value = callback(value);
6097
6098 while (low < high) {
6099 var mid = (low + high) >>> 1;
6100 (callback(array[mid]) < value)
6101 ? low = mid + 1
6102 : high = mid;
6103 }
6104 return low;
6105 }
6106
6107 /**
6108 * Creates an array of unique values, in order, of the provided arrays using
6109 * strict equality for comparisons, i.e. `===`.
6110 *
6111 * @static
6112 * @memberOf _
6113 * @category Arrays
6114 * @param {...Array} [array] The arrays to inspect.
6115 * @returns {Array} Returns an array of combined values.
6116 * @example
6117 *
6118 * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
6119 * // => [1, 2, 3, 5, 4]
6120 */
6121 function union() {
6122 return baseUniq(baseFlatten(arguments, true, true));
6123 }
6124
6125 /**
6126 * Creates a duplicate-value-free version of an array using strict equality
6127 * for comparisons, i.e. `===`. If the array is sorted, providing
6128 * `true` for `isSorted` will use a faster algorithm. If a callback is provided
6129 * each element of `array` is passed through the callback before uniqueness
6130 * is computed. The callback is bound to `thisArg` and invoked with three
6131 * arguments; (value, index, array).
6132 *
6133 * If a property name is provided for `callback` the created "_.pluck" style
6134 * callback will return the property value of the given element.
6135 *
6136 * If an object is provided for `callback` the created "_.where" style callback
6137 * will return `true` for elements that have the properties of the given object,
6138 * else `false`.
6139 *
6140 * @static
6141 * @memberOf _
6142 * @alias unique
6143 * @category Arrays
6144 * @param {Array} array The array to process.
6145 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
6146 * @param {Function|Object|string} [callback=identity] The function called
6147 * per iteration. If a property name or object is provided it will be used
6148 * to create a "_.pluck" or "_.where" style callback, respectively.
6149 * @param {*} [thisArg] The `this` binding of `callback`.
6150 * @returns {Array} Returns a duplicate-value-free array.
6151 * @example
6152 *
6153 * _.uniq([1, 2, 1, 3, 1]);
6154 * // => [1, 2, 3]
6155 *
6156 * _.uniq([1, 1, 2, 2, 3], true);
6157 * // => [1, 2, 3]
6158 *
6159 * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
6160 * // => ['A', 'b', 'C']
6161 *
6162 * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
6163 * // => [1, 2.5, 3]
6164 *
6165 * // using "_.pluck" callback shorthand
6166 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6167 * // => [{ 'x': 1 }, { 'x': 2 }]
6168 */
6169 function uniq(array, isSorted, callback, thisArg) {
6170 // juggle arguments
6171 if (typeof isSorted != 'boolean' && isSorted != null) {
6172 thisArg = callback;
6173 callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
6174 isSorted = false;
6175 }
6176 if (callback != null) {
6177 callback = lodash.createCallback(callback, thisArg, 3);
6178 }
6179 return baseUniq(array, isSorted, callback);
6180 }
6181
6182 /**
6183 * Creates an array excluding all provided values using strict equality for
6184 * comparisons, i.e. `===`.
6185 *
6186 * @static
6187 * @memberOf _
6188 * @category Arrays
6189 * @param {Array} array The array to filter.
6190 * @param {...*} [value] The values to exclude.
6191 * @returns {Array} Returns a new array of filtered values.
6192 * @example
6193 *
6194 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
6195 * // => [2, 3, 4]
6196 */
6197 function without(array) {
6198 return baseDifference(array, slice(arguments, 1));
6199 }
6200
6201 /**
6202 * Creates an array that is the symmetric difference of the provided arrays.
6203 * See http://en.wikipedia.org/wiki/Symmetric_difference.
6204 *
6205 * @static
6206 * @memberOf _
6207 * @category Arrays
6208 * @param {...Array} [array] The arrays to inspect.
6209 * @returns {Array} Returns an array of values.
6210 * @example
6211 *
6212 * _.xor([1, 2, 3], [5, 2, 1, 4]);
6213 * // => [3, 5, 4]
6214 *
6215 * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
6216 * // => [1, 4, 5]
6217 */
6218 function xor() {
6219 var index = -1,
6220 length = arguments.length;
6221
6222 while (++index < length) {
6223 var array = arguments[index];
6224 if (isArray(array) || isArguments(array)) {
6225 var result = result
6226 ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
6227 : array;
6228 }
6229 }
6230 return result || [];
6231 }
6232
6233 /**
6234 * Creates an array of grouped elements, the first of which contains the first
6235 * elements of the given arrays, the second of which contains the second
6236 * elements of the given arrays, and so on.
6237 *
6238 * @static
6239 * @memberOf _
6240 * @alias unzip
6241 * @category Arrays
6242 * @param {...Array} [array] Arrays to process.
6243 * @returns {Array} Returns a new array of grouped elements.
6244 * @example
6245 *
6246 * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6247 * // => [['fred', 30, true], ['barney', 40, false]]
6248 */
6249 function zip() {
6250 var array = arguments.length > 1 ? arguments : arguments[0],
6251 index = -1,
6252 length = array ? max(pluck(array, 'length')) : 0,
6253 result = Array(length < 0 ? 0 : length);
6254
6255 while (++index < length) {
6256 result[index] = pluck(array, index);
6257 }
6258 return result;
6259 }
6260
6261 /**
6262 * Creates an object composed from arrays of `keys` and `values`. Provide
6263 * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
6264 * or two arrays, one of `keys` and one of corresponding `values`.
6265 *
6266 * @static
6267 * @memberOf _
6268 * @alias object
6269 * @category Arrays
6270 * @param {Array} keys The array of keys.
6271 * @param {Array} [values=[]] The array of values.
6272 * @returns {Object} Returns an object composed of the given keys and
6273 * corresponding values.
6274 * @example
6275 *
6276 * _.zipObject(['fred', 'barney'], [30, 40]);
6277 * // => { 'fred': 30, 'barney': 40 }
6278 */
6279 function zipObject(keys, values) {
6280 var index = -1,
6281 length = keys ? keys.length : 0,
6282 result = {};
6283
6284 if (!values && length && !isArray(keys[0])) {
6285 values = [];
6286 }
6287 while (++index < length) {
6288 var key = keys[index];
6289 if (values) {
6290 result[key] = values[index];
6291 } else if (key) {
6292 result[key[0]] = key[1];
6293 }
6294 }
6295 return result;
6296 }
6297
6298 /*--------------------------------------------------------------------------*/
6299
6300 /**
6301 * Creates a function that executes `func`, with the `this` binding and
6302 * arguments of the created function, only after being called `n` times.
6303 *
6304 * @static
6305 * @memberOf _
6306 * @category Functions
6307 * @param {number} n The number of times the function must be called before
6308 * `func` is executed.
6309 * @param {Function} func The function to restrict.
6310 * @returns {Function} Returns the new restricted function.
6311 * @example
6312 *
6313 * var saves = ['profile', 'settings'];
6314 *
6315 * var done = _.after(saves.length, function() {
6316 * console.log('Done saving!');
6317 * });
6318 *
6319 * _.forEach(saves, function(type) {
6320 * asyncSave({ 'type': type, 'complete': done });
6321 * });
6322 * // => logs 'Done saving!', after all saves have completed
6323 */
6324 function after(n, func) {
6325 if (!isFunction(func)) {
6326 throw new TypeError;
6327 }
6328 return function() {
6329 if (--n < 1) {
6330 return func.apply(this, arguments);
6331 }
6332 };
6333 }
6334
6335 /**
6336 * Creates a function that, when called, invokes `func` with the `this`
6337 * binding of `thisArg` and prepends any additional `bind` arguments to those
6338 * provided to the bound function.
6339 *
6340 * @static
6341 * @memberOf _
6342 * @category Functions
6343 * @param {Function} func The function to bind.
6344 * @param {*} [thisArg] The `this` binding of `func`.
6345 * @param {...*} [arg] Arguments to be partially applied.
6346 * @returns {Function} Returns the new bound function.
6347 * @example
6348 *
6349 * var func = function(greeting) {
6350 * return greeting + ' ' + this.name;
6351 * };
6352 *
6353 * func = _.bind(func, { 'name': 'fred' }, 'hi');
6354 * func();
6355 * // => 'hi fred'
6356 */
6357 function bind(func, thisArg) {
6358 return arguments.length > 2
6359 ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
6360 : createWrapper(func, 1, null, null, thisArg);
6361 }
6362
6363 /**
6364 * Binds methods of an object to the object itself, overwriting the existing
6365 * method. Method names may be specified as individual arguments or as arrays
6366 * of method names. If no method names are provided all the function properties
6367 * of `object` will be bound.
6368 *
6369 * @static
6370 * @memberOf _
6371 * @category Functions
6372 * @param {Object} object The object to bind and assign the bound methods to.
6373 * @param {...string} [methodName] The object method names to
6374 * bind, specified as individual method names or arrays of method names.
6375 * @returns {Object} Returns `object`.
6376 * @example
6377 *
6378 * var view = {
6379 * 'label': 'docs',
6380 * 'onClick': function() { console.log('clicked ' + this.label); }
6381 * };
6382 *
6383 * _.bindAll(view);
6384 * jQuery('#docs').on('click', view.onClick);
6385 * // => logs 'clicked docs', when the button is clicked
6386 */
6387 function bindAll(object) {
6388 var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
6389 index = -1,
6390 length = funcs.length;
6391
6392 while (++index < length) {
6393 var key = funcs[index];
6394 object[key] = createWrapper(object[key], 1, null, null, object);
6395 }
6396 return object;
6397 }
6398
6399 /**
6400 * Creates a function that, when called, invokes the method at `object[key]`
6401 * and prepends any additional `bindKey` arguments to those provided to the bound
6402 * function. This method differs from `_.bind` by allowing bound functions to
6403 * reference methods that will be redefined or don't yet exist.
6404 * See http://michaux.ca/articles/lazy-function-definition-pattern.
6405 *
6406 * @static
6407 * @memberOf _
6408 * @category Functions
6409 * @param {Object} object The object the method belongs to.
6410 * @param {string} key The key of the method.
6411 * @param {...*} [arg] Arguments to be partially applied.
6412 * @returns {Function} Returns the new bound function.
6413 * @example
6414 *
6415 * var object = {
6416 * 'name': 'fred',
6417 * 'greet': function(greeting) {
6418 * return greeting + ' ' + this.name;
6419 * }
6420 * };
6421 *
6422 * var func = _.bindKey(object, 'greet', 'hi');
6423 * func();
6424 * // => 'hi fred'
6425 *
6426 * object.greet = function(greeting) {
6427 * return greeting + 'ya ' + this.name + '!';
6428 * };
6429 *
6430 * func();
6431 * // => 'hiya fred!'
6432 */
6433 function bindKey(object, key) {
6434 return arguments.length > 2
6435 ? createWrapper(key, 19, slice(arguments, 2), null, object)
6436 : createWrapper(key, 3, null, null, object);
6437 }
6438
6439 /**
6440 * Creates a function that is the composition of the provided functions,
6441 * where each function consumes the return value of the function that follows.
6442 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
6443 * Each function is executed with the `this` binding of the composed function.
6444 *
6445 * @static
6446 * @memberOf _
6447 * @category Functions
6448 * @param {...Function} [func] Functions to compose.
6449 * @returns {Function} Returns the new composed function.
6450 * @example
6451 *
6452 * var realNameMap = {
6453 * 'pebbles': 'penelope'
6454 * };
6455 *
6456 * var format = function(name) {
6457 * name = realNameMap[name.toLowerCase()] || name;
6458 * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
6459 * };
6460 *
6461 * var greet = function(formatted) {
6462 * return 'Hiya ' + formatted + '!';
6463 * };
6464 *
6465 * var welcome = _.compose(greet, format);
6466 * welcome('pebbles');
6467 * // => 'Hiya Penelope!'
6468 */
6469 function compose() {
6470 var funcs = arguments,
6471 length = funcs.length;
6472
6473 while (length--) {
6474 if (!isFunction(funcs[length])) {
6475 throw new TypeError;
6476 }
6477 }
6478 return function() {
6479 var args = arguments,
6480 length = funcs.length;
6481
6482 while (length--) {
6483 args = [funcs[length].apply(this, args)];
6484 }
6485 return args[0];
6486 };
6487 }
6488
6489 /**
6490 * Creates a function which accepts one or more arguments of `func` that when
6491 * invoked either executes `func` returning its result, if all `func` arguments
6492 * have been provided, or returns a function that accepts one or more of the
6493 * remaining `func` arguments, and so on. The arity of `func` can be specified
6494 * if `func.length` is not sufficient.
6495 *
6496 * @static
6497 * @memberOf _
6498 * @category Functions
6499 * @param {Function} func The function to curry.
6500 * @param {number} [arity=func.length] The arity of `func`.
6501 * @returns {Function} Returns the new curried function.
6502 * @example
6503 *
6504 * var curried = _.curry(function(a, b, c) {
6505 * console.log(a + b + c);
6506 * });
6507 *
6508 * curried(1)(2)(3);
6509 * // => 6
6510 *
6511 * curried(1, 2)(3);
6512 * // => 6
6513 *
6514 * curried(1, 2, 3);
6515 * // => 6
6516 */
6517 function curry(func, arity) {
6518 arity = typeof arity == 'number' ? arity : (+arity || func.length);
6519 return createWrapper(func, 4, null, null, null, arity);
6520 }
6521
6522 /**
6523 * Creates a function that will delay the execution of `func` until after
6524 * `wait` milliseconds have elapsed since the last time it was invoked.
6525 * Provide an options object to indicate that `func` should be invoked on
6526 * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
6527 * to the debounced function will return the result of the last `func` call.
6528 *
6529 * Note: If `leading` and `trailing` options are `true` `func` will be called
6530 * on the trailing edge of the timeout only if the the debounced function is
6531 * invoked more than once during the `wait` timeout.
6532 *
6533 * @static
6534 * @memberOf _
6535 * @category Functions
6536 * @param {Function} func The function to debounce.
6537 * @param {number} wait The number of milliseconds to delay.
6538 * @param {Object} [options] The options object.
6539 * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
6540 * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
6541 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
6542 * @returns {Function} Returns the new debounced function.
6543 * @example
6544 *
6545 * // avoid costly calculations while the window size is in flux
6546 * var lazyLayout = _.debounce(calculateLayout, 150);
6547 * jQuery(window).on('resize', lazyLayout);
6548 *
6549 * // execute `sendMail` when the click event is fired, debouncing subsequent calls
6550 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
6551 * 'leading': true,
6552 * 'trailing': false
6553 * });
6554 *
6555 * // ensure `batchLog` is executed once after 1 second of debounced calls
6556 * var source = new EventSource('/stream');
6557 * source.addEventListener('message', _.debounce(batchLog, 250, {
6558 * 'maxWait': 1000
6559 * }, false);
6560 */
6561 function debounce(func, wait, options) {
6562 var args,
6563 maxTimeoutId,
6564 result,
6565 stamp,
6566 thisArg,
6567 timeoutId,
6568 trailingCall,
6569 lastCalled = 0,
6570 maxWait = false,
6571 trailing = true;
6572
6573 if (!isFunction(func)) {
6574 throw new TypeError;
6575 }
6576 wait = nativeMax(0, wait) || 0;
6577 if (options === true) {
6578 var leading = true;
6579 trailing = false;
6580 } else if (isObject(options)) {
6581 leading = options.leading;
6582 maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
6583 trailing = 'trailing' in options ? options.trailing : trailing;
6584 }
6585 var delayed = function() {
6586 var remaining = wait - (now() - stamp);
6587 if (remaining <= 0) {
6588 if (maxTimeoutId) {
6589 clearTimeout(maxTimeoutId);
6590 }
6591 var isCalled = trailingCall;
6592 maxTimeoutId = timeoutId = trailingCall = undefined;
6593 if (isCalled) {
6594 lastCalled = now();
6595 result = func.apply(thisArg, args);
6596 if (!timeoutId && !maxTimeoutId) {
6597 args = thisArg = null;
6598 }
6599 }
6600 } else {
6601 timeoutId = setTimeout(delayed, remaining);
6602 }
6603 };
6604
6605 var maxDelayed = function() {
6606 if (timeoutId) {
6607 clearTimeout(timeoutId);
6608 }
6609 maxTimeoutId = timeoutId = trailingCall = undefined;
6610 if (trailing || (maxWait !== wait)) {
6611 lastCalled = now();
6612 result = func.apply(thisArg, args);
6613 if (!timeoutId && !maxTimeoutId) {
6614 args = thisArg = null;
6615 }
6616 }
6617 };
6618
6619 return function() {
6620 args = arguments;
6621 stamp = now();
6622 thisArg = this;
6623 trailingCall = trailing && (timeoutId || !leading);
6624
6625 if (maxWait === false) {
6626 var leadingCall = leading && !timeoutId;
6627 } else {
6628 if (!maxTimeoutId && !leading) {
6629 lastCalled = stamp;
6630 }
6631 var remaining = maxWait - (stamp - lastCalled),
6632 isCalled = remaining <= 0;
6633
6634 if (isCalled) {
6635 if (maxTimeoutId) {
6636 maxTimeoutId = clearTimeout(maxTimeoutId);
6637 }
6638 lastCalled = stamp;
6639 result = func.apply(thisArg, args);
6640 }
6641 else if (!maxTimeoutId) {
6642 maxTimeoutId = setTimeout(maxDelayed, remaining);
6643 }
6644 }
6645 if (isCalled && timeoutId) {
6646 timeoutId = clearTimeout(timeoutId);
6647 }
6648 else if (!timeoutId && wait !== maxWait) {
6649 timeoutId = setTimeout(delayed, wait);
6650 }
6651 if (leadingCall) {
6652 isCalled = true;
6653 result = func.apply(thisArg, args);
6654 }
6655 if (isCalled && !timeoutId && !maxTimeoutId) {
6656 args = thisArg = null;
6657 }
6658 return result;
6659 };
6660 }
6661
6662 /**
6663 * Defers executing the `func` function until the current call stack has cleared.
6664 * Additional arguments will be provided to `func` when it is invoked.
6665 *
6666 * @static
6667 * @memberOf _
6668 * @category Functions
6669 * @param {Function} func The function to defer.
6670 * @param {...*} [arg] Arguments to invoke the function with.
6671 * @returns {number} Returns the timer id.
6672 * @example
6673 *
6674 * _.defer(function(text) { console.log(text); }, 'deferred');
6675 * // logs 'deferred' after one or more milliseconds
6676 */
6677 function defer(func) {
6678 if (!isFunction(func)) {
6679 throw new TypeError;
6680 }
6681 var args = slice(arguments, 1);
6682 return setTimeout(function() { func.apply(undefined, args); }, 1);
6683 }
6684
6685 /**
6686 * Executes the `func` function after `wait` milliseconds. Additional arguments
6687 * will be provided to `func` when it is invoked.
6688 *
6689 * @static
6690 * @memberOf _
6691 * @category Functions
6692 * @param {Function} func The function to delay.
6693 * @param {number} wait The number of milliseconds to delay execution.
6694 * @param {...*} [arg] Arguments to invoke the function with.
6695 * @returns {number} Returns the timer id.
6696 * @example
6697 *
6698 * _.delay(function(text) { console.log(text); }, 1000, 'later');
6699 * // => logs 'later' after one second
6700 */
6701 function delay(func, wait) {
6702 if (!isFunction(func)) {
6703 throw new TypeError;
6704 }
6705 var args = slice(arguments, 2);
6706 return setTimeout(function() { func.apply(undefined, args); }, wait);
6707 }
6708
6709 /**
6710 * Creates a function that memoizes the result of `func`. If `resolver` is
6711 * provided it will be used to determine the cache key for storing the result
6712 * based on the arguments provided to the memoized function. By default, the
6713 * first argument provided to the memoized function is used as the cache key.
6714 * The `func` is executed with the `this` binding of the memoized function.
6715 * The result cache is exposed as the `cache` property on the memoized function.
6716 *
6717 * @static
6718 * @memberOf _
6719 * @category Functions
6720 * @param {Function} func The function to have its output memoized.
6721 * @param {Function} [resolver] A function used to resolve the cache key.
6722 * @returns {Function} Returns the new memoizing function.
6723 * @example
6724 *
6725 * var fibonacci = _.memoize(function(n) {
6726 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
6727 * });
6728 *
6729 * fibonacci(9)
6730 * // => 34
6731 *
6732 * var data = {
6733 * 'fred': { 'name': 'fred', 'age': 40 },
6734 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
6735 * };
6736 *
6737 * // modifying the result cache
6738 * var get = _.memoize(function(name) { return data[name]; }, _.identity);
6739 * get('pebbles');
6740 * // => { 'name': 'pebbles', 'age': 1 }
6741 *
6742 * get.cache.pebbles.name = 'penelope';
6743 * get('pebbles');
6744 * // => { 'name': 'penelope', 'age': 1 }
6745 */
6746 function memoize(func, resolver) {
6747 if (!isFunction(func)) {
6748 throw new TypeError;
6749 }
6750 var memoized = function() {
6751 var cache = memoized.cache,
6752 key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
6753
6754 return hasOwnProperty.call(cache, key)
6755 ? cache[key]
6756 : (cache[key] = func.apply(this, arguments));
6757 }
6758 memoized.cache = {};
6759 return memoized;
6760 }
6761
6762 /**
6763 * Creates a function that is restricted to execute `func` once. Repeat calls to
6764 * the function will return the value of the first call. The `func` is executed
6765 * with the `this` binding of the created function.
6766 *
6767 * @static
6768 * @memberOf _
6769 * @category Functions
6770 * @param {Function} func The function to restrict.
6771 * @returns {Function} Returns the new restricted function.
6772 * @example
6773 *
6774 * var initialize = _.once(createApplication);
6775 * initialize();
6776 * initialize();
6777 * // `initialize` executes `createApplication` once
6778 */
6779 function once(func) {
6780 var ran,
6781 result;
6782
6783 if (!isFunction(func)) {
6784 throw new TypeError;
6785 }
6786 return function() {
6787 if (ran) {
6788 return result;
6789 }
6790 ran = true;
6791 result = func.apply(this, arguments);
6792
6793 // clear the `func` variable so the function may be garbage collected
6794 func = null;
6795 return result;
6796 };
6797 }
6798
6799 /**
6800 * Creates a function that, when called, invokes `func` with any additional
6801 * `partial` arguments prepended to those provided to the new function. This
6802 * method is similar to `_.bind` except it does **not** alter the `this` binding.
6803 *
6804 * @static
6805 * @memberOf _
6806 * @category Functions
6807 * @param {Function} func The function to partially apply arguments to.
6808 * @param {...*} [arg] Arguments to be partially applied.
6809 * @returns {Function} Returns the new partially applied function.
6810 * @example
6811 *
6812 * var greet = function(greeting, name) { return greeting + ' ' + name; };
6813 * var hi = _.partial(greet, 'hi');
6814 * hi('fred');
6815 * // => 'hi fred'
6816 */
6817 function partial(func) {
6818 return createWrapper(func, 16, slice(arguments, 1));
6819 }
6820
6821 /**
6822 * This method is like `_.partial` except that `partial` arguments are
6823 * appended to those provided to the new function.
6824 *
6825 * @static
6826 * @memberOf _
6827 * @category Functions
6828 * @param {Function} func The function to partially apply arguments to.
6829 * @param {...*} [arg] Arguments to be partially applied.
6830 * @returns {Function} Returns the new partially applied function.
6831 * @example
6832 *
6833 * var defaultsDeep = _.partialRight(_.merge, _.defaults);
6834 *
6835 * var options = {
6836 * 'variable': 'data',
6837 * 'imports': { 'jq': $ }
6838 * };
6839 *
6840 * defaultsDeep(options, _.templateSettings);
6841 *
6842 * options.variable
6843 * // => 'data'
6844 *
6845 * options.imports
6846 * // => { '_': _, 'jq': $ }
6847 */
6848 function partialRight(func) {
6849 return createWrapper(func, 32, null, slice(arguments, 1));
6850 }
6851
6852 /**
6853 * Creates a function that, when executed, will only call the `func` function
6854 * at most once per every `wait` milliseconds. Provide an options object to
6855 * indicate that `func` should be invoked on the leading and/or trailing edge
6856 * of the `wait` timeout. Subsequent calls to the throttled function will
6857 * return the result of the last `func` call.
6858 *
6859 * Note: If `leading` and `trailing` options are `true` `func` will be called
6860 * on the trailing edge of the timeout only if the the throttled function is
6861 * invoked more than once during the `wait` timeout.
6862 *
6863 * @static
6864 * @memberOf _
6865 * @category Functions
6866 * @param {Function} func The function to throttle.
6867 * @param {number} wait The number of milliseconds to throttle executions to.
6868 * @param {Object} [options] The options object.
6869 * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
6870 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
6871 * @returns {Function} Returns the new throttled function.
6872 * @example
6873 *
6874 * // avoid excessively updating the position while scrolling
6875 * var throttled = _.throttle(updatePosition, 100);
6876 * jQuery(window).on('scroll', throttled);
6877 *
6878 * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
6879 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
6880 * 'trailing': false
6881 * }));
6882 */
6883 function throttle(func, wait, options) {
6884 var leading = true,
6885 trailing = true;
6886
6887 if (!isFunction(func)) {
6888 throw new TypeError;
6889 }
6890 if (options === false) {
6891 leading = false;
6892 } else if (isObject(options)) {
6893 leading = 'leading' in options ? options.leading : leading;
6894 trailing = 'trailing' in options ? options.trailing : trailing;
6895 }
6896 debounceOptions.leading = leading;
6897 debounceOptions.maxWait = wait;
6898 debounceOptions.trailing = trailing;
6899
6900 return debounce(func, wait, debounceOptions);
6901 }
6902
6903 /**
6904 * Creates a function that provides `value` to the wrapper function as its
6905 * first argument. Additional arguments provided to the function are appended
6906 * to those provided to the wrapper function. The wrapper is executed with
6907 * the `this` binding of the created function.
6908 *
6909 * @static
6910 * @memberOf _
6911 * @category Functions
6912 * @param {*} value The value to wrap.
6913 * @param {Function} wrapper The wrapper function.
6914 * @returns {Function} Returns the new function.
6915 * @example
6916 *
6917 * var p = _.wrap(_.escape, function(func, text) {
6918 * return '<p>' + func(text) + '</p>';
6919 * });
6920 *
6921 * p('Fred, Wilma, & Pebbles');
6922 * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
6923 */
6924 function wrap(value, wrapper) {
6925 return createWrapper(wrapper, 16, [value]);
6926 }
6927
6928 /*--------------------------------------------------------------------------*/
6929
6930 /**
6931 * Creates a function that returns `value`.
6932 *
6933 * @static
6934 * @memberOf _
6935 * @category Utilities
6936 * @param {*} value The value to return from the new function.
6937 * @returns {Function} Returns the new function.
6938 * @example
6939 *
6940 * var object = { 'name': 'fred' };
6941 * var getter = _.constant(object);
6942 * getter() === object;
6943 * // => true
6944 */
6945 function constant(value) {
6946 return function() {
6947 return value;
6948 };
6949 }
6950
6951 /**
6952 * Produces a callback bound to an optional `thisArg`. If `func` is a property
6953 * name the created callback will return the property value for a given element.
6954 * If `func` is an object the created callback will return `true` for elements
6955 * that contain the equivalent object properties, otherwise it will return `false`.
6956 *
6957 * @static
6958 * @memberOf _
6959 * @category Utilities
6960 * @param {*} [func=identity] The value to convert to a callback.
6961 * @param {*} [thisArg] The `this` binding of the created callback.
6962 * @param {number} [argCount] The number of arguments the callback accepts.
6963 * @returns {Function} Returns a callback function.
6964 * @example
6965 *
6966 * var characters = [
6967 * { 'name': 'barney', 'age': 36 },
6968 * { 'name': 'fred', 'age': 40 }
6969 * ];
6970 *
6971 * // wrap to create custom callback shorthands
6972 * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
6973 * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
6974 * return !match ? func(callback, thisArg) : function(object) {
6975 * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
6976 * };
6977 * });
6978 *
6979 * _.filter(characters, 'age__gt38');
6980 * // => [{ 'name': 'fred', 'age': 40 }]
6981 */
6982 function createCallback(func, thisArg, argCount) {
6983 var type = typeof func;
6984 if (func == null || type == 'function') {
6985 return baseCreateCallback(func, thisArg, argCount);
6986 }
6987 // handle "_.pluck" style callback shorthands
6988 if (type != 'object') {
6989 return property(func);
6990 }
6991 var props = keys(func),
6992 key = props[0],
6993 a = func[key];
6994
6995 // handle "_.where" style callback shorthands
6996 if (props.length == 1 && a === a && !isObject(a)) {
6997 // fast path the common case of providing an object with a single
6998 // property containing a primitive value
6999 return function(object) {
7000 var b = object[key];
7001 return a === b && (a !== 0 || (1 / a == 1 / b));
7002 };
7003 }
7004 return function(object) {
7005 var length = props.length,
7006 result = false;
7007
7008 while (length--) {
7009 if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
7010 break;
7011 }
7012 }
7013 return result;
7014 };
7015 }
7016
7017 /**
7018 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
7019 * corresponding HTML entities.
7020 *
7021 * @static
7022 * @memberOf _
7023 * @category Utilities
7024 * @param {string} string The string to escape.
7025 * @returns {string} Returns the escaped string.
7026 * @example
7027 *
7028 * _.escape('Fred, Wilma, & Pebbles');
7029 * // => 'Fred, Wilma, &amp; Pebbles'
7030 */
7031 function escape(string) {
7032 return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
7033 }
7034
7035 /**
7036 * This method returns the first argument provided to it.
7037 *
7038 * @static
7039 * @memberOf _
7040 * @category Utilities
7041 * @param {*} value Any value.
7042 * @returns {*} Returns `value`.
7043 * @example
7044 *
7045 * var object = { 'name': 'fred' };
7046 * _.identity(object) === object;
7047 * // => true
7048 */
7049 function identity(value) {
7050 return value;
7051 }
7052
7053 /**
7054 * Adds function properties of a source object to the destination object.
7055 * If `object` is a function methods will be added to its prototype as well.
7056 *
7057 * @static
7058 * @memberOf _
7059 * @category Utilities
7060 * @param {Function|Object} [object=lodash] object The destination object.
7061 * @param {Object} source The object of functions to add.
7062 * @param {Object} [options] The options object.
7063 * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
7064 * @example
7065 *
7066 * function capitalize(string) {
7067 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
7068 * }
7069 *
7070 * _.mixin({ 'capitalize': capitalize });
7071 * _.capitalize('fred');
7072 * // => 'Fred'
7073 *
7074 * _('fred').capitalize().value();
7075 * // => 'Fred'
7076 *
7077 * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
7078 * _('fred').capitalize();
7079 * // => 'Fred'
7080 */
7081 function mixin(object, source, options) {
7082 var chain = true,
7083 methodNames = source && functions(source);
7084
7085 if (!source || (!options && !methodNames.length)) {
7086 if (options == null) {
7087 options = source;
7088 }
7089 ctor = lodashWrapper;
7090 source = object;
7091 object = lodash;
7092 methodNames = functions(source);
7093 }
7094 if (options === false) {
7095 chain = false;
7096 } else if (isObject(options) && 'chain' in options) {
7097 chain = options.chain;
7098 }
7099 var ctor = object,
7100 isFunc = isFunction(ctor);
7101
7102 forEach(methodNames, function(methodName) {
7103 var func = object[methodName] = source[methodName];
7104 if (isFunc) {
7105 ctor.prototype[methodName] = function() {
7106 var chainAll = this.__chain__,
7107 value = this.__wrapped__,
7108 args = [value];
7109
7110 push.apply(args, arguments);
7111 var result = func.apply(object, args);
7112 if (chain || chainAll) {
7113 if (value === result && isObject(result)) {
7114 return this;
7115 }
7116 result = new ctor(result);
7117 result.__chain__ = chainAll;
7118 }
7119 return result;
7120 };
7121 }
7122 });
7123 }
7124
7125 /**
7126 * Reverts the '_' variable to its previous value and returns a reference to
7127 * the `lodash` function.
7128 *
7129 * @static
7130 * @memberOf _
7131 * @category Utilities
7132 * @returns {Function} Returns the `lodash` function.
7133 * @example
7134 *
7135 * var lodash = _.noConflict();
7136 */
7137 function noConflict() {
7138 context._ = oldDash;
7139 return this;
7140 }
7141
7142 /**
7143 * A no-operation function.
7144 *
7145 * @static
7146 * @memberOf _
7147 * @category Utilities
7148 * @example
7149 *
7150 * var object = { 'name': 'fred' };
7151 * _.noop(object) === undefined;
7152 * // => true
7153 */
7154 function noop() {
7155 // no operation performed
7156 }
7157
7158 /**
7159 * Gets the number of milliseconds that have elapsed since the Unix epoch
7160 * (1 January 1970 00:00:00 UTC).
7161 *
7162 * @static
7163 * @memberOf _
7164 * @category Utilities
7165 * @example
7166 *
7167 * var stamp = _.now();
7168 * _.defer(function() { console.log(_.now() - stamp); });
7169 * // => logs the number of milliseconds it took for the deferred function to be called
7170 */
7171 var now = isNative(now = Date.now) && now || function() {
7172 return new Date().getTime();
7173 };
7174
7175 /**
7176 * Converts the given value into an integer of the specified radix.
7177 * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
7178 * `value` is a hexadecimal, in which case a `radix` of `16` is used.
7179 *
7180 * Note: This method avoids differences in native ES3 and ES5 `parseInt`
7181 * implementations. See http://es5.github.io/#E.
7182 *
7183 * @static
7184 * @memberOf _
7185 * @category Utilities
7186 * @param {string} value The value to parse.
7187 * @param {number} [radix] The radix used to interpret the value to parse.
7188 * @returns {number} Returns the new integer value.
7189 * @example
7190 *
7191 * _.parseInt('08');
7192 * // => 8
7193 */
7194 var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
7195 // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
7196 return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
7197 };
7198
7199 /**
7200 * Creates a "_.pluck" style function, which returns the `key` value of a
7201 * given object.
7202 *
7203 * @static
7204 * @memberOf _
7205 * @category Utilities
7206 * @param {string} key The name of the property to retrieve.
7207 * @returns {Function} Returns the new function.
7208 * @example
7209 *
7210 * var characters = [
7211 * { 'name': 'fred', 'age': 40 },
7212 * { 'name': 'barney', 'age': 36 }
7213 * ];
7214 *
7215 * var getName = _.property('name');
7216 *
7217 * _.map(characters, getName);
7218 * // => ['barney', 'fred']
7219 *
7220 * _.sortBy(characters, getName);
7221 * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
7222 */
7223 function property(key) {
7224 return function(object) {
7225 return object[key];
7226 };
7227 }
7228
7229 /**
7230 * Produces a random number between `min` and `max` (inclusive). If only one
7231 * argument is provided a number between `0` and the given number will be
7232 * returned. If `floating` is truey or either `min` or `max` are floats a
7233 * floating-point number will be returned instead of an integer.
7234 *
7235 * @static
7236 * @memberOf _
7237 * @category Utilities
7238 * @param {number} [min=0] The minimum possible value.
7239 * @param {number} [max=1] The maximum possible value.
7240 * @param {boolean} [floating=false] Specify returning a floating-point number.
7241 * @returns {number} Returns a random number.
7242 * @example
7243 *
7244 * _.random(0, 5);
7245 * // => an integer between 0 and 5
7246 *
7247 * _.random(5);
7248 * // => also an integer between 0 and 5
7249 *
7250 * _.random(5, true);
7251 * // => a floating-point number between 0 and 5
7252 *
7253 * _.random(1.2, 5.2);
7254 * // => a floating-point number between 1.2 and 5.2
7255 */
7256 function random(min, max, floating) {
7257 var noMin = min == null,
7258 noMax = max == null;
7259
7260 if (floating == null) {
7261 if (typeof min == 'boolean' && noMax) {
7262 floating = min;
7263 min = 1;
7264 }
7265 else if (!noMax && typeof max == 'boolean') {
7266 floating = max;
7267 noMax = true;
7268 }
7269 }
7270 if (noMin && noMax) {
7271 max = 1;
7272 }
7273 min = +min || 0;
7274 if (noMax) {
7275 max = min;
7276 min = 0;
7277 } else {
7278 max = +max || 0;
7279 }
7280 if (floating || min % 1 || max % 1) {
7281 var rand = nativeRandom();
7282 return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
7283 }
7284 return baseRandom(min, max);
7285 }
7286
7287 /**
7288 * Resolves the value of property `key` on `object`. If `key` is a function
7289 * it will be invoked with the `this` binding of `object` and its result returned,
7290 * else the property value is returned. If `object` is falsey then `undefined`
7291 * is returned.
7292 *
7293 * @static
7294 * @memberOf _
7295 * @category Utilities
7296 * @param {Object} object The object to inspect.
7297 * @param {string} key The name of the property to resolve.
7298 * @returns {*} Returns the resolved value.
7299 * @example
7300 *
7301 * var object = {
7302 * 'cheese': 'crumpets',
7303 * 'stuff': function() {
7304 * return 'nonsense';
7305 * }
7306 * };
7307 *
7308 * _.result(object, 'cheese');
7309 * // => 'crumpets'
7310 *
7311 * _.result(object, 'stuff');
7312 * // => 'nonsense'
7313 */
7314 function result(object, key) {
7315 if (object) {
7316 var value = object[key];
7317 return isFunction(value) ? object[key]() : value;
7318 }
7319 }
7320
7321 /**
7322 * A micro-templating method that handles arbitrary delimiters, preserves
7323 * whitespace, and correctly escapes quotes within interpolated code.
7324 *
7325 * Note: In the development build, `_.template` utilizes sourceURLs for easier
7326 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
7327 *
7328 * For more information on precompiling templates see:
7329 * http://lodash.com/custom-builds
7330 *
7331 * For more information on Chrome extension sandboxes see:
7332 * http://developer.chrome.com/stable/extensions/sandboxingEval.html
7333 *
7334 * @static
7335 * @memberOf _
7336 * @category Utilities
7337 * @param {string} text The template text.
7338 * @param {Object} data The data object used to populate the text.
7339 * @param {Object} [options] The options object.
7340 * @param {RegExp} [options.escape] The "escape" delimiter.
7341 * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
7342 * @param {Object} [options.imports] An object to import into the template as local variables.
7343 * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
7344 * @param {string} [sourceURL] The sourceURL of the template's compiled source.
7345 * @param {string} [variable] The data object variable name.
7346 * @returns {Function|string} Returns a compiled function when no `data` object
7347 * is given, else it returns the interpolated text.
7348 * @example
7349 *
7350 * // using the "interpolate" delimiter to create a compiled template
7351 * var compiled = _.template('hello <%= name %>');
7352 * compiled({ 'name': 'fred' });
7353 * // => 'hello fred'
7354 *
7355 * // using the "escape" delimiter to escape HTML in data property values
7356 * _.template('<b><%- value %></b>', { 'value': '<script>' });
7357 * // => '<b>&lt;script&gt;</b>'
7358 *
7359 * // using the "evaluate" delimiter to generate HTML
7360 * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
7361 * _.template(list, { 'people': ['fred', 'barney'] });
7362 * // => '<li>fred</li><li>barney</li>'
7363 *
7364 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
7365 * _.template('hello ${ name }', { 'name': 'pebbles' });
7366 * // => 'hello pebbles'
7367 *
7368 * // using the internal `print` function in "evaluate" delimiters
7369 * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
7370 * // => 'hello barney!'
7371 *
7372 * // using a custom template delimiters
7373 * _.templateSettings = {
7374 * 'interpolate': /{{([\s\S]+?)}}/g
7375 * };
7376 *
7377 * _.template('hello {{ name }}!', { 'name': 'mustache' });
7378 * // => 'hello mustache!'
7379 *
7380 * // using the `imports` option to import jQuery
7381 * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
7382 * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
7383 * // => '<li>fred</li><li>barney</li>'
7384 *
7385 * // using the `sourceURL` option to specify a custom sourceURL for the template
7386 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
7387 * compiled(data);
7388 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
7389 *
7390 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
7391 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
7392 * compiled.source;
7393 * // => function(data) {
7394 * var __t, __p = '', __e = _.escape;
7395 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
7396 * return __p;
7397 * }
7398 *
7399 * // using the `source` property to inline compiled templates for meaningful
7400 * // line numbers in error messages and a stack trace
7401 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
7402 * var JST = {\
7403 * "main": ' + _.template(mainText).source + '\
7404 * };\
7405 * ');
7406 */
7407 function template(text, data, options) {
7408 // based on John Resig's `tmpl` implementation
7409 // http://ejohn.org/blog/javascript-micro-templating/
7410 // and Laura Doktorova's doT.js
7411 // https://github.com/olado/doT
7412 var settings = lodash.templateSettings;
7413 text = String(text || '');
7414
7415 // avoid missing dependencies when `iteratorTemplate` is not defined
7416 options = defaults({}, options, settings);
7417
7418 var imports = defaults({}, options.imports, settings.imports),
7419 importsKeys = keys(imports),
7420 importsValues = values(imports);
7421
7422 var isEvaluating,
7423 index = 0,
7424 interpolate = options.interpolate || reNoMatch,
7425 source = "__p += '";
7426
7427 // compile the regexp to match each delimiter
7428 var reDelimiters = RegExp(
7429 (options.escape || reNoMatch).source + '|' +
7430 interpolate.source + '|' +
7431 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
7432 (options.evaluate || reNoMatch).source + '|$'
7433 , 'g');
7434
7435 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
7436 interpolateValue || (interpolateValue = esTemplateValue);
7437
7438 // escape characters that cannot be included in string literals
7439 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
7440
7441 // replace delimiters with snippets
7442 if (escapeValue) {
7443 source += "' +\n__e(" + escapeValue + ") +\n'";
7444 }
7445 if (evaluateValue) {
7446 isEvaluating = true;
7447 source += "';\n" + evaluateValue + ";\n__p += '";
7448 }
7449 if (interpolateValue) {
7450 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
7451 }
7452 index = offset + match.length;
7453
7454 // the JS engine embedded in Adobe products requires returning the `match`
7455 // string in order to produce the correct `offset` value
7456 return match;
7457 });
7458
7459 source += "';\n";
7460
7461 // if `variable` is not specified, wrap a with-statement around the generated
7462 // code to add the data object to the top of the scope chain
7463 var variable = options.variable,
7464 hasVariable = variable;
7465
7466 if (!hasVariable) {
7467 variable = 'obj';
7468 source = 'with (' + variable + ') {\n' + source + '\n}\n';
7469 }
7470 // cleanup code by stripping empty strings
7471 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
7472 .replace(reEmptyStringMiddle, '$1')
7473 .replace(reEmptyStringTrailing, '$1;');
7474
7475 // frame code as the function body
7476 source = 'function(' + variable + ') {\n' +
7477 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
7478 "var __t, __p = '', __e = _.escape" +
7479 (isEvaluating
7480 ? ', __j = Array.prototype.join;\n' +
7481 "function print() { __p += __j.call(arguments, '') }\n"
7482 : ';\n'
7483 ) +
7484 source +
7485 'return __p\n}';
7486
7487 // Use a sourceURL for easier debugging.
7488 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
7489 var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
7490
7491 try {
7492 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
7493 } catch(e) {
7494 e.source = source;
7495 throw e;
7496 }
7497 if (data) {
7498 return result(data);
7499 }
7500 // provide the compiled function's source by its `toString` method, in
7501 // supported environments, or the `source` property as a convenience for
7502 // inlining compiled templates during the build process
7503 result.source = source;
7504 return result;
7505 }
7506
7507 /**
7508 * Executes the callback `n` times, returning an array of the results
7509 * of each callback execution. The callback is bound to `thisArg` and invoked
7510 * with one argument; (index).
7511 *
7512 * @static
7513 * @memberOf _
7514 * @category Utilities
7515 * @param {number} n The number of times to execute the callback.
7516 * @param {Function} callback The function called per iteration.
7517 * @param {*} [thisArg] The `this` binding of `callback`.
7518 * @returns {Array} Returns an array of the results of each `callback` execution.
7519 * @example
7520 *
7521 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
7522 * // => [3, 6, 4]
7523 *
7524 * _.times(3, function(n) { mage.castSpell(n); });
7525 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
7526 *
7527 * _.times(3, function(n) { this.cast(n); }, mage);
7528 * // => also calls `mage.castSpell(n)` three times
7529 */
7530 function times(n, callback, thisArg) {
7531 n = (n = +n) > -1 ? n : 0;
7532 var index = -1,
7533 result = Array(n);
7534
7535 callback = baseCreateCallback(callback, thisArg, 1);
7536 while (++index < n) {
7537 result[index] = callback(index);
7538 }
7539 return result;
7540 }
7541
7542 /**
7543 * The inverse of `_.escape` this method converts the HTML entities
7544 * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
7545 * corresponding characters.
7546 *
7547 * @static
7548 * @memberOf _
7549 * @category Utilities
7550 * @param {string} string The string to unescape.
7551 * @returns {string} Returns the unescaped string.
7552 * @example
7553 *
7554 * _.unescape('Fred, Barney &amp; Pebbles');
7555 * // => 'Fred, Barney & Pebbles'
7556 */
7557 function unescape(string) {
7558 return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
7559 }
7560
7561 /**
7562 * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
7563 *
7564 * @static
7565 * @memberOf _
7566 * @category Utilities
7567 * @param {string} [prefix] The value to prefix the ID with.
7568 * @returns {string} Returns the unique ID.
7569 * @example
7570 *
7571 * _.uniqueId('contact_');
7572 * // => 'contact_104'
7573 *
7574 * _.uniqueId();
7575 * // => '105'
7576 */
7577 function uniqueId(prefix) {
7578 var id = ++idCounter;
7579 return String(prefix == null ? '' : prefix) + id;
7580 }
7581
7582 /*--------------------------------------------------------------------------*/
7583
7584 /**
7585 * Creates a `lodash` object that wraps the given value with explicit
7586 * method chaining enabled.
7587 *
7588 * @static
7589 * @memberOf _
7590 * @category Chaining
7591 * @param {*} value The value to wrap.
7592 * @returns {Object} Returns the wrapper object.
7593 * @example
7594 *
7595 * var characters = [
7596 * { 'name': 'barney', 'age': 36 },
7597 * { 'name': 'fred', 'age': 40 },
7598 * { 'name': 'pebbles', 'age': 1 }
7599 * ];
7600 *
7601 * var youngest = _.chain(characters)
7602 * .sortBy('age')
7603 * .map(function(chr) { return chr.name + ' is ' + chr.age; })
7604 * .first()
7605 * .value();
7606 * // => 'pebbles is 1'
7607 */
7608 function chain(value) {
7609 value = new lodashWrapper(value);
7610 value.__chain__ = true;
7611 return value;
7612 }
7613
7614 /**
7615 * Invokes `interceptor` with the `value` as the first argument and then
7616 * returns `value`. The purpose of this method is to "tap into" a method
7617 * chain in order to perform operations on intermediate results within
7618 * the chain.
7619 *
7620 * @static
7621 * @memberOf _
7622 * @category Chaining
7623 * @param {*} value The value to provide to `interceptor`.
7624 * @param {Function} interceptor The function to invoke.
7625 * @returns {*} Returns `value`.
7626 * @example
7627 *
7628 * _([1, 2, 3, 4])
7629 * .tap(function(array) { array.pop(); })
7630 * .reverse()
7631 * .value();
7632 * // => [3, 2, 1]
7633 */
7634 function tap(value, interceptor) {
7635 interceptor(value);
7636 return value;
7637 }
7638
7639 /**
7640 * Enables explicit method chaining on the wrapper object.
7641 *
7642 * @name chain
7643 * @memberOf _
7644 * @category Chaining
7645 * @returns {*} Returns the wrapper object.
7646 * @example
7647 *
7648 * var characters = [
7649 * { 'name': 'barney', 'age': 36 },
7650 * { 'name': 'fred', 'age': 40 }
7651 * ];
7652 *
7653 * // without explicit chaining
7654 * _(characters).first();
7655 * // => { 'name': 'barney', 'age': 36 }
7656 *
7657 * // with explicit chaining
7658 * _(characters).chain()
7659 * .first()
7660 * .pick('age')
7661 * .value();
7662 * // => { 'age': 36 }
7663 */
7664 function wrapperChain() {
7665 this.__chain__ = true;
7666 return this;
7667 }
7668
7669 /**
7670 * Produces the `toString` result of the wrapped value.
7671 *
7672 * @name toString
7673 * @memberOf _
7674 * @category Chaining
7675 * @returns {string} Returns the string result.
7676 * @example
7677 *
7678 * _([1, 2, 3]).toString();
7679 * // => '1,2,3'
7680 */
7681 function wrapperToString() {
7682 return String(this.__wrapped__);
7683 }
7684
7685 /**
7686 * Extracts the wrapped value.
7687 *
7688 * @name valueOf
7689 * @memberOf _
7690 * @alias value
7691 * @category Chaining
7692 * @returns {*} Returns the wrapped value.
7693 * @example
7694 *
7695 * _([1, 2, 3]).valueOf();
7696 * // => [1, 2, 3]
7697 */
7698 function wrapperValueOf() {
7699 return this.__wrapped__;
7700 }
7701
7702 /*--------------------------------------------------------------------------*/
7703
7704 // add functions that return wrapped values when chaining
7705 lodash.after = after;
7706 lodash.assign = assign;
7707 lodash.at = at;
7708 lodash.bind = bind;
7709 lodash.bindAll = bindAll;
7710 lodash.bindKey = bindKey;
7711 lodash.chain = chain;
7712 lodash.compact = compact;
7713 lodash.compose = compose;
7714 lodash.constant = constant;
7715 lodash.countBy = countBy;
7716 lodash.create = create;
7717 lodash.createCallback = createCallback;
7718 lodash.curry = curry;
7719 lodash.debounce = debounce;
7720 lodash.defaults = defaults;
7721 lodash.defer = defer;
7722 lodash.delay = delay;
7723 lodash.difference = difference;
7724 lodash.filter = filter;
7725 lodash.flatten = flatten;
7726 lodash.forEach = forEach;
7727 lodash.forEachRight = forEachRight;
7728 lodash.forIn = forIn;
7729 lodash.forInRight = forInRight;
7730 lodash.forOwn = forOwn;
7731 lodash.forOwnRight = forOwnRight;
7732 lodash.functions = functions;
7733 lodash.groupBy = groupBy;
7734 lodash.indexBy = indexBy;
7735 lodash.initial = initial;
7736 lodash.intersection = intersection;
7737 lodash.invert = invert;
7738 lodash.invoke = invoke;
7739 lodash.keys = keys;
7740 lodash.map = map;
7741 lodash.mapValues = mapValues;
7742 lodash.max = max;
7743 lodash.memoize = memoize;
7744 lodash.merge = merge;
7745 lodash.min = min;
7746 lodash.omit = omit;
7747 lodash.once = once;
7748 lodash.pairs = pairs;
7749 lodash.partial = partial;
7750 lodash.partialRight = partialRight;
7751 lodash.pick = pick;
7752 lodash.pluck = pluck;
7753 lodash.property = property;
7754 lodash.pull = pull;
7755 lodash.range = range;
7756 lodash.reject = reject;
7757 lodash.remove = remove;
7758 lodash.rest = rest;
7759 lodash.shuffle = shuffle;
7760 lodash.sortBy = sortBy;
7761 lodash.tap = tap;
7762 lodash.throttle = throttle;
7763 lodash.times = times;
7764 lodash.toArray = toArray;
7765 lodash.transform = transform;
7766 lodash.union = union;
7767 lodash.uniq = uniq;
7768 lodash.values = values;
7769 lodash.where = where;
7770 lodash.without = without;
7771 lodash.wrap = wrap;
7772 lodash.xor = xor;
7773 lodash.zip = zip;
7774 lodash.zipObject = zipObject;
7775
7776 // add aliases
7777 lodash.collect = map;
7778 lodash.drop = rest;
7779 lodash.each = forEach;
7780 lodash.eachRight = forEachRight;
7781 lodash.extend = assign;
7782 lodash.methods = functions;
7783 lodash.object = zipObject;
7784 lodash.select = filter;
7785 lodash.tail = rest;
7786 lodash.unique = uniq;
7787 lodash.unzip = zip;
7788
7789 // add functions to `lodash.prototype`
7790 mixin(lodash);
7791
7792 /*--------------------------------------------------------------------------*/
7793
7794 // add functions that return unwrapped values when chaining
7795 lodash.clone = clone;
7796 lodash.cloneDeep = cloneDeep;
7797 lodash.contains = contains;
7798 lodash.escape = escape;
7799 lodash.every = every;
7800 lodash.find = find;
7801 lodash.findIndex = findIndex;
7802 lodash.findKey = findKey;
7803 lodash.findLast = findLast;
7804 lodash.findLastIndex = findLastIndex;
7805 lodash.findLastKey = findLastKey;
7806 lodash.has = has;
7807 lodash.identity = identity;
7808 lodash.indexOf = indexOf;
7809 lodash.isArguments = isArguments;
7810 lodash.isArray = isArray;
7811 lodash.isBoolean = isBoolean;
7812 lodash.isDate = isDate;
7813 lodash.isElement = isElement;
7814 lodash.isEmpty = isEmpty;
7815 lodash.isEqual = isEqual;
7816 lodash.isFinite = isFinite;
7817 lodash.isFunction = isFunction;
7818 lodash.isNaN = isNaN;
7819 lodash.isNull = isNull;
7820 lodash.isNumber = isNumber;
7821 lodash.isObject = isObject;
7822 lodash.isPlainObject = isPlainObject;
7823 lodash.isRegExp = isRegExp;
7824 lodash.isString = isString;
7825 lodash.isUndefined = isUndefined;
7826 lodash.lastIndexOf = lastIndexOf;
7827 lodash.mixin = mixin;
7828 lodash.noConflict = noConflict;
7829 lodash.noop = noop;
7830 lodash.now = now;
7831 lodash.parseInt = parseInt;
7832 lodash.random = random;
7833 lodash.reduce = reduce;
7834 lodash.reduceRight = reduceRight;
7835 lodash.result = result;
7836 lodash.runInContext = runInContext;
7837 lodash.size = size;
7838 lodash.some = some;
7839 lodash.sortedIndex = sortedIndex;
7840 lodash.template = template;
7841 lodash.unescape = unescape;
7842 lodash.uniqueId = uniqueId;
7843
7844 // add aliases
7845 lodash.all = every;
7846 lodash.any = some;
7847 lodash.detect = find;
7848 lodash.findWhere = find;
7849 lodash.foldl = reduce;
7850 lodash.foldr = reduceRight;
7851 lodash.include = contains;
7852 lodash.inject = reduce;
7853
7854 mixin(function() {
7855 var source = {}
7856 forOwn(lodash, function(func, methodName) {
7857 if (!lodash.prototype[methodName]) {
7858 source[methodName] = func;
7859 }
7860 });
7861 return source;
7862 }(), false);
7863
7864 /*--------------------------------------------------------------------------*/
7865
7866 // add functions capable of returning wrapped and unwrapped values when chaining
7867 lodash.first = first;
7868 lodash.last = last;
7869 lodash.sample = sample;
7870
7871 // add aliases
7872 lodash.take = first;
7873 lodash.head = first;
7874
7875 forOwn(lodash, function(func, methodName) {
7876 var callbackable = methodName !== 'sample';
7877 if (!lodash.prototype[methodName]) {
7878 lodash.prototype[methodName]= function(n, guard) {
7879 var chainAll = this.__chain__,
7880 result = func(this.__wrapped__, n, guard);
7881
7882 return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
7883 ? result
7884 : new lodashWrapper(result, chainAll);
7885 };
7886 }
7887 });
7888
7889 /*--------------------------------------------------------------------------*/
7890
7891 /**
7892 * The semantic version number.
7893 *
7894 * @static
7895 * @memberOf _
7896 * @type string
7897 */
7898 lodash.VERSION = '2.4.1';
7899
7900 // add "Chaining" functions to the wrapper
7901 lodash.prototype.chain = wrapperChain;
7902 lodash.prototype.toString = wrapperToString;
7903 lodash.prototype.value = wrapperValueOf;
7904 lodash.prototype.valueOf = wrapperValueOf;
7905
7906 // add `Array` functions that return unwrapped values
7907 forEach(['join', 'pop', 'shift'], function(methodName) {
7908 var func = arrayRef[methodName];
7909 lodash.prototype[methodName] = function() {
7910 var chainAll = this.__chain__,
7911 result = func.apply(this.__wrapped__, arguments);
7912
7913 return chainAll
7914 ? new lodashWrapper(result, chainAll)
7915 : result;
7916 };
7917 });
7918
7919 // add `Array` functions that return the existing wrapped value
7920 forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
7921 var func = arrayRef[methodName];
7922 lodash.prototype[methodName] = function() {
7923 func.apply(this.__wrapped__, arguments);
7924 return this;
7925 };
7926 });
7927
7928 // add `Array` functions that return new wrapped values
7929 forEach(['concat', 'slice', 'splice'], function(methodName) {
7930 var func = arrayRef[methodName];
7931 lodash.prototype[methodName] = function() {
7932 return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
7933 };
7934 });
7935
7936 return lodash;
7937 }
7938
7939 /*--------------------------------------------------------------------------*/
7940
7941 // expose Lo-Dash
7942 var _ = runInContext();
7943
7944 // some AMD build optimizers like r.js check for condition patterns like the following:
7945 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
7946 // Expose Lo-Dash to the global object even when an AMD loader is present in
7947 // case Lo-Dash is loaded with a RequireJS shim config.
7948 // See http://requirejs.org/docs/api.html#config-shim
7949 root._ = _;
7950
7951 // define as an anonymous module so, through path mapping, it can be
7952 // referenced as the "underscore" module
7953 define(function() {
7954 return _;
7955 });
7956 }
7957 // check for `exports` after `define` in case a build optimizer adds an `exports` object
7958 else if (freeExports && freeModule) {
7959 // in Node.js or RingoJS
7960 if (moduleExports) {
7961 (freeModule.exports = _)._ = _;
7962 }
7963 // in Narwhal or Rhino -require
7964 else {
7965 freeExports._ = _;
7966 }
7967 }
7968 else {
7969 // in a browser or Rhino
7970 root._ = _;
7971 }
7972}.call(this));
7973
7974}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
7975},{}]},{},[1]);