diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..12d195e --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["react"] +} diff --git a/.gitignore b/.gitignore index 38100f0..16b131a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea node_modules/ node_modules +npm-debug.log +lib/ diff --git a/Gruntfile.js b/Gruntfile.js index d71806b..9f5f64f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,7 +14,7 @@ module.exports = function(grunt) { src: ['example/boot.jsx'], dest: 'example/bundle.js', options: { - transform: ['reactify'] + transform: ['babelify'] } } } diff --git a/README.md b/README.md index b1ce18c..698d1f6 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,16 @@ This value is overridden by the `collapsible` prop value set on the root `")) - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-12 hero"}, - React.createElement("h3", null, "Check out the code for this demo ", React.createElement("a", {href: "https://github.com/MandarinConLaBarba/react-tree-menu/blob/master/example/App.jsx"}, "here"), ".") - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Dynamic (Array)"), - React.createElement("ul", null, - React.createElement("li", null, "This menu is built dynamically using the data prop (array)"), - React.createElement("li", null, "It is collapsible (the default), so expand/collapse icons show"), - React.createElement("li", null, "It has no identifier prop for the TreeMenu, so it uses the array index when emitting events") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Declarative"), - React.createElement("ul", null, - React.createElement("li", null, "This menu is built w/ nested TreeNode components"), - React.createElement("li", null, "It has collapsible=false, so no expand/collapse icons show"), - React.createElement("li", null, "It has identifier=\"id\", so it uses the 'id' prop when emitting events") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Unbound: Won't Update UI State"), - React.createElement("ul", null, - React.createElement("li", null, "This menu doesn't have any handlers applied that update UI state, so it's static.") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Stateful, manages its own UI state"), - React.createElement("ul", null, - React.createElement("li", null, "This menu has stateful=true, so it manages its own state w/o help from the Controller-View.") - ) - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - dynamicExample1 - ), - - React.createElement("div", {className: "col-lg-3"}, - declarativeExample - ), - - React.createElement("div", {className: "col-lg-3"}, - unboundExample - ), - - React.createElement("div", {className: "col-lg-3"}, - statefulExample - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, { - transitionEnterTimeout: 500, - transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("1") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, {transitionEnterTimeout: 500, transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("2") - ) - - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, {transitionEnterTimeout: 500, transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("3") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, {transitionEnterTimeout: 500, transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("4") - ) - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Dynamic (Object)"), - React.createElement("ul", null, - React.createElement("li", null, "This menu is built dynamically using the data prop (object)"), - React.createElement("li", null, "It is collapsible (the default), so expand/collapse icons show"), - React.createElement("li", null, "It has no identifier prop for the TreeMenu, so it uses the object key when emitting events") - ) - ), - - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Dynamic - No Checkboxes"), - React.createElement("ul", null, - React.createElement("li", null, "This menu is built dynamically using the data prop (object)"), - React.createElement("li", null, "It doesn't have checkboxes, but does have selection state") - ) - ), - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Label Filter"), - React.createElement("ul", null, - React.createElement("li", null, "This menu has a labelFilter prop that truncates the displayed label") - ) - ), - React.createElement("div", {className: "col-lg-3"}, - React.createElement("h2", null, "Renderers"), - React.createElement("ul", null, - React.createElement("li", null, "Using renderer (node factory) methods as arguments") - ) - ) - - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - dynamicExample2 - ), - React.createElement("div", {className: "col-lg-3"}, - dynamicExample3 - ), - React.createElement("div", {className: "col-lg-3"}, - labelFilterExample - ), - React.createElement("div", {className: "col-lg-3"}, - rendererExample - ) - ), - - React.createElement("div", {className: "row"}, - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, {transitionEnterTimeout: 500, transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("5") - ) - ), - React.createElement("div", {className: "col-lg-3"}, - React.createElement(CSSTransitionGroup, {transitionEnterTimeout: 500, transitionName: "last-action", transitionLeave: false}, - this._getLastActionNode("6") - ) - ) - ) - - ); - - }, - - _getLastActionNode: function (col) { - - var lastActionNode = React.createElement("div", {className: "text-center alert alert-success tree-event-alert"}, "Waiting for interaction"), - key = "lastAction" + col; - - var action = this.state[key]; - - if (action) { - lastActionNode = ( - React.createElement("div", {className: "text-center alert alert-success tree-event-alert", key: "lastAction_" + col + "_" + action.time}, - React.createElement("h3", null, "Event Received:"), - React.createElement("div", null, React.createElement("strong", null, action.event)), - React.createElement("h3", null, React.createElement("code", null, ""), " Affected: "), - React.createElement("div", null, React.createElement("strong", null, action.node)) - )); - } else { - - } - - return lastActionNode; - - }, - - _getStatefulTreeExample: function () { - - return ( - React.createElement(TreeMenu, { - identifier: "id", - stateful: true, - onTreeNodeClick: this._setLastActionState.bind(this, "clicked", "4"), - onTreeNodeCollapseChange: this._setLastActionState.bind(this, "collapsed", "4"), - onTreeNodeCheckChange: this._setLastActionState.bind(this, "checked", "4"), - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down"}, - React.createElement(TreeNode, {label: "Option 1", checkbox: true, id: "option_1"}), - React.createElement(TreeNode, {label: "Option 2", checkbox: true, id: "option_2"}, - React.createElement(TreeNode, {label: "Option A", checkbox: true, id: "option_2.a"}), - React.createElement(TreeNode, {label: "Option B", checkbox: true, id: "option_2.b"}, - React.createElement(TreeNode, {label: "Option B.x", checkbox: true, id: "option_2.b.x"}), - React.createElement(TreeNode, {label: "Option B.y", checkbox: true, id: "option_2.b.y"}) - ) - ) - ) - ); - }, - - _getUnboundTreeExample: function () { - - return ( - React.createElement(TreeMenu, { - identifier: "id", - onTreeNodeClick: this._setLastActionState.bind(this, "clicked", "3"), - onTreeNodeCollapseChange: this._setLastActionState.bind(this, "collapsed", "3"), - onTreeNodeCheckChange: this._setLastActionState.bind(this, "checked", "3"), - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down"}, - React.createElement(TreeNode, {label: "Option 1", checkbox: true, id: "option_1"}), - React.createElement(TreeNode, {label: "Option 2", checkbox: true, id: "option_2"}, - React.createElement(TreeNode, {label: "Option A", checkbox: true, checked: true, id: "option_2.a"}), - React.createElement(TreeNode, {label: "Option B", checkbox: true, id: "option_2.b"}) - ), - React.createElement(TreeNode, {label: "Option 3", checkbox: true, id: "option_3"}), - React.createElement(TreeNode, {label: "Option 3", checkbox: true, id: "option_3"}) - ) - ); - }, - - _getDeclarativeTreeExample: function () { - - return ( - React.createElement(TreeMenu, { - sort: true, - identifier: "id", - onTreeNodeClick: this._setLastActionState.bind(this, "clicked", "2"), - onTreeNodeCollapseChange: this._handleDeclarativeTreeNodePropChange.bind(this, "collapsed"), - onTreeNodeCheckChange: this._handleDeclarativeTreeNodePropChange.bind(this, "checked"), - collapsible: false, - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down"}, - React.createElement(TreeNode, {label: "Option 1", id: "option_1"}), - React.createElement(TreeNode, {label: "Option 2", id: "option_2"}, - React.createElement(TreeNode, {label: "Option B", checkbox: true, checked: this.state.staticTreeData["option_2.b"].checked, id: "option_2.b"}), - React.createElement(TreeNode, {label: "Option A", checkbox: true, checked: this.state.staticTreeData["option_2.a"].checked, id: "option_2.a"}) - ), - React.createElement(TreeNode, {label: "Option 3", id: "option_3"}), - React.createElement(TreeNode, {label: "Option 4", id: "option_4"}) - ) - ); - }, - - _getLabelFilterExample: function () { - - return ( - React.createElement(TreeMenu, { - identifier: "id", - onTreeNodeClick: function() {}, - onTreeNodeCollapseChange: function() {}, - onTreeNodeCheckChange: function() {}, - collapsible: false, - labelFilter: function(label) { - var max = 10; - if (label.length <= max) return label; - - return label.substring(label, max).concat("..."); - }, - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down"}, - React.createElement(TreeNode, {label: "Option 1 with a long name", id: "option_1"}), - React.createElement(TreeNode, {label: "Option 2 also has a long name", id: "option_2"}, - React.createElement(TreeNode, {label: "Option A with a long name", checkbox: true, id: "option_2.a"}), - React.createElement(TreeNode, {label: "Option B with a long name", checkbox: true, id: "option_2.b"}) - ), - React.createElement(TreeNode, {label: "Option 3 with a long name", id: "option_3"}), - React.createElement(TreeNode, {label: "Option 4 with a long name", id: "option_4"}) - ) - ); - }, - - _getRendererExample: function () { - - return ( - React.createElement(TreeMenu, { - identifier: "id", - onTreeNodeClick: function() {}, - onTreeNodeCollapseChange: function() {}, - onTreeNodeCheckChange: function() {}, - collapsible: false, - labelFilter: function(label) { - var max = 10; - if (label.length <= max) return label; - - return label.substring(label, max).concat("..."); - }, - labelFactory: function(labelClassName, displayLabel) { - return React.createElement("span", {className: labelClassName}, displayLabel, " ", ""); - }, - checkboxFactory: function(checkboxClassName, isChecked) { - return React.createElement("span", {className: checkboxClassName + " fa " + (isChecked ? "fa-check-circle" : "fa-circle-o")}); - }, - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down"}, - React.createElement(TreeNode, {label: "Option 1 with a long name", id: "option_1"}), - React.createElement(TreeNode, {label: "Option 2 also has a long name", id: "option_2", checkbox: true, checked: false}, - React.createElement(TreeNode, {label: "Option A with a long name", checkbox: true, id: "option_2.a"}), - React.createElement(TreeNode, {label: "Option B with a long name", checkbox: true, checked: true, id: "option_2.b"}) - ), - React.createElement(TreeNode, {label: "Option 3 with a long name", id: "option_3"}), - React.createElement(TreeNode, {label: "Option 4 with a long name", id: "option_4"}) - ) - ); - }, - - _getDynamicTreeExample: function () { - - return ( - React.createElement(TreeMenu, { - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down", - onTreeNodeClick: this._setLastActionState.bind(this, "clicked", "1"), - onTreeNodeCollapseChange: this._handleDynamicTreeNodePropChange.bind(this, "collapsed"), - onTreeNodeCheckChange: this._handleDynamicTreeNodePropChange.bind(this, "checked"), - data: this.state.dynamicTreeData}) - ); - - }, - - _getDynamicTreeExample2: function () { - - return ( - React.createElement(TreeMenu, { - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down", - onTreeNodeClick: this._setLastActionState.bind(this, "clicked", "5"), - onTreeNodeCollapseChange: this._handleDynamicObjectTreeNodePropChange.bind(this, 5, "dynamicTreeDataMap","collapsed"), - onTreeNodeCheckChange: this._handleDynamicObjectTreeNodePropChange.bind(this, 5, "dynamicTreeDataMap","checked"), - data: this.state.dynamicTreeDataMap}) - ); - - }, - - _getDynamicTreeExample3: function () { - - return ( - React.createElement(TreeMenu, { - expandIconClass: "fa fa-chevron-right", - collapseIconClass: "fa fa-chevron-down", - onTreeNodeCollapseChange: this._handleDynamicObjectTreeNodePropChange.bind(this, 6, "dynamicTreeDataMap2", "collapsed"), - onTreeNodeCheckChange: this._handleDynamicObjectTreeNodePropChange.bind(this, 6, "dynamicTreeDataMap2","checked"), - onTreeNodeSelectChange: this._handleDynamicObjectTreeNodePropChange.bind(this, 6, "dynamicTreeDataMap2","selected"), - data: this.state.dynamicTreeDataMap2}) - ); - - }, - - _getExamplePanel: function (title, treeMenuNode) { - return React.createElement("div", null, - React.createElement("div", {className: "panel panel-default"}, - React.createElement("div", {className: "panel-heading"}, title + " Menu"), - React.createElement("div", {className: "panel-body"}, - treeMenuNode - ) - ) - ); - }, - - _handleDeclarativeTreeNodePropChange: function (propName, lineage) { - - this._setLastActionState(propName, "2", lineage); - - var nodeId = lineage.pop(); - - var treeState = this.state.staticTreeData; - - treeState[nodeId][propName] = !treeState[nodeId][propName]; - - this.setState({ - staticTreeData : treeState - }); - - }, - - _handleDynamicTreeNodePropChange: function (propName, lineage) { - - this._setLastActionState(propName, "1", lineage); - - this.setState(TreeMenuUtils.getNewTreeState(lineage, this.state.dynamicTreeData, propName)); - - }, - - - _handleDynamicObjectTreeNodePropChange: function (messageWindowKey, stateKey, propName, lineage) { - - this._setLastActionState(propName, messageWindowKey, lineage); - - //Get a node path that includes children, given a key - function getNodePath(nodeKey) { - - if (nodeKey.length === 1) return nodeKey; - - return _(nodeKey).zip(nodeKey.map(function () { - return "children"; - })).flatten().initial().value(); - - } - - var oldState = Immutable.fromJS(this.state[stateKey]); - var nodePath = getNodePath(lineage), - keyPaths = [nodePath.concat([propName])]; - - //Build a list of key paths for all children - function addChildKeys(state, parentPath) { - - var childrenPath = parentPath.concat('children'), - children = state.getIn(childrenPath); - - if (!children || children.size === 0) return; - - children.map(function (value, key) { - keyPaths.push(childrenPath.concat([key, propName])) - addChildKeys(state, childrenPath.concat([key])); - }); - } - - addChildKeys(oldState, nodePath); - - //Get the new prop state - var newPropState = !oldState.getIn(keyPaths[0]); - - //Now create a new map w/ all the changes - var newState = oldState.withMutations(function(state) { - keyPaths.forEach(function (keyPath) { - state.setIn(keyPath, newPropState); - }) - }); - - var mutation = {}; - - mutation[stateKey] = newState.toJS(); - - this.setState(mutation); - - }, - - _setLastActionState: function (action, col, node) { - - var toggleEvents = ["collapsed", "checked", "selected"]; - - if (toggleEvents.indexOf(action) >= 0) { - action += "Changed"; - } - - console.log("Controller View received tree menu " + action + " action: " + node.join(" > ")); - - var key = "lastAction" + col; - - var mutation = {}; - mutation[key] = { - event: action, - node: node.join(" > "), - time: new Date().getTime() - }; - - this.setState(mutation) - } -}); - - -module.exports = App; - - -},{"../index":3,"immutable":5,"lodash":9,"react":240,"react-addons-css-transition-group":78}],2:[function(require,module,exports){ -var React = require('react'); -var ReactDOM = require('react-dom'); -var App = require('./App.jsx'); - - -ReactDOM.render(React.createElement(App, null), document.getElementById('appContainer')); - - -},{"./App.jsx":1,"react":240,"react-dom":79}],3:[function(require,module,exports){ -var api = require('./src/TreeMenu.jsx'); - -api.TreeMenu = require('./src/TreeMenu.jsx'); -api.TreeNode = require('./src/TreeNode.jsx'); -api.Utils = require('./src/TreeMenuUtils'); - -module.exports = api; - - -},{"./src/TreeMenu.jsx":241,"./src/TreeMenuUtils":242,"./src/TreeNode.jsx":243}],4:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; -var queue = []; -var draining = false; - -function drainQueue() { - if (draining) { - return; - } - draining = true; - var currentQueue; - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - var i = -1; - while (++i < len) { - currentQueue[i](); - } - len = queue.length; - } - draining = false; -} -process.nextTick = function (fun) { - queue.push(fun); - if (!draining) { - setTimeout(drainQueue, 0); - } -}; - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],5:[function(require,module,exports){ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - global.Immutable = factory() -}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice; - - function createClass(ctor, superClass) { - if (superClass) { - ctor.prototype = Object.create(superClass.prototype); - } - ctor.prototype.constructor = ctor; - } - - // Used for setting prototype methods that IE8 chokes on. - var DELETE = 'delete'; - - // Constants describing the size of trie nodes. - var SHIFT = 5; // Resulted in best performance after ______? - var SIZE = 1 << SHIFT; - var MASK = SIZE - 1; - - // A consistent shared value representing "not set" which equals nothing other - // than itself, and nothing that could be provided externally. - var NOT_SET = {}; - - // Boolean references, Rough equivalent of `bool &`. - var CHANGE_LENGTH = { value: false }; - var DID_ALTER = { value: false }; - - function MakeRef(ref) { - ref.value = false; - return ref; - } - - function SetRef(ref) { - ref && (ref.value = true); - } - - // A function which returns a value representing an "owner" for transient writes - // to tries. The return value will only ever equal itself, and will not equal - // the return of any subsequent call of this function. - function OwnerID() {} - - // http://jsperf.com/copy-array-inline - function arrCopy(arr, offset) { - offset = offset || 0; - var len = Math.max(0, arr.length - offset); - var newArr = new Array(len); - for (var ii = 0; ii < len; ii++) { - newArr[ii] = arr[ii + offset]; - } - return newArr; - } - - function ensureSize(iter) { - if (iter.size === undefined) { - iter.size = iter.__iterate(returnTrue); - } - return iter.size; - } - - function wrapIndex(iter, index) { - return index >= 0 ? (+index) : ensureSize(iter) + (+index); - } - - function returnTrue() { - return true; - } - - function wholeSlice(begin, end, size) { - return (begin === 0 || (size !== undefined && begin <= -size)) && - (end === undefined || (size !== undefined && end >= size)); - } - - function resolveBegin(begin, size) { - return resolveIndex(begin, size, 0); - } - - function resolveEnd(end, size) { - return resolveIndex(end, size, size); - } - - function resolveIndex(index, size, defaultIndex) { - return index === undefined ? - defaultIndex : - index < 0 ? - Math.max(0, size + index) : - size === undefined ? - index : - Math.min(size, index); - } - - function Iterable(value) { - return isIterable(value) ? value : Seq(value); - } - - - createClass(KeyedIterable, Iterable); - function KeyedIterable(value) { - return isKeyed(value) ? value : KeyedSeq(value); - } - - - createClass(IndexedIterable, Iterable); - function IndexedIterable(value) { - return isIndexed(value) ? value : IndexedSeq(value); - } - - - createClass(SetIterable, Iterable); - function SetIterable(value) { - return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); - } - - - - function isIterable(maybeIterable) { - return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); - } - - function isKeyed(maybeKeyed) { - return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); - } - - function isIndexed(maybeIndexed) { - return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); - } - - function isAssociative(maybeAssociative) { - return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); - } - - function isOrdered(maybeOrdered) { - return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); - } - - Iterable.isIterable = isIterable; - Iterable.isKeyed = isKeyed; - Iterable.isIndexed = isIndexed; - Iterable.isAssociative = isAssociative; - Iterable.isOrdered = isOrdered; - - Iterable.Keyed = KeyedIterable; - Iterable.Indexed = IndexedIterable; - Iterable.Set = SetIterable; - - - var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; - var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; - var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; - var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; - - /* global Symbol */ - - var ITERATE_KEYS = 0; - var ITERATE_VALUES = 1; - var ITERATE_ENTRIES = 2; - - var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; - var FAUX_ITERATOR_SYMBOL = '@@iterator'; - - var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; - - - function Iterator(next) { - this.next = next; - } - - Iterator.prototype.toString = function() { - return '[Iterator]'; - }; - - - Iterator.KEYS = ITERATE_KEYS; - Iterator.VALUES = ITERATE_VALUES; - Iterator.ENTRIES = ITERATE_ENTRIES; - - Iterator.prototype.inspect = - Iterator.prototype.toSource = function () { return this.toString(); } - Iterator.prototype[ITERATOR_SYMBOL] = function () { - return this; - }; - - - function iteratorValue(type, k, v, iteratorResult) { - var value = type === 0 ? k : type === 1 ? v : [k, v]; - iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { - value: value, done: false - }); - return iteratorResult; - } - - function iteratorDone() { - return { value: undefined, done: true }; - } - - function hasIterator(maybeIterable) { - return !!getIteratorFn(maybeIterable); - } - - function isIterator(maybeIterator) { - return maybeIterator && typeof maybeIterator.next === 'function'; - } - - function getIterator(iterable) { - var iteratorFn = getIteratorFn(iterable); - return iteratorFn && iteratorFn.call(iterable); - } - - function getIteratorFn(iterable) { - var iteratorFn = iterable && ( - (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || - iterable[FAUX_ITERATOR_SYMBOL] - ); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } - } - - function isArrayLike(value) { - return value && typeof value.length === 'number'; - } - - createClass(Seq, Iterable); - function Seq(value) { - return value === null || value === undefined ? emptySequence() : - isIterable(value) ? value.toSeq() : seqFromValue(value); - } - - Seq.of = function(/*...values*/) { - return Seq(arguments); - }; - - Seq.prototype.toSeq = function() { - return this; - }; - - Seq.prototype.toString = function() { - return this.__toString('Seq {', '}'); - }; - - Seq.prototype.cacheResult = function() { - if (!this._cache && this.__iterateUncached) { - this._cache = this.entrySeq().toArray(); - this.size = this._cache.length; - } - return this; - }; - - // abstract __iterateUncached(fn, reverse) - - Seq.prototype.__iterate = function(fn, reverse) { - return seqIterate(this, fn, reverse, true); - }; - - // abstract __iteratorUncached(type, reverse) - - Seq.prototype.__iterator = function(type, reverse) { - return seqIterator(this, type, reverse, true); - }; - - - - createClass(KeyedSeq, Seq); - function KeyedSeq(value) { - return value === null || value === undefined ? - emptySequence().toKeyedSeq() : - isIterable(value) ? - (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : - keyedSeqFromValue(value); - } - - KeyedSeq.of = function(/*...values*/) { - return KeyedSeq(arguments); - }; - - KeyedSeq.prototype.toKeyedSeq = function() { - return this; - }; - - KeyedSeq.prototype.toSeq = function() { - return this; - }; - - - - createClass(IndexedSeq, Seq); - function IndexedSeq(value) { - return value === null || value === undefined ? emptySequence() : - !isIterable(value) ? indexedSeqFromValue(value) : - isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); - } - - IndexedSeq.of = function(/*...values*/) { - return IndexedSeq(arguments); - }; - - IndexedSeq.prototype.toIndexedSeq = function() { - return this; - }; - - IndexedSeq.prototype.toString = function() { - return this.__toString('Seq [', ']'); - }; - - IndexedSeq.prototype.__iterate = function(fn, reverse) { - return seqIterate(this, fn, reverse, false); - }; - - IndexedSeq.prototype.__iterator = function(type, reverse) { - return seqIterator(this, type, reverse, false); - }; - - - - createClass(SetSeq, Seq); - function SetSeq(value) { - return ( - value === null || value === undefined ? emptySequence() : - !isIterable(value) ? indexedSeqFromValue(value) : - isKeyed(value) ? value.entrySeq() : value - ).toSetSeq(); - } - - SetSeq.of = function(/*...values*/) { - return SetSeq(arguments); - }; - - SetSeq.prototype.toSetSeq = function() { - return this; - }; - - - - Seq.isSeq = isSeq; - Seq.Keyed = KeyedSeq; - Seq.Set = SetSeq; - Seq.Indexed = IndexedSeq; - - var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; - - Seq.prototype[IS_SEQ_SENTINEL] = true; - - - - // #pragma Root Sequences - - createClass(ArraySeq, IndexedSeq); - function ArraySeq(array) { - this._array = array; - this.size = array.length; - } - - ArraySeq.prototype.get = function(index, notSetValue) { - return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; - }; - - ArraySeq.prototype.__iterate = function(fn, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { - return ii + 1; - } - } - return ii; - }; - - ArraySeq.prototype.__iterator = function(type, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - var ii = 0; - return new Iterator(function() - {return ii > maxIndex ? - iteratorDone() : - iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])} - ); - }; - - - - createClass(ObjectSeq, KeyedSeq); - function ObjectSeq(object) { - var keys = Object.keys(object); - this._object = object; - this._keys = keys; - this.size = keys.length; - } - - ObjectSeq.prototype.get = function(key, notSetValue) { - if (notSetValue !== undefined && !this.has(key)) { - return notSetValue; - } - return this._object[key]; - }; - - ObjectSeq.prototype.has = function(key) { - return this._object.hasOwnProperty(key); - }; - - ObjectSeq.prototype.__iterate = function(fn, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var key = keys[reverse ? maxIndex - ii : ii]; - if (fn(object[key], key, this) === false) { - return ii + 1; - } - } - return ii; - }; - - ObjectSeq.prototype.__iterator = function(type, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - var ii = 0; - return new Iterator(function() { - var key = keys[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? - iteratorDone() : - iteratorValue(type, key, object[key]); - }); - }; - - ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; - - - createClass(IterableSeq, IndexedSeq); - function IterableSeq(iterable) { - this._iterable = iterable; - this.size = iterable.length || iterable.size; - } - - IterableSeq.prototype.__iterateUncached = function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - var iterations = 0; - if (isIterator(iterator)) { - var step; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - } - return iterations; - }; - - IterableSeq.prototype.__iteratorUncached = function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterable = this._iterable; - var iterator = getIterator(iterable); - if (!isIterator(iterator)) { - return new Iterator(iteratorDone); - } - var iterations = 0; - return new Iterator(function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value); - }); - }; - - - - createClass(IteratorSeq, IndexedSeq); - function IteratorSeq(iterator) { - this._iterator = iterator; - this._iteratorCache = []; - } - - IteratorSeq.prototype.__iterateUncached = function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - while (iterations < cache.length) { - if (fn(cache[iterations], iterations++, this) === false) { - return iterations; - } - } - var step; - while (!(step = iterator.next()).done) { - var val = step.value; - cache[iterations] = val; - if (fn(val, iterations++, this) === false) { - break; - } - } - return iterations; - }; - - IteratorSeq.prototype.__iteratorUncached = function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - return new Iterator(function() { - if (iterations >= cache.length) { - var step = iterator.next(); - if (step.done) { - return step; - } - cache[iterations] = step.value; - } - return iteratorValue(type, iterations, cache[iterations++]); - }); - }; - - - - - // # pragma Helper functions - - function isSeq(maybeSeq) { - return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); - } - - var EMPTY_SEQ; - - function emptySequence() { - return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); - } - - function keyedSeqFromValue(value) { - var seq = - Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : - isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : - hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : - typeof value === 'object' ? new ObjectSeq(value) : - undefined; - if (!seq) { - throw new TypeError( - 'Expected Array or iterable object of [k, v] entries, '+ - 'or keyed object: ' + value - ); - } - return seq; - } - - function indexedSeqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value); - if (!seq) { - throw new TypeError( - 'Expected Array or iterable object of values: ' + value - ); - } - return seq; - } - - function seqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value) || - (typeof value === 'object' && new ObjectSeq(value)); - if (!seq) { - throw new TypeError( - 'Expected Array or iterable object of values, or keyed object: ' + value - ); - } - return seq; - } - - function maybeIndexedSeqFromValue(value) { - return ( - isArrayLike(value) ? new ArraySeq(value) : - isIterator(value) ? new IteratorSeq(value) : - hasIterator(value) ? new IterableSeq(value) : - undefined - ); - } - - function seqIterate(seq, fn, reverse, useKeys) { - var cache = seq._cache; - if (cache) { - var maxIndex = cache.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var entry = cache[reverse ? maxIndex - ii : ii]; - if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { - return ii + 1; - } - } - return ii; - } - return seq.__iterateUncached(fn, reverse); - } - - function seqIterator(seq, type, reverse, useKeys) { - var cache = seq._cache; - if (cache) { - var maxIndex = cache.length - 1; - var ii = 0; - return new Iterator(function() { - var entry = cache[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? - iteratorDone() : - iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); - }); - } - return seq.__iteratorUncached(type, reverse); - } - - createClass(Collection, Iterable); - function Collection() { - throw TypeError('Abstract'); - } - - - createClass(KeyedCollection, Collection);function KeyedCollection() {} - - createClass(IndexedCollection, Collection);function IndexedCollection() {} - - createClass(SetCollection, Collection);function SetCollection() {} - - - Collection.Keyed = KeyedCollection; - Collection.Indexed = IndexedCollection; - Collection.Set = SetCollection; - - /** - * An extension of the "same-value" algorithm as [described for use by ES6 Map - * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) - * - * NaN is considered the same as NaN, however -0 and 0 are considered the same - * value, which is different from the algorithm described by - * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). - * - * This is extended further to allow Objects to describe the values they - * represent, by way of `valueOf` or `equals` (and `hashCode`). - * - * Note: because of this extension, the key equality of Immutable.Map and the - * value equality of Immutable.Set will differ from ES6 Map and Set. - * - * ### Defining custom values - * - * The easiest way to describe the value an object represents is by implementing - * `valueOf`. For example, `Date` represents a value by returning a unix - * timestamp for `valueOf`: - * - * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... - * var date2 = new Date(1234567890000); - * date1.valueOf(); // 1234567890000 - * assert( date1 !== date2 ); - * assert( Immutable.is( date1, date2 ) ); - * - * Note: overriding `valueOf` may have other implications if you use this object - * where JavaScript expects a primitive, such as implicit string coercion. - * - * For more complex types, especially collections, implementing `valueOf` may - * not be performant. An alternative is to implement `equals` and `hashCode`. - * - * `equals` takes another object, presumably of similar type, and returns true - * if the it is equal. Equality is symmetrical, so the same result should be - * returned if this and the argument are flipped. - * - * assert( a.equals(b) === b.equals(a) ); - * - * `hashCode` returns a 32bit integer number representing the object which will - * be used to determine how to store the value object in a Map or Set. You must - * provide both or neither methods, one must not exist without the other. - * - * Also, an important relationship between these methods must be upheld: if two - * values are equal, they *must* return the same hashCode. If the values are not - * equal, they might have the same hashCode; this is called a hash collision, - * and while undesirable for performance reasons, it is acceptable. - * - * if (a.equals(b)) { - * assert( a.hashCode() === b.hashCode() ); - * } - * - * All Immutable collections implement `equals` and `hashCode`. - * - */ - function is(valueA, valueB) { - if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { - return true; - } - if (!valueA || !valueB) { - return false; - } - if (typeof valueA.valueOf === 'function' && - typeof valueB.valueOf === 'function') { - valueA = valueA.valueOf(); - valueB = valueB.valueOf(); - } - return typeof valueA.equals === 'function' && - typeof valueB.equals === 'function' ? - valueA.equals(valueB) : - valueA === valueB || (valueA !== valueA && valueB !== valueB); - } - - function fromJS(json, converter) { - return converter ? - fromJSWith(converter, json, '', {'': json}) : - fromJSDefault(json); - } - - function fromJSWith(converter, json, key, parentJSON) { - if (Array.isArray(json)) { - return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); - } - if (isPlainObj(json)) { - return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); - } - return json; - } - - function fromJSDefault(json) { - if (Array.isArray(json)) { - return IndexedSeq(json).map(fromJSDefault).toList(); - } - if (isPlainObj(json)) { - return KeyedSeq(json).map(fromJSDefault).toMap(); - } - return json; - } - - function isPlainObj(value) { - return value && value.constructor === Object; - } - - var Math__imul = - typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ? - Math.imul : - function Math__imul(a, b) { - a = a | 0; // int - b = b | 0; // int - var c = a & 0xffff; - var d = b & 0xffff; - // Shift by 0 fixes the sign on the high part. - return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int - }; - - // v8 has an optimization for storing 31-bit signed numbers. - // Values which have either 00 or 11 as the high order bits qualify. - // This function drops the highest order bit in a signed number, maintaining - // the sign bit. - function smi(i32) { - return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF); - } - - function hash(o) { - if (o === false || o === null || o === undefined) { - return 0; - } - if (typeof o.valueOf === 'function') { - o = o.valueOf(); - if (o === false || o === null || o === undefined) { - return 0; - } - } - if (o === true) { - return 1; - } - var type = typeof o; - if (type === 'number') { - var h = o | 0; - if (h !== o) { - h ^= o * 0xFFFFFFFF; - } - while (o > 0xFFFFFFFF) { - o /= 0xFFFFFFFF; - h ^= o; - } - return smi(h); - } - if (type === 'string') { - return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); - } - if (typeof o.hashCode === 'function') { - return o.hashCode(); - } - return hashJSObj(o); - } - - function cachedHashString(string) { - var hash = stringHashCache[string]; - if (hash === undefined) { - hash = hashString(string); - if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { - STRING_HASH_CACHE_SIZE = 0; - stringHashCache = {}; - } - STRING_HASH_CACHE_SIZE++; - stringHashCache[string] = hash; - } - return hash; - } - - // http://jsperf.com/hashing-strings - function hashString(string) { - // This is the hash from JVM - // The hash code for a string is computed as - // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], - // where s[i] is the ith character of the string and n is the length of - // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 - // (exclusive) by dropping high bits. - var hash = 0; - for (var ii = 0; ii < string.length; ii++) { - hash = 31 * hash + string.charCodeAt(ii) | 0; - } - return smi(hash); - } - - function hashJSObj(obj) { - var hash = weakMap && weakMap.get(obj); - if (hash) return hash; - - hash = obj[UID_HASH_KEY]; - if (hash) return hash; - - if (!canDefineProperty) { - hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; - if (hash) return hash; - - hash = getIENodeHash(obj); - if (hash) return hash; - } - - if (Object.isExtensible && !Object.isExtensible(obj)) { - throw new Error('Non-extensible objects are not allowed as keys.'); - } - - hash = ++objHashUID; - if (objHashUID & 0x40000000) { - objHashUID = 0; - } - - if (weakMap) { - weakMap.set(obj, hash); - } else if (canDefineProperty) { - Object.defineProperty(obj, UID_HASH_KEY, { - 'enumerable': false, - 'configurable': false, - 'writable': false, - 'value': hash - }); - } else if (obj.propertyIsEnumerable && - obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { - // Since we can't define a non-enumerable property on the object - // we'll hijack one of the less-used non-enumerable properties to - // save our hash on it. Since this is a function it will not show up in - // `JSON.stringify` which is what we want. - obj.propertyIsEnumerable = function() { - return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); - }; - obj.propertyIsEnumerable[UID_HASH_KEY] = hash; - } else if (obj.nodeType) { - // At this point we couldn't get the IE `uniqueID` to use as a hash - // and we couldn't use a non-enumerable property to exploit the - // dontEnum bug so we simply add the `UID_HASH_KEY` on the node - // itself. - obj[UID_HASH_KEY] = hash; - } else { - throw new Error('Unable to set a non-enumerable property on object.'); - } - - return hash; - } - - // True if Object.defineProperty works as expected. IE8 fails this test. - var canDefineProperty = (function() { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { - return false; - } - }()); - - // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it - // and avoid memory leaks from the IE cloneNode bug. - function getIENodeHash(node) { - if (node && node.nodeType > 0) { - switch (node.nodeType) { - case 1: // Element - return node.uniqueID; - case 9: // Document - return node.documentElement && node.documentElement.uniqueID; - } - } - } - - // If possible, use a WeakMap. - var weakMap = typeof WeakMap === 'function' && new WeakMap(); - - var objHashUID = 0; - - var UID_HASH_KEY = '__immutablehash__'; - if (typeof Symbol === 'function') { - UID_HASH_KEY = Symbol(UID_HASH_KEY); - } - - var STRING_HASH_CACHE_MIN_STRLEN = 16; - var STRING_HASH_CACHE_MAX_SIZE = 255; - var STRING_HASH_CACHE_SIZE = 0; - var stringHashCache = {}; - - function invariant(condition, error) { - if (!condition) throw new Error(error); - } - - function assertNotInfinite(size) { - invariant( - size !== Infinity, - 'Cannot perform this action with an infinite size.' - ); - } - - createClass(ToKeyedSequence, KeyedSeq); - function ToKeyedSequence(indexed, useKeys) { - this._iter = indexed; - this._useKeys = useKeys; - this.size = indexed.size; - } - - ToKeyedSequence.prototype.get = function(key, notSetValue) { - return this._iter.get(key, notSetValue); - }; - - ToKeyedSequence.prototype.has = function(key) { - return this._iter.has(key); - }; - - ToKeyedSequence.prototype.valueSeq = function() { - return this._iter.valueSeq(); - }; - - ToKeyedSequence.prototype.reverse = function() {var this$0 = this; - var reversedSequence = reverseFactory(this, true); - if (!this._useKeys) { - reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()}; - } - return reversedSequence; - }; - - ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this; - var mappedSequence = mapFactory(this, mapper, context); - if (!this._useKeys) { - mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)}; - } - return mappedSequence; - }; - - ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; - var ii; - return this._iter.__iterate( - this._useKeys ? - function(v, k) {return fn(v, k, this$0)} : - ((ii = reverse ? resolveSize(this) : 0), - function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}), - reverse - ); - }; - - ToKeyedSequence.prototype.__iterator = function(type, reverse) { - if (this._useKeys) { - return this._iter.__iterator(type, reverse); - } - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - var ii = reverse ? resolveSize(this) : 0; - return new Iterator(function() { - var step = iterator.next(); - return step.done ? step : - iteratorValue(type, reverse ? --ii : ii++, step.value, step); - }); - }; - - ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; - - - createClass(ToIndexedSequence, IndexedSeq); - function ToIndexedSequence(iter) { - this._iter = iter; - this.size = iter.size; - } - - ToIndexedSequence.prototype.contains = function(value) { - return this._iter.contains(value); - }; - - ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; - var iterations = 0; - return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse); - }; - - ToIndexedSequence.prototype.__iterator = function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - return new Iterator(function() { - var step = iterator.next(); - return step.done ? step : - iteratorValue(type, iterations++, step.value, step) - }); - }; - - - - createClass(ToSetSequence, SetSeq); - function ToSetSequence(iter) { - this._iter = iter; - this.size = iter.size; - } - - ToSetSequence.prototype.has = function(key) { - return this._iter.contains(key); - }; - - ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; - return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse); - }; - - ToSetSequence.prototype.__iterator = function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator(function() { - var step = iterator.next(); - return step.done ? step : - iteratorValue(type, step.value, step.value, step); - }); - }; - - - - createClass(FromEntriesSequence, KeyedSeq); - function FromEntriesSequence(entries) { - this._iter = entries; - this.size = entries.size; - } - - FromEntriesSequence.prototype.entrySeq = function() { - return this._iter.toSeq(); - }; - - FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; - return this._iter.__iterate(function(entry ) { - // Check if entry exists first so array access doesn't throw for holes - // in the parent iteration. - if (entry) { - validateEntry(entry); - return fn(entry[1], entry[0], this$0); - } - }, reverse); - }; - - FromEntriesSequence.prototype.__iterator = function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator(function() { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - // Check if entry exists first so array access doesn't throw for holes - // in the parent iteration. - if (entry) { - validateEntry(entry); - return type === ITERATE_ENTRIES ? step : - iteratorValue(type, entry[0], entry[1], step); - } - } - }); - }; - - - ToIndexedSequence.prototype.cacheResult = - ToKeyedSequence.prototype.cacheResult = - ToSetSequence.prototype.cacheResult = - FromEntriesSequence.prototype.cacheResult = - cacheResultThrough; - - - function flipFactory(iterable) { - var flipSequence = makeSequence(iterable); - flipSequence._iter = iterable; - flipSequence.size = iterable.size; - flipSequence.flip = function() {return iterable}; - flipSequence.reverse = function () { - var reversedSequence = iterable.reverse.apply(this); // super.reverse() - reversedSequence.flip = function() {return iterable.reverse()}; - return reversedSequence; - }; - flipSequence.has = function(key ) {return iterable.contains(key)}; - flipSequence.contains = function(key ) {return iterable.has(key)}; - flipSequence.cacheResult = cacheResultThrough; - flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; - return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse); - } - flipSequence.__iteratorUncached = function(type, reverse) { - if (type === ITERATE_ENTRIES) { - var iterator = iterable.__iterator(type, reverse); - return new Iterator(function() { - var step = iterator.next(); - if (!step.done) { - var k = step.value[0]; - step.value[0] = step.value[1]; - step.value[1] = k; - } - return step; - }); - } - return iterable.__iterator( - type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, - reverse - ); - } - return flipSequence; - } - - - function mapFactory(iterable, mapper, context) { - var mappedSequence = makeSequence(iterable); - mappedSequence.size = iterable.size; - mappedSequence.has = function(key ) {return iterable.has(key)}; - mappedSequence.get = function(key, notSetValue) { - var v = iterable.get(key, NOT_SET); - return v === NOT_SET ? - notSetValue : - mapper.call(context, v, key, iterable); - }; - mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; - return iterable.__iterate( - function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false}, - reverse - ); - } - mappedSequence.__iteratorUncached = function (type, reverse) { - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - return new Iterator(function() { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - return iteratorValue( - type, - key, - mapper.call(context, entry[1], key, iterable), - step - ); - }); - } - return mappedSequence; - } - - - function reverseFactory(iterable, useKeys) { - var reversedSequence = makeSequence(iterable); - reversedSequence._iter = iterable; - reversedSequence.size = iterable.size; - reversedSequence.reverse = function() {return iterable}; - if (iterable.flip) { - reversedSequence.flip = function () { - var flipSequence = flipFactory(iterable); - flipSequence.reverse = function() {return iterable.flip()}; - return flipSequence; - }; - } - reversedSequence.get = function(key, notSetValue) - {return iterable.get(useKeys ? key : -1 - key, notSetValue)}; - reversedSequence.has = function(key ) - {return iterable.has(useKeys ? key : -1 - key)}; - reversedSequence.contains = function(value ) {return iterable.contains(value)}; - reversedSequence.cacheResult = cacheResultThrough; - reversedSequence.__iterate = function (fn, reverse) {var this$0 = this; - return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse); - }; - reversedSequence.__iterator = - function(type, reverse) {return iterable.__iterator(type, !reverse)}; - return reversedSequence; - } - - - function filterFactory(iterable, predicate, context, useKeys) { - var filterSequence = makeSequence(iterable); - if (useKeys) { - filterSequence.has = function(key ) { - var v = iterable.get(key, NOT_SET); - return v !== NOT_SET && !!predicate.call(context, v, key, iterable); - }; - filterSequence.get = function(key, notSetValue) { - var v = iterable.get(key, NOT_SET); - return v !== NOT_SET && predicate.call(context, v, key, iterable) ? - v : notSetValue; - }; - } - filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; - var iterations = 0; - iterable.__iterate(function(v, k, c) { - if (predicate.call(context, v, k, c)) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this$0); - } - }, reverse); - return iterations; - }; - filterSequence.__iteratorUncached = function (type, reverse) { - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var iterations = 0; - return new Iterator(function() { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var key = entry[0]; - var value = entry[1]; - if (predicate.call(context, value, key, iterable)) { - return iteratorValue(type, useKeys ? key : iterations++, value, step); - } - } - }); - } - return filterSequence; - } - - - function countByFactory(iterable, grouper, context) { - var groups = Map().asMutable(); - iterable.__iterate(function(v, k) { - groups.update( - grouper.call(context, v, k, iterable), - 0, - function(a ) {return a + 1} - ); - }); - return groups.asImmutable(); - } - - - function groupByFactory(iterable, grouper, context) { - var isKeyedIter = isKeyed(iterable); - var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable(); - iterable.__iterate(function(v, k) { - groups.update( - grouper.call(context, v, k, iterable), - function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)} - ); - }); - var coerce = iterableClass(iterable); - return groups.map(function(arr ) {return reify(iterable, coerce(arr))}); - } - - - function sliceFactory(iterable, begin, end, useKeys) { - var originalSize = iterable.size; - - if (wholeSlice(begin, end, originalSize)) { - return iterable; - } - - var resolvedBegin = resolveBegin(begin, originalSize); - var resolvedEnd = resolveEnd(end, originalSize); - - // begin or end will be NaN if they were provided as negative numbers and - // this iterable's size is unknown. In that case, cache first so there is - // a known size. - if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { - return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys); - } - - var sliceSize = resolvedEnd - resolvedBegin; - if (sliceSize < 0) { - sliceSize = 0; - } - - var sliceSeq = makeSequence(iterable); - - sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined; - - if (!useKeys && isSeq(iterable) && sliceSize >= 0) { - sliceSeq.get = function (index, notSetValue) { - index = wrapIndex(this, index); - return index >= 0 && index < sliceSize ? - iterable.get(index + resolvedBegin, notSetValue) : - notSetValue; - } - } - - sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this; - if (sliceSize === 0) { - return 0; - } - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var skipped = 0; - var isSkipping = true; - var iterations = 0; - iterable.__iterate(function(v, k) { - if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this$0) !== false && - iterations !== sliceSize; - } - }); - return iterations; - }; - - sliceSeq.__iteratorUncached = function(type, reverse) { - if (sliceSize && reverse) { - return this.cacheResult().__iterator(type, reverse); - } - // Don't bother instantiating parent iterator if taking 0. - var iterator = sliceSize && iterable.__iterator(type, reverse); - var skipped = 0; - var iterations = 0; - return new Iterator(function() { - while (skipped++ !== resolvedBegin) { - iterator.next(); - } - if (++iterations > sliceSize) { - return iteratorDone(); - } - var step = iterator.next(); - if (useKeys || type === ITERATE_VALUES) { - return step; - } else if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations - 1, undefined, step); - } else { - return iteratorValue(type, iterations - 1, step.value[1], step); - } - }); - } - - return sliceSeq; - } - - - function takeWhileFactory(iterable, predicate, context) { - var takeSequence = makeSequence(iterable); - takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - iterable.__iterate(function(v, k, c) - {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)} - ); - return iterations; - }; - takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var iterating = true; - return new Iterator(function() { - if (!iterating) { - return iteratorDone(); - } - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var k = entry[0]; - var v = entry[1]; - if (!predicate.call(context, v, k, this$0)) { - iterating = false; - return iteratorDone(); - } - return type === ITERATE_ENTRIES ? step : - iteratorValue(type, k, v, step); - }); - }; - return takeSequence; - } - - - function skipWhileFactory(iterable, predicate, context, useKeys) { - var skipSequence = makeSequence(iterable); - skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var isSkipping = true; - var iterations = 0; - iterable.__iterate(function(v, k, c) { - if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, this$0); - } - }); - return iterations; - }; - skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var skipping = true; - var iterations = 0; - return new Iterator(function() { - var step, k, v; - do { - step = iterator.next(); - if (step.done) { - if (useKeys || type === ITERATE_VALUES) { - return step; - } else if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations++, undefined, step); - } else { - return iteratorValue(type, iterations++, step.value[1], step); - } - } - var entry = step.value; - k = entry[0]; - v = entry[1]; - skipping && (skipping = predicate.call(context, v, k, this$0)); - } while (skipping); - return type === ITERATE_ENTRIES ? step : - iteratorValue(type, k, v, step); - }); - }; - return skipSequence; - } - - - function concatFactory(iterable, values) { - var isKeyedIterable = isKeyed(iterable); - var iters = [iterable].concat(values).map(function(v ) { - if (!isIterable(v)) { - v = isKeyedIterable ? - keyedSeqFromValue(v) : - indexedSeqFromValue(Array.isArray(v) ? v : [v]); - } else if (isKeyedIterable) { - v = KeyedIterable(v); - } - return v; - }).filter(function(v ) {return v.size !== 0}); - - if (iters.length === 0) { - return iterable; - } - - if (iters.length === 1) { - var singleton = iters[0]; - if (singleton === iterable || - isKeyedIterable && isKeyed(singleton) || - isIndexed(iterable) && isIndexed(singleton)) { - return singleton; - } - } - - var concatSeq = new ArraySeq(iters); - if (isKeyedIterable) { - concatSeq = concatSeq.toKeyedSeq(); - } else if (!isIndexed(iterable)) { - concatSeq = concatSeq.toSetSeq(); - } - concatSeq = concatSeq.flatten(true); - concatSeq.size = iters.reduce( - function(sum, seq) { - if (sum !== undefined) { - var size = seq.size; - if (size !== undefined) { - return sum + size; - } - } - }, - 0 - ); - return concatSeq; - } - - - function flattenFactory(iterable, depth, useKeys) { - var flatSequence = makeSequence(iterable); - flatSequence.__iterateUncached = function(fn, reverse) { - var iterations = 0; - var stopped = false; - function flatDeep(iter, currentDepth) {var this$0 = this; - iter.__iterate(function(v, k) { - if ((!depth || currentDepth < depth) && isIterable(v)) { - flatDeep(v, currentDepth + 1); - } else if (fn(v, useKeys ? k : iterations++, this$0) === false) { - stopped = true; - } - return !stopped; - }, reverse); - } - flatDeep(iterable, 0); - return iterations; - } - flatSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(type, reverse); - var stack = []; - var iterations = 0; - return new Iterator(function() { - while (iterator) { - var step = iterator.next(); - if (step.done !== false) { - iterator = stack.pop(); - continue; - } - var v = step.value; - if (type === ITERATE_ENTRIES) { - v = v[1]; - } - if ((!depth || stack.length < depth) && isIterable(v)) { - stack.push(iterator); - iterator = v.__iterator(type, reverse); - } else { - return useKeys ? step : iteratorValue(type, iterations++, v, step); - } - } - return iteratorDone(); - }); - } - return flatSequence; - } - - - function flatMapFactory(iterable, mapper, context) { - var coerce = iterableClass(iterable); - return iterable.toSeq().map( - function(v, k) {return coerce(mapper.call(context, v, k, iterable))} - ).flatten(true); - } - - - function interposeFactory(iterable, separator) { - var interposedSequence = makeSequence(iterable); - interposedSequence.size = iterable.size && iterable.size * 2 -1; - interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; - var iterations = 0; - iterable.__iterate(function(v, k) - {return (!iterations || fn(separator, iterations++, this$0) !== false) && - fn(v, iterations++, this$0) !== false}, - reverse - ); - return iterations; - }; - interposedSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - var step; - return new Iterator(function() { - if (!step || iterations % 2) { - step = iterator.next(); - if (step.done) { - return step; - } - } - return iterations % 2 ? - iteratorValue(type, iterations++, separator) : - iteratorValue(type, iterations++, step.value, step); - }); - }; - return interposedSequence; - } - - - function sortFactory(iterable, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; - } - var isKeyedIterable = isKeyed(iterable); - var index = 0; - var entries = iterable.toSeq().map( - function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]} - ).toArray(); - entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach( - isKeyedIterable ? - function(v, i) { entries[i].length = 2; } : - function(v, i) { entries[i] = v[1]; } - ); - return isKeyedIterable ? KeyedSeq(entries) : - isIndexed(iterable) ? IndexedSeq(entries) : - SetSeq(entries); - } - - - function maxFactory(iterable, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; - } - if (mapper) { - var entry = iterable.toSeq() - .map(function(v, k) {return [v, mapper(v, k, iterable)]}) - .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a}); - return entry && entry[0]; - } else { - return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a}); - } - } - - function maxCompare(comparator, a, b) { - var comp = comparator(b, a); - // b is considered the new max if the comparator declares them equal, but - // they are not equal and b is in fact a nullish value. - return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0; - } - - - function zipWithFactory(keyIter, zipper, iters) { - var zipSequence = makeSequence(keyIter); - zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min(); - // Note: this a generic base implementation of __iterate in terms of - // __iterator which may be more generically useful in the future. - zipSequence.__iterate = function(fn, reverse) { - /* generic: - var iterator = this.__iterator(ITERATE_ENTRIES, reverse); - var step; - var iterations = 0; - while (!(step = iterator.next()).done) { - iterations++; - if (fn(step.value[1], step.value[0], this) === false) { - break; - } - } - return iterations; - */ - // indexed: - var iterator = this.__iterator(ITERATE_VALUES, reverse); - var step; - var iterations = 0; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } - return iterations; - }; - zipSequence.__iteratorUncached = function(type, reverse) { - var iterators = iters.map(function(i ) - {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))} - ); - var iterations = 0; - var isDone = false; - return new Iterator(function() { - var steps; - if (!isDone) { - steps = iterators.map(function(i ) {return i.next()}); - isDone = steps.some(function(s ) {return s.done}); - } - if (isDone) { - return iteratorDone(); - } - return iteratorValue( - type, - iterations++, - zipper.apply(null, steps.map(function(s ) {return s.value})) - ); - }); - }; - return zipSequence - } - - - // #pragma Helper Functions - - function reify(iter, seq) { - return isSeq(iter) ? seq : iter.constructor(seq); - } - - function validateEntry(entry) { - if (entry !== Object(entry)) { - throw new TypeError('Expected [K, V] tuple: ' + entry); - } - } - - function resolveSize(iter) { - assertNotInfinite(iter.size); - return ensureSize(iter); - } - - function iterableClass(iterable) { - return isKeyed(iterable) ? KeyedIterable : - isIndexed(iterable) ? IndexedIterable : - SetIterable; - } - - function makeSequence(iterable) { - return Object.create( - ( - isKeyed(iterable) ? KeyedSeq : - isIndexed(iterable) ? IndexedSeq : - SetSeq - ).prototype - ); - } - - function cacheResultThrough() { - if (this._iter.cacheResult) { - this._iter.cacheResult(); - this.size = this._iter.size; - return this; - } else { - return Seq.prototype.cacheResult.call(this); - } - } - - function defaultComparator(a, b) { - return a > b ? 1 : a < b ? -1 : 0; - } - - function forceIterator(keyPath) { - var iter = getIterator(keyPath); - if (!iter) { - // Array might not be iterable in this environment, so we need a fallback - // to our wrapped type. - if (!isArrayLike(keyPath)) { - throw new TypeError('Expected iterable or array-like: ' + keyPath); - } - iter = getIterator(Iterable(keyPath)); - } - return iter; - } - - createClass(Map, KeyedCollection); - - // @pragma Construction - - function Map(value) { - return value === null || value === undefined ? emptyMap() : - isMap(value) ? value : - emptyMap().withMutations(function(map ) { - var iter = KeyedIterable(value); - assertNotInfinite(iter.size); - iter.forEach(function(v, k) {return map.set(k, v)}); - }); - } - - Map.prototype.toString = function() { - return this.__toString('Map {', '}'); - }; - - // @pragma Access - - Map.prototype.get = function(k, notSetValue) { - return this._root ? - this._root.get(0, undefined, k, notSetValue) : - notSetValue; - }; - - // @pragma Modification - - Map.prototype.set = function(k, v) { - return updateMap(this, k, v); - }; - - Map.prototype.setIn = function(keyPath, v) { - return this.updateIn(keyPath, NOT_SET, function() {return v}); - }; - - Map.prototype.remove = function(k) { - return updateMap(this, k, NOT_SET); - }; - - Map.prototype.deleteIn = function(keyPath) { - return this.updateIn(keyPath, function() {return NOT_SET}); - }; - - Map.prototype.update = function(k, notSetValue, updater) { - return arguments.length === 1 ? - k(this) : - this.updateIn([k], notSetValue, updater); - }; - - Map.prototype.updateIn = function(keyPath, notSetValue, updater) { - if (!updater) { - updater = notSetValue; - notSetValue = undefined; - } - var updatedValue = updateInDeepMap( - this, - forceIterator(keyPath), - notSetValue, - updater - ); - return updatedValue === NOT_SET ? undefined : updatedValue; - }; - - Map.prototype.clear = function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._root = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyMap(); - }; - - // @pragma Composition - - Map.prototype.merge = function(/*...iters*/) { - return mergeIntoMapWith(this, undefined, arguments); - }; - - Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); - return mergeIntoMapWith(this, merger, iters); - }; - - Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); - return this.updateIn(keyPath, emptyMap(), function(m ) {return m.merge.apply(m, iters)}); - }; - - Map.prototype.mergeDeep = function(/*...iters*/) { - return mergeIntoMapWith(this, deepMerger(undefined), arguments); - }; - - Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); - return mergeIntoMapWith(this, deepMerger(merger), iters); - }; - - Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); - return this.updateIn(keyPath, emptyMap(), function(m ) {return m.mergeDeep.apply(m, iters)}); - }; - - Map.prototype.sort = function(comparator) { - // Late binding - return OrderedMap(sortFactory(this, comparator)); - }; - - Map.prototype.sortBy = function(mapper, comparator) { - // Late binding - return OrderedMap(sortFactory(this, comparator, mapper)); - }; - - // @pragma Mutability - - Map.prototype.withMutations = function(fn) { - var mutable = this.asMutable(); - fn(mutable); - return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; - }; - - Map.prototype.asMutable = function() { - return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); - }; - - Map.prototype.asImmutable = function() { - return this.__ensureOwner(); - }; - - Map.prototype.wasAltered = function() { - return this.__altered; - }; - - Map.prototype.__iterator = function(type, reverse) { - return new MapIterator(this, type, reverse); - }; - - Map.prototype.__iterate = function(fn, reverse) {var this$0 = this; - var iterations = 0; - this._root && this._root.iterate(function(entry ) { - iterations++; - return fn(entry[1], entry[0], this$0); - }, reverse); - return iterations; - }; - - Map.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeMap(this.size, this._root, ownerID, this.__hash); - }; - - - function isMap(maybeMap) { - return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); - } - - Map.isMap = isMap; - - var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; - - var MapPrototype = Map.prototype; - MapPrototype[IS_MAP_SENTINEL] = true; - MapPrototype[DELETE] = MapPrototype.remove; - MapPrototype.removeIn = MapPrototype.deleteIn; - - - // #pragma Trie Nodes - - - - function ArrayMapNode(ownerID, entries) { - this.ownerID = ownerID; - this.entries = entries; - } - - ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } - } - return notSetValue; - }; - - ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; - } - } - var exists = idx < len; - - if (exists ? entries[idx][1] === value : removed) { - return this; - } - - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - - if (removed && entries.length === 1) { - return; // undefined - } - - if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { - return createNodes(ownerID, entries, key, value); - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - - if (exists) { - if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; - } - } else { - newEntries.push([key, value]); - } - - if (isEditable) { - this.entries = newEntries; - return this; - } - - return new ArrayMapNode(ownerID, newEntries); - }; - - - - - function BitmapIndexedNode(ownerID, bitmap, nodes) { - this.ownerID = ownerID; - this.bitmap = bitmap; - this.nodes = nodes; - } - - BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); - var bitmap = this.bitmap; - return (bitmap & bit) === 0 ? notSetValue : - this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); - }; - - BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var bit = 1 << keyHashFrag; - var bitmap = this.bitmap; - var exists = (bitmap & bit) !== 0; - - if (!exists && value === NOT_SET) { - return this; - } - - var idx = popCount(bitmap & (bit - 1)); - var nodes = this.nodes; - var node = exists ? nodes[idx] : undefined; - var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); - - if (newNode === node) { - return this; - } - - if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { - return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); - } - - if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { - return nodes[idx ^ 1]; - } - - if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { - return newNode; - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; - var newNodes = exists ? newNode ? - setIn(nodes, idx, newNode, isEditable) : - spliceOut(nodes, idx, isEditable) : - spliceIn(nodes, idx, newNode, isEditable); - - if (isEditable) { - this.bitmap = newBitmap; - this.nodes = newNodes; - return this; - } - - return new BitmapIndexedNode(ownerID, newBitmap, newNodes); - }; - - - - - function HashArrayMapNode(ownerID, count, nodes) { - this.ownerID = ownerID; - this.count = count; - this.nodes = nodes; - } - - HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var node = this.nodes[idx]; - return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; - }; - - HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var removed = value === NOT_SET; - var nodes = this.nodes; - var node = nodes[idx]; - - if (removed && !node) { - return this; - } - - var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); - if (newNode === node) { - return this; - } - - var newCount = this.count; - if (!node) { - newCount++; - } else if (!newNode) { - newCount--; - if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { - return packNodes(ownerID, nodes, newCount, idx); - } - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newNodes = setIn(nodes, idx, newNode, isEditable); - - if (isEditable) { - this.count = newCount; - this.nodes = newNodes; - return this; - } - - return new HashArrayMapNode(ownerID, newCount, newNodes); - }; - - - - - function HashCollisionNode(ownerID, keyHash, entries) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entries = entries; - } - - HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } - } - return notSetValue; - }; - - HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - - var removed = value === NOT_SET; - - if (keyHash !== this.keyHash) { - if (removed) { - return this; - } - SetRef(didAlter); - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); - } - - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; - } - } - var exists = idx < len; - - if (exists ? entries[idx][1] === value : removed) { - return this; - } - - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - - if (removed && len === 2) { - return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); - } - - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - - if (exists) { - if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; - } - } else { - newEntries.push([key, value]); - } - - if (isEditable) { - this.entries = newEntries; - return this; - } - - return new HashCollisionNode(ownerID, this.keyHash, newEntries); - }; - - - - - function ValueNode(ownerID, keyHash, entry) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entry = entry; - } - - ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) { - return is(key, this.entry[0]) ? this.entry[1] : notSetValue; - }; - - ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - var keyMatch = is(key, this.entry[0]); - if (keyMatch ? value === this.entry[1] : removed) { - return this; - } - - SetRef(didAlter); - - if (removed) { - SetRef(didChangeSize); - return; // undefined - } - - if (keyMatch) { - if (ownerID && ownerID === this.ownerID) { - this.entry[1] = value; - return this; - } - return new ValueNode(ownerID, this.keyHash, [key, value]); - } - - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); - }; - - - - // #pragma Iterators - - ArrayMapNode.prototype.iterate = - HashCollisionNode.prototype.iterate = function (fn, reverse) { - var entries = this.entries; - for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { - if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { - return false; - } - } - } - - BitmapIndexedNode.prototype.iterate = - HashArrayMapNode.prototype.iterate = function (fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - var node = nodes[reverse ? maxIndex - ii : ii]; - if (node && node.iterate(fn, reverse) === false) { - return false; - } - } - } - - ValueNode.prototype.iterate = function (fn, reverse) { - return fn(this.entry); - } - - createClass(MapIterator, Iterator); - - function MapIterator(map, type, reverse) { - this._type = type; - this._reverse = reverse; - this._stack = map._root && mapIteratorFrame(map._root); - } - - MapIterator.prototype.next = function() { - var type = this._type; - var stack = this._stack; - while (stack) { - var node = stack.node; - var index = stack.index++; - var maxIndex; - if (node.entry) { - if (index === 0) { - return mapIteratorValue(type, node.entry); - } - } else if (node.entries) { - maxIndex = node.entries.length - 1; - if (index <= maxIndex) { - return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); - } - } else { - maxIndex = node.nodes.length - 1; - if (index <= maxIndex) { - var subNode = node.nodes[this._reverse ? maxIndex - index : index]; - if (subNode) { - if (subNode.entry) { - return mapIteratorValue(type, subNode.entry); - } - stack = this._stack = mapIteratorFrame(subNode, stack); - } - continue; - } - } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - }; - - - function mapIteratorValue(type, entry) { - return iteratorValue(type, entry[0], entry[1]); - } - - function mapIteratorFrame(node, prev) { - return { - node: node, - index: 0, - __prev: prev - }; - } - - function makeMap(size, root, ownerID, hash) { - var map = Object.create(MapPrototype); - map.size = size; - map._root = root; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; - } - - var EMPTY_MAP; - function emptyMap() { - return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); - } - - function updateMap(map, k, v) { - var newRoot; - var newSize; - if (!map._root) { - if (v === NOT_SET) { - return map; - } - newSize = 1; - newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); - } else { - var didChangeSize = MakeRef(CHANGE_LENGTH); - var didAlter = MakeRef(DID_ALTER); - newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); - if (!didAlter.value) { - return map; - } - newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); - } - if (map.__ownerID) { - map.size = newSize; - map._root = newRoot; - map.__hash = undefined; - map.__altered = true; - return map; - } - return newRoot ? makeMap(newSize, newRoot) : emptyMap(); - } - - function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (!node) { - if (value === NOT_SET) { - return node; - } - SetRef(didAlter); - SetRef(didChangeSize); - return new ValueNode(ownerID, keyHash, [key, value]); - } - return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); - } - - function isLeafNode(node) { - return node.constructor === ValueNode || node.constructor === HashCollisionNode; - } - - function mergeIntoNode(node, ownerID, shift, keyHash, entry) { - if (node.keyHash === keyHash) { - return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); - } - - var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; - var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - - var newNode; - var nodes = idx1 === idx2 ? - [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : - ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); - - return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); - } - - function createNodes(ownerID, entries, key, value) { - if (!ownerID) { - ownerID = new OwnerID(); - } - var node = new ValueNode(ownerID, hash(key), [key, value]); - for (var ii = 0; ii < entries.length; ii++) { - var entry = entries[ii]; - node = node.update(ownerID, 0, undefined, entry[0], entry[1]); - } - return node; - } - - function packNodes(ownerID, nodes, count, excluding) { - var bitmap = 0; - var packedII = 0; - var packedNodes = new Array(count); - for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { - var node = nodes[ii]; - if (node !== undefined && ii !== excluding) { - bitmap |= bit; - packedNodes[packedII++] = node; - } - } - return new BitmapIndexedNode(ownerID, bitmap, packedNodes); - } - - function expandNodes(ownerID, nodes, bitmap, including, node) { - var count = 0; - var expandedNodes = new Array(SIZE); - for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { - expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; - } - expandedNodes[including] = node; - return new HashArrayMapNode(ownerID, count + 1, expandedNodes); - } - - function mergeIntoMapWith(map, merger, iterables) { - var iters = []; - for (var ii = 0; ii < iterables.length; ii++) { - var value = iterables[ii]; - var iter = KeyedIterable(value); - if (!isIterable(value)) { - iter = iter.map(function(v ) {return fromJS(v)}); - } - iters.push(iter); - } - return mergeIntoCollectionWith(map, merger, iters); - } - - function deepMerger(merger) { - return function(existing, value) - {return existing && existing.mergeDeepWith && isIterable(value) ? - existing.mergeDeepWith(merger, value) : - merger ? merger(existing, value) : value}; - } - - function mergeIntoCollectionWith(collection, merger, iters) { - iters = iters.filter(function(x ) {return x.size !== 0}); - if (iters.length === 0) { - return collection; - } - if (collection.size === 0 && iters.length === 1) { - return collection.constructor(iters[0]); - } - return collection.withMutations(function(collection ) { - var mergeIntoMap = merger ? - function(value, key) { - collection.update(key, NOT_SET, function(existing ) - {return existing === NOT_SET ? value : merger(existing, value)} - ); - } : - function(value, key) { - collection.set(key, value); - } - for (var ii = 0; ii < iters.length; ii++) { - iters[ii].forEach(mergeIntoMap); - } - }); - } - - function updateInDeepMap(existing, keyPathIter, notSetValue, updater) { - var isNotSet = existing === NOT_SET; - var step = keyPathIter.next(); - if (step.done) { - var existingValue = isNotSet ? notSetValue : existing; - var newValue = updater(existingValue); - return newValue === existingValue ? existing : newValue; - } - invariant( - isNotSet || (existing && existing.set), - 'invalid keyPath' - ); - var key = step.value; - var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET); - var nextUpdated = updateInDeepMap( - nextExisting, - keyPathIter, - notSetValue, - updater - ); - return nextUpdated === nextExisting ? existing : - nextUpdated === NOT_SET ? existing.remove(key) : - (isNotSet ? emptyMap() : existing).set(key, nextUpdated); - } - - function popCount(x) { - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x = x + (x >> 8); - x = x + (x >> 16); - return x & 0x7f; - } - - function setIn(array, idx, val, canEdit) { - var newArray = canEdit ? array : arrCopy(array); - newArray[idx] = val; - return newArray; - } - - function spliceIn(array, idx, val, canEdit) { - var newLen = array.length + 1; - if (canEdit && idx + 1 === newLen) { - array[idx] = val; - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - newArray[ii] = val; - after = -1; - } else { - newArray[ii] = array[ii + after]; - } - } - return newArray; - } - - function spliceOut(array, idx, canEdit) { - var newLen = array.length - 1; - if (canEdit && idx === newLen) { - array.pop(); - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - after = 1; - } - newArray[ii] = array[ii + after]; - } - return newArray; - } - - var MAX_ARRAY_MAP_SIZE = SIZE / 4; - var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; - var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; - - createClass(List, IndexedCollection); - - // @pragma Construction - - function List(value) { - var empty = emptyList(); - if (value === null || value === undefined) { - return empty; - } - if (isList(value)) { - return value; - } - var iter = IndexedIterable(value); - var size = iter.size; - if (size === 0) { - return empty; - } - assertNotInfinite(size); - if (size > 0 && size < SIZE) { - return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); - } - return empty.withMutations(function(list ) { - list.setSize(size); - iter.forEach(function(v, i) {return list.set(i, v)}); - }); - } - - List.of = function(/*...values*/) { - return this(arguments); - }; - - List.prototype.toString = function() { - return this.__toString('List [', ']'); - }; - - // @pragma Access - - List.prototype.get = function(index, notSetValue) { - index = wrapIndex(this, index); - if (index < 0 || index >= this.size) { - return notSetValue; - } - index += this._origin; - var node = listNodeFor(this, index); - return node && node.array[index & MASK]; - }; - - // @pragma Modification - - List.prototype.set = function(index, value) { - return updateList(this, index, value); - }; - - List.prototype.remove = function(index) { - return !this.has(index) ? this : - index === 0 ? this.shift() : - index === this.size - 1 ? this.pop() : - this.splice(index, 1); - }; - - List.prototype.clear = function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = this._origin = this._capacity = 0; - this._level = SHIFT; - this._root = this._tail = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyList(); - }; - - List.prototype.push = function(/*...values*/) { - var values = arguments; - var oldSize = this.size; - return this.withMutations(function(list ) { - setListBounds(list, 0, oldSize + values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(oldSize + ii, values[ii]); - } - }); - }; - - List.prototype.pop = function() { - return setListBounds(this, 0, -1); - }; - - List.prototype.unshift = function(/*...values*/) { - var values = arguments; - return this.withMutations(function(list ) { - setListBounds(list, -values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(ii, values[ii]); - } - }); - }; - - List.prototype.shift = function() { - return setListBounds(this, 1); - }; - - // @pragma Composition - - List.prototype.merge = function(/*...iters*/) { - return mergeIntoListWith(this, undefined, arguments); - }; - - List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); - return mergeIntoListWith(this, merger, iters); - }; - - List.prototype.mergeDeep = function(/*...iters*/) { - return mergeIntoListWith(this, deepMerger(undefined), arguments); - }; - - List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); - return mergeIntoListWith(this, deepMerger(merger), iters); - }; - - List.prototype.setSize = function(size) { - return setListBounds(this, 0, size); - }; - - // @pragma Iteration - - List.prototype.slice = function(begin, end) { - var size = this.size; - if (wholeSlice(begin, end, size)) { - return this; - } - return setListBounds( - this, - resolveBegin(begin, size), - resolveEnd(end, size) - ); - }; - - List.prototype.__iterator = function(type, reverse) { - var index = 0; - var values = iterateList(this, reverse); - return new Iterator(function() { - var value = values(); - return value === DONE ? - iteratorDone() : - iteratorValue(type, index++, value); - }); - }; - - List.prototype.__iterate = function(fn, reverse) { - var index = 0; - var values = iterateList(this, reverse); - var value; - while ((value = values()) !== DONE) { - if (fn(value, index++, this) === false) { - break; - } - } - return index; - }; - - List.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - return this; - } - return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); - }; - - - function isList(maybeList) { - return !!(maybeList && maybeList[IS_LIST_SENTINEL]); - } - - List.isList = isList; - - var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; - - var ListPrototype = List.prototype; - ListPrototype[IS_LIST_SENTINEL] = true; - ListPrototype[DELETE] = ListPrototype.remove; - ListPrototype.setIn = MapPrototype.setIn; - ListPrototype.deleteIn = - ListPrototype.removeIn = MapPrototype.removeIn; - ListPrototype.update = MapPrototype.update; - ListPrototype.updateIn = MapPrototype.updateIn; - ListPrototype.mergeIn = MapPrototype.mergeIn; - ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; - ListPrototype.withMutations = MapPrototype.withMutations; - ListPrototype.asMutable = MapPrototype.asMutable; - ListPrototype.asImmutable = MapPrototype.asImmutable; - ListPrototype.wasAltered = MapPrototype.wasAltered; - - - - function VNode(array, ownerID) { - this.array = array; - this.ownerID = ownerID; - } - - // TODO: seems like these methods are very similar - - VNode.prototype.removeBefore = function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var originIndex = (index >>> level) & MASK; - if (originIndex >= this.array.length) { - return new VNode([], ownerID); - } - var removingFirst = originIndex === 0; - var newChild; - if (level > 0) { - var oldChild = this.array[originIndex]; - newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingFirst) { - return this; - } - } - if (removingFirst && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingFirst) { - for (var ii = 0; ii < originIndex; ii++) { - editable.array[ii] = undefined; - } - } - if (newChild) { - editable.array[originIndex] = newChild; - } - return editable; - }; - - VNode.prototype.removeAfter = function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var sizeIndex = ((index - 1) >>> level) & MASK; - if (sizeIndex >= this.array.length) { - return this; - } - var removingLast = sizeIndex === this.array.length - 1; - var newChild; - if (level > 0) { - var oldChild = this.array[sizeIndex]; - newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingLast) { - return this; - } - } - if (removingLast && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingLast) { - editable.array.pop(); - } - if (newChild) { - editable.array[sizeIndex] = newChild; - } - return editable; - }; - - - - var DONE = {}; - - function iterateList(list, reverse) { - var left = list._origin; - var right = list._capacity; - var tailPos = getTailOffset(right); - var tail = list._tail; - - return iterateNodeOrLeaf(list._root, list._level, 0); - - function iterateNodeOrLeaf(node, level, offset) { - return level === 0 ? - iterateLeaf(node, offset) : - iterateNode(node, level, offset); - } - - function iterateLeaf(node, offset) { - var array = offset === tailPos ? tail && tail.array : node && node.array; - var from = offset > left ? 0 : left - offset; - var to = right - offset; - if (to > SIZE) { - to = SIZE; - } - return function() { - if (from === to) { - return DONE; - } - var idx = reverse ? --to : from++; - return array && array[idx]; - }; - } - - function iterateNode(node, level, offset) { - var values; - var array = node && node.array; - var from = offset > left ? 0 : (left - offset) >> level; - var to = ((right - offset) >> level) + 1; - if (to > SIZE) { - to = SIZE; - } - return function() { - do { - if (values) { - var value = values(); - if (value !== DONE) { - return value; - } - values = null; - } - if (from === to) { - return DONE; - } - var idx = reverse ? --to : from++; - values = iterateNodeOrLeaf( - array && array[idx], level - SHIFT, offset + (idx << level) - ); - } while (true); - }; - } - } - - function makeList(origin, capacity, level, root, tail, ownerID, hash) { - var list = Object.create(ListPrototype); - list.size = capacity - origin; - list._origin = origin; - list._capacity = capacity; - list._level = level; - list._root = root; - list._tail = tail; - list.__ownerID = ownerID; - list.__hash = hash; - list.__altered = false; - return list; - } - - var EMPTY_LIST; - function emptyList() { - return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); - } - - function updateList(list, index, value) { - index = wrapIndex(list, index); - - if (index >= list.size || index < 0) { - return list.withMutations(function(list ) { - index < 0 ? - setListBounds(list, index).set(0, value) : - setListBounds(list, 0, index + 1).set(index, value) - }); - } - - index += list._origin; - - var newTail = list._tail; - var newRoot = list._root; - var didAlter = MakeRef(DID_ALTER); - if (index >= getTailOffset(list._capacity)) { - newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); - } else { - newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); - } - - if (!didAlter.value) { - return list; - } - - if (list.__ownerID) { - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; - return list; - } - return makeList(list._origin, list._capacity, list._level, newRoot, newTail); - } - - function updateVNode(node, ownerID, level, index, value, didAlter) { - var idx = (index >>> level) & MASK; - var nodeHas = node && idx < node.array.length; - if (!nodeHas && value === undefined) { - return node; - } - - var newNode; - - if (level > 0) { - var lowerNode = node && node.array[idx]; - var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); - if (newLowerNode === lowerNode) { - return node; - } - newNode = editableVNode(node, ownerID); - newNode.array[idx] = newLowerNode; - return newNode; - } - - if (nodeHas && node.array[idx] === value) { - return node; - } - - SetRef(didAlter); - - newNode = editableVNode(node, ownerID); - if (value === undefined && idx === newNode.array.length - 1) { - newNode.array.pop(); - } else { - newNode.array[idx] = value; - } - return newNode; - } - - function editableVNode(node, ownerID) { - if (ownerID && node && ownerID === node.ownerID) { - return node; - } - return new VNode(node ? node.array.slice() : [], ownerID); - } - - function listNodeFor(list, rawIndex) { - if (rawIndex >= getTailOffset(list._capacity)) { - return list._tail; - } - if (rawIndex < 1 << (list._level + SHIFT)) { - var node = list._root; - var level = list._level; - while (node && level > 0) { - node = node.array[(rawIndex >>> level) & MASK]; - level -= SHIFT; - } - return node; - } - } - - function setListBounds(list, begin, end) { - var owner = list.__ownerID || new OwnerID(); - var oldOrigin = list._origin; - var oldCapacity = list._capacity; - var newOrigin = oldOrigin + begin; - var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; - if (newOrigin === oldOrigin && newCapacity === oldCapacity) { - return list; - } - - // If it's going to end after it starts, it's empty. - if (newOrigin >= newCapacity) { - return list.clear(); - } - - var newLevel = list._level; - var newRoot = list._root; - - // New origin might require creating a higher root. - var offsetShift = 0; - while (newOrigin + offsetShift < 0) { - newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); - newLevel += SHIFT; - offsetShift += 1 << newLevel; - } - if (offsetShift) { - newOrigin += offsetShift; - oldOrigin += offsetShift; - newCapacity += offsetShift; - oldCapacity += offsetShift; - } - - var oldTailOffset = getTailOffset(oldCapacity); - var newTailOffset = getTailOffset(newCapacity); - - // New size might require creating a higher root. - while (newTailOffset >= 1 << (newLevel + SHIFT)) { - newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); - newLevel += SHIFT; - } - - // Locate or create the new tail. - var oldTail = list._tail; - var newTail = newTailOffset < oldTailOffset ? - listNodeFor(list, newCapacity - 1) : - newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; - - // Merge Tail into tree. - if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { - newRoot = editableVNode(newRoot, owner); - var node = newRoot; - for (var level = newLevel; level > SHIFT; level -= SHIFT) { - var idx = (oldTailOffset >>> level) & MASK; - node = node.array[idx] = editableVNode(node.array[idx], owner); - } - node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; - } - - // If the size has been reduced, there's a chance the tail needs to be trimmed. - if (newCapacity < oldCapacity) { - newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); - } - - // If the new origin is within the tail, then we do not need a root. - if (newOrigin >= newTailOffset) { - newOrigin -= newTailOffset; - newCapacity -= newTailOffset; - newLevel = SHIFT; - newRoot = null; - newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); - - // Otherwise, if the root has been trimmed, garbage collect. - } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { - offsetShift = 0; - - // Identify the new top root node of the subtree of the old root. - while (newRoot) { - var beginIndex = (newOrigin >>> newLevel) & MASK; - if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { - break; - } - if (beginIndex) { - offsetShift += (1 << newLevel) * beginIndex; - } - newLevel -= SHIFT; - newRoot = newRoot.array[beginIndex]; - } - - // Trim the new sides of the new root. - if (newRoot && newOrigin > oldOrigin) { - newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); - } - if (newRoot && newTailOffset < oldTailOffset) { - newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); - } - if (offsetShift) { - newOrigin -= offsetShift; - newCapacity -= offsetShift; - } - } - - if (list.__ownerID) { - list.size = newCapacity - newOrigin; - list._origin = newOrigin; - list._capacity = newCapacity; - list._level = newLevel; - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; - return list; - } - return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); - } - - function mergeIntoListWith(list, merger, iterables) { - var iters = []; - var maxSize = 0; - for (var ii = 0; ii < iterables.length; ii++) { - var value = iterables[ii]; - var iter = IndexedIterable(value); - if (iter.size > maxSize) { - maxSize = iter.size; - } - if (!isIterable(value)) { - iter = iter.map(function(v ) {return fromJS(v)}); - } - iters.push(iter); - } - if (maxSize > list.size) { - list = list.setSize(maxSize); - } - return mergeIntoCollectionWith(list, merger, iters); - } - - function getTailOffset(size) { - return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); - } - - createClass(OrderedMap, Map); - - // @pragma Construction - - function OrderedMap(value) { - return value === null || value === undefined ? emptyOrderedMap() : - isOrderedMap(value) ? value : - emptyOrderedMap().withMutations(function(map ) { - var iter = KeyedIterable(value); - assertNotInfinite(iter.size); - iter.forEach(function(v, k) {return map.set(k, v)}); - }); - } - - OrderedMap.of = function(/*...values*/) { - return this(arguments); - }; - - OrderedMap.prototype.toString = function() { - return this.__toString('OrderedMap {', '}'); - }; - - // @pragma Access - - OrderedMap.prototype.get = function(k, notSetValue) { - var index = this._map.get(k); - return index !== undefined ? this._list.get(index)[1] : notSetValue; - }; - - // @pragma Modification - - OrderedMap.prototype.clear = function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._map.clear(); - this._list.clear(); - return this; - } - return emptyOrderedMap(); - }; - - OrderedMap.prototype.set = function(k, v) { - return updateOrderedMap(this, k, v); - }; - - OrderedMap.prototype.remove = function(k) { - return updateOrderedMap(this, k, NOT_SET); - }; - - OrderedMap.prototype.wasAltered = function() { - return this._map.wasAltered() || this._list.wasAltered(); - }; - - OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this; - return this._list.__iterate( - function(entry ) {return entry && fn(entry[1], entry[0], this$0)}, - reverse - ); - }; - - OrderedMap.prototype.__iterator = function(type, reverse) { - return this._list.fromEntrySeq().__iterator(type, reverse); - }; - - OrderedMap.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - var newList = this._list.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - this._list = newList; - return this; - } - return makeOrderedMap(newMap, newList, ownerID, this.__hash); - }; - - - function isOrderedMap(maybeOrderedMap) { - return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); - } - - OrderedMap.isOrderedMap = isOrderedMap; - - OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; - OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; - - - - function makeOrderedMap(map, list, ownerID, hash) { - var omap = Object.create(OrderedMap.prototype); - omap.size = map ? map.size : 0; - omap._map = map; - omap._list = list; - omap.__ownerID = ownerID; - omap.__hash = hash; - return omap; - } - - var EMPTY_ORDERED_MAP; - function emptyOrderedMap() { - return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); - } - - function updateOrderedMap(omap, k, v) { - var map = omap._map; - var list = omap._list; - var i = map.get(k); - var has = i !== undefined; - var newMap; - var newList; - if (v === NOT_SET) { // removed - if (!has) { - return omap; - } - if (list.size >= SIZE && list.size >= map.size * 2) { - newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx}); - newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap(); - if (omap.__ownerID) { - newMap.__ownerID = newList.__ownerID = omap.__ownerID; - } - } else { - newMap = map.remove(k); - newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); - } - } else { - if (has) { - if (v === list.get(i)[1]) { - return omap; - } - newMap = map; - newList = list.set(i, [k, v]); - } else { - newMap = map.set(k, list.size); - newList = list.set(list.size, [k, v]); - } - } - if (omap.__ownerID) { - omap.size = newMap.size; - omap._map = newMap; - omap._list = newList; - omap.__hash = undefined; - return omap; - } - return makeOrderedMap(newMap, newList); - } - - createClass(Stack, IndexedCollection); - - // @pragma Construction - - function Stack(value) { - return value === null || value === undefined ? emptyStack() : - isStack(value) ? value : - emptyStack().unshiftAll(value); - } - - Stack.of = function(/*...values*/) { - return this(arguments); - }; - - Stack.prototype.toString = function() { - return this.__toString('Stack [', ']'); - }; - - // @pragma Access - - Stack.prototype.get = function(index, notSetValue) { - var head = this._head; - while (head && index--) { - head = head.next; - } - return head ? head.value : notSetValue; - }; - - Stack.prototype.peek = function() { - return this._head && this._head.value; - }; - - // @pragma Modification - - Stack.prototype.push = function(/*...values*/) { - if (arguments.length === 0) { - return this; - } - var newSize = this.size + arguments.length; - var head = this._head; - for (var ii = arguments.length - 1; ii >= 0; ii--) { - head = { - value: arguments[ii], - next: head - }; - } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - Stack.prototype.pushAll = function(iter) { - iter = IndexedIterable(iter); - if (iter.size === 0) { - return this; - } - assertNotInfinite(iter.size); - var newSize = this.size; - var head = this._head; - iter.reverse().forEach(function(value ) { - newSize++; - head = { - value: value, - next: head - }; - }); - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - Stack.prototype.pop = function() { - return this.slice(1); - }; - - Stack.prototype.unshift = function(/*...values*/) { - return this.push.apply(this, arguments); - }; - - Stack.prototype.unshiftAll = function(iter) { - return this.pushAll(iter); - }; - - Stack.prototype.shift = function() { - return this.pop.apply(this, arguments); - }; - - Stack.prototype.clear = function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._head = undefined; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyStack(); - }; - - Stack.prototype.slice = function(begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; - } - var resolvedBegin = resolveBegin(begin, this.size); - var resolvedEnd = resolveEnd(end, this.size); - if (resolvedEnd !== this.size) { - // super.slice(begin, end); - return IndexedCollection.prototype.slice.call(this, begin, end); - } - var newSize = this.size - resolvedBegin; - var head = this._head; - while (resolvedBegin--) { - head = head.next; - } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; - } - return makeStack(newSize, head); - }; - - // @pragma Mutability - - Stack.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeStack(this.size, this._head, ownerID, this.__hash); - }; - - // @pragma Iteration - - Stack.prototype.__iterate = function(fn, reverse) { - if (reverse) { - return this.toSeq().cacheResult.__iterate(fn, reverse); - } - var iterations = 0; - var node = this._head; - while (node) { - if (fn(node.value, iterations++, this) === false) { - break; - } - node = node.next; - } - return iterations; - }; - - Stack.prototype.__iterator = function(type, reverse) { - if (reverse) { - return this.toSeq().cacheResult().__iterator(type, reverse); - } - var iterations = 0; - var node = this._head; - return new Iterator(function() { - if (node) { - var value = node.value; - node = node.next; - return iteratorValue(type, iterations++, value); - } - return iteratorDone(); - }); - }; - - - function isStack(maybeStack) { - return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); - } - - Stack.isStack = isStack; - - var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; - - var StackPrototype = Stack.prototype; - StackPrototype[IS_STACK_SENTINEL] = true; - StackPrototype.withMutations = MapPrototype.withMutations; - StackPrototype.asMutable = MapPrototype.asMutable; - StackPrototype.asImmutable = MapPrototype.asImmutable; - StackPrototype.wasAltered = MapPrototype.wasAltered; - - - function makeStack(size, head, ownerID, hash) { - var map = Object.create(StackPrototype); - map.size = size; - map._head = head; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; - } - - var EMPTY_STACK; - function emptyStack() { - return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); - } - - createClass(Set, SetCollection); - - // @pragma Construction - - function Set(value) { - return value === null || value === undefined ? emptySet() : - isSet(value) ? value : - emptySet().withMutations(function(set ) { - var iter = SetIterable(value); - assertNotInfinite(iter.size); - iter.forEach(function(v ) {return set.add(v)}); - }); - } - - Set.of = function(/*...values*/) { - return this(arguments); - }; - - Set.fromKeys = function(value) { - return this(KeyedIterable(value).keySeq()); - }; - - Set.prototype.toString = function() { - return this.__toString('Set {', '}'); - }; - - // @pragma Access - - Set.prototype.has = function(value) { - return this._map.has(value); - }; - - // @pragma Modification - - Set.prototype.add = function(value) { - return updateSet(this, this._map.set(value, true)); - }; - - Set.prototype.remove = function(value) { - return updateSet(this, this._map.remove(value)); - }; - - Set.prototype.clear = function() { - return updateSet(this, this._map.clear()); - }; - - // @pragma Composition - - Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0); - iters = iters.filter(function(x ) {return x.size !== 0}); - if (iters.length === 0) { - return this; - } - if (this.size === 0 && iters.length === 1) { - return this.constructor(iters[0]); - } - return this.withMutations(function(set ) { - for (var ii = 0; ii < iters.length; ii++) { - SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)}); - } - }); - }; - - Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0); - if (iters.length === 0) { - return this; - } - iters = iters.map(function(iter ) {return SetIterable(iter)}); - var originalSet = this; - return this.withMutations(function(set ) { - originalSet.forEach(function(value ) { - if (!iters.every(function(iter ) {return iter.contains(value)})) { - set.remove(value); - } - }); - }); - }; - - Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0); - if (iters.length === 0) { - return this; - } - iters = iters.map(function(iter ) {return SetIterable(iter)}); - var originalSet = this; - return this.withMutations(function(set ) { - originalSet.forEach(function(value ) { - if (iters.some(function(iter ) {return iter.contains(value)})) { - set.remove(value); - } - }); - }); - }; - - Set.prototype.merge = function() { - return this.union.apply(this, arguments); - }; - - Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); - return this.union.apply(this, iters); - }; - - Set.prototype.sort = function(comparator) { - // Late binding - return OrderedSet(sortFactory(this, comparator)); - }; - - Set.prototype.sortBy = function(mapper, comparator) { - // Late binding - return OrderedSet(sortFactory(this, comparator, mapper)); - }; - - Set.prototype.wasAltered = function() { - return this._map.wasAltered(); - }; - - Set.prototype.__iterate = function(fn, reverse) {var this$0 = this; - return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse); - }; - - Set.prototype.__iterator = function(type, reverse) { - return this._map.map(function(_, k) {return k}).__iterator(type, reverse); - }; - - Set.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return this.__make(newMap, ownerID); - }; - - - function isSet(maybeSet) { - return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); - } - - Set.isSet = isSet; - - var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; - - var SetPrototype = Set.prototype; - SetPrototype[IS_SET_SENTINEL] = true; - SetPrototype[DELETE] = SetPrototype.remove; - SetPrototype.mergeDeep = SetPrototype.merge; - SetPrototype.mergeDeepWith = SetPrototype.mergeWith; - SetPrototype.withMutations = MapPrototype.withMutations; - SetPrototype.asMutable = MapPrototype.asMutable; - SetPrototype.asImmutable = MapPrototype.asImmutable; - - SetPrototype.__empty = emptySet; - SetPrototype.__make = makeSet; - - function updateSet(set, newMap) { - if (set.__ownerID) { - set.size = newMap.size; - set._map = newMap; - return set; - } - return newMap === set._map ? set : - newMap.size === 0 ? set.__empty() : - set.__make(newMap); - } - - function makeSet(map, ownerID) { - var set = Object.create(SetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; - } - - var EMPTY_SET; - function emptySet() { - return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); - } - - createClass(OrderedSet, Set); - - // @pragma Construction - - function OrderedSet(value) { - return value === null || value === undefined ? emptyOrderedSet() : - isOrderedSet(value) ? value : - emptyOrderedSet().withMutations(function(set ) { - var iter = SetIterable(value); - assertNotInfinite(iter.size); - iter.forEach(function(v ) {return set.add(v)}); - }); - } - - OrderedSet.of = function(/*...values*/) { - return this(arguments); - }; - - OrderedSet.fromKeys = function(value) { - return this(KeyedIterable(value).keySeq()); - }; - - OrderedSet.prototype.toString = function() { - return this.__toString('OrderedSet {', '}'); - }; - - - function isOrderedSet(maybeOrderedSet) { - return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); - } - - OrderedSet.isOrderedSet = isOrderedSet; - - var OrderedSetPrototype = OrderedSet.prototype; - OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; - - OrderedSetPrototype.__empty = emptyOrderedSet; - OrderedSetPrototype.__make = makeOrderedSet; - - function makeOrderedSet(map, ownerID) { - var set = Object.create(OrderedSetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; - } - - var EMPTY_ORDERED_SET; - function emptyOrderedSet() { - return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); - } - - createClass(Record, KeyedCollection); - - function Record(defaultValues, name) { - var RecordType = function Record(values) { - if (!(this instanceof RecordType)) { - return new RecordType(values); - } - this._map = Map(values); - }; - - var keys = Object.keys(defaultValues); - - var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); - RecordTypePrototype.constructor = RecordType; - name && (RecordTypePrototype._name = name); - RecordTypePrototype._defaultValues = defaultValues; - RecordTypePrototype._keys = keys; - RecordTypePrototype.size = keys.length; - - try { - keys.forEach(function(key ) { - Object.defineProperty(RecordType.prototype, key, { - get: function() { - return this.get(key); - }, - set: function(value) { - invariant(this.__ownerID, 'Cannot set on an immutable record.'); - this.set(key, value); - } - }); - }); - } catch (error) { - // Object.defineProperty failed. Probably IE8. - } - - return RecordType; - } - - Record.prototype.toString = function() { - return this.__toString(recordName(this) + ' {', '}'); - }; - - // @pragma Access - - Record.prototype.has = function(k) { - return this._defaultValues.hasOwnProperty(k); - }; - - Record.prototype.get = function(k, notSetValue) { - if (!this.has(k)) { - return notSetValue; - } - var defaultVal = this._defaultValues[k]; - return this._map ? this._map.get(k, defaultVal) : defaultVal; - }; - - // @pragma Modification - - Record.prototype.clear = function() { - if (this.__ownerID) { - this._map && this._map.clear(); - return this; - } - var SuperRecord = Object.getPrototypeOf(this).constructor; - return SuperRecord._empty || (SuperRecord._empty = makeRecord(this, emptyMap())); - }; - - Record.prototype.set = function(k, v) { - if (!this.has(k)) { - throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); - } - var newMap = this._map && this._map.set(k, v); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }; - - Record.prototype.remove = function(k) { - if (!this.has(k)) { - return this; - } - var newMap = this._map && this._map.remove(k); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }; - - Record.prototype.wasAltered = function() { - return this._map.wasAltered(); - }; - - Record.prototype.__iterator = function(type, reverse) {var this$0 = this; - return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse); - }; - - Record.prototype.__iterate = function(fn, reverse) {var this$0 = this; - return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse); - }; - - Record.prototype.__ensureOwner = function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map && this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return makeRecord(this, newMap, ownerID); - }; - - - var RecordPrototype = Record.prototype; - RecordPrototype[DELETE] = RecordPrototype.remove; - RecordPrototype.deleteIn = - RecordPrototype.removeIn = MapPrototype.removeIn; - RecordPrototype.merge = MapPrototype.merge; - RecordPrototype.mergeWith = MapPrototype.mergeWith; - RecordPrototype.mergeIn = MapPrototype.mergeIn; - RecordPrototype.mergeDeep = MapPrototype.mergeDeep; - RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; - RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; - RecordPrototype.setIn = MapPrototype.setIn; - RecordPrototype.update = MapPrototype.update; - RecordPrototype.updateIn = MapPrototype.updateIn; - RecordPrototype.withMutations = MapPrototype.withMutations; - RecordPrototype.asMutable = MapPrototype.asMutable; - RecordPrototype.asImmutable = MapPrototype.asImmutable; - - - function makeRecord(likeRecord, map, ownerID) { - var record = Object.create(Object.getPrototypeOf(likeRecord)); - record._map = map; - record.__ownerID = ownerID; - return record; - } - - function recordName(record) { - return record._name || record.constructor.name; - } - - function deepEqual(a, b) { - if (a === b) { - return true; - } - - if ( - !isIterable(b) || - a.size !== undefined && b.size !== undefined && a.size !== b.size || - a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash || - isKeyed(a) !== isKeyed(b) || - isIndexed(a) !== isIndexed(b) || - isOrdered(a) !== isOrdered(b) - ) { - return false; - } - - if (a.size === 0 && b.size === 0) { - return true; - } - - var notAssociative = !isAssociative(a); - - if (isOrdered(a)) { - var entries = a.entries(); - return b.every(function(v, k) { - var entry = entries.next().value; - return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); - }) && entries.next().done; - } - - var flipped = false; - - if (a.size === undefined) { - if (b.size === undefined) { - a.cacheResult(); - } else { - flipped = true; - var _ = a; - a = b; - b = _; - } - } - - var allEqual = true; - var bSize = b.__iterate(function(v, k) { - if (notAssociative ? !a.has(v) : - flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { - allEqual = false; - return false; - } - }); - - return allEqual && a.size === bSize; - } - - createClass(Range, IndexedSeq); - - function Range(start, end, step) { - if (!(this instanceof Range)) { - return new Range(start, end, step); - } - invariant(step !== 0, 'Cannot step a Range by 0'); - start = start || 0; - if (end === undefined) { - end = Infinity; - } - step = step === undefined ? 1 : Math.abs(step); - if (end < start) { - step = -step; - } - this._start = start; - this._end = end; - this._step = step; - this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); - if (this.size === 0) { - if (EMPTY_RANGE) { - return EMPTY_RANGE; - } - EMPTY_RANGE = this; - } - } - - Range.prototype.toString = function() { - if (this.size === 0) { - return 'Range []'; - } - return 'Range [ ' + - this._start + '...' + this._end + - (this._step > 1 ? ' by ' + this._step : '') + - ' ]'; - }; - - Range.prototype.get = function(index, notSetValue) { - return this.has(index) ? - this._start + wrapIndex(this, index) * this._step : - notSetValue; - }; - - Range.prototype.contains = function(searchValue) { - var possibleIndex = (searchValue - this._start) / this._step; - return possibleIndex >= 0 && - possibleIndex < this.size && - possibleIndex === Math.floor(possibleIndex); - }; - - Range.prototype.slice = function(begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; - } - begin = resolveBegin(begin, this.size); - end = resolveEnd(end, this.size); - if (end <= begin) { - return new Range(0, 0); - } - return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); - }; - - Range.prototype.indexOf = function(searchValue) { - var offsetValue = searchValue - this._start; - if (offsetValue % this._step === 0) { - var index = offsetValue / this._step; - if (index >= 0 && index < this.size) { - return index - } - } - return -1; - }; - - Range.prototype.lastIndexOf = function(searchValue) { - return this.indexOf(searchValue); - }; - - Range.prototype.__iterate = function(fn, reverse) { - var maxIndex = this.size - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(value, ii, this) === false) { - return ii + 1; - } - value += reverse ? -step : step; - } - return ii; - }; - - Range.prototype.__iterator = function(type, reverse) { - var maxIndex = this.size - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - var ii = 0; - return new Iterator(function() { - var v = value; - value += reverse ? -step : step; - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); - }); - }; - - Range.prototype.equals = function(other) { - return other instanceof Range ? - this._start === other._start && - this._end === other._end && - this._step === other._step : - deepEqual(this, other); - }; - - - var EMPTY_RANGE; - - createClass(Repeat, IndexedSeq); - - function Repeat(value, times) { - if (!(this instanceof Repeat)) { - return new Repeat(value, times); - } - this._value = value; - this.size = times === undefined ? Infinity : Math.max(0, times); - if (this.size === 0) { - if (EMPTY_REPEAT) { - return EMPTY_REPEAT; - } - EMPTY_REPEAT = this; - } - } - - Repeat.prototype.toString = function() { - if (this.size === 0) { - return 'Repeat []'; - } - return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; - }; - - Repeat.prototype.get = function(index, notSetValue) { - return this.has(index) ? this._value : notSetValue; - }; - - Repeat.prototype.contains = function(searchValue) { - return is(this._value, searchValue); - }; - - Repeat.prototype.slice = function(begin, end) { - var size = this.size; - return wholeSlice(begin, end, size) ? this : - new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); - }; - - Repeat.prototype.reverse = function() { - return this; - }; - - Repeat.prototype.indexOf = function(searchValue) { - if (is(this._value, searchValue)) { - return 0; - } - return -1; - }; - - Repeat.prototype.lastIndexOf = function(searchValue) { - if (is(this._value, searchValue)) { - return this.size; - } - return -1; - }; - - Repeat.prototype.__iterate = function(fn, reverse) { - for (var ii = 0; ii < this.size; ii++) { - if (fn(this._value, ii, this) === false) { - return ii + 1; - } - } - return ii; - }; - - Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this; - var ii = 0; - return new Iterator(function() - {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()} - ); - }; - - Repeat.prototype.equals = function(other) { - return other instanceof Repeat ? - is(this._value, other._value) : - deepEqual(other); - }; - - - var EMPTY_REPEAT; - - /** - * Contributes additional methods to a constructor - */ - function mixin(ctor, methods) { - var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; }; - Object.keys(methods).forEach(keyCopier); - Object.getOwnPropertySymbols && - Object.getOwnPropertySymbols(methods).forEach(keyCopier); - return ctor; - } - - Iterable.Iterator = Iterator; - - mixin(Iterable, { - - // ### Conversion to other types - - toArray: function() { - assertNotInfinite(this.size); - var array = new Array(this.size || 0); - this.valueSeq().__iterate(function(v, i) { array[i] = v; }); - return array; - }, - - toIndexedSeq: function() { - return new ToIndexedSequence(this); - }, - - toJS: function() { - return this.toSeq().map( - function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value} - ).__toJS(); - }, - - toJSON: function() { - return this.toSeq().map( - function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value} - ).__toJS(); - }, - - toKeyedSeq: function() { - return new ToKeyedSequence(this, true); - }, - - toMap: function() { - // Use Late Binding here to solve the circular dependency. - return Map(this.toKeyedSeq()); - }, - - toObject: function() { - assertNotInfinite(this.size); - var object = {}; - this.__iterate(function(v, k) { object[k] = v; }); - return object; - }, - - toOrderedMap: function() { - // Use Late Binding here to solve the circular dependency. - return OrderedMap(this.toKeyedSeq()); - }, - - toOrderedSet: function() { - // Use Late Binding here to solve the circular dependency. - return OrderedSet(isKeyed(this) ? this.valueSeq() : this); - }, - - toSet: function() { - // Use Late Binding here to solve the circular dependency. - return Set(isKeyed(this) ? this.valueSeq() : this); - }, - - toSetSeq: function() { - return new ToSetSequence(this); - }, - - toSeq: function() { - return isIndexed(this) ? this.toIndexedSeq() : - isKeyed(this) ? this.toKeyedSeq() : - this.toSetSeq(); - }, - - toStack: function() { - // Use Late Binding here to solve the circular dependency. - return Stack(isKeyed(this) ? this.valueSeq() : this); - }, - - toList: function() { - // Use Late Binding here to solve the circular dependency. - return List(isKeyed(this) ? this.valueSeq() : this); - }, - - - // ### Common JavaScript methods and properties - - toString: function() { - return '[Iterable]'; - }, - - __toString: function(head, tail) { - if (this.size === 0) { - return head + tail; - } - return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; - }, - - - // ### ES6 Collection methods (ES6 Array and Map) - - concat: function() {var values = SLICE$0.call(arguments, 0); - return reify(this, concatFactory(this, values)); - }, - - contains: function(searchValue) { - return this.some(function(value ) {return is(value, searchValue)}); - }, - - entries: function() { - return this.__iterator(ITERATE_ENTRIES); - }, - - every: function(predicate, context) { - assertNotInfinite(this.size); - var returnValue = true; - this.__iterate(function(v, k, c) { - if (!predicate.call(context, v, k, c)) { - returnValue = false; - return false; - } - }); - return returnValue; - }, - - filter: function(predicate, context) { - return reify(this, filterFactory(this, predicate, context, true)); - }, - - find: function(predicate, context, notSetValue) { - var entry = this.findEntry(predicate, context); - return entry ? entry[1] : notSetValue; - }, - - findEntry: function(predicate, context) { - var found; - this.__iterate(function(v, k, c) { - if (predicate.call(context, v, k, c)) { - found = [k, v]; - return false; - } - }); - return found; - }, - - findLastEntry: function(predicate, context) { - return this.toSeq().reverse().findEntry(predicate, context); - }, - - forEach: function(sideEffect, context) { - assertNotInfinite(this.size); - return this.__iterate(context ? sideEffect.bind(context) : sideEffect); - }, - - join: function(separator) { - assertNotInfinite(this.size); - separator = separator !== undefined ? '' + separator : ','; - var joined = ''; - var isFirst = true; - this.__iterate(function(v ) { - isFirst ? (isFirst = false) : (joined += separator); - joined += v !== null && v !== undefined ? v : ''; - }); - return joined; - }, - - keys: function() { - return this.__iterator(ITERATE_KEYS); - }, - - map: function(mapper, context) { - return reify(this, mapFactory(this, mapper, context)); - }, - - reduce: function(reducer, initialReduction, context) { - assertNotInfinite(this.size); - var reduction; - var useFirst; - if (arguments.length < 2) { - useFirst = true; - } else { - reduction = initialReduction; - } - this.__iterate(function(v, k, c) { - if (useFirst) { - useFirst = false; - reduction = v; - } else { - reduction = reducer.call(context, reduction, v, k, c); - } - }); - return reduction; - }, - - reduceRight: function(reducer, initialReduction, context) { - var reversed = this.toKeyedSeq().reverse(); - return reversed.reduce.apply(reversed, arguments); - }, - - reverse: function() { - return reify(this, reverseFactory(this, true)); - }, - - slice: function(begin, end) { - return reify(this, sliceFactory(this, begin, end, true)); - }, - - some: function(predicate, context) { - return !this.every(not(predicate), context); - }, - - sort: function(comparator) { - return reify(this, sortFactory(this, comparator)); - }, - - values: function() { - return this.__iterator(ITERATE_VALUES); - }, - - - // ### More sequential methods - - butLast: function() { - return this.slice(0, -1); - }, - - isEmpty: function() { - return this.size !== undefined ? this.size === 0 : !this.some(function() {return true}); - }, - - count: function(predicate, context) { - return ensureSize( - predicate ? this.toSeq().filter(predicate, context) : this - ); - }, - - countBy: function(grouper, context) { - return countByFactory(this, grouper, context); - }, - - equals: function(other) { - return deepEqual(this, other); - }, - - entrySeq: function() { - var iterable = this; - if (iterable._cache) { - // We cache as an entries array, so we can just return the cache! - return new ArraySeq(iterable._cache); - } - var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); - entriesSequence.fromEntrySeq = function() {return iterable.toSeq()}; - return entriesSequence; - }, - - filterNot: function(predicate, context) { - return this.filter(not(predicate), context); - }, - - findLast: function(predicate, context, notSetValue) { - return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); - }, - - first: function() { - return this.find(returnTrue); - }, - - flatMap: function(mapper, context) { - return reify(this, flatMapFactory(this, mapper, context)); - }, - - flatten: function(depth) { - return reify(this, flattenFactory(this, depth, true)); - }, - - fromEntrySeq: function() { - return new FromEntriesSequence(this); - }, - - get: function(searchKey, notSetValue) { - return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue); - }, - - getIn: function(searchKeyPath, notSetValue) { - var nested = this; - // Note: in an ES6 environment, we would prefer: - // for (var key of searchKeyPath) { - var iter = forceIterator(searchKeyPath); - var step; - while (!(step = iter.next()).done) { - var key = step.value; - nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET; - if (nested === NOT_SET) { - return notSetValue; - } - } - return nested; - }, - - groupBy: function(grouper, context) { - return groupByFactory(this, grouper, context); - }, - - has: function(searchKey) { - return this.get(searchKey, NOT_SET) !== NOT_SET; - }, - - hasIn: function(searchKeyPath) { - return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET; - }, - - isSubset: function(iter) { - iter = typeof iter.contains === 'function' ? iter : Iterable(iter); - return this.every(function(value ) {return iter.contains(value)}); - }, - - isSuperset: function(iter) { - return iter.isSubset(this); - }, - - keySeq: function() { - return this.toSeq().map(keyMapper).toIndexedSeq(); - }, - - last: function() { - return this.toSeq().reverse().first(); - }, - - max: function(comparator) { - return maxFactory(this, comparator); - }, - - maxBy: function(mapper, comparator) { - return maxFactory(this, comparator, mapper); - }, - - min: function(comparator) { - return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); - }, - - minBy: function(mapper, comparator) { - return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); - }, - - rest: function() { - return this.slice(1); - }, - - skip: function(amount) { - return this.slice(Math.max(0, amount)); - }, - - skipLast: function(amount) { - return reify(this, this.toSeq().reverse().skip(amount).reverse()); - }, - - skipWhile: function(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, true)); - }, - - skipUntil: function(predicate, context) { - return this.skipWhile(not(predicate), context); - }, - - sortBy: function(mapper, comparator) { - return reify(this, sortFactory(this, comparator, mapper)); - }, - - take: function(amount) { - return this.slice(0, Math.max(0, amount)); - }, - - takeLast: function(amount) { - return reify(this, this.toSeq().reverse().take(amount).reverse()); - }, - - takeWhile: function(predicate, context) { - return reify(this, takeWhileFactory(this, predicate, context)); - }, - - takeUntil: function(predicate, context) { - return this.takeWhile(not(predicate), context); - }, - - valueSeq: function() { - return this.toIndexedSeq(); - }, - - - // ### Hashable Object - - hashCode: function() { - return this.__hash || (this.__hash = hashIterable(this)); - }, - - - // ### Internal - - // abstract __iterate(fn, reverse) - - // abstract __iterator(type, reverse) - }); - - // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; - // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; - // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; - // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; - - var IterablePrototype = Iterable.prototype; - IterablePrototype[IS_ITERABLE_SENTINEL] = true; - IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; - IterablePrototype.__toJS = IterablePrototype.toArray; - IterablePrototype.__toStringMapper = quoteString; - IterablePrototype.inspect = - IterablePrototype.toSource = function() { return this.toString(); }; - IterablePrototype.chain = IterablePrototype.flatMap; - - // Temporary warning about using length - (function () { - try { - Object.defineProperty(IterablePrototype, 'length', { - get: function () { - if (!Iterable.noLengthWarning) { - var stack; - try { - throw new Error(); - } catch (error) { - stack = error.stack; - } - if (stack.indexOf('_wrapObject') === -1) { - console && console.warn && console.warn( - 'iterable.length has been deprecated, '+ - 'use iterable.size or iterable.count(). '+ - 'This warning will become a silent error in a future version. ' + - stack - ); - return this.size; - } - } - } - }); - } catch (e) {} - })(); - - - - mixin(KeyedIterable, { - - // ### More sequential methods - - flip: function() { - return reify(this, flipFactory(this)); - }, - - findKey: function(predicate, context) { - var entry = this.findEntry(predicate, context); - return entry && entry[0]; - }, - - findLastKey: function(predicate, context) { - return this.toSeq().reverse().findKey(predicate, context); - }, - - keyOf: function(searchValue) { - return this.findKey(function(value ) {return is(value, searchValue)}); - }, - - lastKeyOf: function(searchValue) { - return this.findLastKey(function(value ) {return is(value, searchValue)}); - }, - - mapEntries: function(mapper, context) {var this$0 = this; - var iterations = 0; - return reify(this, - this.toSeq().map( - function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)} - ).fromEntrySeq() - ); - }, - - mapKeys: function(mapper, context) {var this$0 = this; - return reify(this, - this.toSeq().flip().map( - function(k, v) {return mapper.call(context, k, v, this$0)} - ).flip() - ); - }, - - }); - - var KeyedIterablePrototype = KeyedIterable.prototype; - KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; - KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; - KeyedIterablePrototype.__toJS = IterablePrototype.toObject; - KeyedIterablePrototype.__toStringMapper = function(v, k) {return k + ': ' + quoteString(v)}; - - - - mixin(IndexedIterable, { - - // ### Conversion to other types - - toKeyedSeq: function() { - return new ToKeyedSequence(this, false); - }, - - - // ### ES6 Collection methods (ES6 Array and Map) - - filter: function(predicate, context) { - return reify(this, filterFactory(this, predicate, context, false)); - }, - - findIndex: function(predicate, context) { - var entry = this.findEntry(predicate, context); - return entry ? entry[0] : -1; - }, - - indexOf: function(searchValue) { - var key = this.toKeyedSeq().keyOf(searchValue); - return key === undefined ? -1 : key; - }, - - lastIndexOf: function(searchValue) { - return this.toSeq().reverse().indexOf(searchValue); - }, - - reverse: function() { - return reify(this, reverseFactory(this, false)); - }, - - slice: function(begin, end) { - return reify(this, sliceFactory(this, begin, end, false)); - }, - - splice: function(index, removeNum /*, ...values*/) { - var numArgs = arguments.length; - removeNum = Math.max(removeNum | 0, 0); - if (numArgs === 0 || (numArgs === 2 && !removeNum)) { - return this; - } - index = resolveBegin(index, this.size); - var spliced = this.slice(0, index); - return reify( - this, - numArgs === 1 ? - spliced : - spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) - ); - }, - - - // ### More collection methods - - findLastIndex: function(predicate, context) { - var key = this.toKeyedSeq().findLastKey(predicate, context); - return key === undefined ? -1 : key; - }, - - first: function() { - return this.get(0); - }, - - flatten: function(depth) { - return reify(this, flattenFactory(this, depth, false)); - }, - - get: function(index, notSetValue) { - index = wrapIndex(this, index); - return (index < 0 || (this.size === Infinity || - (this.size !== undefined && index > this.size))) ? - notSetValue : - this.find(function(_, key) {return key === index}, undefined, notSetValue); - }, - - has: function(index) { - index = wrapIndex(this, index); - return index >= 0 && (this.size !== undefined ? - this.size === Infinity || index < this.size : - this.indexOf(index) !== -1 - ); - }, - - interpose: function(separator) { - return reify(this, interposeFactory(this, separator)); - }, - - interleave: function(/*...iterables*/) { - var iterables = [this].concat(arrCopy(arguments)); - var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables); - var interleaved = zipped.flatten(true); - if (zipped.size) { - interleaved.size = zipped.size * iterables.length; - } - return reify(this, interleaved); - }, - - last: function() { - return this.get(-1); - }, - - skipWhile: function(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, false)); - }, - - zip: function(/*, ...iterables */) { - var iterables = [this].concat(arrCopy(arguments)); - return reify(this, zipWithFactory(this, defaultZipper, iterables)); - }, - - zipWith: function(zipper/*, ...iterables */) { - var iterables = arrCopy(arguments); - iterables[0] = this; - return reify(this, zipWithFactory(this, zipper, iterables)); - }, - - }); - - IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; - IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; - - - - mixin(SetIterable, { - - // ### ES6 Collection methods (ES6 Array and Map) - - get: function(value, notSetValue) { - return this.has(value) ? value : notSetValue; - }, - - contains: function(value) { - return this.has(value); - }, - - - // ### More sequential methods - - keySeq: function() { - return this.valueSeq(); - }, - - }); - - SetIterable.prototype.has = IterablePrototype.contains; - - - // Mixin subclasses - - mixin(KeyedSeq, KeyedIterable.prototype); - mixin(IndexedSeq, IndexedIterable.prototype); - mixin(SetSeq, SetIterable.prototype); - - mixin(KeyedCollection, KeyedIterable.prototype); - mixin(IndexedCollection, IndexedIterable.prototype); - mixin(SetCollection, SetIterable.prototype); - - - // #pragma Helper functions - - function keyMapper(v, k) { - return k; - } - - function entryMapper(v, k) { - return [k, v]; - } - - function not(predicate) { - return function() { - return !predicate.apply(this, arguments); - } - } - - function neg(predicate) { - return function() { - return -predicate.apply(this, arguments); - } - } - - function quoteString(value) { - return typeof value === 'string' ? JSON.stringify(value) : value; - } - - function defaultZipper() { - return arrCopy(arguments); - } - - function defaultNegComparator(a, b) { - return a < b ? 1 : a > b ? -1 : 0; - } - - function hashIterable(iterable) { - if (iterable.size === Infinity) { - return 0; - } - var ordered = isOrdered(iterable); - var keyed = isKeyed(iterable); - var h = ordered ? 1 : 0; - var size = iterable.__iterate( - keyed ? - ordered ? - function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } : - function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } : - ordered ? - function(v ) { h = 31 * h + hash(v) | 0; } : - function(v ) { h = h + hash(v) | 0; } - ); - return murmurHashOfSize(size, h); - } - - function murmurHashOfSize(size, h) { - h = Math__imul(h, 0xCC9E2D51); - h = Math__imul(h << 15 | h >>> -15, 0x1B873593); - h = Math__imul(h << 13 | h >>> -13, 5); - h = (h + 0xE6546B64 | 0) ^ size; - h = Math__imul(h ^ h >>> 16, 0x85EBCA6B); - h = Math__imul(h ^ h >>> 13, 0xC2B2AE35); - h = smi(h ^ h >>> 16); - return h; - } - - function hashMerge(a, b) { - return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int - } - - var Immutable = { - - Iterable: Iterable, - - Seq: Seq, - Collection: Collection, - Map: Map, - OrderedMap: OrderedMap, - List: List, - Stack: Stack, - Set: Set, - OrderedSet: OrderedSet, - - Record: Record, - Range: Range, - Repeat: Repeat, - - is: is, - fromJS: fromJS, - - }; - - return Immutable; - -})); -},{}],6:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule invariant - */ - -'use strict'; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if (process.env.NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -}).call(this,require('_process')) -},{"_process":4}],7:[function(require,module,exports){ -var arrayMap = require('../internal/arrayMap'), - baseCallback = require('../internal/baseCallback'), - baseMap = require('../internal/baseMap'), - isArray = require('../lang/isArray'); - -/** - * Creates an array of values by running each element in `collection` through - * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * Many lodash methods are guarded to work as interatees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, - * `dropRight`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, `slice`, - * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `random`, `range`, `sample`, `uniq`, and `words` - * - * @static - * @memberOf _ - * @alias collect - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new mapped array. - * @example - * - * _.map([1, 2, 3], function(n) { return n * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); - * // => [3, 6, 9] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // using the "_.property" callback shorthand - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ -function map(collection, iteratee, thisArg) { - var func = isArray(collection) ? arrayMap : baseMap; - iteratee = baseCallback(iteratee, thisArg, 3); - return func(collection, iteratee); -} - -module.exports = map; - -},{"../internal/arrayMap":13,"../internal/baseCallback":15,"../internal/baseMap":29,"../lang/isArray":63}],8:[function(require,module,exports){ -var baseCallback = require('../internal/baseCallback'), - baseEach = require('../internal/baseEach'), - baseSortBy = require('../internal/baseSortBy'), - compareAscending = require('../internal/compareAscending'), - isIterateeCall = require('../internal/isIterateeCall'), - isLength = require('../internal/isLength'); - -/** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through `iteratee`. This method performs - * a stable sort, that is, it preserves the original sort order of equal elements. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [iteratee=_.identity] The function - * invoked per iteration. If a property name or an object is provided it is - * used to create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new sorted array. - * @example - * - * _.sortBy([1, 2, 3], function(n) { return Math.sin(n); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); - * // => [3, 1, 2] - * - * var users = [ - * { 'user': 'fred' }, - * { 'user': 'pebbles' }, - * { 'user': 'barney' } - * ]; - * - * // using the "_.property" callback shorthand - * _.pluck(_.sortBy(users, 'user'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ -function sortBy(collection, iteratee, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = isLength(length) ? Array(length) : []; - - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - iteratee = baseCallback(iteratee, thisArg, 3); - baseEach(collection, function(value, key, collection) { - result[++index] = { 'criteria': iteratee(value, key, collection), 'index': index, 'value': value }; - }); - return baseSortBy(result, compareAscending); -} - -module.exports = sortBy; - -},{"../internal/baseCallback":15,"../internal/baseEach":20,"../internal/baseSortBy":34,"../internal/compareAscending":40,"../internal/isIterateeCall":52,"../internal/isLength":53}],9:[function(require,module,exports){ -(function (global){ -/** - * @license - * lodash 3.2.0 (Custom Build) - * Build: `lodash modern -d -o ./index.js` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.7.0 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '3.2.0'; - - /** Used to compose bitmasks for wrapper metadata. */ - var BIND_FLAG = 1, - BIND_KEY_FLAG = 2, - CURRY_BOUND_FLAG = 4, - CURRY_FLAG = 8, - CURRY_RIGHT_FLAG = 16, - PARTIAL_FLAG = 32, - PARTIAL_RIGHT_FLAG = 64, - REARG_FLAG = 128, - ARY_FLAG = 256; - - /** Used as default options for `_.trunc`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect when a function becomes hot. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 0, - LAZY_MAP_FLAG = 1, - LAZY_WHILE_FLAG = 2; - - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, - reUnescapedHtml = /[&<>"'`]/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** - * Used to match ES template delimiters. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) - * for more details. - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect named functions. */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to detect hexadecimal string values. */ - var reHexPrefix = /^0[xX]/; - - /** Used to detect host constructors (Safari > 5). */ - var reHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** - * Used to match `RegExp` special characters. - * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special) - * for more details. - */ - var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, - reHasRegExpChars = RegExp(reRegExpChars.source); - - /** Used to detect functions containing a `this` reference. */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to match words to create compound words. */ - var reWords = (function() { - var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', - lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; - - return RegExp(upper + '{2,}(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); - }()); - - /** Used to detect and test for whitespace. */ - var whitespace = ( - // Basic whitespace characters. - ' \t\x0b\f\xa0\ufeff' + - - // Line terminators. - '\n\r\u2028\u2029' + - - // Unicode category "Zs" space separators. - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', - 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - 'window', 'WinRTError' - ]; - - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dateTag] = typedArrayTags[errorTag] = - typedArrayTags[funcTag] = typedArrayTags[mapTag] = - typedArrayTags[numberTag] = typedArrayTags[objectTag] = - typedArrayTags[regexpTag] = typedArrayTags[setTag] = - typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = - cloneableTags[dateTag] = cloneableTags[float32Tag] = - cloneableTags[float64Tag] = cloneableTags[int8Tag] = - cloneableTags[int16Tag] = cloneableTags[int32Tag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[stringTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[mapTag] = cloneableTags[setTag] = - cloneableTags[weakMapTag] = false; - - /** Used as an internal `_.debounce` options object by `_.throttle`. */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used to map latin-1 supplementary letters to basic latin letters. */ - var deburredLetters = { - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss' - }; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** - * Used as a reference to the global object. - * - * The `this` value is used if it is the global object to avoid Greasemonkey's - * restricted `window` object, otherwise the `window` object is used. - */ - var root = (objectTypes[typeof window] && window !== (this && this.window)) ? window : this; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `compareAscending` which compares values and - * sorts them in ascending order without guaranteeing a stable sort. - * - * @private - * @param {*} value The value to compare to `other`. - * @param {*} other The value to compare to `value`. - * @returns {number} Returns the sort order indicator for `value`. - */ - function baseCompareAscending(value, other) { - if (value !== other) { - var valIsReflexive = value === value, - othIsReflexive = other === other; - - if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) { - return 1; - } - if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) { - return -1; - } - } - return 0; - } - - /** - * The base implementation of `_.indexOf` without support for binary searches. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return indexOfNaN(array, fromIndex); - } - var index = (fromIndex || 0) - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.sortBy` and `_.sortByAll` which uses `comparer` - * to define the sort order of `array` and replaces criteria objects with their - * corresponding values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * Converts `value` to a string if it is not one. An empty string is returned - * for `null` or `undefined` values. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - if (typeof value == 'string') { - return value; - } - return value == null ? '' : (value + ''); - } - - /** - * Used by `_.max` and `_.min` as the default callback for string values. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the code unit of the first character of the string. - */ - function charAtCallback(string) { - return string.charCodeAt(0); - } - - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the first character not found in `chars`. - */ - function charsLeftIndex(string, chars) { - var index = -1, - length = string.length; - - while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the last character not found in `chars`. - */ - function charsRightIndex(string, chars) { - var index = string.length; - - while (index-- && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } - - /** - * Used by `_.sortBy` to compare transformed elements of a collection and stable - * sort them in ascending order. - * - * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); - } - - /** - * Used by `_.sortByAll` to compare multiple properties of each element - * in a collection and stable sort them in ascending order. - * - * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultipleAscending(object, other) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length; - - while (++index < length) { - var result = baseCompareAscending(objCriteria[index], othCriteria[index]); - if (result) { - return result; - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://code.google.com/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - function deburrLetter(letter) { - return deburredLetters[letter]; - } - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(chr) { - return htmlEscapes[chr]; - } - - /** - * Used by `_.template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Gets the index at which the first occurrence of `NaN` is found in `array`. - * If `fromRight` is provided elements of `array` are iterated from right to left. - * - * @private - * @param {Array} array The array to search. - * @param {number} [fromIndex] The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched `NaN`, else `-1`. - */ - function indexOfNaN(array, fromIndex, fromRight) { - var length = array.length, - index = fromRight ? (fromIndex || length) : ((fromIndex || 0) - 1); - - while ((fromRight ? index-- : ++index < length)) { - var other = array[index]; - if (other !== other) { - return index; - } - } - return -1; - } - - /** - * Checks if `value` is object-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - */ - function isObjectLike(value) { - return (value && typeof value == 'object') || false; - } - - /** - * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a - * character code is whitespace. - * - * @private - * @param {number} charCode The character code to inspect. - * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. - */ - function isSpace(charCode) { - return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || - (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; - } - } - return result; - } - - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } - return result; - } - - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the first non-whitespace character. - */ - function trimmedLeftIndex(string) { - var index = -1, - length = string.length; - - while (++index < length && isSpace(string.charCodeAt(index))) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the last non-whitespace character. - */ - function trimmedRightIndex(string) { - var index = string.length; - - while (index-- && isSpace(string.charCodeAt(index))) {} - return index; - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(chr) { - return htmlUnescapes[chr]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the given `context` object. - * - * @static - * @memberOf _ - * @category Utility - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'add': function(a, b) { return a + b; } }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'sub': function(a, b) { return a - b; } }); - * - * _.isFunction(_.add); - * // => true - * _.isFunction(_.sub); - * // => false - * - * lodash.isFunction(lodash.add); - * // => false - * lodash.isFunction(lodash.sub); - * // => true - * - * // using `context` to mock `Date#getTime` use in `_.now` - * var mock = _.runInContext({ - * 'Date': function() { - * return { 'getTime': getTimeMock }; - * } - * }); - * - * // or creating a suped-up `defer` in Node.js - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See https://es5.github.io/#x11.1.5 for more details. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** Used for native method references. */ - var arrayProto = Array.prototype, - objectProto = Object.prototype; - - /** Used to detect DOM support. */ - var document = (document = context.window) && document.document; - - /** Used to resolve the decompiled source of functions. */ - var fnToString = Function.prototype.toString; - - /** Used to the length of n-tuples for `_.unzip`. */ - var getLength = baseProperty('length'); - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** - * Used to resolve the `toStringTag` of values. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) - * for more details. - */ - var objToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = context._; - - /** Used to detect if a method is native. */ - var reNative = RegExp('^' + - escapeRegExp(objToString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Native method references. */ - var ArrayBuffer = isNative(ArrayBuffer = context.ArrayBuffer) && ArrayBuffer, - bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, - ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - push = arrayProto.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - Set = isNative(Set = context.Set) && Set, - setTimeout = context.setTimeout, - splice = arrayProto.splice, - Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, - WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; - - /** Used to clone array buffers. */ - var Float64Array = (function() { - // Safari 5 errors when using an array buffer to initialize a typed array - // where the array buffer's `byteLength` is not a multiple of the typed - // array's `BYTES_PER_ELEMENT`. - try { - var func = isNative(func = context.Float64Array) && func, - result = new func(new ArrayBuffer(10), 0, 1) && func; - } catch(e) {} - return result; - }()); - - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsFinite = context.isFinite, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = isNative(nativeNow = Date.now) && nativeNow, - nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used as references for `-Infinity` and `Infinity`. */ - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** Used as the size, in bytes, of each `Float64Array` element. */ - var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; - - /** - * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * for more details. - */ - var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit chaining. - * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that return a boolean or single value will - * automatically end the chain returning the unwrapped value. Explicit chaining - * may be enabled using `_.chain`. The execution of chained methods is lazy, - * that is, execution is deferred until `_#value` is implicitly or explicitly - * called. - * - * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization that merges iteratees to avoid creating intermediate - * arrays and reduce the number of iteratee executions. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * The wrapper methods that support shortcut fusion are: - * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, - * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, - * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, - * and `where` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, - * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, - * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, - * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, - * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, - * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `keysIn`, `map`, `mapValues`, `matches`, `memoize`, `merge`, `mixin`, - * `negate`, `noop`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, - * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `splice`, `spread`, - * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, - * `unshift`, `unzip`, `values`, `valuesIn`, `where`, `without`, `wrap`, `xor`, - * `zip`, and `zipObject` - * - * The wrapper methods that are **not** chainable by default are: - * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, - * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, - * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, - * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, - * `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, - * `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, - * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, - * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `unescape`, `uniqueId`, `value`, and `words` - * - * The wrapper method `sample` will return a wrapped value when `n` is provided, - * otherwise an unwrapped value is returned. - * - * @name _ - * @constructor - * @category Chain - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, n) { return sum + n; }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { return n * n; }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable chaining for all wrapper methods. - * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. - */ - function LodashWrapper(value, chainAll, actions) { - this.__wrapped__ = value; - this.__actions__ = actions || []; - this.__chain__ = !!chainAll; - } - - /** - * An object environment feature flags. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function(x) { - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but Firefox OS certified apps, older Opera mobile browsers, and - * the PlayStation 3; forced `false` for Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if the DOM is supported. - * - * @memberOf _.support - * @type boolean - */ - try { - support.dom = document.createDocumentFragment().nodeType === 11; - } catch(e) { - support.dom = false; - } - - /** - * Detect if `arguments` object indexes are non-enumerable. - * - * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object - * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat - * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` - * checks for indexes that exceed their function's formal parameters with - * associated values of `0`. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); - } catch(e) { - support.nonEnumArgs = true; - } - }(0, 0)); - - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = null; - this.__dir__ = 1; - this.__dropCount__ = 0; - this.__filtered__ = false; - this.__iteratees__ = null; - this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = null; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var actions = this.__actions__, - iteratees = this.__iteratees__, - views = this.__views__, - result = new LazyWrapper(this.__wrapped__); - - result.__actions__ = actions ? arrayCopy(actions) : null; - result.__dir__ = this.__dir__; - result.__dropCount__ = this.__dropCount__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; - result.__takeCount__ = this.__takeCount__; - result.__views__ = views ? arrayCopy(views) : null; - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(); - if (!isArray(array)) { - return baseWrapperValue(array, this.__actions__); - } - var dir = this.__dir__, - isRight = dir < 0, - view = getView(0, array.length, this.__views__), - start = view.start, - end = view.end, - length = end - start, - dropCount = this.__dropCount__, - takeCount = nativeMin(length, this.__takeCount__), - index = isRight ? end : start - 1, - iteratees = this.__iteratees__, - iterLength = iteratees ? iteratees.length : 0, - resIndex = 0, - result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - computed = iteratee(value, index, array), - type = data.type; - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - if (dropCount) { - dropCount--; - } else { - result[resIndex++] = value; - } - } - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a cache object to store key/value pairs. - * - * @private - * @static - * @name Cache - * @memberOf _.memoize - */ - function MapCache() { - this.__data__ = {}; - } - - /** - * Removes `key` and its value from the cache. - * - * @private - * @name delete - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. - */ - function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; - } - - /** - * Gets the cached value for `key`. - * - * @private - * @name get - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to get. - * @returns {*} Returns the cached value. - */ - function mapGet(key) { - return key == '__proto__' ? undefined : this.__data__[key]; - } - - /** - * Checks if a cached value for `key` exists. - * - * @private - * @name has - * @memberOf _.memoize.Cache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapHas(key) { - return key != '__proto__' && hasOwnProperty.call(this.__data__, key); - } - - /** - * Adds `value` to `key` of the cache. - * - * @private - * @name set - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to cache. - * @param {*} value The value to cache. - * @returns {Object} Returns the cache object. - */ - function mapSet(key, value) { - if (key != '__proto__') { - this.__data__[key] = value; - } - return this; - } - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates a cache object to store unique values. - * - * @private - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var length = values ? values.length : 0; - - this.data = { 'hash': nativeCreate(null), 'set': new Set }; - while (length--) { - this.push(values[length]); - } - } - - /** - * Checks if `value` is in `cache` mimicking the return signature of - * `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache to search. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var data = cache.data, - result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; - - return result ? 0 : -1; - } - - /** - * Adds `value` to the cache. - * - * @private - * @name push - * @memberOf SetCache - * @param {*} value The value to cache. - */ - function cachePush(value) { - var data = this.data; - if (typeof value == 'string' || isObject(value)) { - data.set.add(value); - } else { - data.hash[value] = true; - } - } - - /*------------------------------------------------------------------------*/ - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function arrayCopy(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * A specialized version of `_.forEach` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * A specialized version of `_.max` for arrays without support for iteratees. - * - * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the maximum value. - */ - function arrayMax(array) { - var index = -1, - length = array.length, - result = NEGATIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value > result) { - result = value; - } - } - return result; - } - - /** - * A specialized version of `_.min` for arrays without support for iteratees. - * - * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the minimum value. - */ - function arrayMin(array) { - var index = -1, - length = array.length, - result = POSITIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value < result) { - result = value; - } - } - return result; - } - - /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the first element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the last element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - if (initFromArray && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * Used by `_.defaults` to customize its `_.assign` use. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignDefaults(objectValue, sourceValue) { - return typeof objectValue == 'undefined' ? sourceValue : objectValue; - } - - /** - * Used by `_.template` to customize its `_.assign` use. - * - * **Note:** This method is like `assignDefaults` except that it ignores - * inherited property values when checking if a property is `undefined`. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @param {string} key The key associated with the object and source values. - * @param {Object} object The destination object. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignOwnDefaults(objectValue, sourceValue, key, object) { - return (typeof objectValue == 'undefined' || !hasOwnProperty.call(object, key)) - ? sourceValue - : objectValue; - } - - /** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize assigning values. - * @returns {Object} Returns the destination object. - */ - function baseAssign(object, source, customizer) { - var props = keys(source); - if (!customizer) { - return baseCopy(source, object, props); - } - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index], - value = object[key], - result = customizer(value, source[key], key, object, source); - - if ((result === result ? result !== value : value === value) || - (typeof value == 'undefined' && !(key in object))) { - object[key] = result; - } - } - return object; - } - - /** - * The base implementation of `_.at` without support for strings and individual - * key arguments. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {number[]|string[]} [props] The property names or indexes of elements to pick. - * @returns {Array} Returns the new array of picked elements. - */ - function baseAt(collection, props) { - var index = -1, - length = collection.length, - isArr = isLength(length), - propsLength = props.length, - result = Array(propsLength); - - while(++index < propsLength) { - var key = props[index]; - if (isArr) { - key = parseFloat(key); - result[index] = isIndex(key, length) ? collection[key] : undefined; - } else { - result[index] = collection[key]; - } - } - return result; - } - - /** - * Copies the properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Object} [object={}] The object to copy properties to. - * @param {Array} props The property names to copy. - * @returns {Object} Returns `object`. - */ - function baseCopy(source, object, props) { - if (!props) { - props = object; - object = {}; - } - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; - } - - /** - * The base implementation of `_.bindAll` without support for individual - * method name arguments. - * - * @private - * @param {Object} object The object to bind and assign the bound methods to. - * @param {string[]} methodNames The object method names to bind. - * @returns {Object} Returns `object`. - */ - function baseBindAll(object, methodNames) { - var index = -1, - length = methodNames.length; - - while (++index < length) { - var key = methodNames[index]; - object[key] = createWrapper(object[key], BIND_FLAG, object); - } - return object; - } - - /** - * The base implementation of `_.callback` which supports specifying the - * number of arguments to provide to `func`. - * - * @private - * @param {*} [func=_.identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. - */ - function baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return (typeof thisArg != 'undefined' && isBindable(func)) - ? bindCallback(func, thisArg, argCount) - : func; - } - if (func == null) { - return identity; - } - if (type == 'object') { - return baseMatches(func); - } - return typeof thisArg == 'undefined' - ? baseProperty(func + '') - : baseMatchesProperty(func + '', thisArg); - } - - /** - * The base implementation of `_.clone` without support for argument juggling - * and `this` binding `customizer` functions. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The object `value` belongs to. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { - var result; - if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); - } - if (typeof result != 'undefined') { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return arrayCopy(value, result); - } - } else { - var tag = objToString.call(value), - isFunc = tag == funcTag; - - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return baseCopy(value, result, keys(value)); - } - } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); - } - } - // Check for circular references and return corresponding clone. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - // Add the source value to the stack of traversed objects and associate it with its clone. - stackA.push(value); - stackB.push(result); - - // Recursively populate clone (susceptible to call stack limits). - (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { - result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); - }); - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - - /** - * The base implementation of `_.delay` and `_.defer` which accepts an index - * of where to slice the arguments to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The `arguments` object to slice and provide to `func`. - * @returns {number} Returns the timer id. - */ - function baseDelay(func, wait, args, fromIndex) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait); - } - - /** - * The base implementation of `_.difference` which accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values) { - var length = array ? array.length : 0, - result = []; - - if (!length) { - return result; - } - var index = -1, - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - cache = isCommon && values.length >= 200 && createCache(values), - valuesLength = values.length; - - if (cache) { - indexOf = cacheIndexOf; - isCommon = false; - values = cache; - } - outer: - while (++index < length) { - var value = array[index]; - - if (isCommon && value === value) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === value) { - continue outer; - } - } - result.push(value); - } - else if (indexOf(values, value) < 0) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. - */ - function baseEach(collection, iteratee) { - var length = collection ? collection.length : 0; - if (!isLength(length)) { - return baseForOwn(collection, iteratee); - } - var index = -1, - iterable = toObject(collection); - - while (++index < length) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - } - - /** - * The base implementation of `_.forEachRight` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. - */ - function baseEachRight(collection, iteratee) { - var length = collection ? collection.length : 0; - if (!isLength(length)) { - return baseForOwnRight(collection, iteratee); - } - var iterable = toObject(collection); - while (length--) { - if (iteratee(iterable[length], length, iterable) === false) { - break; - } - } - return collection; - } - - /** - * The base implementation of `_.every` without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (typeof end == 'undefined' || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : end >>> 0; - start >>>= 0; - - while (start < length) { - array[start++] = value; - } - return array; - } - - /** - * The base implementation of `_.filter` without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, - * without support for callback shorthands and `this` binding, which iterates - * over `collection` using the provided `eachFunc`. - * - * @private - * @param {Array|Object|string} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @param {boolean} [retKey] Specify returning the key of the found element - * instead of the element itself. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFind(collection, predicate, eachFunc, retKey) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = retKey ? key : value; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with added support for restricting - * flattening and specifying the start index. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param {boolean} [isStrict] Restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, isDeep, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - - if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) { - if (isDeep) { - // Recursively flatten arrays (susceptible to call stack limits). - value = baseFlatten(value, isDeep, isStrict); - } - var valIndex = -1, - valLength = value.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[++resIndex] = value[valIndex]; - } - } else if (!isStrict) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForIn` and `baseForOwn` which iterates - * over `object` properties returned by `keysFunc` invoking `iteratee` for - * each property. Iterator functions may exit iteration early by explicitly - * returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - function baseFor(object, iteratee, keysFunc) { - var index = -1, - iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (++index < length) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - function baseForRight(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[length]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } - - /** - * The base implementation of `_.forIn` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); - } - - /** - * The base implementation of `_.forOwn` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from those provided. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the new array of filtered property names. - */ - function baseFunctions(object, props) { - var index = -1, - length = props.length, - resIndex = -1, - result = []; - - while (++index < length) { - var key = props[index]; - if (isFunction(object[key])) { - result[++resIndex] = key; - } - } - return result; - } - - /** - * The base implementation of `_.invoke` which requires additional arguments - * to be provided as an array of arguments rather than individually. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {Array} [args] The arguments to invoke the method with. - * @returns {Array} Returns the array of results. - */ - function baseInvoke(collection, methodName, args) { - var index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = isLength(length) ? Array(length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? methodName : (value != null && value[methodName]); - result[++index] = func ? func.apply(value, args) : undefined; - }); - return result; - } - - /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) { - // Exit early for identical values. - if (value === other) { - // Treat `+0` vs. `-0` as not equal. - return value !== 0 || (1 / value == 1 / other); - } - var valType = typeof value, - othType = typeof other; - - // Exit early for unlike primitive values. - if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || - value == null || other == null) { - // Return `false` unless both values are `NaN`. - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `value` objects. - * @param {Array} [stackB=[]] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = objToString.call(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } - } - if (!othIsArr) { - othTag = objToString.call(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } - } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); - } - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); - } - if (!isSameTag) { - return false; - } - // Assume cyclic values are equal. - // For more information on detecting circular references see https://es5.github.io/#JO. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - // Add `object` and `other` to the stack of traversed objects. - stackA.push(object); - stackB.push(other); - - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; - } - - /** - * The base implementation of `_.isMatch` without support for callback - * shorthands or `this` binding. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The source property names to match. - * @param {Array} values The source values to match. - * @param {Array} strictCompareFlags Strict comparison flags for source values. - * @param {Function} [customizer] The function to customize comparing objects. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, props, values, strictCompareFlags, customizer) { - var length = props.length; - if (object == null) { - return !length; - } - var index = -1, - noCustomizer = !customizer; - - while (++index < length) { - if ((noCustomizer && strictCompareFlags[index]) - ? values[index] !== object[props[index]] - : !hasOwnProperty.call(object, props[index]) - ) { - return false; - } - } - index = -1; - while (++index < length) { - var key = props[index]; - if (noCustomizer && strictCompareFlags[index]) { - var result = hasOwnProperty.call(object, key); - } else { - var objValue = object[key], - srcValue = values[index]; - - result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (typeof result == 'undefined') { - result = baseIsEqual(srcValue, objValue, customizer, true); - } - } - if (!result) { - return false; - } - } - return true; - } - - /** - * The base implementation of `_.map` without support for callback shorthands - * or `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var result = []; - baseEach(collection, function(value, key, collection) { - result.push(iteratee(value, key, collection)); - }); - return result; - } - - /** - * The base implementation of `_.matches` which does not clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. - */ - function baseMatches(source) { - var props = keys(source), - length = props.length; - - if (length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return function(object) { - return object != null && value === object[key] && hasOwnProperty.call(object, key); - }; - } - } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = source[props[length]]; - values[length] = value; - strictCompareFlags[length] = isStrictComparable(value); - } - return function(object) { - return baseIsMatch(object, props, values, strictCompareFlags); - }; - } - - /** - * The base implementation of `_.matchesProperty` which does not coerce `key` - * to a string. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} value The value to compare. - * @returns {Function} Returns the new function. - */ - function baseMatchesProperty(key, value) { - if (isStrictComparable(value)) { - return function(object) { - return object != null && object[key] === value; - }; - } - return function(object) { - return object != null && baseIsEqual(value, object[key], null, true); - }; - } - - /** - * The base implementation of `_.merge` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {Object} Returns the destination object. - */ - function baseMerge(object, source, customizer, stackA, stackB) { - var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source)); - - (isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) { - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - return baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); - } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = typeof result == 'undefined'; - - if (isCommon) { - result = srcValue; - } - if ((isSrcArr || typeof result != 'undefined') && - (isCommon || (result === result ? result !== value : value === value))) { - object[key] = result; - } - }); - return object; - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { - var length = stackA.length, - srcValue = source[key]; - - while (length--) { - if (stackA[length] == srcValue) { - object[key] = stackB[length]; - return; - } - } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = typeof result == 'undefined'; - - if (isCommon) { - result = srcValue; - if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (value ? arrayCopy(value) : []); - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - result = isArguments(value) - ? toPlainObject(value) - : (isPlainObject(value) ? value : {}); - } - else { - isCommon = false; - } - } - // Add the source value to the stack of traversed objects and associate - // it with its merged value. - stackA.push(srcValue); - stackB.push(result); - - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); - } else if (result === result ? result !== value : value === value) { - object[key] = result; - } - } - - /** - * The base implementation of `_.property` which does not coerce `key` to a string. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.pullAt` without support for individual - * index arguments. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - */ - function basePullAt(array, indexes) { - var length = indexes.length, - result = baseAt(array, indexes); - - indexes.sort(baseCompareAscending); - while (length--) { - var index = parseFloat(indexes[length]); - if (index != previous && isIndex(index)) { - var previous = index; - splice.call(array, index, 1); - } - } - return result; - } - - /** - * The base implementation of `_.random` without support for argument juggling - * and returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns the random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands or `this` binding, which iterates over `collection` - * using the provided `eachFunc`. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initFromCollection Specify using the first or last element - * of `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initFromCollection - ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `setData` without support for hot loop detection. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (typeof end == 'undefined' || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : (end - start) >>> 0; - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for callback shorthands - * or `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function baseUniq(array, iteratee) { - var index = -1, - indexOf = getIndexOf(), - length = array.length, - isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= 200, - seen = isLarge && createCache(), - result = []; - - if (seen) { - indexOf = cacheIndexOf; - isCommon = false; - } else { - isLarge = false; - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (isCommon && value === value) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (indexOf(seen, computed) < 0) { - if (iteratee || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * returned by `keysFunc`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to peform to resolve the unwrapped value. - * @returns {*} Returns the resolved unwrapped value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - var index = -1, - length = actions.length; - - while (++index < length) { - var args = [result], - action = actions[index]; - - push.apply(args, action.args); - result = action.func.apply(action.thisArg, args); - } - return result; - } - - /** - * Performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest, instead - * of the lowest, index at which a value should be inserted into `array`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function binaryIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (retHighest ? (computed <= value) : (computed < value)) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return binaryIndexBy(array, value, identity, retHighest); - } - - /** - * This function is like `binaryIndex` except that it invokes `iteratee` for - * `value` and each element of `array` to compute their sort ranking. The - * iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [retHighest] Specify returning the highest, instead - * of the lowest, index at which a value should be inserted into `array`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsUndef = typeof value == 'undefined'; - - while (low < high) { - var mid = floor((low + high) / 2), - computed = iteratee(array[mid]), - isReflexive = computed === computed; - - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || typeof computed != 'undefined'); - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - /** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. - * - * @private - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. - */ - function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (typeof thisArg == 'undefined') { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; - } - return function() { - return func.apply(thisArg, arguments); - }; - } - - /** - * Creates a clone of the given array buffer. - * - * @private - * @param {ArrayBuffer} buffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function bufferClone(buffer) { - return bufferSlice.call(buffer, 0); - } - if (!bufferSlice) { - // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. - bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { - var byteLength = buffer.byteLength, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); - - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, 0, floatLength)); - } - if (byteLength != offset) { - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders) { - var holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - leftIndex = -1, - leftLength = partials.length, - result = Array(argsLength + leftLength); - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - while (argsLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders) { - var holdersIndex = -1, - holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - rightIndex = -1, - rightLength = partials.length, - result = Array(argsLength + rightLength); - - while (++argsIndex < argsLength) { - result[argsIndex] = args[argsIndex]; - } - var pad = argsIndex; - while (++rightIndex < rightLength) { - result[pad + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - result[pad + holders[holdersIndex]] = args[argsIndex++]; - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an accumulator - * object composed from the results of running each element in the collection - * through an iteratee. - * - * @private - * @param {Function} setter The function to set keys and values of the accumulator object. - * @param {Function} [initializer] The function to initialize the accumulator object. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; - iteratee = getCallback(iteratee, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, iteratee(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, iteratee(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that assigns properties of source object(s) to a given - * destination object. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return function() { - var length = arguments.length, - object = arguments[0]; - - if (length < 2 || object == null) { - return object; - } - if (length > 3 && isIterateeCall(arguments[1], arguments[2], arguments[3])) { - length = 2; - } - // Juggle arguments. - if (length > 3 && typeof arguments[length - 2] == 'function') { - var customizer = bindCallback(arguments[--length - 1], arguments[length--], 5); - } else if (length > 2 && typeof arguments[length - 1] == 'function') { - customizer = arguments[--length]; - } - var index = 0; - while (++index < length) { - var source = arguments[index]; - if (source) { - assigner(object, source, customizer); - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` and invokes it with the `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new bound function. - */ - function createBindWrapper(func, thisArg) { - var Ctor = createCtorWrapper(func); - - function wrapper() { - return (this instanceof wrapper ? Ctor : func).apply(thisArg, arguments); - } - return wrapper; - } - - /** - * Creates a `Set` cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [values] The values to cache. - * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. - */ - var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { - return new SetCache(values); - }; - - /** - * Creates a function that produces compound words out of the words in a - * given string. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - var index = -1, - array = words(deburr(string)), - length = array.length, - result = ''; - - while (++index < length) { - result = callback(result, array[index], index); - } - return result; - }; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtorWrapper(Ctor) { - return function() { - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, arguments); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a function that gets the extremum value of a collection. - * - * @private - * @param {Function} arrayFunc The function to get the extremum value from an array. - * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, - * extremum value. - * @returns {Function} Returns the new extremum function. - */ - function createExtremum(arrayFunc, isMin) { - return function(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - var func = getCallback(), - noIteratee = iteratee == null; - - if (!(func === baseCallback && noIteratee)) { - noIteratee = false; - iteratee = func(iteratee, thisArg, 3); - } - if (noIteratee) { - var isArr = isArray(collection); - if (!isArr && isString(collection)) { - iteratee = charAtCallback; - } else { - return arrayFunc(isArr ? collection : toIterable(collection)); - } - } - return extremumBy(collection, iteratee, isMin); - }; - } - - /** - * Creates a function that wraps `func` and invokes it with optional `this` - * binding of, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & ARY_FLAG, - isBind = bitmask & BIND_FLAG, - isBindKey = bitmask & BIND_KEY_FLAG, - isCurry = bitmask & CURRY_FLAG, - isCurryBound = bitmask & CURRY_BOUND_FLAG, - isCurryRight = bitmask & CURRY_RIGHT_FLAG; - - var Ctor = !isBindKey && createCtorWrapper(func), - key = func; - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it to other functions. - var length = arguments.length, - index = length, - args = Array(length); - - while (index--) { - args[index] = arguments[index]; - } - if (partials) { - args = composeArgs(args, partials, holders); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight); - } - if (isCurry || isCurryRight) { - var placeholder = wrapper.placeholder, - argsHolders = replaceHolders(args, placeholder); - - length -= argsHolders.length; - if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : null, - newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : null, - newHoldersRight = isCurry ? null : argsHolders, - newPartials = isCurry ? args : null, - newPartialsRight = isCurry ? null : args; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!isCurryBound) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var result = createHybridWrapper(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity); - result.placeholder = placeholder; - return result; - } - } - var thisBinding = isBind ? thisArg : this; - if (isBindKey) { - func = thisBinding[key]; - } - if (argPos) { - args = reorder(args, argPos); - } - if (isAry && ary < args.length) { - args.length = ary; - } - return (this instanceof wrapper ? (Ctor || createCtorWrapper(func)) : func).apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates the pad required for `string` based on the given padding length. - * The `chars` string may be truncated if the number of padding characters - * exceeds the padding length. - * - * @private - * @param {string} string The string to create padding for. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the pad for `string`. - */ - function createPad(string, length, chars) { - var strLength = string.length; - length = +length; - - if (strLength >= length || !nativeIsFinite(length)) { - return ''; - } - var padLength = length - strLength; - chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); - } - - /** - * Creates a function that wraps `func` and invokes it with the optional `this` - * binding of `thisArg` and the `partials` prepended to those provided to - * the wrapper. - * - * @private - * @param {Function} func The function to partially apply arguments to. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to the new function. - * @returns {Function} Returns the new bound function. - */ - function createPartialWrapper(func, bitmask, thisArg, partials) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtorWrapper(func); - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it `func`. - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(argsLength + leftLength); - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return (this instanceof wrapper ? Ctor : func).apply(isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = null; - } - length -= (holders ? holders.length : 0); - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = null; - } - var data = !isBindKey && getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - - if (data && data !== true) { - mergeData(newData, data); - bitmask = newData[1]; - arity = newData[9]; - } - newData[9] = arity == null - ? (isBindKey ? 0 : func.length) - : (nativeMax(arity - length, 0) || 0); - - if (bitmask == BIND_FLAG) { - var result = createBindWrapper(newData[0], newData[2]); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { - result = createPartialWrapper.apply(undefined, newData); - } else { - result = createHybridWrapper.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setter(result, newData); - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length, - result = true; - - if (arrLength != othLength && !(isWhere && othLength > arrLength)) { - return false; - } - // Deep compare the contents, ignoring non-numeric properties. - while (result && ++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - result = undefined; - if (customizer) { - result = isWhere - ? customizer(othValue, arrValue, index) - : customizer(arrValue, othValue, index); - } - if (typeof result == 'undefined') { - // Recursively compare arrays (susceptible to call stack limits). - if (isWhere) { - var othIndex = othLength; - while (othIndex--) { - othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); - if (result) { - break; - } - } - } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); - } - } - } - return !!result; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} value The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag) { - switch (tag) { - case boolTag: - case dateTag: - // Coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. - return +object == +other; - - case errorTag: - return object.name == other.name && object.message == other.message; - - case numberTag: - // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - // But, treat `-0` vs. `+0` as not equal. - : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings primitives and string - // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. - return object == (other + ''); - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; - - if (objLength != othLength && !isWhere) { - return false; - } - var hasCtor, - index = -1; - - while (++index < objLength) { - var key = objProps[index], - result = hasOwnProperty.call(other, key); - - if (result) { - var objValue = object[key], - othValue = other[key]; - - result = undefined; - if (customizer) { - result = isWhere - ? customizer(othValue, objValue, key) - : customizer(objValue, othValue, key); - } - if (typeof result == 'undefined') { - // Recursively compare objects (susceptible to call stack limits). - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB); - } - } - if (!result) { - return false; - } - hasCtor || (hasCtor = key == 'constructor'); - } - if (!hasCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { - return false; - } - } - return true; - } - - /** - * Gets the extremum value of `collection` invoking `iteratee` for each value - * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments; (value, index, collection). - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [isMin] Specify returning the minimum, instead of the - * maximum, extremum value. - * @returns {*} Returns the extremum value. - */ - function extremumBy(collection, iteratee, isMin) { - var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, - computed = exValue, - result = computed; - - baseEach(collection, function(value, index, collection) { - var current = iteratee(value, index, collection); - if ((isMin ? current < computed : current > computed) || (current === exValue && current === result)) { - computed = current; - result = value; - } - }); - return result; - } - - /** - * Gets the appropriate "callback" function. If the `_.callback` method is - * customized this function returns the custom method, otherwise it returns - * the `baseCallback` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. - * - * @private - * @returns {Function} Returns the chosen function or its result. - */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized this function returns the custom method, otherwise it returns - * the `baseIndexOf` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. - * - * @private - * @returns {Function|number} Returns the chosen function or its result. - */ - function getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} [transforms] The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms ? transforms.length : 0; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add array properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; - } - return new Ctor; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return bufferClone(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - var buffer = object.buffer; - return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - var result = new Ctor(object.source, reFlags.exec(object)); - result.lastIndex = object.lastIndex; - } - return result; - } - - /** - * Checks if `func` is eligible for `this` binding. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is eligible, else `false`. - */ - function isBindable(func) { - var support = lodash.support, - result = !(support.funcNames ? func.name : support.funcDecomp); - - if (!result) { - var source = fnToString.call(func); - if (!support.funcNames) { - result = !reFuncName.test(source); - } - if (!result) { - // Check if `func` references the `this` keyword and store the result. - result = reThis.test(source) || isNative(func); - baseSetData(func, result); - } - } - return result; - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - value = +value; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; - } - - /** - * Checks if the provided arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number') { - var length = object.length, - prereq = isLength(length) && isIndex(index, length); - } else { - prereq = type == 'string' && index in object; - } - return prereq && object[index] === value; - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on ES `ToLength`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ - function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers required to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` - * augment function arguments, making the order in which they are executed important, - * preventing the merging of metadata. However, we make an exception for a safe - * common case where curried functions have `_.ary` and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask; - - var arityFlags = ARY_FLAG | REARG_FLAG, - bindFlags = BIND_FLAG | BIND_KEY_FLAG, - comboFlags = arityFlags | bindFlags | CURRY_BOUND_FLAG | CURRY_RIGHT_FLAG; - - var isAry = bitmask & ARY_FLAG && !(srcBitmask & ARY_FLAG), - isRearg = bitmask & REARG_FLAG && !(srcBitmask & REARG_FLAG), - argPos = (isRearg ? data : source)[7], - ary = (isAry ? data : source)[8]; - - var isCommon = !(bitmask >= REARG_FLAG && srcBitmask > bindFlags) && - !(bitmask > bindFlags && srcBitmask >= REARG_FLAG); - - var isCombo = (newBitmask >= arityFlags && newBitmask <= comboFlags) && - (bitmask < REARG_FLAG || ((isRearg || isAry) && argPos.length <= ary)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = arrayCopy(value); - } - // Use source `ary` if it's smaller. - if (srcBitmask & ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * A specialized version of `_.pick` that picks `object` properties specified - * by the `props` array. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property names to pick. - * @returns {Object} Returns the new object. - */ - function pickByArray(object, props) { - object = toObject(object); - - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - return result; - } - - /** - * A specialized version of `_.pick` that picks `object` properties `predicate` - * returns truthy for. - * - * @private - * @param {Object} object The source object. - * @param {Function} predicate The function invoked per iteration. - * @returns {Object} Returns the new object. - */ - function pickByCallback(object, predicate) { - var result = {}; - baseForIn(object, function(value, key, object) { - if (predicate(value, key, object)) { - result[key] = value; - } - }); - return result; - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = arrayCopy(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity function - * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = (function() { - var count = 0, - lastCalled = 0; - - return function(key, value) { - var stamp = now(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return key; - } - } else { - count = 0; - } - return baseSetData(key, value); - }; - }()); - - /** - * A fallback implementation of `_.isPlainObject` which checks if `value` - * is an object created by the `Object` constructor or has a `[[Prototype]]` - * of `null`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var Ctor, - support = lodash.support; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag) || - (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. - * - * @private - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. - */ - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length, - support = lodash.support; - - var allowIndexes = length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to an array-like object if it is not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array|Object} Returns the array-like object. - */ - function toIterable(value) { - if (value == null) { - return []; - } - if (!isLength(value.length)) { - return values(value); - } - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to an object if it is not one. - * - * @private - * @param {*} value The value to process. - * @returns {Object} Returns the object. - */ - function toObject(value) { - return isObject(value) ? value : Object(value); - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - return wrapper instanceof LazyWrapper - ? wrapper.clone() - : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `collection` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new array containing chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if (guard ? isIterateeCall(array, size, guard) : size == null) { - size = 1; - } else { - size = nativeMax(+size || 1, 1); - } - var index = 0, - length = array ? array.length : 0, - resIndex = -1, - result = Array(ceil(length / size)); - - while (index < length) { - result[++resIndex] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using - * `SameValueZero` for equality comparisons. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.difference([1, 2, 3], [5, 2, 10]); - * // => [1, 3] - */ - function difference() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var value = arguments[index]; - if (isArray(value) || isArguments(value)) { - break; - } - } - return baseDifference(value, baseFlatten(arguments, false, true, ++index)); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that match the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRightWhile([1, 2, 3], function(n) { return n > 1; }); - * // => [1] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.dropRightWhile(users, { 'age': 1, 'active': false }), 'user'); - * // => ['barney', 'fred'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); - * // => ['barney'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - predicate = getCallback(predicate, thisArg, 3); - while (length-- && predicate(array[length], length, array)) {} - return baseSlice(array, 0, length + 1); - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropWhile([1, 2, 3], function(n) { return n < 3; }); - * // => [3] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.dropWhile(users, { 'age': 36, 'active': false }), 'user'); - * // => ['fred', 'pebbles'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.dropWhile(users, 'active', false), 'user'); - * // => ['pebbles'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var index = -1; - predicate = getCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) {} - return baseSlice(array, index); - } - - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function fill(array, value, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for, instead of the element itself. - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.findIndex(users, function(chr) { return chr.age < 40; }); - * // => 0 - * - * // using the "_.matches" callback shorthand - * _.findIndex(users, { 'age': 40, 'active': true }); - * // => 1 - * - * // using the "_.matchesProperty" callback shorthand - * _.findIndex(users, 'age', 1); - * // => 2 - * - * // using the "_.property" callback shorthand - * _.findIndex(users, 'active'); - * // => 1 - */ - function findIndex(array, predicate, thisArg) { - var index = -1, - length = array ? array.length : 0; - - predicate = getCallback(predicate, thisArg, 3); - while (++index < length) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.findLastIndex(users, function(chr) { return chr.age < 40; }); - * // => 2 - * - * // using the "_.matches" callback shorthand - * _.findLastIndex(users, { 'age': 36, 'active': true }); - * // => 0 - * - * // using the "_.matchesProperty" callback shorthand - * _.findLastIndex(users, 'age', 40); - * // => 1 - * - * // using the "_.property" callback shorthand - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, thisArg) { - var length = array ? array.length : 0; - predicate = getCallback(predicate, thisArg, 3); - while (length--) { - if (predicate(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @alias head - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([]); - * // => undefined - */ - function first(array) { - return array ? array[0] : undefined; - } - - /** - * Flattens a nested array. If `isDeep` is `true` the array is recursively - * flattened, otherwise it is only flattened a single level. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, [[4]]]; - * - * // using `isDeep` - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, 4]; - */ - function flatten(array, isDeep, guard) { - var length = array ? array.length : 0; - if (guard && isIterateeCall(array, isDeep, guard)) { - isDeep = false; - } - return length ? baseFlatten(array, isDeep) : []; - } - - /** - * Recursively flattens a nested array. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to recursively flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using `SameValueZero` for equality comparisons. If `fromIndex` is negative, - * it is used as the offset from the end of `array`. If `array` is sorted - * providing `true` for `fromIndex` performs a faster binary search. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * // using `fromIndex` - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * // performing a binary search - * _.indexOf([4, 4, 5, 5, 6, 6], 5, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } else if (fromIndex) { - var index = binaryIndex(array, value), - other = array[index]; - - return (value === value ? value === other : other !== other) ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - return dropRight(array, 1); - } - - /** - * Creates an array of unique values in all provided arrays using `SameValueZero` - * for equality comparisons. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = [], - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf; - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(isCommon && value.length >= 120 && createCache(argsIndex && value)); - } - } - argsLength = args.length; - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = [], - seen = caches[0]; - - outer: - while (++index < length) { - value = array[index]; - if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value)) < 0) { - argsIndex = argsLength; - while (--argsIndex) { - var cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - if (seen) { - seen.push(value); - } - result.push(value); - } - } - return result; - } - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; - } - - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=array.length-1] The index to search from - * or `true` to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * // using `fromIndex` - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - * - * // performing a binary search - * _.lastIndexOf([4, 4, 5, 5, 6, 6], 5, true); - * // => 3 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; - } else if (fromIndex) { - index = binaryIndex(array, value, true) - 1; - var other = array[index]; - return (value === value ? value === other : other !== other) ? index : -1; - } - if (value !== value) { - return indexOfNaN(array, index, true); - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from `array` using `SameValueZero` for equality - * comparisons. - * - * **Notes:** - * - Unlike `_.without`, this method mutates `array`. - * - `SameValueZero` comparisons are like strict equality comparisons, e.g. `===`, - * except that `NaN` matches `NaN`. See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull() { - var array = arguments[0]; - if (!(array && array.length)) { - return array; - } - var index = 0, - indexOf = getIndexOf(), - length = arguments.length; - - while (++index < length) { - var fromIndex = 0, - value = arguments[index]; - - while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { - splice.call(array, fromIndex, 1); - } - } - return array; - } - - /** - * Removes elements from `array` corresponding to the given indexes and returns - * an array of the removed elements. Indexes may be specified as an array of - * indexes or as individual arguments. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove, - * specified as individual indexes or arrays of indexes. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [5, 10, 15, 20]; - * var evens = _.pullAt(array, [1, 3]); - * - * console.log(array); - * // => [5, 15] - * - * console.log(evens); - * // => [10, 20] - */ - function pullAt(array) { - return basePullAt(array || [], baseFlatten(arguments, false, false, 1)); - } - - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is bound to - * `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * **Note:** Unlike `_.filter`, this method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { return n % 2 == 0; }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - predicate = getCallback(predicate, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @alias tail - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - */ - function rest(array) { - return drop(array, 1); - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This function is used instead of `Array#slice` to support node - * lists in IE < 9 and to ensure dense arrays are returned. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - return baseSlice(array, start, end); - } - - /** - * Uses a binary search to determine the lowest index at which `value` should - * be inserted into `array` in order to maintain its sort order. If an iteratee - * function is provided it is invoked for `value` and each element of `array` - * to compute their sort ranking. The iteratee is bound to `thisArg` and - * invoked with one argument; (value). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - * - * _.sortedIndex([4, 4, 5, 5, 6, 6], 5); - * // => 2 - * - * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; - * - * // using an iteratee function - * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { - * return this.data[word]; - * }, dict); - * // => 1 - * - * // using the "_.property" callback shorthand - * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 1 - */ - function sortedIndex(array, value, iteratee, thisArg) { - var func = getCallback(iteratee); - return (func === baseCallback && iteratee == null) - ? binaryIndex(array, value) - : binaryIndexBy(array, value, func(iteratee, thisArg, 1)); - } - - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 4, 5, 5, 6, 6], 5); - * // => 4 - */ - function sortedLastIndex(array, value, iteratee, thisArg) { - var func = getCallback(iteratee); - return (func === baseCallback && iteratee == null) - ? binaryIndex(array, value, true) - : binaryIndexBy(array, value, func(iteratee, thisArg, 1), true); - } - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRightWhile([1, 2, 3], function(n) { return n > 1; }); - * // => [2, 3] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.takeRightWhile(users, { 'age': 1, 'active': true }), 'user'); - * // => ['pebbles'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); - * // => ['fred', 'pebbles'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); - * // => [] - */ - function takeRightWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - predicate = getCallback(predicate, thisArg, 3); - while (length-- && predicate(array[length], length, array)) {} - return baseSlice(array, length + 1); - } - - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is bound to - * `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per element. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeWhile([1, 2, 3], function(n) { return n < 3; }); - * // => [1, 2] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.takeWhile(users, { 'age': 36, 'active': true }), 'user'); - * // => ['barney'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.takeWhile(users, 'active', false), 'user'); - * // => ['barney', 'fred'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); - * // => [] - */ - function takeWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var index = -1; - predicate = getCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) {} - return baseSlice(array, 0, index); - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * `SameValueZero` for equality comparisons. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, false, true)); - } - - /** - * Creates a duplicate-value-free version of an array using `SameValueZero` - * for equality comparisons. Providing `true` for `isSorted` performs a faster - * search algorithm for sorted arrays. If an iteratee function is provided it - * is invoked for each value in the array to generate the criterion by which - * uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @alias unique - * @category Array - * @param {Array} array The array to inspect. - * @param {boolean} [isSorted] Specify the array is sorted. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1]); - * // => [1, 2] - * - * // using `isSorted` - * _.uniq([1, 1, 2], true); - * // => [1, 2] - * - * // using an iteratee function - * _.uniq([1, 2.5, 1.5, 2], function(n) { return this.floor(n); }, Math); - * // => [1, 2.5] - * - * // using the "_.property" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - // Juggle arguments. - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; - isSorted = false; - } - var func = getCallback(); - if (!(func === baseCallback && iteratee == null)) { - iteratee = func(iteratee, thisArg, 3); - } - return (isSorted && getIndexOf() == baseIndexOf) - ? sortedUniq(array, iteratee) - : baseUniq(array, iteratee); - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-`_.zip` - * configuration. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - * - * _.unzip(zipped); - * // => [['fred', 'barney'], [30, 40], [true, false]] - */ - function unzip(array) { - var index = -1, - length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, - result = Array(length); - - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; - } - - /** - * Creates an array excluding all provided values using `SameValueZero` for - * equality comparisons. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to filter. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, baseSlice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See [Wikipedia](https://en.wikipedia.org/wiki/Symmetric_difference) for - * more details. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseDifference(result, array).concat(baseDifference(array, result)) - : array; - } - } - return result ? baseUniq(result) : []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second elements - * of the given arrays, and so on. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var length = arguments.length, - array = Array(length); - - while (length--) { - array[length] = arguments[length]; - } - return unzip(array); - } - - /** - * Creates an object composed from arrays of property names and values. Provide - * either a single two dimensional array, e.g. `[[key1, value1], [key2, value2]]` - * or two arrays, one of property names and one of corresponding values. - * - * @static - * @memberOf _ - * @alias object - * @category Array - * @param {Array} props The property names. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(props, values) { - var index = -1, - length = props ? props.length : 0, - result = {}; - - if (length && !values && !isArray(props[0])) { - values = []; - } - while (++index < length) { - var key = props[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object that wraps `value` with explicit method - * chaining enabled. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _.chain(users) - * .sortBy('age') - * .map(function(chr) { return chr.user + ' is ' + chr.age; }) - * .first() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor is - * bound to `thisArg` and invoked with one argument; (value). The purpose of - * this method is to "tap into" a method chain in order to perform operations - * on intermediate results within the chain. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { array.pop(); }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor, thisArg) { - interceptor.call(thisArg, value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _([1, 2, 3]) - * .last() - * .thru(function(value) { return [value]; }) - * .value(); - * // => [3] - */ - function thru(value, interceptor, thisArg) { - return interceptor.call(thisArg, value); - } - - /** - * Enables explicit method chaining on the wrapper object. - * - * @name chain - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // without explicit chaining - * _(users).first(); - * // => { 'user': 'barney', 'age': 36 } - * - * // with explicit chaining - * _(users).chain() - * .first() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chained sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapper = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapper = wrapper.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapper.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Creates a clone of the chained sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapper = _(array).map(_.partial(Math.pow, _, 2)); - * - * var other = [3, 4]; - * var otherWrapper = wrapper.plant(other); - * - * otherWrapper.value(); - * // => [9, 16] - * - * wrapper.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof LodashWrapper) { - var clone = wrapperClone(parent); - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * Reverses the wrapped array so the first element becomes the last, the - * second element becomes the second to last, and so on. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new reversed `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - if (this.__actions__.length) { - value = new LazyWrapper(this); - } - return new LodashWrapper(value.reverse(), this.__chain__); - } - return this.thru(function(value) { - return value.reverse(); - }); - } - - /** - * Produces the result of coercing the unwrapped value to a string. - * - * @name toString - * @memberOf _ - * @category Chain - * @returns {string} Returns the coerced string value. - * @example - * - * _([1, 2, 3]).toString(); - * // => '1,2,3' - */ - function wrapperToString() { - return (this.value() + ''); - } - - /** - * Executes the chained sequence to extract the unwrapped value. - * - * @name value - * @memberOf _ - * @alias run, toJSON, valueOf - * @category Chain - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements corresponding to the given keys, or indexes, - * of `collection`. Keys may be specified as individual arguments or as arrays - * of keys. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [props] The property names - * or indexes of elements to pick, specified individually or in arrays. - * @returns {Array} Returns the new array of picked elements. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var length = collection ? collection.length : 0; - if (isLength(length)) { - collection = toIterable(collection); - } - return baseAt(collection, baseFlatten(arguments, false, false, 1)); - } - - /** - * Checks if `value` is in `collection` using `SameValueZero` for equality - * comparisons. If `fromIndex` is negative, it is used as the offset from - * the end of `collection`. - * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. - * - * @static - * @memberOf _ - * @alias contains, include - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {*} target The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if a matching element is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.includes('pebbles', 'eb'); - * // => true - */ - function includes(collection, target, fromIndex) { - var length = collection ? collection.length : 0; - if (!isLength(length)) { - collection = values(collection); - length = collection.length; - } - if (!length) { - return false; - } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } else { - fromIndex = 0; - } - return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) - : (getIndexOf(collection, target, fromIndex) > -1); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the number of times the key was returned by `iteratee`. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(n) { return Math.floor(n); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(n) { return this.floor(n); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * The predicate is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // using the "_.matches" callback shorthand - * _.every(users, { 'age': 36, 'active': false }); - * // => false - * - * // using the "_.matchesProperty" callback shorthand - * _.every(users, 'active', false); - * // => true - * - * // using the "_.property" callback shorthand - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (typeof predicate != 'function' || typeof thisArg != 'undefined') { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. - * @example - * - * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); - * // => [2, 4] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); - * // => ['barney'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.filter(users, 'active', false), 'user'); - * // => ['fred'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.filter(users, 'active'), 'user'); - * // => ['barney'] - */ - function filter(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, predicate); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias detect - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.result(_.find(users, function(chr) { return chr.age < 40; }), 'user'); - * // => 'barney' - * - * // using the "_.matches" callback shorthand - * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); - * // => 'pebbles' - * - * // using the "_.matchesProperty" callback shorthand - * _.result(_.find(users, 'active', false), 'user'); - * // => 'fred' - * - * // using the "_.property" callback shorthand - * _.result(_.find(users, 'active'), 'user'); - * // => 'barney' - */ - function find(collection, predicate, thisArg) { - if (isArray(collection)) { - var index = findIndex(collection, predicate, thisArg); - return index > -1 ? collection[index] : undefined; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFind(collection, predicate, baseEach); - } - - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { return n % 2 == 1; }); - * // => 3 - */ - function findLast(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(collection, predicate, baseEachRight); - } - - /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning the first element that has equivalent property - * values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); - * // => 'barney' - * - * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); - * // => 'fred' - */ - function findWhere(collection, source) { - return find(collection, baseMatches(source)); - } - - /** - * Iterates over elements of `collection` invoking `iteratee` for each element. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Iterator functions may exit iteration early - * by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(n) { console.log(n); }).value(); - * // => logs each value from left to right and returns the array - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); - * // => logs each value-key pair and returns the object (iteration order is not guaranteed) - */ - function forEach(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEach(collection, iteratee) - : baseEach(collection, bindCallback(iteratee, thisArg, 3)); - } - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(n) { console.log(n); }).join(','); - * // => logs each value from right to left and returns the array - */ - function forEachRight(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, bindCallback(iteratee, thisArg, 3)); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(n) { return Math.floor(n); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(n) { return this.floor(n); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using the "_.property" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - result[key] = [value]; - } - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the last element responsible for generating the key. The - * iteratee function is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keyData = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keyData, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { return String.fromCharCode(object.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { return this.fromCharCode(object.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in `collection`, - * returning an array of the results of each invoked method. Any additional - * arguments are provided to each invoked method. If `methodName` is a function - * it is invoked for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - return baseInvoke(collection, methodName, baseSlice(arguments, 2)); - } - - /** - * Creates an array of values by running each element in `collection` through - * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * Many lodash methods are guarded to work as interatees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, - * `dropRight`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, `slice`, - * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `random`, `range`, `sample`, `uniq`, and `words` - * - * @static - * @memberOf _ - * @alias collect - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new mapped array. - * @example - * - * _.map([1, 2, 3], function(n) { return n * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); - * // => [3, 6, 9] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // using the "_.property" callback shorthand - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee, thisArg) { - var func = isArray(collection) ? arrayMap : baseMap; - iteratee = getCallback(iteratee, thisArg, 3); - return func(collection, iteratee); - } - - /** - * Gets the maximum value of `collection`. If `collection` is empty or falsey - * `-Infinity` is returned. If an iteratee function is provided it is invoked - * for each value in `collection` to generate the criterion by which the value - * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * _.max([]); - * // => -Infinity - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * _.max(users, function(chr) { return chr.age; }); - * // => { 'user': 'fred', 'age': 40 }; - * - * // using the "_.property" callback shorthand - * _.max(users, 'age'); - * // => { 'user': 'fred', 'age': 40 }; - */ - var max = createExtremum(arrayMax); - - /** - * Gets the minimum value of `collection`. If `collection` is empty or falsey - * `Infinity` is returned. If an iteratee function is provided it is invoked - * for each value in `collection` to generate the criterion by which the value - * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * If a property name or object is provided it is used to create a "_.property" - * or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * _.min([]); - * // => Infinity - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * _.min(users, function(chr) { return chr.age; }); - * // => { 'user': 'barney', 'age': 36 }; - * - * // using the "_.property" callback shorthand - * _.min(users, 'age'); - * // => { 'user': 'barney', 'age': 36 }; - */ - var min = createExtremum(arrayMin, true); - - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, while the second of which - * contains elements `predicate` returns falsey for. The predicate is bound - * to `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * _.partition([1, 2, 3], function(n) { return n % 2; }); - * // => [[1, 3], [2]] - * - * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; }, Math); - * // => [[1, 3], [2]] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * var mapper = function(array) { return _.pluck(array, 'user'); }; - * - * // using the "_.matches" callback shorthand - * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); - * // => [['pebbles'], ['barney', 'fred']] - * - * // using the "_.matchesProperty" callback shorthand - * _.map(_.partition(users, 'active', false), mapper); - * // => [['barney', 'pebbles'], ['fred']] - * - * // using the "_.property" callback shorthand - * _.map(_.partition(users, 'active'), mapper); - * // => [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); - - /** - * Gets the value of `key` from all elements in `collection`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} key The key of the property to pluck. - * @returns {Array} Returns the property values. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * _.pluck(users, 'user'); - * // => ['barney', 'fred'] - * - * var userIndex = _.indexBy(users, 'user'); - * _.pluck(userIndex, 'age'); - * // => [36, 40] (iteration order is not guaranteed) - */ - function pluck(collection, key) { - return map(collection, baseProperty(key)); - } - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` through `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not provided the first element of `collection` is used as the initial - * value. The `iteratee` is bound to `thisArg`and invoked with four arguments; - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as interatees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `merge`, and `sortAllBy` - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, n) { return sum + n; }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, n, key) { - * result[key] = n * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator, thisArg) { - var func = isArray(collection) ? arrayReduce : baseReduce; - return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEach); - } - - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * _.reduceRight(array, function(flattened, other) { return flattened.concat(other); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, iteratee, accumulator, thisArg) { - var func = isArray(collection) ? arrayReduceRight : baseReduce; - return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEachRight); - } - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. - * @example - * - * var odds = _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); - * // => [1, 3] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * // using the "_.matches" callback shorthand - * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); - * // => ['barney'] - * - * // using the "_.matchesProperty" callback shorthand - * _.pluck(_.reject(users, 'active', false), 'user'); - * // => ['fred'] - * - * // using the "_.property" callback shorthand - * _.pluck(_.reject(users, 'active'), 'user'); - * // => ['barney'] - */ - function reject(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, function(value, index, collection) { - return !predicate(value, index, collection); - }); - } - - /** - * Gets a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {*} Returns the random sample(s). - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (guard ? isIterateeCall(collection, n, guard) : n == null) { - collection = toIterable(collection); - var length = collection.length; - return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(n < 0 ? 0 : (+n || 0), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See [Wikipedia](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle) - * for more details. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - collection = toIterable(collection); - - var index = -1, - length = collection.length, - result = Array(length); - - while (++index < length) { - var rand = baseRandom(0, index); - if (index != rand) { - result[index] = result[rand]; - } - result[rand] = collection[index]; - } - return result; - } - - /** - * Gets the size of `collection` by returning `collection.length` for - * array-like values or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the size of `collection`. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return isLength(length) ? length : keys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * The function returns as soon as it finds a passing value and does not iterate - * over the entire collection. The predicate is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * // using the "_.matches" callback shorthand - * _.some(users, { 'age': 1, 'active': true }); - * // => false - * - * // using the "_.matchesProperty" callback shorthand - * _.some(users, 'active', false); - * // => true - * - * // using the "_.property" callback shorthand - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, thisArg) { - var func = isArray(collection) ? arraySome : baseSome; - if (typeof predicate != 'function' || typeof thisArg != 'undefined') { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through `iteratee`. This method performs - * a stable sort, that is, it preserves the original sort order of equal elements. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [iteratee=_.identity] The function - * invoked per iteration. If a property name or an object is provided it is - * used to create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new sorted array. - * @example - * - * _.sortBy([1, 2, 3], function(n) { return Math.sin(n); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); - * // => [3, 1, 2] - * - * var users = [ - * { 'user': 'fred' }, - * { 'user': 'pebbles' }, - * { 'user': 'barney' } - * ]; - * - * // using the "_.property" callback shorthand - * _.pluck(_.sortBy(users, 'user'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function sortBy(collection, iteratee, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = isLength(length) ? Array(length) : []; - - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - iteratee = getCallback(iteratee, thisArg, 3); - baseEach(collection, function(value, key, collection) { - result[++index] = { 'criteria': iteratee(value, key, collection), 'index': index, 'value': value }; - }); - return baseSortBy(result, compareAscending); - } - - /** - * This method is like `_.sortBy` except that it sorts by property names - * instead of an iteratee function. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(string|string[])} props The property names to sort by, - * specified as individual property names or arrays of property names. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 26 }, - * { 'user': 'fred', 'age': 30 } - * ]; - * - * _.map(_.sortByAll(users, ['user', 'age']), _.values); - * // => [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortByAll(collection) { - var args = arguments; - if (args.length > 3 && isIterateeCall(args[1], args[2], args[3])) { - args = [collection, args[1]]; - } - var index = -1, - length = collection ? collection.length : 0, - props = baseFlatten(args, false, false, 1), - result = isLength(length) ? Array(length) : []; - - baseEach(collection, function(value) { - var length = props.length, - criteria = Array(length); - - while (length--) { - criteria[length] = value == null ? undefined : value[props[length]]; - } - result[++index] = { 'criteria': criteria, 'index': index, 'value': value }; - }); - return baseSortBy(result, compareMultipleAscending); - } - - /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning an array of all elements that have equivalent - * property values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {Array} Returns the new filtered array. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, - * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); - * // => ['barney'] - * - * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); - * // => ['fred'] - */ - function where(collection, source) { - return filter(collection, baseMatches(source)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Date - * @example - * - * _.defer(function(stamp) { console.log(_.now() - stamp); }, _.now()); - * // => logs the number of milliseconds it took for the deferred function to be invoked - */ - var now = nativeNow || function() { - return new Date().getTime(); - }; - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it is called `n` or more times. - * - * @static - * @memberOf _ - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'done saving!' after the two async saves have completed - */ - function after(n, func) { - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - n = nativeIsFinite(n = +n) ? n : 0; - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that accepts up to `n` arguments ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - if (guard && isIterateeCall(func, n, guard)) { - n = null; - } - n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); - return createWrapper(func, ARY_FLAG, null, null, null, null, n); - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it is called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 4 contacts to the list - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } else { - func = null; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and prepends any additional `_.bind` arguments to those provided to the - * bound function. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind` this method does not set the `length` - * property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [args] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var greet = function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * }; - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // using placeholders - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - function bind(func, thisArg) { - var bitmask = BIND_FLAG; - if (arguments.length > 2) { - var partials = baseSlice(arguments, 2), - holders = replaceHolders(partials, bind.placeholder); - - bitmask |= PARTIAL_FLAG; - } - return createWrapper(func, bitmask, thisArg, partials, holders); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all enumerable function - * properties, own and inherited, of `object` are bound. - * - * **Note:** This method does not set the `length` property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...(string|string[])} [methodNames] The object method names to bind, - * specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs' when the element is clicked - */ - function bindAll(object) { - return baseBindAll(object, - arguments.length > 1 - ? baseFlatten(arguments, false, false, 1) - : functions(object) - ); - } - - /** - * Creates a function that invokes the method at `object[key]` and prepends - * any additional `_.bindKey` arguments to those provided to the bound function. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. - * See [Peter Michaux's article](http://michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [args] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // using placeholders - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (arguments.length > 2) { - var partials = baseSlice(arguments, 2), - holders = replaceHolders(partials, bindKey.placeholder); - - bitmask |= PARTIAL_FLAG; - } - return createWrapper(key, bitmask, object, partials, holders); - } - - /** - * Creates a function that accepts one or more arguments of `func` that when - * called either invokes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` may be specified - * if `func.length` is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method does not set the `length` property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // using placeholders - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - function curry(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_FLAG, null, null, null, null, null, arity); - result.placeholder = curry.placeholder; - return result; - } - - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method does not set the `length` property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // using placeholders - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - function curryRight(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_RIGHT_FLAG, null, null, null, null, null, arity); - result.placeholder = curryRight.placeholder; - return result; - } - - /** - * Creates a function that delays invoking `func` until after `wait` milliseconds - * have elapsed since the last time it was invoked. The created function comes - * with a `cancel` method to cancel delayed invocations. Provide an options - * object to indicate that `func` should be invoked on the leading and/or - * trailing edge of the `wait` timeout. Subsequent calls to the debounced - * function return the result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify invoking on the leading - * edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be - * delayed before it is invoked. - * @param {boolean} [options.trailing=true] Specify invoking on the trailing - * edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // invoke `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // ensure `batchLog` is invoked once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * jQuery(source).on('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * })); - * - * // cancel a debounced call - * var todoChanges = _.debounce(batchLog, 1000); - * Object.observe(models.todo, todoChanges); - * - * Object.observe(models, function(changes) { - * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { - * todoChanges.cancel(); - * } - * }, ['delete']); - * - * // ...at some point `models.todo` is changed - * models.todo.completed = true; - * - * // ...before 1 second has passed `models.todo` is deleted - * // which cancels the debounced `todoChanges` call - * delete models.todo; - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = wait < 0 ? 0 : wait; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); - trailing = 'trailing' in options ? options.trailing : trailing; - } - - function cancel() { - if (timeoutId) { - clearTimeout(timeoutId); - } - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - } - - function delayed() { - var remaining = wait - (now() - stamp); - if (remaining <= 0 || remaining > wait) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - } - - function maxDelayed() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } - - function debounced() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - } - debounced.cancel = cancel; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - return baseDelay(func, 1, arguments, 1); - } - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - return baseDelay(func, wait, arguments, 2); - } - - /** - * Creates a function that returns the result of invoking the provided - * functions with the `this` binding of the created function, where each - * successive invocation is supplied the return value of the previous. - * - * @static - * @memberOf _ - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function add(x, y) { - * return x + y; - * } - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flow(add, square); - * addSquare(1, 2); - * // => 9 - */ - function flow() { - var funcs = arguments, - length = funcs.length; - - if (!length) { - return function() { return arguments[0]; }; - } - if (!arrayEvery(funcs, isFunction)) { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var index = 0, - result = funcs[index].apply(this, arguments); - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - } - - /** - * This method is like `_.flow` except that it creates a function that - * invokes the provided functions from right to left. - * - * @static - * @memberOf _ - * @alias backflow, compose - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function add(x, y) { - * return x + y; - * } - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flowRight(square, add); - * addSquare(1, 2); - * // => 9 - */ - function flowRight() { - var funcs = arguments, - fromIndex = funcs.length - 1; - - if (fromIndex < 0) { - return function() { return arguments[0]; }; - } - if (!arrayEvery(funcs, isFunction)) { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var index = fromIndex, - result = funcs[index].apply(this, arguments); - - while (index--) { - result = funcs[index].call(this, result); - } - return result; - }; - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is coerced to a string and used as the - * cache key. The `func` is invoked with the `this` binding of the memoized - * function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the ES `Map` method interface - * of `get`, `has`, and `set`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) - * for more details. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var upperCase = _.memoize(function(string) { - * return string.toUpperCase(); - * }); - * - * upperCase('fred'); - * // => 'FRED' - * - * // modifying the result cache - * upperCase.cache.set('fred', 'BARNEY'); - * upperCase('fred'); - * // => 'BARNEY' - * - * // replacing `_.memoize.Cache` - * var object = { 'user': 'fred' }; - * var other = { 'user': 'barney' }; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'fred' } - * - * _.memoize.Cache = WeakMap; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'barney' } - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : arguments[0]; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, arguments); - cache.set(key, result); - return result; - }; - memoized.cache = new memoize.Cache; - return memoized; - } - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - return !predicate.apply(this, arguments); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first call. The `func` is invoked - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` invokes `createApplication` once - */ - function once(func) { - return before(func, 2); - } - - /** - * Creates a function that invokes `func` with `partial` arguments prepended - * to those provided to the new function. This method is like `_.bind` except - * it does **not** alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method does not set the `length` property of partially - * applied functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [args] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // using placeholders - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - function partial(func) { - var partials = baseSlice(arguments, 1), - holders = replaceHolders(partials, partial.placeholder); - - return createWrapper(func, PARTIAL_FLAG, null, partials, holders); - } - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to those provided to the new function. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method does not set the `length` property of partially - * applied functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [args] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // using placeholders - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - function partialRight(func) { - var partials = baseSlice(arguments, 1), - holders = replaceHolders(partials, partialRight.placeholder); - - return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders); - } - - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified indexes where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes, - * specified as individual indexes or arrays of indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, 2, 0, 1); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - * - * var map = _.rearg(_.map, [1, 0]); - * map(function(n) { return n * 3; }, [1, 2, 3]); - * // => [3, 6, 9] - */ - function rearg(func) { - var indexes = baseFlatten(arguments, false, false, 1); - return createWrapper(func, REARG_FLAG, null, null, null, indexes); - } - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and the array of arguments provided to the created - * function much like [Function#apply](http://es5.github.io/#x15.3.4.3). - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to spread arguments over. - * @returns {*} Returns the new function. - * @example - * - * var spread = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * spread(['Fred', 'hello']); - * // => 'Fred says hello' - * - * // with a Promise - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * var add = function(x, y) { - * return x + y; - * }; - * - * numbers.then(_.spread(add)); - * // => a Promise of 76 - */ - function spread(func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function(array) { - return func.apply(this, array); - }; - } - - /** - * Creates a function that only invokes `func` at most once per every `wait` - * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invocations. Provide an options object to indicate that `func` - * should be invoked on the leading and/or trailing edge of the `wait` timeout. - * Subsequent calls to the throttled function return the result of the last - * `func` call. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle invocations to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify invoking on the leading - * edge of the timeout. - * @param {boolean} [options.trailing=true] Specify invoking on the trailing - * edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }) - * jQuery('.interactive').on('click', throttled); - * - * // cancel a trailing throttled call - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = +wait; - debounceOptions.trailing = trailing; - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Any additional arguments provided to the function are - * appended to those provided to the wrapper function. The wrapper is invoked - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

' + func(text) + '

'; - * }); - * - * p('fred, barney, & pebbles'); - * // => '

fred, barney, & pebbles

' - */ - function wrap(value, wrapper) { - wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, - * otherwise they are assigned by reference. If `customizer` is provided it is - * invoked to produce the cloned values. If `customizer` returns `undefined` - * cloning is handled by the method instead. The `customizer` is bound to - * `thisArg` and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the structured clone algorithm. - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) - * for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var shallow = _.clone(users); - * shallow[0] === users[0]; - * // => true - * - * var deep = _.clone(users, true); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var body = _.clone(document.body, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }); - * - * body === document.body - * // => false - * body.nodeName - * // => BODY - * body.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, customizer, thisArg) { - // Juggle arguments. - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = customizer; - customizer = isIterateeCall(value, isDeep, thisArg) ? null : isDeep; - isDeep = false; - } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, isDeep, customizer); - } - - /** - * Creates a deep clone of `value`. If `customizer` is provided it is invoked - * to produce the cloned values. If `customizer` returns `undefined` cloning - * is handled by the method instead. The `customizer` is bound to `thisArg` - * and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the structured clone algorithm. - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) - * for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var deep = _.cloneDeep(users); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var el = _.cloneDeep(document.body, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * body === document.body - * // => false - * body.nodeName - * // => BODY - * body.childNodes.length; - * // => 20 - */ - function cloneDeep(value, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, true, customizer); - } - - /** - * Checks if `value` is classified as an `arguments` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - var length = isObjectLike(value) ? value.length : undefined; - return (isLength(length) && objToString.call(value) == argsTag) || false; - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * (function() { return _.isArray(arguments); })(); - * // => false - */ - var isArray = nativeIsArray || function(value) { - return (isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag) || false; - }; - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return (value === true || value === false || isObjectLike(value) && objToString.call(value) == boolTag) || false; - } - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - function isDate(value) { - return (isObjectLike(value) && objToString.call(value) == dateTag) || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement(''); - * // => false - */ - function isElement(value) { - return (value && value.nodeType === 1 && isObjectLike(value) && - objToString.call(value).indexOf('Element') > -1) || false; - } - // Fallback for environments without DOM support. - if (!support.dom) { - isElement = function(value) { - return (value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value)) || false; - }; - } - - /** - * Checks if a value is empty. A value is considered empty unless it is an - * `arguments` object, array, string, or jQuery-like collection with a length - * greater than `0` or an object with own enumerable properties. - * - * @static - * @memberOf _ - * @category Lang - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (value == null) { - return true; - } - var length = value.length; - if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) || - (isObjectLike(value) && isFunction(value.splice)))) { - return !length; - } - return !keys(value).length; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. If `customizer` is provided it is invoked to compare values. - * If `customizer` returns `undefined` comparisons are handled by the method - * instead. The `customizer` is bound to `thisArg` and invoked with three - * arguments; (value, other [, index|key]). - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. Functions and DOM nodes - * are **not** supported. Provide a customizer function to extend support - * for comparing other values. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'user': 'fred' }; - * var other = { 'user': 'fred' }; - * - * object == other; - * // => false - * - * _.isEqual(object, other); - * // => true - * - * // using a customizer callback - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqual(array, other, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; - * }); - * // => true - */ - function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { - return value === other; - } - var result = customizer ? customizer(value, other) : undefined; - return typeof result == 'undefined' ? baseIsEqual(value, other, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - return (isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag) || false; - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on ES `Number.isFinite`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite) - * for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(10); - * // => true - * - * _.isFinite('10'); - * // => false - * - * _.isFinite(true); - * // => false - * - * _.isFinite(Object(10)); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - var isFinite = nativeNumIsFinite || function(value) { - return typeof value == 'number' && nativeIsFinite(value); - }; - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - // Avoid a Chakra JIT bug in compatibility modes of IE 11. - // See https://github.com/jashkenas/underscore/issues/1621 for more details. - return typeof value == 'function' || false; - } - // Fallback for environments that return incorrect `typeof` operator results. - if (isFunction(/x/) || (Uint8Array && !isFunction(Uint8Array))) { - isFunction = function(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return objToString.call(value) == funcTag; - }; - } - - /** - * Checks if `value` is the language type of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return type == 'function' || (value && type == 'object') || false; - } - - /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. If `customizer` is provided - * it is invoked to compare values. If `customizer` returns `undefined` - * comparisons are handled by the method instead. The `customizer` is bound - * to `thisArg` and invoked with three arguments; (value, other, index|key). - * - * **Note:** This method supports comparing properties of arrays, booleans, - * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions - * and DOM nodes are **not** supported. Provide a customizer function to extend - * support for comparing other values. - * - * @static - * @memberOf _ - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.isMatch(object, { 'age': 40 }); - * // => true - * - * _.isMatch(object, { 'age': 36 }); - * // => false - * - * // using a customizer callback - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatch(object, source, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; - * }); - * // => true - */ - function isMatch(object, source, customizer, thisArg) { - var props = keys(source), - length = props.length; - - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - if (!customizer && length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return object != null && value === object[key] && hasOwnProperty.call(object, key); - } - } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = values[length] = source[props[length]]; - strictCompareFlags[length] = isStrictComparable(value); - } - return baseIsMatch(object, props, values, strictCompareFlags, customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is not the same as native `isNaN` which returns `true` - * for `undefined` and other non-numeric values. See the [ES5 spec](https://es5.github.io/#x15.1.2.4) - * for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some host objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a native function. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (value == null) { - return false; - } - if (objToString.call(value) == funcTag) { - return reNative.test(fnToString.call(value)); - } - return (isObjectLike(value) && reHostCtor.test(value)) || false; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified - * as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isNumber(8.4); - * // => true - * - * _.isNumber(NaN); - * // => true - * - * _.isNumber('8.4'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag) || false; - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * **Note:** This method assumes objects created by the `Object` constructor - * have no inherited enumerable properties. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && objToString.call(value) == objectTag)) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - function isRegExp(value) { - return (isObjectLike(value) && objToString.call(value) == regexpTag) || false; - } - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag) || false; - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - function isTypedArray(value) { - return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Converts `value` to an array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3); - * // => [2, 3] - */ - function toArray(value) { - var length = value ? value.length : 0; - if (!isLength(length)) { - return values(value); - } - if (!length) { - return []; - } - return arrayCopy(value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable - * properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return baseCopy(value, keysIn(value)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources overwrite property assignments of previous sources. - * If `customizer` is provided it is invoked to produce the assigned values. - * The `customizer` is bound to `thisArg` and invoked with five arguments; - * (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); - * // => { 'user': 'fred', 'age': 40 } - * - * // using a customizer callback - * var defaults = _.partialRight(_.assign, function(value, other) { - * return typeof value == 'undefined' ? other : value; - * }); - * - * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - var assign = createAssigner(baseAssign); - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties, guard) { - var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = null; - } - return properties ? baseCopy(properties, result, keys(properties)) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property are ignored. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - function defaults(object) { - if (object == null) { - return object; - } - var args = arrayCopy(arguments); - args.push(assignDefaults); - return assign.apply(undefined, args); - } - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element `predicate` returns truthy for, instead of the element itself. - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {string|undefined} Returns the key of the matched element, else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(chr) { return chr.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // using the "_.matches" callback shorthand - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // using the "_.matchesProperty" callback shorthand - * _.findKey(users, 'active', false); - * // => 'fred' - * - * // using the "_.property" callback shorthand - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwn, true); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * If a property name is provided for `predicate` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {string|undefined} Returns the key of the matched element, else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(chr) { return chr.age < 40; }); - * // => returns `pebbles` assuming `_.findKey` returns `barney` - * - * // using the "_.matches" callback shorthand - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // using the "_.matchesProperty" callback shorthand - * _.findLastKey(users, 'active', false); - * // => 'fred' - * - * // using the "_.property" callback shorthand - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwnRight, true); - } - - /** - * Iterates over own and inherited enumerable properties of an object invoking - * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked - * with three arguments; (value, key, object). Iterator functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) - */ - function forIn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseFor(object, iteratee, keysIn); - } - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' - */ - function forInRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keysIn); - } - - /** - * Iterates over own enumerable properties of an object invoking `iteratee` - * for each property. The `iteratee` is bound to `thisArg` and invoked with - * three arguments; (value, key, object). Iterator functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (iteration order is not guaranteed) - */ - function forOwn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseForOwn(object, iteratee); - } - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keys); - } - - /** - * Creates an array of function property names from all enumerable properties, - * own and inherited, of `object`. - * - * @static - * @memberOf _ - * @alias methods - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of property names. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', ...] - */ - function functions(object) { - return baseFunctions(object, keysIn(object)); - } - - /** - * Checks if `key` exists as a direct property of `object` instead of an - * inherited property. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @param {string} key The key to check. - * @returns {boolean} Returns `true` if `key` is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite property - * assignments of previous values unless `multiValue` is `true`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to invert. - * @param {boolean} [multiValue] Allow multiple values per key. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - * - * // without `multiValue` - * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }); - * // => { 'fred': 'third', 'barney': 'second' } - * - * // with `multiValue` - * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }, true); - * // => { 'fred': ['first', 'third'], 'barney': ['second'] } - */ - function invert(object, multiValue, guard) { - if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = null; - } - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; - - if (multiValue) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - } - else { - result[value] = key; - } - } - return result; - } - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) - * for more details. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (object) { - var Ctor = object.constructor, - length = object.length; - } - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && (length && isLength(length)))) { - return shimKeys(object); - } - return isObject(object) ? nativeKeys(object) : []; - }; - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; - - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through `iteratee`. The - * iteratee function is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `iteratee` the created "_.property" - * style callback returns the property value of the given element. - * - * If value is also provided for `thisArg` the created "_.matchesProperty" - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created "_.matches" style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. If a property name or object is provided it is used to - * create a "_.property" or "_.matches" style callback respectively. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the new mapped object. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(n) { return n * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * // using the "_.property" callback shorthand - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee, thisArg) { - var result = {}; - iteratee = getCallback(iteratee, thisArg, 3); - - baseForOwn(object, function(value, key, object) { - result[key] = iteratee(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it is invoked to produce the merged values of the destination and - * source properties. If `customizer` returns `undefined` merging is handled - * by the method instead. The `customizer` is bound to `thisArg` and invoked - * with five arguments; (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } - * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(object, other, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - */ - var merge = createAssigner(baseMerge); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable properties of `object` that are not omitted. - * Property names may be specified as individual arguments or as arrays of - * property names. If `predicate` is provided it is invoked for each property - * of `object` omitting the properties `predicate` returns truthy for. The - * predicate is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to omit, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.omit(object, 'age'); - * // => { 'user': 'fred' } - * - * _.omit(object, _.isNumber); - * // => { 'user': 'fred' } - */ - function omit(object, predicate, thisArg) { - if (object == null) { - return {}; - } - if (typeof predicate != 'function') { - var props = arrayMap(baseFlatten(arguments, false, false, 1), String); - return pickByArray(object, baseDifference(keysIn(object), props)); - } - predicate = bindCallback(predicate, thisArg, 3); - return pickByCallback(object, function(value, key, object) { - return !predicate(value, key, object); - }); - } - - /** - * Creates a two dimensional array of the key-value pairs for `object`, - * e.g. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates an object composed of the picked `object` properties. Property - * names may be specified as individual arguments or as arrays of property - * names. If `predicate` is provided it is invoked for each property of `object` - * picking the properties `predicate` returns truthy for. The predicate is - * bound to `thisArg` and invoked with three arguments; (value, key, object). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.pick(object, 'user'); - * // => { 'user': 'fred' } - * - * _.pick(object, _.isString); - * // => { 'user': 'fred' } - */ - function pick(object, predicate, thisArg) { - if (object == null) { - return {}; - } - return typeof predicate == 'function' - ? pickByCallback(object, bindCallback(predicate, thisArg, 3)) - : pickByArray(object, baseFlatten(arguments, false, false, 1)); - } - - /** - * Resolves the value of property `key` on `object`. If the value of `key` is - * a function it is invoked with the `this` binding of `object` and its result - * is returned, else the property value is returned. If the property value is - * `undefined` the `defaultValue` is used in its place. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {string} key The key of the property to resolve. - * @param {*} [defaultValue] The value returned if the property value - * resolves to `undefined`. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'user': 'fred', 'age': _.constant(40) }; - * - * _.result(object, 'user'); - * // => 'fred' - * - * _.result(object, 'age'); - * // => 40 - * - * _.result(object, 'status', 'busy'); - * // => 'busy' - * - * _.result(object, 'status', _.constant('busy')); - * // => 'busy' - */ - function result(object, key, defaultValue) { - var value = object == null ? undefined : object[key]; - if (typeof value == 'undefined') { - value = defaultValue; - } - return isFunction(value) ? value.call(object) : value; - } - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own enumerable - * properties through `iteratee`, with each invocation potentially mutating - * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked - * with four arguments; (accumulator, value, key, object). Iterator functions - * may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Array|Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6], function(result, n) { - * n *= n; - * if (n % 2) { - * return result.push(n) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, n, key) { - * result[key] = n * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, iteratee, accumulator, thisArg) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = getCallback(iteratee, thisArg, 4); - - if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); - } - } else { - accumulator = {}; - } - } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Creates an array of the own enumerable property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return baseValues(object, keys(object)); - } - - /** - * Creates an array of the own and inherited enumerable property values - * of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number is returned. - * If `floating` is `true`, or either `min` or `max` are floats, a floating-point - * number is returned instead of an integer. - * - * @static - * @memberOf _ - * @category Number - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - if (floating && isIterateeCall(min, max, floating)) { - max = floating = null; - } - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (noMax && typeof min == 'boolean') { - floating = min; - min = 1; - } - else if (typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - noMax = false; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); - } - return baseRandom(min, max); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to camel case. - * See [Wikipedia](https://en.wikipedia.org/wiki/CamelCase) for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar'); - * // => 'fooBar' - * - * _.camelCase('__foo_bar__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); - }); - - /** - * Capitalizes the first character of `string`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('fred'); - * // => 'Fred' - */ - function capitalize(string) { - string = baseToString(string); - return string && (string.charAt(0).toUpperCase() + string.slice(1)); - } - - /** - * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. - * See [Wikipedia](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('déjà vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = baseToString(string); - return string && string.replace(reLatin1, deburrLetter); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search from. - * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = baseToString(string); - target = (target + ''); - - var length = string.length; - position = (typeof position == 'undefined' ? length : nativeMin(position < 0 ? 0 : (+position || 0), length)) - target.length; - return position >= 0 && string.indexOf(target, position) == position; - } - - /** - * Converts the characters "&", "<", ">", '"', "'", and '`', in `string` to - * their corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional characters - * use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't require escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. - * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * Backticks are escaped because in Internet Explorer < 9, they can break out - * of attribute values or HTML comments. See [#102](https://html5sec.org/#102), - * [#108](https://html5sec.org/#108), and [#133](https://html5sec.org/#133) of - * the [HTML5 Security Cheatsheet](https://html5sec.org/) for more details. - * - * When working with HTML you should always quote attribute values to reduce - * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping) - * for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - // Reset `lastIndex` because in IE < 9 `String#replace` does not. - string = baseToString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", - * "+", "(", ")", "[", "]", "{" and "}" in `string`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ - function escapeRegExp(string) { - string = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; - } - - /** - * Converts `string` to kebab case (a.k.a. spinal case). - * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for - * more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__foo_bar__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); - }); - - /** - * Pads `string` on the left and right sides if it is shorter then the given - * padding length. The `chars` string may be truncated if the number of padding - * characters can't be evenly divided by the padding length. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = baseToString(string); - length = +length; - - var strLength = string.length; - if (strLength >= length || !nativeIsFinite(length)) { - return string; - } - var mid = (length - strLength) / 2, - leftLength = floor(mid), - rightLength = ceil(mid); - - chars = createPad('', rightLength, chars); - return chars.slice(0, leftLength) + string + chars; - } - - /** - * Pads `string` on the left side if it is shorter then the given padding - * length. The `chars` string may be truncated if the number of padding - * characters exceeds the padding length. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padLeft('abc', 6); - * // => ' abc' - * - * _.padLeft('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padLeft('abc', 3); - * // => 'abc' - */ - function padLeft(string, length, chars) { - string = baseToString(string); - return string && (createPad(string, length, chars) + string); - } - - /** - * Pads `string` on the right side if it is shorter then the given padding - * length. The `chars` string may be truncated if the number of padding - * characters exceeds the padding length. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padRight('abc', 6); - * // => 'abc ' - * - * _.padRight('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padRight('abc', 3); - * // => 'abc' - */ - function padRight(string, length, chars) { - string = baseToString(string); - return string && (string + createPad(string, length, chars)); - } - - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, - * in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the ES5 implementation of `parseInt`. - * See the [ES5 spec](https://es5.github.io/#E) for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - if (guard && isIterateeCall(string, radix, guard)) { - radix = 0; - } - return nativeParseInt(string, radix); - } - // Fallback for environments with pre-ES5 implementations. - if (nativeParseInt(whitespace + '08') != 8) { - parseInt = function(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. - // Chrome fails to trim leading whitespace characters. - // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = trim(string); - return nativeParseInt(string, radix || (reHexPrefix.test(string) ? 16 : 10)); - }; - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=0] The number of times to repeat the string. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n) { - var result = ''; - string = baseToString(string); - n = +n; - if (n < 1 || !string || !nativeIsFinite(n)) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = floor(n / 2); - string += string; - } while (n); - - return result; - } - - /** - * Converts `string` to snake case. - * See [Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--foo-bar'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); - - /** - * Converts `string` to start case. - * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) - * for more details. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__foo_bar__'); - * // => 'Foo Bar' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = baseToString(string); - position = position == null ? 0 : nativeMin(position < 0 ? 0 : (+position || 0), string.length); - return string.lastIndexOf(target, position) == position; - } - - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is provided it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes sourceURLs for easier debugging. - * See the [HTML5 Rocks article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for more details. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as free variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. - * @param {string} [options.variable] The data object variable name. - * @param- {Object} [otherOptions] Enables the legacy `options` param signature. - * @returns {Function} Returns the compiled template function. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // using the HTML "escape" delimiter to escape data property values - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '