From 515cded2a4dcbe07a29047d15bb20fd7b45d2716 Mon Sep 17 00:00:00 2001 From: David Davidson Date: Thu, 17 Dec 2015 16:59:51 -0800 Subject: [PATCH] 0.0.4 - Adds Label, plus up-to-date docs --- dist/victory.js | 47404 ++++++++++++++++++-------------------- dist/victory.js.map | 2 +- dist/victory.min.js | 26 + dist/victory.min.js.map | 1 + package.json | 2 +- 5 files changed, 22593 insertions(+), 24842 deletions(-) create mode 100644 dist/victory.min.js create mode 100644 dist/victory.min.js.map diff --git a/dist/victory.js b/dist/victory.js index b99439b4c..911c39970 100644 --- a/dist/victory.js +++ b/dist/victory.js @@ -7,7 +7,7 @@ exports["Victory"] = factory(require("react")); else root["Victory"] = factory(root["React"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_3__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_6__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -60,25 +60,28 @@ return /******/ (function(modules) { // webpackBootstrap value: true }); - var _victoryAnimation = __webpack_require__(1); + var _victoryAnimation = __webpack_require__(55); - var _victoryAxis = __webpack_require__(8); + var _victoryAxis = __webpack_require__(60); - var _victoryBar = __webpack_require__(47); + var _victoryBar = __webpack_require__(66); - var _victoryChart = __webpack_require__(49); + var _victoryChart = __webpack_require__(70); - var _victoryLine = __webpack_require__(53); + var _victoryLine = __webpack_require__(1); - var _victoryPie = __webpack_require__(55); + var _victoryLabel = __webpack_require__(43); - var _victoryScatter = __webpack_require__(57); + var _victoryPie = __webpack_require__(72); + + var _victoryScatter = __webpack_require__(76); exports.VictoryAnimation = _victoryAnimation.VictoryAnimation; exports.VictoryAxis = _victoryAxis.VictoryAxis; exports.VictoryBar = _victoryBar.VictoryBar; exports.VictoryChart = _victoryChart.VictoryChart; exports.VictoryLine = _victoryLine.VictoryLine; + exports.VictoryLabel = _victoryLabel.VictoryLabel; exports.VictoryPie = _victoryPie.VictoryPie; exports.VictoryScatter = _victoryScatter.VictoryScatter; @@ -89,21 +92,21 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; module.exports = { - VictoryAnimation: __webpack_require__(2) + VictoryLine: __webpack_require__(2) }; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { - /*global requestAnimationFrame, cancelAnimationFrame, setTimeout*/ - "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; @@ -114,11278 +117,5052 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _react = __webpack_require__(3); + var _lodash = __webpack_require__(4); - var _react2 = _interopRequireDefault(_react); + var _lodash2 = _interopRequireDefault(_lodash); - var _d3 = __webpack_require__(4); + var _react = __webpack_require__(6); - var _d32 = _interopRequireDefault(_d3); + var _react2 = _interopRequireDefault(_react); - var _util = __webpack_require__(5); + var _radium = __webpack_require__(7); - (0, _util.addVictoryInterpolator)(); + var _radium2 = _interopRequireDefault(_radium); - var VictoryAnimation = (function (_React$Component) { - _inherits(VictoryAnimation, _React$Component); + var _d3Scale = __webpack_require__(34); - _createClass(VictoryAnimation, null, [{ - key: "propTypes", - value: { - children: _react2["default"].PropTypes.func, - velocity: _react2["default"].PropTypes.number, - easing: _react2["default"].PropTypes.string, - delay: _react2["default"].PropTypes.number, - onEnd: _react2["default"].PropTypes.func, - data: _react2["default"].PropTypes.oneOfType([_react2["default"].PropTypes.object, _react2["default"].PropTypes.array]) - }, - enumerable: true - }, { - key: "defaultProps", - value: { - /* velocity modifies step each frame */ - velocity: 0.02, - /* easing modifies step each frame */ - easing: "quad-in-out", - /* delay between transitions */ - delay: 0, - /* we got nothin' */ - data: {} - }, - enumerable: true - }]); + var _d3Scale2 = _interopRequireDefault(_d3Scale); - function VictoryAnimation(props) { - _classCallCheck(this, VictoryAnimation); + var _lineSegment = __webpack_require__(3); - _get(Object.getPrototypeOf(VictoryAnimation.prototype), "constructor", this).call(this, props); - /* defaults */ - this.state = Array.isArray(this.props.data) ? this.props.data[0] : this.props.data; - this.interpolator = null; - this.step = 0; - this.queue = []; - /* build easing function */ - this.ease = _d32["default"].ease(this.props.easing); - /* - unlike React.createClass({}), there is no autobinding of this in ES6 classes - so we bind functionToBeRunEachFrame to current instance of victory animation class - */ - this.functionToBeRunEachFrame = this.functionToBeRunEachFrame.bind(this); - } + var _lineSegment2 = _interopRequireDefault(_lineSegment); - /* lifecycle */ + var _lineLabel = __webpack_require__(42); - _createClass(VictoryAnimation, [{ - key: "componentWillReceiveProps", - value: function componentWillReceiveProps(nextProps) { - var _this = this; + var _lineLabel2 = _interopRequireDefault(_lineLabel); - /* cancel existing loop if it exists */ - if (this.raf) { - cancelAnimationFrame(this.raf); - } - /* If an object was supplied */ - if (Array.isArray(nextProps.data) === false) { - /* compare cached version to next props */ - this.interpolator = _d32["default"].interpolate(this.state, nextProps.data); - /* reset step to zero */ - this.step = 0; - /* start request animation frame */ - setTimeout(function () { - _this.raf = _this.functionToBeRunEachFrame(); - }, this.props.delay); - /* If an array was supplied */ - } else { - /* Build our tween queue */ - nextProps.data.forEach(function (data) { - _this.queue.push(data); - }); - /* Start traversing the tween queue */ - this.traverseQueue(); - } - } - }, { - key: "componentWillUnmount", - value: function componentWillUnmount() { - if (this.raf) { - cancelAnimationFrame(this.raf); - } - } + var _victoryUtil = __webpack_require__(45); - /* Traverse the tween queue */ - }, { - key: "traverseQueue", - value: function traverseQueue() { - var _this2 = this; + var _victoryUtil2 = _interopRequireDefault(_victoryUtil); - if (this.queue.length > 0) { - /* Get the next index */ - var data = this.queue[0]; - /* compare cached version to next props */ - this.interpolator = _d32["default"].interpolate(this.state, data); - /* reset step to zero */ - this.step = 0; - setTimeout(function () { - _this2.raf = _this2.functionToBeRunEachFrame(); - }, this.props.delay); - } else if (this.props.onEnd) { - this.props.onEnd(); - } - } + var _victoryAnimation = __webpack_require__(55); - /* every frame we... */ - }, { - key: "functionToBeRunEachFrame", - value: function functionToBeRunEachFrame() { - /* - step can generate imprecise values, sometimes greater than 1 - if this happens set the state to 1 and return, cancelling the loop - */ - if (this.step >= 1) { - this.step = 1; - this.setState(this.interpolator(this.step)); - if (this.queue.length > 0) { - cancelAnimationFrame(this.raf); - this.queue.shift(); - this.traverseQueue(); - } else if (this.props.onEnd) { - this.props.onEnd(); - } - return; - } - /* - if we're not at the end of the loop, set the state by passing - current step value that's transformed by the ease function to the - interpolator, which is cached for performance whenever props are received - */ - this.setState(this.interpolator(this.ease(this.step))); - /* increase step by velocity */ - this.step += this.props.velocity; - /* - requestAnimationFrame calls a function on a frame. - continue the loop by feeding functionToBeRunEachFrame - */ - this.raf = requestAnimationFrame(this.functionToBeRunEachFrame); - } - }, { - key: "render", - value: function render() { - return this.props.children(this.state); - } - }]); + var defaultStyles = { + data: { + strokeWidth: 2, + fill: "none", + stroke: "#756f6a", + opacity: 1 + }, + labels: { + padding: 5, + fontFamily: "Helvetica", + fontSize: 10, + strokeWidth: 0, + stroke: "transparent", + textAnchor: "start" + } + }; - return VictoryAnimation; - })(_react2["default"].Component); + var VictoryLine = (function (_React$Component) { + _inherits(VictoryLine, _React$Component); - exports["default"] = VictoryAnimation; - module.exports = exports["default"]; - -/***/ }, -/* 3 */ -/***/ function(module, exports) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_3__; - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;!function() { - var d3 = { - version: "3.5.10" - }; - var d3_arraySlice = [].slice, d3_array = function(list) { - return d3_arraySlice.call(list); - }; - var d3_document = this.document; - function d3_documentElement(node) { - return node && (node.ownerDocument || node.document || node).documentElement; - } - function d3_window(node) { - return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView); + function VictoryLine() { + _classCallCheck(this, _VictoryLine); + + _get(Object.getPrototypeOf(_VictoryLine.prototype), "constructor", this).apply(this, arguments); } - if (d3_document) { - try { - d3_array(d3_document.documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; + + _createClass(VictoryLine, [{ + key: "getCalculatedValues", + value: function getCalculatedValues(props) { + this.style = this.getStyles(props); + this.padding = this.getPadding(props); + this.range = { + x: this.getRange(props, "x"), + y: this.getRange(props, "y") }; - } - } - if (!Date.now) Date.now = function() { - return +new Date(); - }; - if (d3_document) { - try { - d3_document.createElement("DIV").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); + this.dataset = this.getData(props); + this.dataSegments = this.getDataSegments(); + this.domain = { + x: this.getDomain(props, "x"), + y: this.getDomain(props, "y") }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); + this.scale = { + x: this.getScale(props, "x"), + y: this.getScale(props, "y") }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); + } + }, { + key: "getStyles", + value: function getStyles(props) { + var style = props.style || defaultStyles; + var data = style.data; + var labels = style.labels; + var parent = style.parent; + + return { + parent: _lodash2["default"].merge({ height: props.height, width: props.width }, parent), + labels: _lodash2["default"].merge({}, defaultStyles.labels, labels), + data: _lodash2["default"].merge({}, defaultStyles.data, data) }; } - } - d3.ascending = d3_ascending; - function d3_ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; + }, { + key: "getPadding", + value: function getPadding(props) { + var padding = _lodash2["default"].isNumber(props.padding) ? props.padding : 0; + var paddingObj = _lodash2["default"].isObject(props.padding) ? props.padding : {}; + return { + top: paddingObj.top || padding, + bottom: paddingObj.bottom || padding, + left: paddingObj.left || padding, + right: paddingObj.right || padding + }; } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; + }, { + key: "getScale", + value: function getScale(props, axis) { + var scale = undefined; + if (props.scale && props.scale[axis]) { + scale = props.scale[axis].copy(); + } else if (props.scale && !_lodash2["default"].isObject(props.scale)) { + scale = props.scale.copy(); + } else { + scale = _d3Scale2["default"].linear().copy(); } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; + var range = this.range[axis]; + var domain = this.domain[axis]; + scale.range(range); + scale.domain(domain); + return scale; } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; + }, { + key: "getDomain", + value: function getDomain(props, axis) { + if (props.domain && props.domain[axis]) { + return props.domain[axis]; + } else if (props.domain && !_lodash2["default"].isObject(props.domain)) { + return props.domain; + } else { + return [_lodash2["default"].min(_lodash2["default"].pluck(this.dataset, axis)), _lodash2["default"].max(_lodash2["default"].pluck(this.dataset, axis))]; } } - return [ a, c ]; - }; - function d3_number(x) { - return x === null ? NaN : +x; - } - function d3_numeric(x) { - return !isNaN(x); - } - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = +array[i])) s += a; - } else { - while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - d3.mean = function(array, f) { - var s = 0, n = array.length, a, i = -1, j = n; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; - } - if (j) return s / j; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - var numbers = [], n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); + }, { + key: "getRange", + value: function getRange(props, axis) { + // if the range is not given in props, calculate it from width, height and margin + return axis === "x" ? [this.padding.left, props.width - this.padding.right] : [props.height - this.padding.bottom, this.padding.top]; } - if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); - }; - d3.variance = function(array, f) { - var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) { - if (d3_numeric(a = d3_number(array[i]))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } else { - while (++i < n) { - if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } - if (j > 1) return s / (j - 1); - }; - d3.deviation = function() { - var v = d3.variance.apply(this, arguments); - return v ? Math.sqrt(v) : v; - }; - function d3_bisector(compare) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - } - var d3_bisect = d3_bisector(d3_ascending); - d3.bisectLeft = d3_bisect.left; - d3.bisect = d3.bisectRight = d3_bisect.right; - d3.bisector = function(f) { - return d3_bisector(f.length === 1 ? function(d, x) { - return d3_ascending(f(d), x); - } : f); - }; - d3.shuffle = function(array, i0, i1) { - if ((m = arguments.length) < 3) { - i1 = array.length; - if (m < 2) i0 = 0; - } - var m = i1 - i0, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; + }, { + key: "getData", + value: function getData(props) { + if (props.data) { + return props.data; } + var x = this.returnOrGenerateX(props); + var y = this.returnOrGenerateY(props, x); + var n = _lodash2["default"].min([x.length, y.length]); + // create a dataset from x and y with n points + var dataset = _lodash2["default"].zip(_lodash2["default"].take(x, n), _lodash2["default"].take(y, n)); + // return data as an array of objects + return _lodash2["default"].map(dataset, function (point) { + return { x: point[0], y: point[1] }; + }); } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - var n = arrays.length, m, i = -1, j = 0, merged, array; - while (++i < n) j += arrays[i].length; - merged = new Array(j); - while (--n >= 0) { - array = arrays[n]; - m = array.length; - while (--m >= 0) { - merged[--j] = array[m]; + }, { + key: "returnOrGenerateX", + value: function returnOrGenerateX(props) { + if (props.x) { + return props.x; } + // if x is not given in props, create an array of values evenly + // spaced across the x domain + var domainFromProps = props.domain && props.domain.x || props.domain; + var domainFromScale = props.scale && props.scale.x ? props.scale.x.domain() : props.scale.domain(); + var domain = domainFromProps || domainFromScale; + var samples = _lodash2["default"].isArray(props.y) ? props.y.length : props.samples; + var step = _lodash2["default"].max(domain) / samples; + // return an array of x values spaced across the domain, + // include the maximum of the domain + var xArray = _lodash2["default"].union(_lodash2["default"].range(_lodash2["default"].min(domain), _lodash2["default"].max(domain), step), [_lodash2["default"].max(domain)]); + return _lodash2["default"].filter(xArray, function (x) { + return x !== 0; + }); } - return merged; - }; - var abs = Math.abs; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; + }, { + key: "returnOrGenerateY", + value: function returnOrGenerateY(props, x) { + if (_lodash2["default"].isFunction(props.y)) { + // if y is a function, apply the function y to to each value of the array x, + // and return the results as an array + return _lodash2["default"].map(x, function (datum) { + return props.y(datum); + }); } + // y is either a function or an array, and is never undefined + // if it isn't a function, just return it. + return props.y; } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } - d3.map = function(object, f) { - var map = new d3_Map(); - if (object instanceof d3_Map) { - object.forEach(function(key, value) { - map.set(key, value); + }, { + key: "getDataSegments", + value: function getDataSegments() { + var orderedData = _lodash2["default"].sortBy(this.dataset, "x"); + var segments = []; + var segmentStartIndex = 0; + _lodash2["default"].each(orderedData, function (datum, index) { + if (_lodash2["default"].isNull(datum.y) || _lodash2["default"].isUndefined(datum.y)) { + segments.push(orderedData.slice(segmentStartIndex, index)); + segmentStartIndex = index + 1; + } }); - } else if (Array.isArray(object)) { - var i = -1, n = object.length, o; - if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); - } else { - for (var key in object) map.set(key, object[key]); - } - return map; - }; - function d3_Map() { - this._ = Object.create(null); - } - var d3_map_proto = "__proto__", d3_map_zero = "\x00"; - d3_class(d3_Map, { - has: d3_map_has, - get: function(key) { - return this._[d3_map_escape(key)]; - }, - set: function(key, value) { - return this._[d3_map_escape(key)] = value; - }, - remove: d3_map_remove, - keys: d3_map_keys, - values: function() { - var values = []; - for (var key in this._) values.push(this._[key]); - return values; - }, - entries: function() { - var entries = []; - for (var key in this._) entries.push({ - key: d3_map_unescape(key), - value: this._[key] + segments.push(orderedData.slice(segmentStartIndex, orderedData.length)); + return _lodash2["default"].filter(segments, function (segment) { + return !_lodash2["default"].isEmpty(segment); }); - return entries; - }, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); } - }); - function d3_map_escape(key) { - return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; - } - function d3_map_unescape(key) { - return (key += "")[0] === d3_map_zero ? key.slice(1) : key; - } - function d3_map_has(key) { - return d3_map_escape(key) in this._; - } - function d3_map_remove(key) { - return (key = d3_map_escape(key)) in this._ && delete this._[key]; - } - function d3_map_keys() { - var keys = []; - for (var key in this._) keys.push(d3_map_unescape(key)); - return keys; - } - function d3_map_size() { - var size = 0; - for (var key in this._) ++size; - return size; - } - function d3_map_empty() { - for (var key in this._) return false; - return true; - } - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; + }, { + key: "getLabelStyle", + value: function getLabelStyle() { + // match labels styles to data style by default (fill, opacity, others?) + var opacity = this.style.data.opacity; + // match label color to data color if it is not given. + // use fill instead of stroke for text + var fill = this.style.data.stroke; + var padding = this.style.labels.padding || 0; + return _lodash2["default"].merge({ opacity: opacity, fill: fill, padding: padding }, this.style.labels); } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) + }, { + key: "renderLine", + value: function renderLine() { + var _this = this; + + return _lodash2["default"].map(this.dataSegments, function (segment, index) { + return _react2["default"].createElement(_lineSegment2["default"], { + key: "line-segment-" + index, + data: segment, + interpolation: _this.props.interpolation, + scale: _this.scale, + style: _this.style.data }); }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() { - this._ = Object.create(null); - } - d3_class(d3_Set, { - has: d3_map_has, - add: function(key) { - this._[d3_map_escape(key += "")] = true; - return key; - }, - remove: d3_map_remove, - values: d3_map_keys, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key)); - } - }); - d3.behavior = {}; - function d3_identity(d) { - return d; - } - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.slice(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.slice(i + 1); - type = type.slice(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); + }, { + key: "renderLabel", + value: function renderLabel() { + if (!this.props.label) { + return undefined; } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } + var position = { + x: this.scale.x.call(this, _lodash2["default"].last(_lodash2["default"].flatten(this.dataSegments)).x), + y: this.scale.y.call(this, _lodash2["default"].last(_lodash2["default"].flatten(this.dataSegments)).y) }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatches = function(n, s) { - var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")]; - d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - return d3_selectMatches(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = Sizzle; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3.select(d3_document.documentElement); - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; + return _react2["default"].createElement(_lineLabel2["default"], { + key: "line-label", + data: this.dataset, + position: position, + label: this.props.label, + style: this.getLabelStyle() + }); } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); + }, { + key: "renderData", + value: function renderData() { + return _react2["default"].createElement( + "g", + { style: this.style.parent }, + this.renderLine(), + this.renderLabel() + ); } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; + }, { + key: "render", + value: function render() { + var _this2 = this; + + // If animating, return a `VictoryAnimation` element that will create + // a new `VictoryLine` with nearly identical props, except (1) tweened + // and (2) `animate` set to null so we don't recurse forever. + if (this.props.animate) { + // Do less work by having `VictoryAnimation` tween only values that + // make sense to tween. In the future, allow customization of animated + // prop whitelist/blacklist? + var animateData = _lodash2["default"].pick(this.props, ["data", "domain", "height", "padding", "samples", "style", "width", "x", "y"]); + return _react2["default"].createElement( + _victoryAnimation.VictoryAnimation, + _extends({}, this.props.animate, { data: animateData }), + function (props) { + return _react2["default"].createElement(VictoryLine, _extends({}, _this2.props, props, { animate: null })); + } + ); + } else { + this.getCalculatedValues(this.props); } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; + var style = this.style.parent; + var group = _react2["default"].createElement( + "g", + { style: style }, + this.renderData() + ); + return this.props.standalone ? _react2["default"].createElement( + "svg", + { style: style }, + group + ) : group; } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classes(name) { - return (name + "").trim().split(/^|\s+/); - } - function d3_selection_classed(name, value) { - name = d3_selection_classes(name).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); + }], [{ + key: "role", + value: "line", + enumerable: true + }, { + key: "propTypes", + value: { + /** + * The animate prop specifies props for victory-animation to use. It this prop is + * not given, the line will not tween between changing data / style props. + * Large datasets might animate slowly due to the inherent limits of svg rendering. + * @examples {velocity: 0.02, onEnd: () => alert("done!")} + */ + animate: _react.PropTypes.object, + /** + * The data prop specifies the data to be plotted. Data should be in the form of an array + * of data points where each data point should be an object with x and y properties. + * @examples [{x: 1, y: 12}, {x: 10, y: 25}, {x: 100, y: 34}] + */ + data: _react.PropTypes.arrayOf(_react.PropTypes.shape({ + x: _react.PropTypes.any, + y: _react.PropTypes.any + })), + /** + * The domain prop describes the range of values your chart will include. This prop can be + * given as a array of the minimum and maximum expected values for your chart, + * or as an object that specifies separate arrays for x and y. + * If this prop is not provided, a domain will be calculated from data, or other + * available information. + * @examples [-1, 1], {x: [0, 100], y: [0, 1]} + */ + domain: _react.PropTypes.oneOfType([_victoryUtil2["default"].PropTypes.domain, _react.PropTypes.shape({ + x: _victoryUtil2["default"].PropTypes.domain, + y: _victoryUtil2["default"].PropTypes.domain + })]), + /** + * The height props specifies the height of the chart container element in pixels + */ + height: _victoryUtil2["default"].PropTypes.nonNegative, + /** + * The interpolation prop determines how data points should be connected + * when plotting a line + */ + interpolation: _react.PropTypes.oneOf(["basis", "basisClosed", "basisOpen", "bundle", "cardinal", "cardinalClosed", "cardinalOpen", "catmullRom", "catmullRomClosed", "catmullRomOpen", "linear", "linearClosed", "monotone", "natural", "radial", "step", "stepAfter", "stepBefore"]), + /** + * The label prop specifies a label to display at the end of a line component, + * this prop can be given as a value, or as an entire label component + */ + label: _react.PropTypes.any, + /** + * The padding props specifies the amount of padding in number of pixels between + * the edge of the chart and any rendered child components. This prop can be given + * as a number or as an object with padding specified for top, bottom, left + * and right. + */ + padding: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.shape({ + top: _react.PropTypes.number, + bottom: _react.PropTypes.number, + left: _react.PropTypes.number, + right: _react.PropTypes.number + })]), + /** + * The samples prop specifies how many individual points to plot when plotting + * y as a function of x. Samples is ignored if x props are provided instead. + */ + samples: _victoryUtil2["default"].PropTypes.nonNegative, + /** + * The scale prop determines which scales your chart should use. This prop can be + * given as a function, or as an object that specifies separate functions for x and y. + * @examples d3Scale.time(), {x: d3Scale.linear(), y: d3Scale.log()} + */ + scale: _react.PropTypes.oneOfType([_victoryUtil2["default"].PropTypes.scale, _react.PropTypes.shape({ + x: _victoryUtil2["default"].PropTypes.scale, + y: _victoryUtil2["default"].PropTypes.scale + })]), + /** + * The standalone prop determines whether the component will render a standalone svg + * or a tag that will be included in an external svg. Set standalone to false to + * compose VictoryLine with other components within an enclosing tag. + */ + standalone: _react.PropTypes.bool, + /** + * The style prop specifies styles for your chart. VictoryLine relies on Radium, + * so valid Radium style objects should work for this prop, however height, width, and margin + * are used to calculate range, and need to be expressed as a number of pixels + * @examples {data: {stroke: "red"}, labels: {fontSize: 14}} + */ + style: _react.PropTypes.shape({ + parent: _react.PropTypes.object, + data: _react.PropTypes.object, + labels: _react.PropTypes.object + }), + /** + * The width props specifies the width of the chart container element in pixels + */ + width: _victoryUtil2["default"].PropTypes.nonNegative, + /** + * The x prop provides another way to supply data for line to plot. This prop can be given + * as an array of values, and it will be plotted against whatever y prop is provided. If no + * props are provided for y, the values in x will be plotted as the identity function (x) => x. + * @examples [1, 2, 3] + */ + x: _victoryUtil2["default"].PropTypes.homogeneousArray, + /** + * The y prop provides another way to supply data for line to plot. This prop can be given + * as a function of x, or an array of values. If x props are given, they will be used + * in plotting (x, y) data points. If x props are not provided, a set of x values + * evenly spaced across the x domain will be calculated, and used for plotting data points. + * @examples (x) => Math.sin(x), [1, 2, 3] + */ + y: _react.PropTypes.oneOfType([_react.PropTypes.array, _react.PropTypes.func]) + }, + enumerable: true + }, { + key: "defaultProps", + value: { + height: 300, + interpolation: "linear", + padding: 50, + samples: 50, + scale: _d3Scale2["default"].linear(), + standalone: true, + width: 450, + y: function y(x) { + return x; } - }; + }, + enumerable: true + }]); + + var _VictoryLine = VictoryLine; + VictoryLine = (0, _radium2["default"])(VictoryLine) || VictoryLine; + return VictoryLine; + })(_react2["default"].Component); + + exports["default"] = VictoryLine; + module.exports = exports["default"]; + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _lodash = __webpack_require__(4); + + var _lodash2 = _interopRequireDefault(_lodash); + + var _react = __webpack_require__(6); + + var _react2 = _interopRequireDefault(_react); + + var _radium = __webpack_require__(7); + + var _radium2 = _interopRequireDefault(_radium); + + var _d3Shape = __webpack_require__(32); + + var _d3Shape2 = _interopRequireDefault(_d3Shape); + + var LineSegment = (function (_React$Component) { + _inherits(LineSegment, _React$Component); + + function LineSegment() { + _classCallCheck(this, _LineSegment); + + _get(Object.getPrototypeOf(_LineSegment.prototype), "constructor", this).apply(this, arguments); } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) { - var node = this.node(); - return d3_window(node).getComputedStyle(node, null).getPropertyValue(name); - } - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); + + _createClass(LineSegment, [{ + key: "evaluateStyle", + value: function evaluateStyle(style) { + var _this = this; + + return _lodash2["default"].transform(style, function (result, value, key) { + result[key] = _this.evaluateProp(value); + }); } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; + }, { + key: "evaluateProp", + value: function evaluateProp(prop) { + return _lodash2["default"].isFunction(prop) ? prop.call(this, this.props.data) : prop; } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - function create() { - var document = this.ownerDocument, namespace = this.namespaceURI; - return namespace ? document.createElementNS(namespace, name) : document.createElement(name); + }, { + key: "getCalculatedValues", + value: function getCalculatedValues(props) { + this.style = this.evaluateStyle(props.style); + this.interpolation = this.evaluateProp(props.interpolation); + var xScale = props.scale.x; + var yScale = props.scale.y; + var lineFunction = _d3Shape2["default"].line().curve(_d3Shape2["default"][this.interpolation]).x(function (data) { + return xScale(data.x); + }).y(function (data) { + return yScale(data.y); + }); + this.path = lineFunction(props.data); } - function createNS() { - return this.ownerDocument.createElementNS(name.space, name.local); + }, { + key: "renderLine", + value: function renderLine() { + return _react2["default"].createElement("path", { style: this.style, d: this.path }); } - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(d3_selectionRemove); - }; - function d3_selectionRemove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - } - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; + }, { + key: "render", + value: function render() { + this.getCalculatedValues(this.props); + return this.renderLine(); } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue; - for (i = -1; ++i < n; ) { - if (node = group[i]) { - if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues[i] = keyValue; - } - } - for (i = -1; ++i < m; ) { - if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } else if (node !== true) { - updateNodes[i] = node; - node.__data__ = nodeData; - } - nodeByKeyValue.set(keyValue, true); - } - for (i = -1; ++i < n; ) { - if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3_ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - d3_selection_each(this, function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3.select = function(node) { - var group; - if (typeof node === "string") { - group = [ d3_select(node, d3_document) ]; - group.parentNode = d3_document.documentElement; - } else { - group = [ node ]; - group.parentNode = d3_documentElement(node); - } - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group; - if (typeof nodes === "string") { - group = d3_array(d3_selectAll(nodes, d3_document)); - group.parentNode = d3_document.documentElement; - } else { - group = d3_array(nodes); - group.parentNode = null; - } - return d3_selection([ group ]); - }; - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.slice(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - if (d3_document) { - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - } - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect, d3_event_dragId = 0; - function d3_event_dragSuppress(node) { - var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); - if (d3_event_dragSelect == null) { - d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect"); - } - if (d3_event_dragSelect) { - var style = d3_documentElement(node).style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - } - return function(suppressClick) { - w.on(name, null); - if (d3_event_dragSelect) style[d3_event_dragSelect] = select; - if (suppressClick) { - var off = function() { - w.on(click, null); - }; - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0) { - var window = d3_window(container); - if (window.scrollX || window.scrollY) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, - point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touch = function(container, touches, identifier) { - if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; - if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { - if ((touch = touches[i]).identifier === identifier) { - return d3_mousePoint(container, touch); - } - } - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function dragstart(id, position, subject, move, end) { - return function() { - var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId); - if (origin) { - dragOffset = origin.apply(that, arguments); - dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; - } else { - dragOffset = [ 0, 0 ]; - } - dispatch({ - type: "dragstart" - }); - function moved() { - var position1 = position(parent, dragId), dx, dy; - if (!position1) return; - dx = position1[0] - position0[0]; - dy = position1[1] - position0[1]; - dragged |= dx | dy; - position0 = position1; - dispatch({ - type: "drag", - x: position1[0] + dragOffset[0], - y: position1[1] + dragOffset[1], - dx: dx, - dy: dy - }); - } - function ended() { - if (!position(parent, dragId)) return; - dragSubject.on(move + dragName, null).on(end + dragName, null); - dragRestore(dragged); - dispatch({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - function d3_behavior_dragTouchId() { - return d3.event.changedTouches[0].identifier; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_cross2d(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); - } - function d3_sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; - } - function d3_cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; - } - function d3_tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S; - if (d2 < ε2) { - S = Math.log(w1 / w0) / ρ; - i = function(t) { - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * t * S) ]; - }; - } else { - var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); - S = (r1 - r0) / ρ; - i = function(t) { - var s = t * S, coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; - }; - } - i.duration = S * 1e3; - return i; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - if (!d3_behavior_zoomWheel) { - d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - } - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var dispatch = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(dispatch); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(dispatch); - }; - }).each("interrupt.zoom", function() { - zoomended(dispatch); - }).each("end.zoom", function() { - zoomended(dispatch); - }); - } else { - this.__chart__ = view; - zoomstarted(dispatch); - zoomed(dispatch); - zoomended(dispatch); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: null - }; - scaleTo(+_); - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.duration = function(_) { - if (!arguments.length) return duration; - duration = +_; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function zoomTo(that, p, l, k) { - that.__chart__ = { - x: view.x, - y: view.y, - k: view.k - }; - scaleTo(Math.pow(2, k)); - translateTo(center0 = p, l); - that = d3.select(that); - if (duration > 0) that = that.transition().duration(duration); - that.call(zoom.event); - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(dispatch) { - if (!zooming++) dispatch({ - type: "zoomstart" - }); - } - function zoomed(dispatch) { - rescale(); - dispatch({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(dispatch) { - if (!--zooming) dispatch({ - type: "zoomend" - }), center0 = null; - } - function mousedowned() { - var that = this, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that); - d3_selection_interrupt.call(that); - zoomstarted(dispatch); - function moved() { - dragged = 1; - translateTo(d3.mouse(that), location0); - zoomed(dispatch); - } - function ended() { - subject.on(mousemove, null).on(mouseup, null); - dragRestore(dragged); - zoomended(dispatch); - } - } - function touchstarted() { - var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that); - started(); - zoomstarted(dispatch); - subject.on(mousedown, null).on(touchstart, started); - function relocate() { - var touches = d3.touches(that); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var target = d3.event.target; - d3.select(target).on(touchmove, moved).on(touchend, ended); - targets.push(target); - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0]; - zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1); - d3_eventPreventDefault(); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(that), p0, l0, p1, l1; - d3_selection_interrupt.call(that); - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(dispatch); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - d3.selectAll(targets).on(zoomName, null); - subject.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(dispatch); - } - } - function mousewheeled() { - var dispatch = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), - translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(dispatch); - }, 50); - d3_eventPreventDefault(); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(center0, translate0); - zoomed(dispatch); - } - function dblclicked() { - var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2; - zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel; - d3.color = d3_color; - function d3_color() {} - d3_color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = d3_hsl; - function d3_hsl(h, s, l) { - return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l); - } - var d3_hslPrototype = d3_hsl.prototype = new d3_color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return new d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = d3_hcl; - function d3_hcl(h, c, l) { - return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l); - } - var d3_hclPrototype = d3_hcl.prototype = new d3_color(); - d3_hclPrototype.brighter = function(k) { - return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = d3_lab; - function d3_lab(l, a, b) { - return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b); - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_lab.prototype = new d3_color(); - d3_labPrototype.brighter = function(k) { - return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = d3_rgb; - function d3_rgb(r, g, b) { - return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b); - } - function d3_rgbNumber(value) { - return new d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - var d3_rgbPrototype = d3_rgb.prototype = new d3_color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return new d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k)); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_rgb(k * this.r, k * this.g, k * this.b); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, color; - m1 = /([a-z]+)\((.*)\)/.exec(format = format.toLowerCase()); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (color = d3_rgb_names.get(format)) { - return rgb(color.r, color.g, color.b); - } - if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) { - if (format.length === 4) { - r = (color & 3840) >> 4; - r = r >> 4 | r; - g = color & 240; - g = g >> 4 | g; - b = color & 15; - b = b << 4 | b; - } else if (format.length === 7) { - r = (color & 16711680) >> 16; - g = (color & 65280) >> 8; - b = color & 255; - } - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return new d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - rebeccapurple: 6697881, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - function d3_xhrHasResponse(request) { - var type = request.responseType; - return type && type !== "text" ? request.response : request.responseText; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr; - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.slice(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.slice(j, I - k); - } - return text.slice(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && (a = f(a, n++)) == null) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function() { - d3_timer.apply(this, arguments); - }; - function d3_timer(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - c: callback, - t: time, - n: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - return timer; - } - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_mark() { - var now = Date.now(), timer = d3_timer_queueHead; - while (timer) { - if (now >= timer.t && timer.c(now - timer.t)) timer.c = null; - timer = timer.n; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.c) { - if (t1.t < time) time = t1.t; - t1 = (t0 = t1).n; - } else { - t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; - } - } - d3_timer_queueTail = t0; - return time; - } - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value = +value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - function d3_locale_numberFormat(locale) { - var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) { - var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0; - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = locale_grouping[j = (j + 1) % locale_grouping.length]; - } - return t.reverse().join(locale_thousands); - } : d3_identity; - return function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") prefix = "0" + type.toLowerCase(); - - case "c": - exponent = false; - - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - var fullSuffix = suffix; - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign; - if (scale < 0) { - var unit = d3.formatPrefix(value, precision); - value = unit.scale(value); - fullSuffix = unit.symbol + suffix; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before, after; - if (i < 0) { - var j = exponent ? value.lastIndexOf("e") : -1; - if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j); - } else { - before = value.substring(0, i); - after = locale_decimal + value.substring(i + 1); - } - if (!zfill && comma) before = formatGroup(before, Infinity); - var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity); - negative += prefix; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; - }; - }; - } - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_time = d3.time = {}, d3_date = Date; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - function d3_locale_timeFormat(locale) { - var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.slice(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.slice(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("W" in d || "U" in d) { - if (!("w" in d)) d.w = "W" in d ? 1 : 0; - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - d3_time_format.utc = function(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - }; - d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; - var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); - locale_periods.forEach(function(p, i) { - d3_time_periodLookup.set(p.toLowerCase(), i); - }); - var d3_time_formats = { - a: function(d) { - return locale_shortDays[d.getDay()]; - }, - A: function(d) { - return locale_days[d.getDay()]; - }, - b: function(d) { - return locale_shortMonths[d.getMonth()]; - }, - B: function(d) { - return locale_months[d.getMonth()]; - }, - c: d3_time_format(locale_dateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return locale_periods[+(d.getHours() >= 12)]; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(locale_date), - X: d3_time_format(locale_time), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - return d3_time_format; - } - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.slice(i, i + 1)); - return n ? i + n[0].length : -1; - } - function d3_time_formatMulti(formats) { - var n = formats.length, i = -1; - while (++i < n) formats[i][0] = this(formats[i][0]); - return function(date) { - var i = 0, f = formats[i]; - while (!f[1](date)) f = formats[++i]; - return f[0](date); - }; - } - d3.locale = function(locale) { - return { - numberFormat: d3_locale_numberFormat(locale), - timeFormat: d3_locale_timeFormat(locale) - }; - }; - var d3_locale_enUS = d3.locale({ - decimal: ".", - thousands: ",", - grouping: [ 3 ], - currency: [ "$", "" ], - dateTime: "%a %b %e %X %Y", - date: "%m/%d/%Y", - time: "%H:%M:%S", - periods: [ "AM", "PM" ], - days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], - shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] - }); - d3.format = d3_locale_enUS.numberFormat; - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; - var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); - a.o = b; - subject.push(a); - clip.push(b); - a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); - b = new d3_geo_clipPolygonIntersection(p1, null, a, true); - a.o = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { - clip[i].e = entry = !entry; - } - var start = subject[0], points, point; - while (1) { - var current = start, isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - listener.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, listener); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, listener); - } - current = current.p; - } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; - } - function d3_geo_clipPolygonIntersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; - this.e = entry; - this.v = false; - this.n = this.p = null; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { - return function(rotate, listener) { - var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); - if (segments.length) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); - } else if (clipStartInside) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (polygonStarted) listener.polygonEnd(), polygonStarted = false; - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - var point = rotate(λ, φ); - if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); - } - function pointLine(λ, φ) { - var point = rotate(λ, φ); - line.point(point[0], point[1]); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; - function pointRing(λ, φ) { - ring.push([ λ, φ ]); - var point = rotate(λ, φ); - ringListener.point(point[0], point[1]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - if (n > 0) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - } - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); - if (abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * halfπ; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (abs(from[0] - to[0]) > ε) { - var s = from[0] < to[0] ? π : -π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); - polarAngle += antimeridian ? dλ + sdλ * τ : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - } - function d3_geom_clipLine(x0, y0, x1, y1) { - return function(line) { - var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - if (t0 > 0) line.a = { - x: ax + t0 * dx, - y: ay + t0 * dy - }; - if (t1 < 1) line.b = { - x: ax + t1 * dx, - y: ay + t1 * dy - }; - return line; - }; - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - clean = true; - }, - polygonEnd: function() { - listener = listener_; - segments = d3.merge(segments); - var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; - if (inside || visible) { - listener.polygonStart(); - if (inside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (visible) { - d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); - } - listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function pointVisible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (pointVisible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first, clean; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = pointVisible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var l = { - a: { - x: x_, - y: y_ - }, - b: { - x: x, - y: y - } - }; - if (clipLine(l)) { - if (!v_) { - listener.lineStart(); - listener.point(l.a.x, l.a.y); - } - listener.point(l.b.x, l.b.y); - if (!v) listener.lineEnd(); - clean = false; - } else if (v) { - listener.lineStart(); - listener.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.x, b.x); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x + pointRadius, y); - context.arc(x, y, pointRadius, 0, τ); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - return (maxDepth ? resampleRecursive : resampleNone)(stream); - } - function resampleNone(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - }); - } - function resampleRecursive(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - return d3_geo_projectionRadians(resample(stream)); - }; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - function d3_geo_transformPoint(stream, point) { - return { - point: point, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadians(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }); - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_identityRotation(λ, φ) { - return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - } - d3_geo_identityRotation.invert = d3_geo_equirectangular; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * τ; - } else { - from = radius + direction * τ; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(π / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - if (F > 0) { - if (φ < -halfπ + ε) φ = -halfπ + ε; - } else { - if (φ > halfπ - ε) φ = halfπ - ε; - } - var ρ = F / Math.pow(t(φ), n); - return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var ρ = G - φ; - return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; + }], [{ + key: "propTypes", + value: { + data: _react.PropTypes.array, + interpolation: _react.PropTypes.string, + scale: _react.PropTypes.object, + style: _react.PropTypes.object + }, + enumerable: true + }]); + + var _LineSegment = LineSegment; + LineSegment = (0, _radium2["default"])(LineSegment) || LineSegment; + return LineSegment; + })(_react2["default"].Component); + + exports["default"] = LineSegment; + module.exports = exports["default"]; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** + * @license + * lodash 3.10.1 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * 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.10.1'; + + /** 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, + ARY_FLAG = 128, + REARG_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 as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_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 property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; + + /** 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 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 + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** 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', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; + + /** 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 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' }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' }; - (d3.geo.transverseMercator = function() { - var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; - projection.center = function(_) { - return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]); - }; - projection.rotate = function(_) { - return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), - [ _[0], _[1], _[2] - 90 ]); - }; - return rotate([ 0, 0, 90 ]); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - function d3_geom_pointX(d) { - return d[0]; - } - function d3_geom_pointY(d) { - return d[1]; - } - d3.geom.hull = function(vertices) { - var x = d3_geom_pointX, y = d3_geom_pointY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; - for (i = 0; i < n; i++) { - points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); - } - points.sort(d3_geom_hullOrder); - for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); - var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); - var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; - for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); - for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); - return polygon; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' }; - function d3_geom_hullUpper(points) { - var n = points.length, hull = [ 0, 1 ], hs = 2; - for (var i = 2; i < n; i++) { - while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; - hull[hs++] = i; - } - return hull.slice(0, hs); - } - function d3_geom_hullOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; + + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; + + /** 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. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * 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. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; - function d3_geom_voronoiBeach() { - d3_geom_voronoiRedBlackNode(this); - this.edge = this.site = this.circle = null; - } - function d3_geom_voronoiCreateBeach(site) { - var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); - beach.site = site; - return beach; - } - function d3_geom_voronoiDetachBeach(beach) { - d3_geom_voronoiDetachCircle(beach); - d3_geom_voronoiBeaches.remove(beach); - d3_geom_voronoiBeachPool.push(beach); - d3_geom_voronoiRedBlackNode(beach); - } - function d3_geom_voronoiRemoveBeach(beach) { - var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { - x: x, - y: y - }, previous = beach.P, next = beach.N, disappearing = [ beach ]; - d3_geom_voronoiDetachBeach(beach); - var lArc = previous; - while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { - previous = lArc.P; - disappearing.unshift(lArc); - d3_geom_voronoiDetachBeach(lArc); - lArc = previous; - } - disappearing.unshift(lArc); - d3_geom_voronoiDetachCircle(lArc); - var rArc = next; - while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { - next = rArc.N; - disappearing.push(rArc); - d3_geom_voronoiDetachBeach(rArc); - rArc = next; - } - disappearing.push(rArc); - d3_geom_voronoiDetachCircle(rArc); - var nArcs = disappearing.length, iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiAddBeach(site) { - var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; - while (node) { - dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; - if (dxl > ε) node = node.L; else { - dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); - if (dxr > ε) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -ε) { - lArc = node.P; - rArc = node; - } else if (dxr > -ε) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; } } - var newArc = d3_geom_voronoiCreateBeach(site); - d3_geom_voronoiBeaches.insert(lArc, newArc); - if (!lArc && !rArc) return; - if (lArc === rArc) { - d3_geom_voronoiDetachCircle(lArc); - rArc = d3_geom_voronoiCreateBeach(lArc.site); - d3_geom_voronoiBeaches.insert(newArc, rArc); - newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - return; - } - if (!rArc) { - newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - return; - } - d3_geom_voronoiDetachCircle(lArc); - d3_geom_voronoiDetachCircle(rArc); - var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { - x: (cy * hb - by * hc) / d + ax, - y: (bx * hc - cx * hb) / d + ay - }; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); - rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiLeftBreakPoint(arc, directrix) { - var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; - if (!pby2) return rfocx; - var lArc = arc.P; - if (!lArc) return -Infinity; - site = lArc.site; - var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; - if (!plby2) return lfocx; - var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - return (rfocx + lfocx) / 2; - } - function d3_geom_voronoiRightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - } - function d3_geom_voronoiCell(site) { - this.site = site; - this.edges = []; - } - d3_geom_voronoiCell.prototype.prepare = function() { - var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; - while (iHalfEdge--) { - edge = halfEdges[iHalfEdge].edge; - if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); - } - halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); - return halfEdges.length; - }; - function d3_geom_voronoiCloseCells(extent) { - var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; - while (iCell--) { - cell = cells[iCell]; - if (!cell || !cell.prepare()) continue; - halfEdges = cell.edges; - nHalfEdges = halfEdges.length; - iHalfEdge = 0; - while (iHalfEdge < nHalfEdges) { - end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; - start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; - if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { - halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { - x: x0, - y: abs(x2 - x0) < ε ? y2 : y1 - } : abs(y3 - y1) < ε && x1 - x3 > ε ? { - x: abs(y2 - y1) < ε ? x2 : x1, - y: y1 - } : abs(x3 - x1) < ε && y3 - y0 > ε ? { - x: x1, - y: abs(x2 - x1) < ε ? y2 : y0 - } : abs(y3 - y0) < ε && x3 - x0 > ε ? { - x: abs(y2 - y0) < ε ? x2 : x0, - y: y0 - } : null), cell.site, null)); - ++nHalfEdges; - } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; } } + return -1; } - function d3_geom_voronoiHalfEdgeOrder(a, b) { - return b.angle - a.angle; - } - function d3_geom_voronoiCircle() { - d3_geom_voronoiRedBlackNode(this); - this.x = this.y = this.arc = this.site = this.cy = null; - } - function d3_geom_voronoiAttachCircle(arc) { - var lArc = arc.P, rArc = arc.N; - if (!lArc || !rArc) return; - var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; - if (lSite === rSite) return; - var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; - var d = 2 * (ax * cy - ay * cx); - if (d >= -ε2) return; - var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; - var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = cy + Math.sqrt(x * x + y * y); - circle.cy = cy; - arc.circle = circle; - var before = null, node = d3_geom_voronoiCircles._; - while (node) { - if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { - if (node.L) node = node.L; else { - before = node.P; - break; - } - } else { - if (node.R) node = node.R; else { - before = node; - break; - } - } + + /** + * 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 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); } - d3_geom_voronoiCircles.insert(before, circle); - if (!before) d3_geom_voronoiFirstCircle = circle; - } - function d3_geom_voronoiDetachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; - d3_geom_voronoiCircles.remove(circle); - d3_geom_voronoiCirclePool.push(circle); - d3_geom_voronoiRedBlackNode(circle); - arc.circle = null; - } - } - function d3_geom_voronoiClipEdges(extent) { - var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; - while (i--) { - e = edges[i]; - if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { - e.a = e.b = null; - edges.splice(i, 1); - } - } - } - function d3_geom_voronoiConnectEdge(edge, extent) { - var vb = edge.b; - if (vb) return true; - var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!va) va = { - x: fx, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: fx, - y: y1 - }; - } else { - if (!va) va = { - x: fx, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: fx, - y: y0 - }; + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!va) va = { - x: (y0 - fb) / fm, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: (y1 - fb) / fm, - y: y1 - }; - } else { - if (!va) va = { - x: (y1 - fb) / fm, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: (y0 - fb) / fm, - y: y0 - }; - } - } else { - if (ly < ry) { - if (!va) va = { - x: x0, - y: fm * x0 + fb - }; else if (va.x >= x1) return; - vb = { - x: x1, - y: fm * x1 + fb - }; - } else { - if (!va) va = { - x: x1, - y: fm * x1 + fb - }; else if (va.x < x0) return; - vb = { - x: x0, - y: fm * x0 + fb - }; + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(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; + } + + /** + * Converts `value` to a string if it's 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) { + return value == null ? '' : (value + ''); + } + + /** + * 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. + * @param {Object} other The other object to compare. + * @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 `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); } } - edge.a = va; - edge.b = vb; - return true; - } - function d3_geom_voronoiEdge(lSite, rSite) { - this.l = lSite; - this.r = rSite; - this.a = this.b = null; - } - function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, rSite); - d3_geom_voronoiEdges.push(edge); - if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); - if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); - d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); - d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); - return edge; - } - function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, null); - edge.a = va; - edge.b = vb; - d3_geom_voronoiEdges.push(edge); - return edge; - } - function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { - if (!edge.a && !edge.b) { - edge.a = vertex; - edge.l = lSite; - edge.r = rSite; - } else if (edge.l === rSite) { - edge.b = vertex; - } else { - edge.a = vertex; - } + // 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]; } - function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { - var va = edge.a, vb = edge.b; - this.edge = edge; - this.site = lSite; - this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); + + /** + * 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]; } - d3_geom_voronoiHalfEdge.prototype = { - start: function() { - return this.edge.l === this.site ? this.edge.a : this.edge.b; - }, - end: function() { - return this.edge.l === this.site ? this.edge.b : this.edge.a; + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; } - }; - function d3_geom_voronoiRedBlackTree() { - this._ = null; - } - function d3_geom_voronoiRedBlackNode(node) { - node.U = node.C = node.L = node.R = node.P = node.N = null; - } - d3_geom_voronoiRedBlackTree.prototype = { - insert: function(after, node) { - var parent, grandpa, uncle; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = d3_geom_voronoiRedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - d3_geom_voronoiRedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - d3_geom_voronoiRedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; - var parent = node.U, sibling, left = node.L, right = node.R, next, red; - if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); - if (parent) { - if (parent.L === node) parent.L = next; else parent.R = next; - } else { - this._ = next; - } - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } - if (node) node.U = parent; - if (red) return; - if (node && node.C) { - node.C = false; - return; + return '\\' + 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`. + * + * @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 = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; } - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateRight(this, parent); - sibling = parent.L; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - d3_geom_voronoiRedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); - if (node) node.C = false; } - }; - function d3_geom_voronoiRedBlackRotateLeft(tree, node) { - var p = node, q = node.R, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; - } - function d3_geom_voronoiRedBlackRotateRight(tree, node) { - var p = node, q = node.L, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; - } - function d3_geom_voronoiRedBlackFirst(node) { - while (node.L) node = node.L; - return node; - } - function d3_geom_voronoi(sites, bbox) { - var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; - d3_geom_voronoiEdges = []; - d3_geom_voronoiCells = new Array(sites.length); - d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); - d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); - while (true) { - circle = d3_geom_voronoiFirstCircle; - if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { - if (site.x !== x0 || site.y !== y0) { - d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); - d3_geom_voronoiAddBeach(site); - x0 = site.x, y0 = site.y; - } - site = sites.pop(); - } else if (circle) { - d3_geom_voronoiRemoveBeach(circle.arc); - } else { - break; + 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'; + } + + /** + * 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; } } - if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); - var diagram = { - cells: d3_geom_voronoiCells, - edges: d3_geom_voronoiEdges - }; - d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; - return diagram; - } - function d3_geom_voronoiVertexOrder(a, b) { - return b.y - a.y || b.x - a.x; - } - d3.geom.voronoi = function(points) { - var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; - if (points) return voronoi(points); - function voronoi(data) { - var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; - d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { - var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { - var s = e.start(); - return [ s.x, s.y ]; - }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; - polygon.point = data[i]; - }); - return polygons; - } - function sites(data) { - return data.map(function(d, i) { - return { - x: Math.round(fx(d, i) / ε) * ε, - y: Math.round(fy(d, i) / ε) * ε, - i: i - }; - }); - } - voronoi.links = function(data) { - return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { - return edge.l && edge.r; - }).map(function(edge) { - return { - source: data[edge.l.i], - target: data[edge.r.i] - }; - }); - }; - voronoi.triangles = function(data) { - var triangles = []; - d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { - var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; - while (++j < m) { - e0 = e1; - s0 = s1; - e1 = edges[j].edge; - s1 = e1.l === site ? e1.r : e1.l; - if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { - triangles.push([ data[i], data[s0.i], data[s1.i] ]); - } - } - }); - return triangles; - }; - voronoi.x = function(_) { - return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; - clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - return voronoi; - }; - var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; - function d3_geom_voronoiTriangleArea(a, b, c) { - return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); + return result; } - d3.geom.delaunay = function(vertices) { - return d3.geom.voronoi().triangles(vertices); - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_geom_pointX, y = d3_geom_pointY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (abs(nx - x) + abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } + + /** + * 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; } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = xm; else x2 = xm; - if (below) y1 = ym; else y2 = ym; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - root.find = function(point) { - return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; + 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; } - function d3_geom_quadtreeCompatY(d) { - return d.y; + + /** + * 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; } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; + + /** + * 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]; } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) { - var minDistance2 = Infinity, closestPoint; - (function find(node, x1, y1, x2, y2) { - if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return; - if (point = node.point) { - var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy; - if (distance2 < minDistance2) { - var distance = Math.sqrt(minDistance2 = distance2); - x0 = x - distance, y0 = y - distance; - x3 = x + distance, y3 = y + distance; - closestPoint = point; - } - } - var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym; - for (var i = below << 1 | right, j = i + 4; i < j; ++i) { - if (node = children[i & 3]) switch (i & 3) { - case 0: - find(node, x1, y1, xm, ym); - break; - case 1: - find(node, xm, y1, x2, ym); - break; + /*--------------------------------------------------------------------------*/ - case 2: - find(node, x1, ym, xm, y2); - break; + /** + * 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({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => 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; - case 3: - find(node, xm, ym, x2, y2); - break; + /** 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, + stringProto = String.prototype; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + 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 = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * 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 retrieve a single value or may return a + * primitive 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 strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly 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 have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * 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`, `defaultsDeep`, + * `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`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `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`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `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(total, n) { + * return total + 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); } } - })(root, x0, y0, x3, y3); - return closestPoint; - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - a = +a, b = +b; - return function(t) { - return a * (1 - t) + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; - a = a + "", b = b + ""; - while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { - if ((bs = bm.index) > bi) { - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { - if (s[i]) s[i] += bm; else s[++i] = bm; - } else { - s[++i] = null; - q.push({ - i: i, - x: d3_interpolateNumber(am, bm) - }); - } - bi = d3_interpolate_numberB.lastIndex; - } - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { - return b(t) + ""; - }) : function() { - return b; - } : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); - } - var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\(|hsl\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * halfπ); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransformPop(s) { - return s.length ? s.pop() + "," : ""; - } - function d3_interpolateTranslate(ta, tb, s, q) { - if (ta[0] !== tb[0] || ta[1] !== tb[1]) { - var i = s.push("translate(", null, ",", null, ")"); - q.push({ - i: i - 4, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: i - 2, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } - } - function d3_interpolateRotate(ra, rb, s, q) { - if (ra !== rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(d3_interpolateTransformPop(s) + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(d3_interpolateTransformPop(s) + "rotate(" + rb + ")"); + return new LodashWrapper(value); } - } - function d3_interpolateSkew(wa, wb, s, q) { - if (wa !== wb) { - q.push({ - i: s.push(d3_interpolateTransformPop(s) + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(d3_interpolateTransformPop(s) + "skewX(" + wb + ")"); + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. } - } - function d3_interpolateScale(ka, kb, s, q) { - if (ka[0] !== kb[0] || ka[1] !== kb[1]) { - var i = s.push(d3_interpolateTransformPop(s) + "scale(", null, ",", null, ")"); - q.push({ - i: i - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: i - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] !== 1 || kb[1] !== 1) { - s.push(d3_interpolateTransformPop(s) + "scale(" + kb + ")"); + + /** + * 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; } - } - function d3_interpolateTransform(a, b) { - var s = [], q = []; - a = d3.transform(a), b = d3.transform(b); - d3_interpolateTranslate(a.translate, b.translate, s, q); - d3_interpolateRotate(a.rotate, b.rotate, s, q); - d3_interpolateSkew(a.skew, b.skew, s, q); - d3_interpolateScale(a.scale, b.scale, s, q); - a = b = null; - return function(t) { - var i = -1, n = q.length, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return (x - a) / b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return Math.max(0, Math.min(1, (x - a) / b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * 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 } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); + }; + + /*------------------------------------------------------------------------*/ + + /** + * 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__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + 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; } - k = (τ - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; + 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(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } } } + result[resIndex++] = value; } - if (sortChords) resort(); + return result; } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), timer, size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; - if (dw * dw / theta2 < dn) { - if (dn < chargeDistance2) { - var k = quad.charge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - return true; - } - if (quad.point && dn && dn < chargeDistance2) { - var k = quad.pointCharge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; + + /** + * 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]; } - force.tick = function() { - if ((alpha *= .99) < .005) { - timer = null; - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight + t.weight ? s.weight / (s.weight + t.weight) : .5); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.chargeDistance = function(x) { - if (!arguments.length) return Math.sqrt(chargeDistance2); - chargeDistance2 = x * x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return Math.sqrt(theta2); - theta2 = x * x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) { - alpha = x; - } else { - timer.c = null, timer.t = NaN, timer = null; - event.end({ - type: "end", - alpha: alpha = 0 - }); - } - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - timer = d3_timer(force.tick); - } - return force; - }; - force.start = function() { - var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - if (!neighbors) { - neighbors = new Array(n); - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - var candidates = neighbors[i], j = -1, l = candidates.length, x; - while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x; - return Math.random() * size; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); + + /** + * 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]; } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function hierarchy(root) { - var stack = [ root ], nodes = [], node; - root.depth = 0; - while ((node = stack.pop()) != null) { - nodes.push(node); - if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { - var n, childs, child; - while (--n >= 0) { - stack.push(child = childs[n]); - child.parent = node; - child.depth = node.depth + 1; - } - if (value) node.value = 0; - node.children = childs; - } else { - if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; - delete node.children; - } - } - d3_layout_hierarchyVisitAfter(root, function(node) { - var childs, parent; - if (sort && (childs = node.children)) childs.sort(sort); - if (value && (parent = node.parent)) parent.value += node.value; - }); - return nodes; + + /** + * 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); } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - if (value) { - d3_layout_hierarchyVisitBefore(root, function(node) { - if (node.children) node.value = 0; - }); - d3_layout_hierarchyVisitAfter(root, function(node) { - var parent; - if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; - if (parent = node.parent) parent.value += node.value; - }); - } - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyVisitBefore(node, callback) { - var nodes = [ node ]; - while ((node = nodes.pop()) != null) { - callback(node); - if ((children = node.children) && (n = children.length)) { - var n, children; - while (--n >= 0) nodes.push(children[n]); + + /** + * Sets `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; } - } - function d3_layout_hierarchyVisitAfter(node, callback) { - var nodes = [ node ], nodes2 = []; - while ((node = nodes.pop()) != null) { - nodes2.push(node); - if ((children = node.children) && (n = children.length)) { - var i = -1, n, children; - while (++i < n) nodes.push(children[i]); + + /*------------------------------------------------------------------------*/ + + /** + * + * 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]); } } - while ((node = nodes2.pop()) != null) { - callback(node); + + /** + * 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; } - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } + + /** + * 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; } } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0; - function pie(data) { - var n = data.length, values = data.map(function(d, i) { - return +value.call(pie, d, i); - }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), sum = d3.sum(values), k = sum ? (da - n * pa) / sum : 0, index = d3.range(n), arcs = [], v; - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - index.forEach(function(i) { - arcs[i] = { - data: data[i], - value: v = values[i], - startAngle: a, - endAngle: a += v * k + pa, - padAngle: p - }; - }); - return arcs; - } - pie.value = function(_) { - if (!arguments.length) return value; - value = _; - return pie; - }; - pie.sort = function(_) { - if (!arguments.length) return sort; - sort = _; - return pie; - }; - pie.startAngle = function(_) { - if (!arguments.length) return startAngle; - startAngle = _; - return pie; - }; - pie.endAngle = function(_) { - if (!arguments.length) return endAngle; - endAngle = _; - return pie; - }; - pie.padAngle = function(_) { - if (!arguments.length) return padAngle; - padAngle = _; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - if (!(n = data.length)) return data; - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var m = series[0].length, n, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; } - return data; + return result; } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } + + /** + * 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 bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `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; } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; } + return array; } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `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 bins; + return array; } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r -= dr; - }); + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `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; + } } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; + return true; } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } + + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; } } + return result; } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); - d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; - d3_layout_hierarchyVisitBefore(root1, secondWalk); - if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { - var left = root0, right = root0, bottom = root0; - d3_layout_hierarchyVisitBefore(root0, function(node) { - if (node.x < left.x) left = node; - if (node.x > right.x) right = node; - if (node.depth > bottom.depth) bottom = node; - }); - var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); - d3_layout_hierarchyVisitBefore(root0, function(node) { - node.x = (node.x + tx) * kx; - node.y = node.depth * ky; - }); - } - return nodes; - } - function wrapTree(root0) { - var root1 = { - A: null, - children: [ root0 ] - }, queue = [ root1 ], node1; - while ((node1 = queue.pop()) != null) { - for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { - queue.push((children[i] = child = { - _: children[i], - parent: node1, - children: (child = children[i].children) && child.slice() || [], - A: null, - a: null, - z: 0, - m: 0, - c: 0, - s: 0, - t: null, - i: i - }).a = child); + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `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 root1.children[0]; + return result; } - function firstWalk(v) { - var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; - if (children.length) { - d3_layout_treeShift(v); - var midpoint = (children[0].z + children[children.length - 1].z) / 2; - if (w) { - v.z = w.z + separation(v._, w._); - v.m = v.z - midpoint; - } else { - v.z = midpoint; - } - } else if (w) { - v.z = w.z + separation(v._, w._); - } - v.parent.A = apportion(v, w, v.parent.A || siblings[0]); - } - function secondWalk(v) { - v._.x = v.z + v.parent.m; - v.m += v.parent.m; - } - function apportion(v, w, ancestor) { - if (w) { - var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop.a = v; - shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); - sip += shift; - sop += shift; - } - sim += vim.m; - sip += vip.m; - som += vom.m; - sop += vop.m; - } - if (vim && !d3_layout_treeRight(vop)) { - vop.t = vim; - vop.m += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom.t = vip; - vom.m += sip - som; - ancestor = v; - } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `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 ancestor; - } - function sizeNode(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null ? sizeNode : null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) == null ? null : sizeNode; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(v) { - var children = v.children; - return children.length ? children[0] : v.t; - } - function d3_layout_treeRight(v) { - var children = v.children, n; - return (n = children.length) ? children[n - 1] : v.t; - } - function d3_layout_treeMove(wm, wp, shift) { - var change = shift / (wp.i - wm.i); - wp.c -= change; - wp.s += shift; - wm.c += change; - wp.z += shift; - wp.m += shift; - } - function d3_layout_treeShift(v) { - var shift = 0, change = 0, children = v.children, i = children.length, w; - while (--i >= 0) { - w = children[i]; - w.z += shift; - w.m += shift; - shift += w.s + (change += w.c); - } - } - function d3_layout_treeAncestor(vim, v, ancestor) { - return vim.a.parent === v.parent ? vim.a : ancestor; - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_hierarchyVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; + return result; } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; } + return array; } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = root.y = 0; - if (root.value) root.dx = size[0], root.dy = size[1]; else root.dx = root.dy = 0; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - bates: function(m) { - var random = d3.random.irwinHall(m); - return function() { - return random() / m; - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `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]; } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; } - function scale(x) { - return output(x); + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `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; } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var range = d3_scale_linearTickRange(domain, m); - if (format) { - var match = d3_format_re.exec(format); - match.shift(); - if (match[8] === "s") { - var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); - if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); - match[8] = "f"; - format = d3.format(match.join("")); - return function(d) { - return format(prefix.scale(d)) + prefix.symbol; - }; + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `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; + } } - if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); - format = match.join(""); - } else { - format = ",." + d3_scale_linearPrecision(range[2]) + "f"; + return false; } - return d3.format(format); - } - var d3_scale_linearFormatSignificant = { - s: 1, - g: 1, - p: 1, - r: 1, - e: 1 - }; - function d3_scale_linearPrecision(value) { - return -Math.floor(Math.log(value) / Math.LN10 + .01); - } - function d3_scale_linearFormatPrecision(type, range) { - var p = d3_scale_linearPrecision(range[2]); - return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); + + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; + + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); + + /** + * 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 objectValue === undefined ? sourceValue : objectValue; } - function scale(x) { - return linear(log(x)); + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function 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 (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); + + /** + * A specialized version of `_.assign` for customizing assigned values 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 assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + 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)) || + (value === undefined && !(key in object))) { + object[key] = result; } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); + return object; } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); + + /** + * The base implementation of `_.at` without support for string collections + * 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, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, - 0) : (stop - start) / (domain.length - 1 + padding); - range = steps(start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeRoundPoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), - 0) : (stop - start) / (domain.length - 1 + padding) | 0; - range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step); - rangeBand = 0; - ranger = { - t: "rangeRoundPoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)); - range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; + + /** + * 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 thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; + + /** + * 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 (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 baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its 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; } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; + + /** + * 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 = undefined; + } + return result || {}; + }; + }()); + + /** + * 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 provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; + + /** + * 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 >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + 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) < 0) { + result.push(value); + } + } + return result; } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; + + /** + * 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`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * 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`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `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; } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - function d3_zero() { - return 0; - } - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; - function arc() { - var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1; - if (r1 < r0) rc = r1, r1 = r0, r0 = rc; - if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z"; - var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = []; - if (ap = (+padAngle.apply(this, arguments) || 0) / 2) { - rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments); - if (!cw) p1 *= -1; - if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap)); - if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap)); - } - if (r1) { - x0 = r1 * Math.cos(a0 + p1); - y0 = r1 * Math.sin(a0 + p1); - x1 = r1 * Math.cos(a1 - p1); - y1 = r1 * Math.sin(a1 - p1); - var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1; - if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) { - var h1 = (a0 + a1) / 2; - x0 = r1 * Math.cos(h1); - y0 = r1 * Math.sin(h1); - x1 = y1 = null; - } - } else { - x0 = y0 = 0; - } - if (r0) { - x2 = r0 * Math.cos(a1 - p0); - y2 = r0 * Math.sin(a1 - p0); - x3 = r0 * Math.cos(a0 + p0); - y3 = r0 * Math.sin(a0 + p0); - var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1; - if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) { - var h0 = (a0 + a1) / 2; - x2 = r0 * Math.cos(h0); - y2 = r0 * Math.sin(h0); - x3 = y3 = null; + + /** + * 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|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; } - } else { - x2 = y2 = 0; - } - if (da > ε && (rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) { - cr = r0 < r1 ^ cw ? 0 : 1; - var rc1 = rc, rc0 = rc; - if (da < π) { - var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); - rc0 = Math.min(rc, (r0 - lc) / (kc - 1)); - rc1 = Math.min(rc, (r1 - lc) / (kc + 1)); + }); + 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 = (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 and `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); } - if (x1 != null) { - var t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw); - if (rc === rc1) { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]); - } else { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]); - } - } else { - path.push("M", x0, ",", y0); + }); + 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; } - if (x3 != null) { - var t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw); - if (rc === rc0) { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); + }); + 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-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); } else { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); + arrayPush(result, value); } - } else { - path.push("L", x2, ",", y2); + } else if (!isStrict) { + result[result.length] = value; } - } else { - path.push("M", x0, ",", y0); - if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1); - path.push("L", x2, ",", y2); - if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3); } - path.push("Z"); - return path.join(""); + return result; } - function circleSegment(r1, cw) { - return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee 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`. + */ + var baseFor = createBaseFor(); + + /** + * 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`. + */ + var baseForRight = createBaseFor(true); + + /** + * 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); } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.cornerRadius = function(v) { - if (!arguments.length) return cornerRadius; - cornerRadius = d3_functor(v); - return arc; - }; - arc.padRadius = function(v) { - if (!arguments.length) return padRadius; - padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.padAngle = function(v) { - if (!arguments.length) return padAngle; - padAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcAuto = "auto"; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_arcPadAngle(d) { - return d && d.padAngle; - } - function d3_svg_arcSweep(x0, y0, x1, y1) { - return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; - } - function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) { - var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; - if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; - return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ]; - } - function d3_svg_line(projection) { - var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; + + /** + * 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); } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.length > 1 ? points.join("L") : points + "Z"; - } - function d3_svg_lineLinearClosed(points) { - return points.join("L") + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinearClosed(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (abs(d) < ε) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; + + /** + * 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; } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] - halfπ; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - d3_selectionPrototype.transition = function(name) { - var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, ns, id, transition); - subgroup.push(node); + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; } + return (index && index == length) ? object : undefined; } - return d3_transition(subgroups, ns, id); - }; - d3_selectionPrototype.interrupt = function(name) { - return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name))); - }; - var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace()); - function d3_selection_interruptNS(ns) { - return function() { - var lock, activeId, active; - if ((lock = this[ns]) && (active = lock[activeId = lock.active])) { - active.timer.c = null; - active.timer.t = NaN; - if (--lock.count) delete lock[activeId]; else delete this[ns]; - lock.active += .5; - active.event && active.event.interrupt.call(this, this.__data__, active.index); + + /** + * 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} [isLoose] 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, isLoose, stackA, stackB) { + if (value === other) { + return true; } - }; - } - function d3_transition(groups, ns, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.namespace = ns; - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection, name) { - return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, ns, id, node[ns][id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node[ns][id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition); - subgroup.push(subnode); - } + + /** + * 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} [isLoose] 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, isLoose, 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); } } - } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); } } - } - return d3_transition(subgroups, this.namespace, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) return this.node()[ns][id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node[ns][id].tween.remove(name); - } : function(node) { - node[ns][id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id, ns = groups.namespace; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node[ns][id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - var ns = this.namespace; - return this.each("end.transition", function() { - var p; - if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node[ns][id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].delay; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node[ns][id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].duration; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node[ns][id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - try { - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node[ns][id]; - type.call(node, node.__data__, i, j); - }); - } finally { - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); } - } else { - d3_selection_each(this, function(node) { - var transition = node[ns][id]; - (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = node[ns][id0]; - d3_transitionNode(node, i, ns, id1, { - time: transition.time, - ease: transition.ease, - delay: transition.delay + transition.duration, - duration: transition.duration - }); + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); } - subgroup.push(node); } - } - return d3_transition(subgroups, ns, id1); - }; - function d3_transitionNamespace(name) { - return name == null ? "__transition__" : "__transition_" + name + "__"; - } - function d3_transitionNode(node, i, ns, id, inherit) { - var lock = node[ns] || (node[ns] = { - active: 0, - count: 0 - }), transition = lock[id], time, timer, duration, ease, tweens; - function schedule(elapsed) { - var delay = transition.delay; - timer.t = delay + time; - if (delay <= elapsed) return start(elapsed - delay); - timer.c = start; - } - function start(elapsed) { - var activeId = lock.active, active = lock[activeId]; - if (active) { - active.timer.c = null; - active.timer.t = NaN; - --lock.count; - delete lock[activeId]; - active.event && active.event.interrupt.call(node, node.__data__, active.index); - } - for (var cancelId in lock) { - if (+cancelId < id) { - var cancel = lock[cancelId]; - cancel.timer.c = null; - cancel.timer.t = NaN; - --lock.count; - delete lock[cancelId]; + 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; } } - timer.c = tick; - d3_timer(function() { - if (timer.c && tick(elapsed || 1)) { - timer.c = null; - timer.t = NaN; - } - return 1; - }, 0, time); - lock.active = id; - transition.event && transition.event.start.call(node, node.__data__, i); - tweens = []; - transition.tween.forEach(function(key, value) { - if (value = value.call(node, node.__data__, i)) { - tweens.push(value); - } - }); - ease = transition.ease; - duration = transition.duration; + // 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, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; } - function tick(elapsed) { - var t = elapsed / duration, e = ease(t), n = tweens.length; - while (n > 0) { - tweens[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, node.__data__, i); - if (--lock.count) delete lock[id]; else delete node[ns]; - return 1; + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; } - } - if (!transition) { - time = inherit.time; - timer = d3_timer(schedule, 0, time); - transition = lock[id] = { - tween: new d3_Map(), - time: time, - timer: timer, - delay: inherit.delay, - duration: inherit.duration, - ease: inherit.ease, - index: i - }; - inherit = null; - ++lock.count; - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); - var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform; - var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2; - if (orient === "bottom" || orient === "top") { - tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2"; - text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize); - } else { - tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2"; - text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start"); - pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize); + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; } - lineEnter.attr(y2, sign * innerTickSize); - textEnter.attr(y1, sign * tickSpacing); - lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize); - textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing); - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function(d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } } else { - tickExit.call(tickTransform, scale1, scale0); - } - tickEnter.call(tickTransform, scale0, scale1); - tickUpdate.call(tickTransform, scale1, scale1); - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = d3_array(arguments); - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x0, x1) { - selection.attr("transform", function(d) { - var v0 = x0(d); - return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)"; - }); - } - function d3_svg_axisY(selection, y0, y1) { - selection.attr("transform", function(d) { - var v0 = y0(d); - return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } } - redraw(gUpdate); - }); + } + return true; } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; + + /** + * The base implementation of `_.map` 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} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); }); + return result; } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; + + /** + * 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 matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; } - d3_eventPreventDefault(); - } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); + return function(object) { + return baseIsMatch(object, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, 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 merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); + }); + 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 merged values. + * @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; } } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; + else { + isCommon = false; } } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); + // 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; } } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @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]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; - var d3_time_formatUtc = d3_time_format.utc; - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); + return array; } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { - return d.getMilliseconds(); - } ], [ ":%S", function(d) { - return d.getSeconds(); - } ], [ "%I:%M", function(d) { - return d.getMinutes(); - } ], [ "%I %p", function(d) { - return d.getHours(); - } ], [ "%a %d", function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ "%b %d", function(d) { - return d.getDate() != 1; - } ], [ "%B", function(d) { - return d.getMonth(); - } ], [ "%Y", d3_true ] ]); - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); - }, - floor: d3_identity, - ceil: d3_identity - }; - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { - return d.getUTCMilliseconds(); - } ], [ ":%S", function(d) { - return d.getUTCSeconds(); - } ], [ "%I:%M", function(d) { - return d.getUTCMinutes(); - } ], [ "%I %p", function(d) { - return d.getUTCHours(); - } ], [ "%a %d", function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ "%b %d", function(d) { - return d.getUTCDate() != 1; - } ], [ "%B", function(d) { - return d.getUTCMonth(); - } ], [ "%Y", d3_true ] ]); - d3_time_scaleUtcMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - if (true) this.d3 = d3, !(__WEBPACK_AMD_DEFINE_FACTORY__ = (d3), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); else if (typeof module === "object" && module.exports) module.exports = d3; else this.d3 = d3; - }(); - -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + /** + * 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 + nativeFloor(nativeRandom() * (max - min + 1)); + } - var _d3 = __webpack_require__(4); + /** + * The base implementation of `_.reduce` and `_.reduceRight` 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 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; + } - var _d32 = _interopRequireDefault(_d3); + /** + * 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; + }; - var _lodash = __webpack_require__(6); + /** + * 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; - var _lodash2 = _interopRequireDefault(_lodash); + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; - var isInterpolatable = function isInterpolatable(obj) { - // d3 turns null into 0 and undefined into NaN, which we don't want. - if (obj !== null) { - switch (typeof obj) { - case "undefined": - return false; - case "number": - // The standard `isNaN` is fine in this case since we already know the - // type is number. - return !isNaN(obj) && _lodash2["default"].isFinite(obj); - case "string": - // d3 might not *actually* be able to interpolate the string, but it - // won't cause any issues to let it try. - return true; - case "boolean": - // d3 turns Booleans into integers, which we don't want. Sure, we could - // interpolate from 0 -> 1, but we'd be sending a non-Boolean to - // something expecting a Boolean. - return false; - case "object": - // Don't try to interpolate class instances (except Date or Array). - return _lodash2["default"].isDate(obj) || _lodash2["default"].isArray(obj) || _lodash2["default"].isPlainObject(obj); - case "function": - // Careful! There may be extra properties on function objects that the - // component expects to access - for instance, it may be a `d3.scale()` - // function, which has its own methods attached. We don't know if the - // component is only going to call the function (in which case it's - // safely interpolatable) or if it's going to access special properties - // (in which case our function generated from `interpolateFunction` will - // most likely cause an error. We could check for enumerable properties - // on the function object here to see if it's a "plain" function, but - // let's just require that components prevent such function props from - // being animated in the first place. - return true; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; } - } - return false; - }; - exports.isInterpolatable = isInterpolatable; - /** - * Interpolate immediately to the end value at the given step `when`. - * Some nicer default behavior might be to jump at the halfway point or return - * `a` if `t` is 0 (instead of always returning `b`). But d3's default - * interpolator does not do these things: - * - * d3.interpolate('aaa', 'bbb')(0) === 'bbb' - * - * ...and things might get wonky if we don't replicate that behavior. - * - * @param {any} a - Start value. - * @param {any} b - End value. - * @param {Number} when - Step value (0 to 1) at which to jump to `b`. - * @returns {Function} An interpolation function. - */ - var interpolateImmediate = function interpolateImmediate(a, b) { - var when = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2]; + /** + * The base implementation of `_.some` without support for callback shorthands + * and `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; - return function (t) { - return t < when ? a : b; - }; - }; + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } - exports.interpolateImmediate = interpolateImmediate; - /** - * Interpolate to or from a function. The interpolated value will be a function - * that calls `a` (if it's a function) and `b` (if it's a function) and calls - * `d3.interpolate` on the resulting values. Note that our function won't - * necessarily be called (that's up to the component this eventually gets - * passed to) - but if it does get called, it will return an appropriately - * interpolated value. - * - * @param {any} a - Start value. - * @param {any} b - End value. - * @returns {Function} An interpolation function. - */ - var interpolateFunction = function interpolateFunction(a, b) { - return function (t) { - if (t >= 1) { - return b; + /** + * The base implementation of `_.sortBy` 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; } - return function () { - /* eslint-disable no-invalid-this */ - var aval = typeof a === "function" ? a.apply(this, arguments) : a; - var bval = typeof b === "function" ? b.apply(this, arguments) : b; - return _d32["default"].interpolate(aval, bval)(t); - }; - }; - }; - exports.interpolateFunction = interpolateFunction; - /** - * By default, the list of interpolators used by `d3.interpolate` has a few - * downsides: - * - * - `null` values get turned into 0. - * - `undefined`, `function`, and some other value types get turned into NaN. - * - Boolean types get turned into numbers, which probably will be meaningless - * to whatever is consuming them. - * - It tries to interpolate between identical start and end values, doing - * unnecessary calculations that sometimes result in floating point rounding - * errors. - * - * If only the default interpolators are used, `VictoryAnimation` will happily - * pass down NaN (and other bad) values as props to the wrapped component. - * The component will then either use the incorrect values or complain that it - * was passed props of the incorrect type. This custom interpolator is added - * using the `d3.interpolators` API, and prevents such cases from happening - * for most values. - * - * @param {any} a - Start value. - * @param {any} b - End value. - * @returns {Function|undefined} An interpolation function, if necessary. - */ - var victoryInterpolator = function victoryInterpolator(a, b) { - // If the values are strictly equal, or either value is not interpolatable, - // just use either the start value `a` or end value `b` at every step, as - // there is no reasonable in-between value. - if (a === b || !isInterpolatable(a) || !isInterpolatable(b)) { - return interpolateImmediate(a, b); - } - if (typeof a === "function" || typeof b === "function") { - return interpolateFunction(a, b); - } - }; + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; - exports.victoryInterpolator = victoryInterpolator; - var interpolatorAdded = false; + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - var addVictoryInterpolator = function addVictoryInterpolator() { - if (!interpolatorAdded) { - _d32["default"].interpolators.push(victoryInterpolator); - interpolatorAdded = true; - } - }; - exports.addVictoryInterpolator = addVictoryInterpolator; - -/***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { - - var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** - * @license - * lodash 3.10.1 (Custom Build) - * Build: `lodash modern -d -o ./index.js` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - ;(function() { + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } - /** Used as the semantic version number. */ - var VERSION = '3.10.1'; + /** + * The base implementation of `_.sum` 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 {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } - /** 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, - ARY_FLAG = 128, - REARG_FLAG = 256; + /** + * 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 >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; - /** Used as default options for `_.trunc`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; + 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; - /** Used to detect when a function becomes hot. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; + 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) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @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); - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2; + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } - /** `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]'; + /** + * 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 value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; - 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]'; + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } - /** 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; + /** + * 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 qualified index. + * @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; - /** 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); + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + /** + * 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 qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); - /** - * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) - * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). - */ - var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, - reHasRegExpChars = RegExp(reRegExpChars.source); + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; - /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ - var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } - /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + /** + * 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 (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); + }; + } - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; + /** + * 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) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); - /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0[xX]/; + view.set(new Uint8Array(buffer)); + return result; + } - /** Used to detect host constructors (Safari > 5). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; + /** + * 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(leftLength + argsLength); - /** Used to detect unsigned integer values. */ - var reIsUint = /^\d+$/; + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + /** + * 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); - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @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); - /** 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]+'; + if (isArray(collection)) { + var index = -1, + length = collection.length; - return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); - }()); + 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; + }; + } - /** 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', 'isFinite', - 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' - ]; + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } - /** 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; + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); - /** 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; + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } - /** 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' - }; + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; + /** + * 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() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; + /** + * 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`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } - /** Used to escape characters for inclusion in compiled regexes. */ - var regexpEscapes = { - '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', - '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', - 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', - 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', - 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' - }; + /** + * 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 = ''; - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + /** + * 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() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } - /** Detect free variable `global` from Node.js. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } - /** Detect free variable `self`. */ - var freeSelf = objectTypes[typeof self] && self && self.Object && self; + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } - /** Detect free variable `window`. */ - var freeWindow = objectTypes[typeof window] && window && window.Object && window; + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } - /** - * Used as a reference to the global object. - * - * The `this` value is used if it's the global object to avoid Greasemonkey's - * restricted `window` object, otherwise the `window` object is used. - */ - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } - /*--------------------------------------------------------------------------*/ + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } - /** - * 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. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function baseCompareAscending(value, other) { - if (value !== other) { - var valIsNull = value === null, - valIsUndef = value === undefined, - valIsReflexive = value === value; + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); - var othIsNull = other === null, - othIsUndef = other === undefined, - othIsReflexive = other === other; + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; - if ((value > other && !othIsNull) || !valIsReflexive || - (valIsNull && !othIsUndef && othIsReflexive) || - (valIsUndef && othIsReflexive)) { - return 1; - } - if ((value < other && !valIsNull) || !othIsReflexive || - (othIsNull && !valIsUndef && valIsReflexive) || - (othIsUndef && valIsReflexive)) { - return -1; - } - } - return 0; - } + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to search. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromRight) { - var length = array.length, - index = fromRight ? length : -1; + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; } - return -1; - } - /** - * 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 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); + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; } - var index = fromIndex - 1, - length = array.length; - while (++index < length) { - if (array[index] === value) { - return index; - } + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; } - return -1; - } - /** - * The base implementation of `_.isFunction` without support for environments - * with incorrect `typeof` results. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - */ - function baseIsFunction(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; - } + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } - /** - * Converts `value` to a string if it's 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) { - return value == null ? '' : (value + ''); - } + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); - /** - * 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; + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } - while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } - /** - * 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; + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } - while (index-- && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } - /** - * 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. - * @param {Object} other The other object to compare. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); - } + /** + * 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, + Ctor = isBindKey ? undefined : createCtorWrapper(func); - /** - * Used by `_.sortByOrder` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, - * a value is sorted in ascending order if its corresponding order is "asc", and - * descending if "desc". - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; + 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 < length) { - var result = baseCompareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; + while (index--) { + args[index] = arguments[index]; } - var order = orders[index]; - return result * ((order === 'asc' || order === true) ? 1 : -1); - } - } - // 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]; - } + 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); - /** - * 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]; - } + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; - /** - * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. - * - * @private - * @param {string} chr The matched character to escape. - * @param {string} leadingChar The capture group for a leading character. - * @param {string} whitespaceChar The capture group for a whitespace character. - * @returns {string} Returns the escaped character. - */ - function escapeRegExpChar(chr, leadingChar, whitespaceChar) { - if (leadingChar) { - chr = regexpEscapes[chr]; - } else if (whitespaceChar) { - chr = stringEscapes[chr]; - } - return '\\' + chr; - } + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - /** - * 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]; - } + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); - /** - * Gets the index at which the first occurrence of `NaN` is found in `array`. - * - * @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 = fromIndex + (fromRight ? 0 : -1); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; - while ((fromRight ? index-- : ++index < length)) { - var other = array[index]; - if (other !== other) { - return index; + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); } + return wrapper; } - 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'; - } - - /** - * 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 = []; + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `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 createPadding(string, length, chars) { + var strLength = string.length; + length = +length; - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; + if (strLength >= length || !nativeIsFinite(length)) { + return ''; } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); } - 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 = []; + /** + * 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); - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; + 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(leftLength + argsLength); - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); } + return wrapper; } - 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; - } + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } - /** - * 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]; - } + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } - /*--------------------------------------------------------------------------*/ + /** + * 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 = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; - /** - * 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({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => 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; + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - /** 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; + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); - /** Used for native method references. */ - var arrayProto = Array.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; + 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); + } - /** Used to resolve the decompiled source of functions. */ - var fnToString = Function.prototype.toString; + /** + * 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} [isLoose] 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, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; - /** Used to generate unique IDs. */ - var idCounter = 0; + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } /** - * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. + * 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} object 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`. */ - var objToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Native method references. */ - var ArrayBuffer = context.ArrayBuffer, - clearTimeout = context.clearTimeout, - parseFloat = context.parseFloat, - pow = Math.pow, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - Set = getNative(context, 'Set'), - setTimeout = context.setTimeout, - splice = arrayProto.splice, - Uint8Array = context.Uint8Array, - WeakMap = getNative(context, 'WeakMap'); + 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; - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeCreate = getNative(Object, 'create'), - nativeFloor = Math.floor, - nativeIsArray = getNative(Array, 'isArray'), - nativeIsFinite = context.isFinite, - nativeKeys = getNative(Object, 'keys'), - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = getNative(Date, 'now'), - nativeParseInt = context.parseInt, - nativeRandom = Math.random; + case errorTag: + return object.name == other.name && object.message == other.message; - /** Used as references for `-Infinity` and `Infinity`. */ - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + 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; + } /** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) - * of an array-like value. + * 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} [isLoose] 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`. */ - var MAX_SAFE_INTEGER = 9007199254740991; + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; - /** Used to lookup unminified function names. */ - var realNames = {}; + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + 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; + } /** - * 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 retrieve a single value or may return a - * primitive 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 strategy which merge iteratee calls; this can help - * to avoid the creation of intermediate data structures and greatly 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 have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, - * `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * 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`, `defaultsDeep`, - * `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`, `mapKeys`, `mapValues`, `matches`, - * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, - * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, - * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, - * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, - * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, - * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, - * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, - * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, - * `inRange`, `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`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, - * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, - * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, - * `unescape`, `uniqueId`, `value`, and `words` + * 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. * - * The wrapper method `sample` will return a wrapped value when `n` is provided, - * otherwise an unwrapped value 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`. * - * @name _ - * @constructor - * @category Chain - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example + * @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 name of `func`. * - * var wrapped = _([1, 2, 3]); + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * 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. * - * // returns an unwrapped value - * wrapped.reduce(function(total, n) { - * return total + n; - * }); - * // => 6 + * @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 "length" property value of `object`. * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { - * return n * n; - * }); + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. * - * _.isArray(squares); - * // => false + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the propery names, values, and compare flags of `object`. * - * _.isArray(squares.value()); - * // => true + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. */ - 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); - } + function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); } - return new LodashWrapper(value); + return result; } /** - * The function whose prototype all chaining wrappers inherit from. + * Gets the native function at `key` of `object`. * * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. */ - function baseLodash() { - // No operation performed. + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; } /** - * The base constructor for creating `lodash` wrapper objects. + * Gets the view, applying any `transforms` to the `start` and `end` positions. * * @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. + * @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 LodashWrapper(value, chainAll, actions) { - this.__wrapped__ = value; - this.__actions__ = actions || []; - this.__chain__ = !!chainAll; + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + 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 }; } /** - * An object environment feature flags. + * Initializes an array clone. * - * @static - * @memberOf _ - * @type Object + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. */ - var support = lodash.support = {}; + 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; + } /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. + * Initializes an object clone. * - * @static - * @memberOf _ - * @type Object + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. */ - lodash.templateSettings = { + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': reEscape, + /** + * 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); - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': reEvaluate, + case boolTag: + case dateTag: + return new Ctor(+object); - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, + 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); - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', + case numberTag: + case stringTag: + return new Ctor(object); - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); } - }; + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } - /*------------------------------------------------------------------------*/ + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * Checks if `value` is a valid array-like index. * * @private - * @param {*} value The value to wrap. + * @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 LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = []; + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; } /** - * Creates a clone of the lazy wrapper object. + * Checks if the provided arguments are from an iteratee call. * * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. + * @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 lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = arrayCopy(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = arrayCopy(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = arrayCopy(this.__views__); - return result; + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; } /** - * Reverses the direction of lazy iteration. + * Checks if `value` is a property name and not a property path. * * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; } - return result; + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); } /** - * Extracts the unwrapped value from its lazy wrapper. + * Checks if `func` has a lazy counterpart. * * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { - return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; + var other = lodash[funcName]; + if (func === other) { + return true; } - return result; + var data = getData(other); + return !!data && func === data[0]; } - /*------------------------------------------------------------------------*/ + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @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; + } /** - * Creates a cache object to store key/value pairs. + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private - * @static - * @name Cache - * @memberOf _.memoize + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. */ - function MapCache() { - this.__data__ = {}; + function isStrictComparable(value) { + return value === value && !isObject(value); } /** - * Removes `key` and its value from the cache. + * 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 - * @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`. + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. */ - function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // 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; } /** - * Gets the cached value for `key`. + * Used by `_.defaultsDeep` to customize its `_.merge` use. * * @private - * @name get - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to get. - * @returns {*} Returns the cached value. + * @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 mapGet(key) { - return key == '__proto__' ? undefined : this.__data__[key]; + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); } /** - * Checks if a cached value for `key` exists. + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. * * @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`. + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. */ - function mapHas(key) { - return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + 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; } /** - * Sets `value` to `key` of the cache. + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. * * @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. + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. */ - function mapSet(key, value) { - if (key != '__proto__') { - this.__data__[key] = value; - } - return this; + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; } - /*------------------------------------------------------------------------*/ - /** - * - * Creates a cache object to store unique values. + * 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} [values] The values to cache. + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. */ - function SetCache(values) { - var length = values ? values.length : 0; + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); - this.data = { 'hash': nativeCreate(null), 'set': new Set }; while (length--) { - this.push(values[length]); + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; } + return array; } /** - * Checks if `value` is in `cache` mimicking the return signature of - * `_.indexOf` by returning `0` if the value is found, else `-1`. + * 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 {Object} cache The cache to search. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. */ - function cacheIndexOf(cache, value) { - var data = cache.data, - result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + var setData = (function() { + var count = 0, + lastCalled = 0; - return result ? 0 : -1; - } + 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); + }; + }()); /** - * Adds `value` to the cache. + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. * * @private - * @name push - * @memberOf SetCache - * @param {*} value The value to cache. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. */ - function cachePush(value) { - var data = this.data; - if (typeof value == 'string' || isObject(value)) { - data.set.add(value); - } else { - data.hash[value] = true; - } - } + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; - /*------------------------------------------------------------------------*/ + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); - /** - * Creates a new array joining `array` with `other`. - * - * @private - * @param {Array} array The array to join. - * @param {Array} other The other array to join. - * @returns {Array} Returns the new concatenated array. - */ - function arrayConcat(array, other) { var index = -1, - length = array.length, - othIndex = -1, - othLength = other.length, - result = Array(length + othLength); + result = []; - while (++index < length) { - result[index] = array[index]; - } - while (++othIndex < othLength) { - result[index++] = other[othIndex]; + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } } return result; } /** - * Copies the values of `source` to `array`. + * Converts `value` to an array-like object if it's not one. * * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. */ - function arrayCopy(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; + function toIterable(value) { + if (value == null) { + return []; } - return array; + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); } /** - * A specialized version of `_.forEach` for arrays without support for callback - * shorthands and `this` binding. + * Converts `value` to an object if it's not one. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @param {*} value The value to process. + * @returns {Object} Returns the object. */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; + function toObject(value) { + return isObject(value) ? value : Object(value); } /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands and `this` binding. + * Converts `value` to property path array if it's not one. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } + function toPath(value) { + if (isArray(value)) { + return value; } - return array; + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; } /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands and `this` binding. + * Creates a clone of `wrapper`. * * @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`. + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); } + /*------------------------------------------------------------------------*/ + /** - * A specialized version of `baseExtremum` for arrays which invokes `iteratee` - * with one argument: (value). + * 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. * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. + * @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 arrayExtremum(array, iteratee, comparator, exValue) { - var index = -1, - length = array.length, - computed = exValue, - result = computed; - - while (++index < length) { - var value = array[index], - current = +iteratee(value); + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); - if (comparator(current, computed)) { - computed = current; - result = value; - } + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); } return result; } /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands and `this` binding. + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. + * @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 arrayFilter(array, predicate) { + function compact(array) { var index = -1, - length = array.length, + length = array ? array.length : 0, resIndex = -1, result = []; while (++index < length) { var value = array[index]; - if (predicate(value, index, array)) { + if (value) { result[++resIndex] = value; } } @@ -11393,3375 +5170,4785 @@ return /******/ (function(modules) { // webpackBootstrap } /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands and `this` binding. + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. * - * @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; - } - - /** - * Appends the elements of `values` to `array`. + * @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 * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands and `this` binding. + * Creates a slice of `array` with `n` elements dropped from the beginning. * - * @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. + * @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 arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; } - return accumulator; + return baseSlice(array, n < 0 ? 0 : n); } /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands and `this` binding. + * Creates a slice of `array` with `n` elements dropped from the end. * - * @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. + * @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 arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - if (initFromArray && length) { - accumulator = array[--length]; + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; } - return accumulator; + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); } /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands and `this` binding. + * 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). * - * @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`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 iteration. + * @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', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', '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 arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; } /** - * A specialized version of `_.sum` for arrays without support for callback - * shorthands and `this` binding.. + * 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). * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 iteration. + * @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', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', '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 arraySum(array, iteratee) { - var length = array.length, - result = 0; - - while (length--) { - result += +iteratee(array[length]) || 0; - } - return result; + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; } /** - * Used by `_.defaults` to customize its `_.assign` use. + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. * - * @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. + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @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`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] */ - function assignDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : objectValue; + 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); } /** - * Used by `_.template` to customize its `_.assign` use. + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. * - * **Note:** This function is like `assignDefaults` except that it ignores - * inherited property values when checking if a property is `undefined`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. * - * @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. + * If a 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. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 */ - function assignOwnDefaults(objectValue, sourceValue, key, object) { - return (objectValue === undefined || !hasOwnProperty.call(object, key)) - ? sourceValue - : objectValue; - } + var findIndex = createFindIndex(); /** - * A specialized version of `_.assign` for customizing assigned values without - * support for argument juggling, multiple sources, and `this` binding `customizer` - * functions. + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 */ - function assignWith(object, source, customizer) { - var index = -1, - props = keys(source), - 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)) || - (value === undefined && !(key in object))) { - object[key] = result; - } - } - return object; - } + var findLastIndex = createFindIndex(true); /** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `customizer` functions. + * Gets the first element of `array`. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. + * @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 baseAssign(object, source) { - return source == null - ? object - : baseCopy(source, keys(source), object); + function first(array) { + return array ? array[0] : undefined; } /** - * The base implementation of `_.at` without support for string collections - * and individual key arguments. + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. * - * @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. + * @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 baseAt(collection, props) { - var index = -1, - isNil = collection == null, - isArr = !isNil && isArrayLike(collection), - length = isArr ? collection.length : 0, - propsLength = props.length, - result = Array(propsLength); - - while(++index < propsLength) { - var key = props[index]; - if (isArr) { - result[index] = isIndex(key, length) ? collection[key] : undefined; - } else { - result[index] = isNil ? undefined : collection[key]; - } + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; } - return result; + return length ? baseFlatten(array, isDeep) : []; } /** - * Copies properties of `source` to `object`. + * Recursively flattens a nested array. * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property names to copy. - * @param {Object} [object={}] The object to copy properties to. - * @returns {Object} Returns `object`. + * @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 baseCopy(source, props, object) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; } /** - * The base implementation of `_.callback` which supports specifying the - * number of arguments to provide to `func`. + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-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. * - * @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. + * @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, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 */ - function baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return thisArg === undefined - ? func - : bindCallback(func, thisArg, argCount); - } - if (func == null) { - return identity; + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; } - if (type == 'object') { - return baseMatches(func); + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; } - return thisArg === undefined - ? property(func) - : baseMatchesProperty(func, thisArg); + return baseIndexOf(array, value, fromIndex || 0); } /** - * The base implementation of `_.clone` without support for argument juggling - * and `this` binding `customizer` functions. + * Gets all but the last element of `array`. * - * @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. + * @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 baseClone(value, isDeep, customizer, key, object, stackA, stackB) { - var result; - if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); - } - if (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; + function initial(array) { + return dropRight(array, 1); + } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return baseAssign(result, value); - } - } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); - } - } - // Check for circular references and return its corresponding clone. - stackA || (stackA = []); - stackB || (stackB = []); + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; } - // Add the source value to the stack of traversed objects and associate it with its clone. - stackA.push(value); - stackB.push(result); + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; - // 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); - }); + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } return result; - } + }); /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. + * Gets the last element of `array`. * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } /** - * The base implementation of `_.delay` and `_.defer` which accepts an index - * of where to slice the arguments to provide to `func`. + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The arguments provide to `func`. - * @returns {number} Returns the timer id. + * @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, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; } - return setTimeout(function() { func.apply(undefined, args); }, wait); + 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]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; } /** - * The base implementation of `_.difference` which accepts a single array - * of values to exclude. + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @returns {Array} Returns the new array of filtered values. + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @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 baseDifference(array, values) { - var length = array ? array.length : 0, - result = []; + function pull() { + var args = arguments, + array = args[0]; - if (!length) { - return result; + if (!(array && array.length)) { + return array; } - var index = -1, + var index = 0, indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, - valuesLength = values.length; + length = args.length; - if (cache) { - indexOf = cacheIndexOf; - isCommon = false; - values = cache; - } - outer: while (++index < length) { - var value = array[index]; + var fromIndex = 0, + value = args[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) < 0) { - result.push(value); + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); } } - return result; + return array; } /** - * The base implementation of `_.forEach` without support for callback - * shorthands and `this` binding. + * 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. * - * @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`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for callback - * shorthands and `this` binding. + * **Note:** Unlike `_.at`, this method mutates `array`. * - * @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`. + * @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] */ - var baseEachRight = createBaseEach(baseForOwnRight, true); + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); /** - * The base implementation of `_.every` without support for callback - * shorthands and `this` binding. + * 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). * - * @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` + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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. + * @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 baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { return result; - }); + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); return result; } /** - * 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|key, collection). + * Gets all but the first element of `array`. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. + * @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 baseExtremum(collection, iteratee, comparator, exValue) { - var computed = exValue, - result = computed; - - baseEach(collection, function(value, index, collection) { - var current = +iteratee(value, index, collection); - if (comparator(current, computed) || (current === exValue && current === result)) { - computed = current; - result = value; - } - }); - return result; + function rest(array) { + return drop(array, 1); } /** - * The base implementation of `_.fill` without an iteratee call guard. + * Creates a slice of `array` from `start` up to, but not including, `end`. * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. + * **Note:** This method 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 `array`. + * @returns {Array} Returns the slice of `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 = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; } - length = start > end ? 0 : (end >>> 0); - start >>>= 0; - - while (start < length) { - array[start++] = value; + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; } - return array; + return baseSlice(array, start, end); } /** - * The base implementation of `_.filter` without support for callback - * shorthands and `this` binding. + * 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). * - * @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. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 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. + * @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], 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 baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } + var sortedIndex = createSortedIndex(); /** - * 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`. + * 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. * - * @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`. + * @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. + * @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], 5); + * // => 4 */ - 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; - } + var sortedLastIndex = createSortedIndex(true); /** - * The base implementation of `_.flatten` with added support for restricting - * flattening and specifying the start index. + * Creates a slice of `array` with `n` elements taken from the beginning. * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. + * @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 baseFlatten(array, isDeep, isStrict, result) { - result || (result = []); - - var index = -1, - length = array.length; + 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); + } - while (++index < length) { - var value = array[index]; - if (isObjectLike(value) && isArrayLike(value) && - (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } + /** + * 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 []; } - return result; + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); } /** - * The base implementation of `baseForIn` and `baseForOwn` which iterates - * over `object` properties returned by `keysFunc` invoking `iteratee` for - * each property. Iteratee functions may exit iteration early by explicitly - * returning `false`. + * 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). * - * @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`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * 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. * - * @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`. + * If a 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 iteration. + * @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', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), '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'); + * // => [] */ - var baseForRight = createBaseFor(true); + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } /** - * The base implementation of `_.forIn` without support for callback - * shorthands and `this` binding. + * 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). * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 iteration. + * @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', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), '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 baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; } /** - * The base implementation of `_.forOwn` without support for callback - * shorthands and `this` binding. + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] */ - function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); - } + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); /** - * The base implementation of `_.forOwnRight` without support for callback - * shorthands and `this` binding. + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element 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). * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 _ + * @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. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // 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 baseForOwnRight(object, iteratee) { - return baseForRight(object, iteratee, keys); + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); } /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from those provided. + * 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. * - * @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. + * @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 baseFunctions(object, props) { + function unzip(array) { + if (!(array && array.length)) { + return []; + } var index = -1, - length = props.length, - resIndex = -1, - result = []; + length = 0; - while (++index < length) { - var key = props[index]; - if (isFunction(object[key])) { - result[++resIndex] = key; + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); } return result; } /** - * The base implementation of `get` without support for string paths - * and default values. + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path of the property to get. - * @param {string} [pathKey] The key representation of path. - * @returns {*} Returns the resolved value. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] */ - function baseGet(object, path, pathKey) { - if (object == null) { - return; - } - if (pathKey !== undefined && pathKey in toObject(object)) { - path = [pathKey]; + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; } - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[path[index++]]; + var result = unzip(array); + if (iteratee == null) { + return result; } - return (index && index == length) ? object : undefined; + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); } /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. * - * @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} [isLoose] 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`. + * @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, 3], 1, 2); + * // => [3] */ - function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); - } + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); /** - * 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. + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. * - * @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} [isLoose] 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`. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] */ - function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, 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); - } - if (!isLoose) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, 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 = []); + function xor() { + var index = -1, + length = arguments.length; - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; } } - // 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, isLoose, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; + return result ? baseUniq(result) : []; } /** - * The base implementation of `_.isMatch` without support for callback - * shorthands and `this` binding. + * 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. * - * @private - * @param {Object} object The object to inspect. - * @param {Array} matchData The propery names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparing objects. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = toObject(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { - return false; - } - } - } - return true; - } + * @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]] + */ + var zip = restParam(unzip); /** - * The base implementation of `_.map` without support for callback shorthands - * and `this` binding. + * The inverse of `_.pairs`; this method returns 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. * - * @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. + * @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', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } */ - function baseMap(collection, iteratee) { + function zipObject(props, values) { var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; + length = props ? props.length : 0, + result = {}; - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); + 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; } /** - * The base implementation of `_.matches` which does not clone `source`. + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - var key = matchData[0][0], - value = matchData[0][1]; + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; - return function(object) { - if (object == null) { - return false; - } - return object[key] === value && (value !== undefined || (key in toObject(object))); - }; + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; } - return function(object) { - return baseIsMatch(object, matchData); - }; - } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); + + /*------------------------------------------------------------------------*/ /** - * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to compare. - * @returns {Function} Returns the new function. + * @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 baseMatchesProperty(path, srcValue) { - var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(srcValue), - pathKey = (path + ''); - - path = toPath(path); - return function(object) { - if (object == null) { - return false; - } - var key = pathKey; - object = toObject(object); - if ((isArr || !isCommon) && !(key in object)) { - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - key = last(path); - object = toObject(object); - } - return object[key] === srcValue - ? (srcValue !== undefined || (key in object)) - : baseIsEqual(srcValue, object[key], undefined, true); - }; + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; } /** - * The base implementation of `_.merge` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. + * 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. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merged values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {Object} Returns `object`. + * @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 baseMerge(object, source, customizer, stackA, stackB) { - if (!isObject(object)) { - return object; - } - var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), - props = isSrcArr ? undefined : keys(source); + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); - } - else { - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; + /** + * 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 + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } - if (isCommon) { - result = srcValue; - } - if ((result !== undefined || (isSrcArr && !(key in object))) && - (isCommon || (result === result ? (result !== value) : (value === value)))) { - object[key] = result; - } - } - }); - return object; + /** + * 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); } /** - * 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. + * Executes the chained sequence and returns the wrapped result. * - * @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 merged values. - * @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`. + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] */ - 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 = result === undefined; - - if (isCommon) { - result = srcValue; - if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (isArrayLike(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; - } + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); } /** - * The base implementation of `_.property` without support for deep paths. + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); /** - * A specialized version of `baseProperty` which supports deep paths. + * Creates a clone of the chained sequence planting `value` as the wrapped value. * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new function. + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] */ - function basePropertyDeep(path) { - var pathKey = (path + ''); - path = toPath(path); - return function(object) { - return baseGet(object, path, pathKey); - }; + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; } /** - * The base implementation of `_.pullAt` without support for individual - * index arguments and capturing the removed elements. + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. + * **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 basePullAt(array, indexes) { - var length = array ? indexes.length : 0; - while (length--) { - var index = indexes[length]; - if (index != previous && isIndex(index)) { - var previous = index; - splice.call(array, index, 1); + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); } - return array; + return this.thru(interceptor); } /** - * The base implementation of `_.random` without support for argument juggling - * and returning floating-point numbers. + * Produces the result of coercing the unwrapped value to a string. * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns the random number. + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' */ - function baseRandom(min, max) { - return min + nativeFloor(nativeRandom() * (max - min + 1)); + function wrapperToString() { + return (this.value() + ''); } /** - * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands and `this` binding, which iterates over `collection` - * using the provided `eachFunc`. + * Executes the chained sequence to extract the unwrapped value. * - * @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. + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] */ - 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; + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); } + /*------------------------------------------------------------------------*/ + /** - * The base implementation of `setData` without support for hot loop detection. + * 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. * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. + * @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'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); /** - * The base implementation of `_.slice` without an iteratee call guard. + * 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). * - * @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`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @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 } */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; + /** + * 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 a 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. + * @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'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', '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 (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); } - return result; + return func(collection, predicate); } /** - * The base implementation of `_.some` without support for callback shorthands - * and `this` binding. + * 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). * - * @private + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * 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 baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); } /** - * The base implementation of `_.sortBy` which uses `comparer` to define - * the sort order of `array` and replaces criteria objects with their - * corresponding values. + * 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 a 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. + * @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' * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } + var find = createFind(baseEach); /** - * The base implementation of `_.sortByOrder` without param guards. + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @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 baseSortByOrder(collection, iteratees, orders) { - var callback = getCallback(), - index = -1; - - iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - - var result = baseMap(collection, function(value) { - var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } + var findLast = createFind(baseEachRight, true); /** - * The base implementation of `_.sum` without support for callback shorthands - * and `this` binding. + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. + * **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 baseSum(collection, iteratee) { - var result = 0; - baseEach(collection, function(value, index, collection) { - result += +iteratee(value, index, collection) || 0; - }); - return result; + function findWhere(collection, source) { + return find(collection, baseMatches(source)); } /** - * The base implementation of `_.uniq` without support for callback shorthands - * and `this` binding. + * 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). Iteratee functions may exit iteration early + * by explicitly returning `false`. * - * @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. + * **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]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ - function baseUniq(array, iteratee) { - var index = -1, - indexOf = getIndexOf(), - length = array.length, - isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= LARGE_ARRAY_SIZE, - seen = isLarge ? createCache() : null, - 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) < 0) { - if (iteratee || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } + var forEach = createForEach(arrayEach, baseEach); /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. * - * @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. + * @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]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array */ - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } + var forEachRight = createForEach(arrayEachRight, baseEachRight); /** - * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, - * and `_.takeWhile` without support for callback shorthands and `this` binding. + * 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). * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @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'] } */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); /** - * 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. + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to peform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. + * @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. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @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 baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; } - var index = -1, - length = actions.length; - - while (++index < length) { - var action = actions[index]; - result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); } - return result; + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); } /** - * 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. + * 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). * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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 Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @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 } } */ - 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)) && computed !== null) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return binaryIndexBy(array, value, identity, retHighest); - } + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** - * 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). + * Invokes the method at `path` of 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`. * - * @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 qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path 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 binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsNull = value === null, - valIsUndef = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - isDef = computed !== undefined, - isReflexive = computed === computed; + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsNull) { - setLow = isReflexive && isDef && (retHighest || computed != null); - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || isDef); - } else if (computed == null) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); /** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. + * 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 `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `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. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } * - * @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 (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. + * _.map([1, 2], timesThree); + * // => [3, 6] * - * @private - * @param {ArrayBuffer} buffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] */ - function bufferClone(buffer) { - var result = new ArrayBuffer(buffer.byteLength), - view = new Uint8Array(result); - - view.set(new Uint8Array(buffer)); - return result; + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); } /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. + * 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). * - * @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. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a 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. + * @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.2, 3.4], [2.3]] + * + * 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']] */ - function composeArgs(args, partials, holders) { - var holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - leftIndex = -1, - leftLength = partials.length, - result = Array(leftLength + argsLength); - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - while (argsLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. + * Gets the property value of `path` from all elements in `collection`. * - * @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. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path 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 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 offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - return result; + function pluck(collection, path) { + return map(collection, property(path)); } /** - * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * 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). * - * @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; - }; - } + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @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 + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); /** - * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. + * @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 createAssigner(assigner) { - return restParam(function(object, sources) { - var index = -1, - length = object == null ? 0 : sources.length, - customizer = length > 2 ? sources[length - 2] : undefined, - guard = length > 2 ? sources[2] : undefined, - thisArg = length > 1 ? sources[length - 1] : undefined; + var reduceRight = createReduce(arrayReduceRight, baseEachRight); - if (typeof customizer == 'function') { - customizer = bindCallback(customizer, thisArg, 5); - length -= 2; - } else { - customizer = typeof thisArg == 'function' ? thisArg : undefined; - length -= (customizer ? 1 : 0); - } - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, customizer); - } - } - return object; + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @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. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.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); }); } /** - * Creates a `baseEach` or `baseEachRight` function. + * Gets a random element or `n` random elements from a collection. * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. + * @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 createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - return eachFunc(collection, iteratee); - } - var index = fromRight ? length : -1, - iterable = toObject(collection); + 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 index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; } /** - * Creates a base function for `_.forIn` or `_.forInRight`. + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. + * @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 createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length)) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); } /** - * Creates a function that wraps `func` and invokes it with the `this` - * binding of `thisArg`. + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. * - * @private - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new bound function. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 */ - function createBindWrapper(func, thisArg) { - var Ctor = createCtorWrapper(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(thisArg, arguments); - } - return wrapper; + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; } /** - * Creates a `Set` cache object to optimize linear searches of large arrays. + * 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 a 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. + * @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', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true * - * @private - * @param {Array} [values] The values to cache. - * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true */ - function createCache(values) { - return (nativeCreate && Set) ? new SetCache(values) : null; + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); } /** - * Creates a function that produces compound words out of the words in a - * given string. + * 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). * - * @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`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. + * If a 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 Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @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 createCtorWrapper(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. - // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); } /** - * Creates a `_.curry` or `_.curryRight` function. + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. * - * @private - * @param {boolean} flag The curry bit flag. - * @returns {Function} Returns the new curry function. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee 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|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function createCurry(flag) { - function curryFunc(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = undefined; - } - var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryFunc.placeholder; - return result; + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; } - return curryFunc; - } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); /** - * Creates a `_.defaults` or `_.defaultsDeep` function. + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". * - * @private - * @param {Function} assigner The function to assign values. - * @param {Function} customizer The function to customize assigned values. - * @returns {Function} Returns the new defaults function. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee 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[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function createDefaults(assigner, customizer) { - return restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(customizer); - return assigner.apply(undefined, args); - }); + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); } /** - * Creates a `_.max` or `_.min` function. + * 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 * - * @private - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {Function} Returns the new extremum function. + * 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 createExtremum(comparator, exValue) { - return function(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - iteratee = getCallback(iteratee, thisArg, 3); - if (iteratee.length == 1) { - collection = isArray(collection) ? collection : toIterable(collection); - var result = arrayExtremum(collection, iteratee, comparator, exValue); - if (!(collection.length && result === exValue)) { - return result; - } - } - return baseExtremum(collection, iteratee, comparator, exValue); - }; + function where(collection, source) { + return filter(collection, baseMatches(source)); } + /*------------------------------------------------------------------------*/ + /** - * Creates a `_.find` or `_.findLast` function. + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. + * @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 */ - function createFind(eachFunc, fromRight) { - return function(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate, fromRight); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, eachFunc); - }; - } + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ /** - * Creates a `_.findIndex` or `_.findLastIndex` function. + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. + * @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 createFindIndex(fromRight) { - return function(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; + 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); } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, fromRight); }; } /** - * Creates a `_.findKey` or `_.findLastKey` function. + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new find function. + * @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 createFindKey(objectFunc) { - return function(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, objectFunc, true); - }; + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** - * Creates a `_.flow` or `_.flowRight` function. + * 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. * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. + * @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 createFlow(fromRight) { + 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() { - var wrapper, - length = arguments.length, - index = fromRight ? length : -1, - leftIndex = 0, - funcs = Array(length); - - while ((fromRight ? index-- : ++index < length)) { - var func = funcs[leftIndex++] = arguments[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { - wrapper = new LodashWrapper([], true); - } + if (--n > 0) { + result = func.apply(this, arguments); } - index = wrapper ? -1 : length; - while (++index < length) { - func = funcs[index]; - - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; - - if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); - } + if (n <= 1) { + func = undefined; } - return function() { - var args = arguments, - value = args[0]; - - if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; + return result; }; } /** - * Creates a function for `_.forEach` or `_.forEachRight`. + * 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. * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each 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 {...*} [partials] 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 createForEach(arrayFunc, eachFunc) { - return function(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee) - : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); - }; - } + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); /** - * Creates a function for `_.forIn` or `_.forInRight`. + * 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. * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. + * **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 createForIn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee, keysIn); - }; - } + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); /** - * Creates a function for `_.forOwn` or `_.forOwnRight`. + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each 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://peter.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 {...*} [partials] 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 createForOwn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee); - }; - } + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); /** - * Creates a function for `_.mapKeys` or `_.mapValues`. + * 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. * - * @private - * @param {boolean} [isMapKeys] Specify mapping keys instead of values. - * @returns {Function} Returns the new map function. + * 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 createObjectMapper(isMapKeys) { - return function(object, iteratee, thisArg) { - var result = {}; - iteratee = getCallback(iteratee, thisArg, 3); - - baseForOwn(object, function(value, key, object) { - var mapped = iteratee(value, key, object); - key = isMapKeys ? mapped : key; - value = isMapKeys ? value : mapped; - result[key] = value; - }); - return result; - }; - } + var curry = createCurry(CURRY_FLAG); /** - * Creates a function for `_.padLeft` or `_.padRight`. + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. * - * @private - * @param {boolean} [fromRight] Specify padding from the right. - * @returns {Function} Returns the new pad function. + * 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 createPadDir(fromRight) { - return function(string, length, chars) { - string = baseToString(string); - return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); - }; - } + var curryRight = createCurry(CURRY_RIGHT_FLAG); /** - * Creates a `_.partial` or `_.partialRight` function. + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced 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=0] 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 + * })); * - * @private - * @param {boolean} flag The partial bit flag. - * @returns {Function} Returns the new partial function. - */ - function createPartial(flag) { - var partialFunc = restParam(function(func, partials) { - var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, undefined, partials, holders); - }); - return partialFunc; - } - - /** - * Creates a function for `_.reduce` or `_.reduceRight`. + * // 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 + * })); * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. - */ - function createReduce(arrayFunc, eachFunc) { - return function(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); - }; - } - - /** - * Creates a function that wraps `func` and invokes it with optional `this` - * binding of, partial application, and currying. + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); * - * @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. + * 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 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, - Ctor = isBindKey ? undefined : createCtorWrapper(func); + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; - 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); + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + 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; + } - while (index--) { - args[index] = arguments[index]; + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); } - if (partials) { - args = composeArgs(args, partials, holders); + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight); + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); } - if (isCurry || isCurryRight) { - var placeholder = wrapper.placeholder, - argsHolders = replaceHolders(args, placeholder); + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } - length -= argsHolders.length; - if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : undefined, - newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : undefined, - newHoldersRight = isCurry ? undefined : argsHolders, - newPartials = isCurry ? args : undefined, - newPartialsRight = isCurry ? undefined : args; + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + function maxDelayed() { + complete(trailing, timeoutId); + } - if (!isCurryBound) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], - result = createHybridWrapper.apply(undefined, newData); + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); - if (isLaziable(func)) { - setData(result, newData); + 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); } - result.placeholder = placeholder; - return result; + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); } } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - if (argPos) { - args = reorder(args, argPos); + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); } - if (isAry && ary < args.length) { - args.length = ary; + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtorWrapper(func); + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); } - return fn.apply(thisBinding, args); + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; } - return wrapper; + debounced.cancel = cancel; + return debounced; } /** - * Creates the padding required for `string` based on the given `length`. - * The `chars` string is truncated if the number of characters exceeds `length`. + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. * - * @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`. + * @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 createPadding(string, length, chars) { - var strLength = string.length; - length = +length; + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); - if (strLength >= length || !nativeIsFinite(length)) { - return ''; - } - var padLength = length - strLength; - chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); - } + /** + * 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 + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); /** - * 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. + * 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. * - * @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. + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 */ - 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(leftLength + argsLength); - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, args); - } - return wrapper; - } + var flow = createFlow(); /** - * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - precision = precision === undefined ? 0 : (+precision || 0); - if (precision) { - precision = pow(10, precision); - return func(number * precision) / precision; - } - return func(number); - }; - } + var flowRight = createFlow(true); /** - * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * 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. * - * @private - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {Function} Returns the new index 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 [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @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 createSortedIndex(retHighest) { - return function(array, value, iteratee, thisArg) { - var callback = getCallback(iteratee); - return (iteratee == null && callback === baseCallback) - ? binaryIndex(array, value, retHighest) - : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; }; + memoized.cache = new memoize.Cache; + return memoized; } /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. + * Creates a function that runs each argument through a corresponding + * transform function. * - * @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. + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] */ - function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { throw new TypeError(FUNC_ERROR_TEXT); } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - length -= (holders ? holders.length : 0); - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - - if (data) { - 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); - } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. + * 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. * - * @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} [isLoose] 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`. + * @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 equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isLoose && othLength > arrLength)) { - return false; - } - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index], - result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; - - if (result !== undefined) { - if (result) { - continue; - } - return false; - } - // Recursively compare arrays (susceptible to call stack limits). - if (isLoose) { - if (!arraySome(other, function(othValue) { - return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - })) { - return false; - } - } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { - return false; - } + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - return true; + return function() { + return !predicate.apply(this, arguments); + }; } /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. + * 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 and arguments of the created function. * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example * - * @private - * @param {Object} object 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`. + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once */ - 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; + function once(func) { + return before(2, func); + } - case numberTag: - // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - : object == +other; + /** + * 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 {...*} [partials] 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' + */ + var partial = createPartial(PARTIAL_FLAG); - 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; - } + /** + * 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 {...*} [partials] 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' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. + * 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. * - * @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} [isLoose] 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`. + * @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 equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); - if (objLength != othLength && !isLoose) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { - return false; - } + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - var skipCtor = isLoose; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key], - result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); - // Recursively compare objects (susceptible to call stack limits). - if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { - return false; + while (++index < length) { + rest[index] = args[start + index]; } - skipCtor || (skipCtor = key == 'constructor'); - } - if (!skipCtor) { - 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; + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); } - } - return true; + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; } /** - * 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. + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). * - * @private - * @returns {Function} Returns the chosen function or its result. + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; } /** - * Gets metadata for `func`. + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled 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. * - * @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 name of `func`. + * **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. * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. + * 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=0] 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 + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); */ - function getFuncName(func) { - var result = func.name, - array = realNames[result], - length = array ? array.length : 0; + function throttle(func, wait, options) { + var leading = true, + trailing = true; - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - return result; + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); } /** - * 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. + * 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. * - * @private - * @returns {Function|number} Returns the chosen function or its result. + * @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 getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); } + /*------------------------------------------------------------------------*/ + /** - * Gets the "length" property value of `object`. + * 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 function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-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. * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ - var getLength = baseProperty('length'); - - /** - * Gets the propery names, values, and compare flags of `object`. + * @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 * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. + * 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 el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 */ - function getMatchData(object) { - var result = pairs(object), - length = result.length; - - while (length--) { - result[length][2] = isStrictComparable(result[length][1]); + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; } - return result; + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); } /** - * Gets the native function at `key` of `object`. + * 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]). * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = object == null ? undefined : object[key]; - return isNative(value) ? value : undefined; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-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. * - * @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. + * @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) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - 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 }; + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); } /** - * Initializes an array clone. + * Checks if `value` is greater than `other`. * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false */ - 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; + function gt(value, other) { + return value > other; } /** - * Initializes an object clone. + * Checks if `value` is greater than or equal to `other`. * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false */ - function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; - } - return new Ctor; + function gte(value, other) { + return value >= other; } /** - * Initializes an object clone based on its `toStringTag`. + * Checks if `value` is classified as an `arguments` object. * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example * - * @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. + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false */ - 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; + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); } /** - * Invokes the method at `path` on `object`. + * Checks if `value` is classified as an `Array` object. * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. + * @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 + * + * _.isArray(function() { return arguments; }()); + * // => false */ - function invokePath(object, path, args) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); - } - var func = object == null ? object : object[path]; - return func == null ? undefined : func.apply(object, args); - } + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; /** - * Checks if `value` is array-like. + * Checks if `value` is classified as a boolean primitive or object. * - * @private + * @static + * @memberOf _ + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false */ - function isArrayLike(value) { - return value != null && isLength(getLength(value)); + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); } /** - * Checks if `value` is a valid array-like index. + * Checks if `value` is classified as a `Date` object. * - * @private + * @static + * @memberOf _ + * @category Lang * @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 = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - 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. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example * - * @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`. + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object)) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); - } - return false; + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; } /** - * Checks if `value` is a property name and not a property path. + * Checks if `value` is a DOM element. * - * @private + * @static + * @memberOf _ + * @category Lang * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false */ - function isKey(value, object) { - var type = typeof value; - if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { - return true; - } - if (isArray(value)) { - return false; - } - var result = !reIsDeepProp.test(value); - return result || (object != null && value in toObject(object)); + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); } /** - * Checks if `func` has a lazy counterpart. + * Checks if `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. * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + * @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 isLaziable(func) { - var funcName = getFuncName(func); - if (!(funcName in LazyWrapper.prototype)) { - return false; - } - var other = lodash[funcName]; - if (func === other) { + function isEmpty(value) { + if (value == null) { return true; } - var data = getData(other); - return !!data && func === data[0]; + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; } /** - * Checks if `value` is a valid array-like 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 function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * **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. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @static + * @memberOf _ + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @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) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true */ - function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; } /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. * - * @private + * @static + * @memberOf _ + * @category Lang * @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 && !isObject(value); - } - - /** - * Merges the function metadata of `source` into `data`. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example * - * 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. + * _.isError(new Error); + * // => true * - * @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, - isCommon = newBitmask < ARY_FLAG; - - var isCombo = - (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || - (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || - (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); - - // 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; + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; } /** - * Used by `_.defaultsDeep` to customize its `_.merge` use. + * Checks if `value` is a finite primitive number. * - * @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. + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * + * @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 */ - function mergeDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); } /** - * A specialized version of `_.pick` which picks `object` properties specified - * by `props`. + * Checks if `value` is classified as a `Function` object. * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property names to pick. - * @returns {Object} Returns the new 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 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; + function isFunction(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 isObject(value) && objToString.call(value) == funcTag; } /** - * A specialized version of `_.pick` which picks `object` properties `predicate` - * returns truthy for. + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * - * @private - * @param {Object} object The source object. - * @param {Function} predicate The function invoked per iteration. - * @returns {Object} Returns the new object. + * @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 pickByCallback(object, predicate) { - var result = {}; - baseForIn(object, function(value, key, object) { - if (predicate(value, key, object)) { - result[key] = value; - } - }); - return result; + 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 !!value && (type == 'object' || type == 'function'); } /** - * 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. + * 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). * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. + * **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 value comparisons. + * @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 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; + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); } /** - * Sets metadata for `func`. + * Checks if `value` is `NaN`. * - * **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. + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. + * @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 */ - 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); - }; - }()); + 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; + } /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. + * Checks if `value` is a native function. * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; - - var allowIndexes = !!length && isLength(length) && - (isArray(object) || 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); - } + * @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; } - return result; + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); } /** - * Converts `value` to an array-like object if it's not one. + * Checks if `value` is `null`. * - * @private - * @param {*} value The value to process. - * @returns {Array|Object} Returns the array-like object. + * @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 toIterable(value) { - if (value == null) { - return []; - } - if (!isArrayLike(value)) { - return values(value); - } - return isObject(value) ? value : Object(value); + function isNull(value) { + return value === null; } /** - * Converts `value` to an object if it's not one. + * Checks if `value` is classified as a `Number` primitive or object. * - * @private - * @param {*} value The value to process. - * @returns {Object} Returns the 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 toObject(value) { - return isObject(value) ? value : Object(value); + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); } /** - * Converts `value` to property path array if it's not one. + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. + * **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 */ - function toPath(value) { - if (isArray(value)) { - return value; + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; } - var result = []; - baseToString(value).replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + // 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 result; + return result === undefined || hasOwnProperty.call(value, result); } /** - * Creates a clone of `wrapper`. + * Checks if `value` is classified as a `RegExp` object. * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. + * @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 wrapperClone(wrapper) { - return wrapper instanceof LazyWrapper - ? wrapper.clone() - : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; } - /*------------------------------------------------------------------------*/ - /** - * 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. + * Checks if `value` is classified as a `String` primitive or object. * * @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. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] + * _.isString('abc'); + * // => true * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] + * _.isString(1); + * // => false */ - function chunk(array, size, guard) { - if (guard ? isIterateeCall(array, size, guard) : size == null) { - size = 1; - } else { - size = nativeMax(nativeFloor(size) || 1, 1); - } - var index = 0, - length = array ? array.length : 0, - resIndex = -1, - result = Array(nativeCeil(length / size)); + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } - while (index < length) { - result[++resIndex] = baseSlice(array, index, (index += size)); - } - return result; + /** + * 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)]; } /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. + * Checks if `value` is `undefined`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = -1, - result = []; + function isUndefined(value) { + return value === undefined; + } - while (++index < length) { - var value = array[index]; - if (value) { - result[++resIndex] = value; - } - } - return result; + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; } /** - * Creates an array of unique `array` values not included in the other - * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * Checks if `value` is less than or equal to `other`. * * @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. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. * @example * - * _.difference([1, 2, 3], [4, 2]); - * // => [1, 3] + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false */ - var difference = restParam(function(array, values) { - return (isObjectLike(array) && isArrayLike(array)) - ? baseDifference(array, baseFlatten(values, false, true)) - : []; - }); + function lte(value, other) { + return value <= other; + } /** - * Creates a slice of `array` with `n` elements dropped from the beginning. + * Converts `value` to an array. * * @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`. + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. * @example * - * _.drop([1, 2, 3]); + * (function() { + * return _.toArray(arguments).slice(1); + * }(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; + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } if (!length) { return []; } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, n < 0 ? 0 : n); + return arrayCopy(value); } /** - * Creates a slice of `array` with `n` elements dropped from the end. + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. * * @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`. + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. * @example * - * _.dropRight([1, 2, 3]); - * // => [1, 2] + * function Foo() { + * this.b = 2; + * } * - * _.dropRight([1, 2, 3], 2); - * // => [1] + * Foo.prototype.c = 3; * - * _.dropRight([1, 2, 3], 5); - * // => [] + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 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); + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); } + /*------------------------------------------------------------------------*/ + /** - * 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 a 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`. + * 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 Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * _.dropRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [1] + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['barney', 'fred'] + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); - * // => ['barney'] + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; * - * // using the `_.property` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } */ - function dropRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) - : []; - } + var merge = createAssigner(baseMerge); /** - * 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 a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * 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). * - * 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:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * _.dropWhile([1, 2, 3], function(n) { - * return n < 3; + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; * }); - * // => [3] * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * 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; + * } * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['fred', 'pebbles'] + * function Circle() { + * Shape.call(this); + * } * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropWhile(users, 'active', false), 'user'); - * // => ['pebbles'] + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); * - * // using the `_.property` callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true */ - function dropWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true) - : []; + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; } /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. + * 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 values of the same property are ignored. * - * **Note:** This method mutates `array`. + * **Note:** This method mutates `object`. * * @static * @memberOf _ - * @category Array - * @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`. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. * @example * - * var array = [1, 2, 3]; + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] + * **Note:** This method mutates `object`. * - * _.fill(Array(3), 2); - * // => [2, 2, 2] + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } * - * _.fill([4, 6, 8], '*', 1, 2); - * // => [4, '*', 8] */ - 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); - } + var defaultsDeep = createDefaults(merge, mergeDefaults); /** - * This method is like `_.find` except that it returns the index of the first + * This method is like `_.find` 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` @@ -14777,42 +9964,42 @@ return /******/ (function(modules) { // webpackBootstrap * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to search. + * @category Object + * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; * - * _.findIndex(users, function(chr) { - * return chr.user == 'barney'; + * _.findKey(users, function(chr) { + * return chr.age < 40; * }); - * // => 0 + * // => 'barney' (iteration order is not guaranteed) * * // using the `_.matches` callback shorthand - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' * * // using the `_.matchesProperty` callback shorthand - * _.findIndex(users, 'active', false); - * // => 0 + * _.findKey(users, 'active', false); + * // => 'fred' * * // using the `_.property` callback shorthand - * _.findIndex(users, 'active'); - * // => 2 + * _.findKey(users, 'active'); + * // => 'barney' */ - var findIndex = createFindIndex(); + var findKey = createFindKey(baseForOwn); /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. + * 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. @@ -14827,2240 +10014,2357 @@ return /******/ (function(modules) { // webpackBootstrap * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to search. + * @category Object + * @param {Object} object The object to search. * @param {Function|Object|string} [predicate=_.identity] The function invoked * per iteration. * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; * - * _.findLastIndex(users, function(chr) { - * return chr.user == 'pebbles'; + * _.findLastKey(users, function(chr) { + * return chr.age < 40; * }); - * // => 2 + * // => returns `pebbles` assuming `_.findKey` returns `barney` * * // using the `_.matches` callback shorthand - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' * * // using the `_.matchesProperty` callback shorthand - * _.findLastIndex(users, 'active', false); - * // => 2 + * _.findLastKey(users, 'active', false); + * // => 'fred' * * // using the `_.property` callback shorthand - * _.findLastIndex(users, 'active'); - * // => 0 + * _.findLastKey(users, 'active'); + * // => 'pebbles' */ - var findLastIndex = createFindIndex(true); + var findLastKey = createFindKey(baseForOwnRight); /** - * Gets the first element of `array`. + * 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). Iteratee functions may exit + * iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @alias head - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. + * @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 * - * _.first([1, 2, 3]); - * // => 1 + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.first([]); - * // => undefined + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) */ - function first(array) { - return array ? array[0] : undefined; - } + var forIn = createForIn(baseFor); /** - * Flattens a nested array. If `isDeep` is `true` the array is recursively - * flattened, otherwise it is only flattened a single level. + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. * * @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. + * @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 * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * // using `isDeep` - * _.flatten([1, [2, 3, [4]]], true); - * // => [1, 2, 3, 4] + * 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 flatten(array, isDeep, guard) { - var length = array ? array.length : 0; - if (guard && isIterateeCall(array, isDeep, guard)) { - isDeep = false; - } - return length ? baseFlatten(array, isDeep) : []; - } + var forInRight = createForIn(baseForRight); /** - * Recursively flattens a nested array. + * 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). Iteratee functions may exit iteration + * early by explicitly returning `false`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to recursively flatten. - * @returns {Array} Returns the new flattened array. + * @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 * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; - } + var forOwn = createForOwn(baseForOwn); /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-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. + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. * * @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`. + * @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 * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * // using `fromIndex` - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 + * Foo.prototype.c = 3; * - * // performing a binary search - * _.indexOf([1, 1, 2, 2], 2, true); - * // => 2 + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' */ - 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; - } else if (fromIndex) { - var index = binaryIndex(array, value); - if (index < length && - (value === value ? (value === array[index]) : (array[index] !== array[index]))) { - return index; - } - return -1; - } - return baseIndexOf(array, value, fromIndex || 0); - } + var forOwnRight = createForOwn(baseForOwnRight); /** - * Gets all but the last element of `array`. + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. * @example * - * _.initial([1, 2, 3]); - * // => [1, 2] + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] */ - function initial(array) { - return dropRight(array, 1); + function functions(object) { + return baseFunctions(object, keysIn(object)); } /** - * Creates an array of unique values that are included in all of the provided - * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of shared values. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. * @example - * _.intersection([1, 2], [4, 2], [2, 1]); - * // => [2] + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' */ - var intersection = restParam(function(arrays) { - var othLength = arrays.length, - othIndex = othLength, - caches = Array(length), - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - result = []; - - while (othIndex--) { - var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; - caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; - } - var array = arrays[0], - index = -1, - length = array ? array.length : 0, - seen = caches[0]; - - outer: - while (++index < length) { - value = array[index]; - if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { - var othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { - continue outer; - } - } - if (seen) { - seen.push(value); - } - result.push(value); - } - } - return result; - }); + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } /** - * Gets the last element of `array`. + * Checks if `path` is a direct property. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. * @example * - * _.last([1, 2, 3]); - * // => 3 + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + path = last(path); + result = hasOwnProperty.call(object, path); + } + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); } /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. + * 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 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`. + * @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 * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 + * var object = { 'a': 1, 'b': 2, 'c': 1 }; * - * // using `fromIndex` - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 + * _.invert(object); + * // => { '1': 'c', '2': 'b' } * - * // performing a binary search - * _.lastIndexOf([1, 1, 2, 2], 2, true); - * // => 3 + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; } - 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]; - if (value === value ? (value === other) : (other !== other)) { - return index; + 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]; + } } - return -1; - } - if (value !== value) { - return indexOfNaN(array, index, true); - } - while (index--) { - if (array[index] === value) { - return index; + else { + result[value] = key; } } - return -1; + return result; } /** - * Removes all provided values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * Creates an array of the own enumerable property names of `object`. * - * **Note:** Unlike `_.without`, this method mutates `array`. + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * var array = [1, 2, 3, 1, 2, 3]; + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] */ - function pull() { - var args = arguments, - array = args[0]; + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; - if (!(array && array.length)) { - return array; + /** + * 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 query. + * @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 []; } - var index = 0, - indexOf = getIndexOf(), - length = args.length; + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; - while (++index < length) { - var fromIndex = 0, - value = args[index]; + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; - while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { - splice.call(array, fromIndex, 1); + 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 array; + return result; } /** - * 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`. + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. * * @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. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. * @example * - * var array = [5, 10, 15, 20]; - * var evens = _.pullAt(array, 1, 3); - * - * console.log(array); - * // => [5, 15] - * - * console.log(evens); - * // => [10, 20] + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } */ - var pullAt = restParam(function(array, indexes) { - indexes = baseFlatten(indexes); - - var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(baseCompareAscending)); - return result; - }); + var mapKeys = createObjectMapper(true); /** - * 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). + * 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 `predicate` the created `_.property` + * If a property name is provided for `iteratee` the created `_.property` * style callback returns the property value of the given element. * * If a 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 + * 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`. * - * **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 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new array of removed elements. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. * @example * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; * }); + * // => { 'a': 3, 'b': 6 } * - * console.log(array); - * // => [1, 3] + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; * - * console.log(evens); - * // => [2, 4] + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ - function remove(array, predicate, thisArg) { - var result = []; - if (!(array && array.length)) { - return result; + var mapValues = createObjectMapper(); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @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' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); } + var predicate = bindCallback(props[0], props[1], 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 query. + * @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) { + object = toObject(object); + var index = -1, - indexes = [], - length = array.length; + props = keys(object), + length = props.length, + result = Array(length); - predicate = getCallback(predicate, thisArg, 3); while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } + var key = props[index]; + result[index] = [key, object[key]]; } - basePullAt(array, indexes); return result; } /** - * Gets all but the first element of `array`. + * 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 _ - * @alias tail - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. + * @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 * - * _.rest([1, 2, 3]); - * // => [2, 3] + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } */ - function rest(array) { - return drop(array, 1); - } + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of `Array#slice` to support node - * lists in IE < 9 and to ensure dense arrays are returned. + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is 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`. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' */ - 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; + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; } - return baseSlice(array, start, end); + return isFunction(result) ? result.call(object) : result; } /** - * 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 `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a 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`. + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. * * @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. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. * @example * - * _.sortedIndex([30, 50], 40); - * // => 1 - * - * _.sortedIndex([4, 4, 5, 5], 5); - * // => 2 - * - * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * // using an iteratee function - * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { - * return this.data[word]; - * }, dict); - * // => 1 + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 * - * // using the `_.property` callback shorthand - * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 1 + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 */ - var sortedIndex = createSortedIndex(); + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } /** - * 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. + * 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). Iteratee functions + * may exit iteration early by explicitly returning `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. + * @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 {number} Returns the index at which `value` should be inserted - * into `array`. + * @returns {*} Returns the accumulated value. * @example * - * _.sortedLastIndex([4, 4, 5, 5], 5); - * // => 4 + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } */ - var sortedLastIndex = createSortedIndex(true); + 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 : undefined); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } /** - * Creates a slice of `array` with `n` elements taken from the beginning. + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. * * @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`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. * @example * - * _.take([1, 2, 3]); - * // => [1] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.take([1, 2, 3], 2); - * // => [1, 2] + * Foo.prototype.c = 3; * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) * - * _.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); + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); } /** - * Creates a slice of `array` with `n` elements taken from the end. + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. * * @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`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. * @example * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] + * Foo.prototype.c = 3; * - * _.takeRight([1, 2, 3], 0); - * // => [] + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) */ - 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); + function valuesIn(object) { + return baseValues(object, keysIn(object)); } + /*------------------------------------------------------------------------*/ + /** - * 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 a 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`. + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. * @example * - * _.takeRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [2, 3] + * _.inRange(3, 2, 4); + * // => true * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; + * _.inRange(4, 8); + * // => true * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['pebbles'] + * _.inRange(4, 2); + * // => false * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); - * // => ['fred', 'pebbles'] + * _.inRange(2, 2); + * // => false * - * // using the `_.property` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); - * // => [] + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false */ - function takeRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) - : []; + function inRange(value, start, end) { + start = +start || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); } /** - * 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 a 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`. + * 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 Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @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 * - * _.takeWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [1, 2] - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false}, - * { 'user': 'pebbles', 'active': true } - * ]; + * _.random(0, 5); + * // => an integer between 0 and 5 * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['barney'] + * _.random(5); + * // => also an integer between 0 and 5 * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeWhile(users, 'active', false), 'user'); - * // => ['barney', 'fred'] + * _.random(5, true); + * // => a floating-point number between 0 and 5 * - * // using the `_.property` callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); - * // => [] + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 */ - function takeWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3)) - : []; + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + 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); } + /*------------------------------------------------------------------------*/ + /** - * Creates an array of unique values, in order, from all of the provided arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. * @example * - * _.union([1, 2], [4, 2], [2, 1]); - * // => [1, 2, 4] - */ - var union = restParam(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurence of each element - * is kept. Providing `true` for `isSorted` performs a faster search algorithm - * for sorted arrays. If an iteratee function is provided it is invoked for - * each element 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 `iteratee` the created `_.property` - * style callback returns the property value of the given element. + * _.camelCase('Foo Bar'); + * // => 'fooBar' * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * _.camelCase('--foo-bar'); + * // => 'fooBar' * - * 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`. + * _.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 _ - * @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. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new duplicate-value-free array. + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. * @example * - * _.uniq([2, 1, 2]); - * // => [2, 1] - * - * // 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 }] + * _.capitalize('fred'); + * // => 'Fred' */ - function uniq(array, isSorted, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (isSorted != null && typeof isSorted != 'boolean') { - thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; - isSorted = false; - } - var callback = getCallback(); - if (!(iteratee == null && callback === baseCallback)) { - iteratee = callback(iteratee, thisArg, 3); - } - return (isSorted && getIndexOf() == baseIndexOf) - ? sortedUniq(array, iteratee) - : baseUniq(array, iteratee); + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); } /** - * 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. + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). * * @static * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. * @example * - * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - * - * _.unzip(zipped); - * // => [['fred', 'barney'], [30, 40], [true, false]] + * _.deburr('déjà vu'); + * // => 'deja vu' */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var index = -1, - length = 0; - - array = arrayFilter(array, function(group) { - if (isArrayLike(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - var result = Array(length); - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); } /** - * This method is like `_.unzip` except that it accepts an iteratee to specify - * how regrouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). + * Checks if `string` ends with the given target string. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee] The function to combine regrouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new array of regrouped elements. + * @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 * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] + * _.endsWith('abc', 'c'); + * // => true * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true */ - function unzipWith(array, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - iteratee = bindCallback(iteratee, thisArg, 4); - return arrayMap(result, function(group) { - return arrayReduce(group, iteratee, undefined, true); - }); + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; } /** - * Creates an array excluding all provided values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. + * 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 need 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 [#59](https://html5sec.org/#59), + * [#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](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. * * @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. + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. * @example * - * _.without([1, 2, 1, 3], 1, 2); - * // => [3] + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' */ - var without = restParam(function(array, values) { - return isArrayLike(array) - ? baseDifference(array, values) - : []; - }); + 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; + } /** - * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the provided arrays. + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of values. + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. * @example * - * _.xor([1, 2], [4, 2]); - * // => [1, 4] + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArrayLike(array)) { - var result = result - ? arrayPush(baseDifference(result, array), baseDifference(array, result)) - : array; - } - } - return result ? baseUniq(result) : []; + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); } /** - * 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. + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. * @example * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' */ - var zip = restParam(unzip); + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); /** - * The inverse of `_.pairs`; this method returns 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. + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. * - * @static - * @memberOf _ - * @alias object - * @category Array - * @param {Array} props The property names. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. + * @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 * - * _.zipObject([['fred', 30], ['barney', 40]]); - * // => { 'fred': 30, 'barney': 40 } + * _.pad('abc', 8); + * // => ' abc ' * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' */ - function zipObject(props, values) { - var index = -1, - length = props ? props.length : 0, - result = {}; + function pad(string, length, chars) { + string = baseToString(string); + length = +length; - 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]; - } + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; } - return result; + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; } /** - * This method is like `_.zip` except that it accepts an iteratee to specify - * how grouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee] The function to combine grouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new array of grouped elements. + * @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 * - * _.zipWith([1, 2], [10, 20], [100, 200], _.add); - * // => [111, 222] + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' */ - var zipWith = restParam(function(arrays) { - var length = arrays.length, - iteratee = length > 2 ? arrays[length - 2] : undefined, - thisArg = length > 1 ? arrays[length - 1] : undefined; - - if (length > 2 && typeof iteratee == 'function') { - length -= 2; - } else { - iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; - thisArg = undefined; - } - arrays.length = length; - return unzipWith(arrays, iteratee, thisArg); - }); - - /*------------------------------------------------------------------------*/ + var padLeft = createPadDir(); /** - * Creates a `lodash` object that wraps `value` with explicit method - * chaining enabled. + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ - * @category Chain - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. + * @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 * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; + * _.padRight('abc', 6); + * // => 'abc ' * - * var youngest = _.chain(users) - * .sortBy('age') - * .map(function(chr) { - * return chr.user + ' is ' + chr.age; - * }) - * .first() - * .value(); - * // => 'pebbles is 1' + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } + var padRight = createPadDir(true); /** - * 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. + * 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](https://es5.github.io/#E) + * of `parseInt`. * * @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`. + * @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 * - * _([1, 2, 3]) - * .tap(function(array) { - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] */ - function tap(value, interceptor, thisArg) { - interceptor.call(thisArg, value); - return value; + function parseInt(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 || (reHasHexPrefix.test(string) ? 16 : 10)); } /** - * This method is like `_.tap` except that it returns the result of `interceptor`. + * Repeats the given string `n` times. * * @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`. + * @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 * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' */ - function thru(value, interceptor, thisArg) { - return interceptor.call(thisArg, value); + 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 = nativeFloor(n / 2); + string += string; + } while (n); + + return result; } /** - * Enables explicit method chaining on the wrapper object. + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). * - * @name chain + * @static * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' * - * // without explicit chaining - * _(users).first(); - * // => { 'user': 'barney', 'age': 36 } + * _.snakeCase('fooBar'); + * // => 'foo_bar' * - * // with explicit chaining - * _(users).chain() - * .first() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' */ - function wrapperChain() { - return chain(this); - } + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); /** - * Executes the chained sequence and returns the wrapped result. + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * - * @name commit + * @static * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. * @example * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] + * _.startCase('--foo-bar'); + * // => 'Foo Bar' * - * wrapped.last(); - * // => 3 + * _.startCase('fooBar'); + * // => 'Foo Bar' * - * console.log(array); - * // => [1, 2, 3] + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); /** - * Creates a new array joining a wrapped array with any additional arrays - * and/or values. + * Checks if `string` starts with the given target string. * - * @name concat + * @static * @memberOf _ - * @category Chain - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. + * @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 * - * var array = [1]; - * var wrapped = _(array).concat(2, [3], [[4]]); + * _.startsWith('abc', 'a'); + * // => true * - * console.log(wrapped.value()); - * // => [1, 2, 3, [4]] + * _.startsWith('abc', 'b'); + * // => false * - * console.log(array); - * // => [1] + * _.startsWith('abc', 'b', 1); + * // => true */ - var wrapperConcat = restParam(function(values) { - values = baseFlatten(values); - return this.thru(function(array) { - return arrayConcat(isArray(array) ? array : [toObject(array)], values); - }); - }); + 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 clone of the chained sequence planting `value` as the wrapped value. + * 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. * - * @name plant + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * 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 Chain - * @returns {Object} Returns the new `lodash` wrapper instance. + * @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 * - * var array = [1, 2]; - * var wrapped = _(array).map(function(value) { - * return Math.pow(value, 2); - * }); + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' * - * var other = [3, 4]; - * var otherWrapped = wrapped.plant(other); + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '