From 3f5ca10c39a9f7d55e0f6943caf8f6ff762a0222 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 1 May 2015 17:24:44 +0200 Subject: [PATCH 1/2] mitmweb: add editor --- libmproxy/web/app.py | 2 +- libmproxy/web/static/app.js | 440 ++-- libmproxy/web/static/vendor.js | 2698 +++++++++++--------- web/src/js/components/common.js | 5 + web/src/js/components/editor.js | 189 ++ web/src/js/components/flowview/messages.js | 196 +- web/src/js/components/header.js | 2 +- web/src/js/components/prompt.js | 2 +- 8 files changed, 1954 insertions(+), 1580 deletions(-) create mode 100644 web/src/js/components/editor.js diff --git a/libmproxy/web/app.py b/libmproxy/web/app.py index 6bb522e11..9582d97b7 100644 --- a/libmproxy/web/app.py +++ b/libmproxy/web/app.py @@ -119,7 +119,7 @@ class FlowHandler(RequestHandler): def put(self, flow_id): flow = self.flow - self.state.backup(flow) + flow.backup() for a, b in self.json.iteritems(): if a == "request": diff --git a/libmproxy/web/static/app.js b/libmproxy/web/static/app.js index 62cd8357d..3531174e6 100644 --- a/libmproxy/web/static/app.js +++ b/libmproxy/web/static/app.js @@ -440,7 +440,7 @@ module.exports = { Query: Query }; -},{"./dispatcher.js":20,"jquery":"jquery","lodash":"lodash"}],3:[function(require,module,exports){ +},{"./dispatcher.js":21,"jquery":"jquery","lodash":"lodash"}],3:[function(require,module,exports){ var React = require("react"); var ReactRouter = require("react-router"); var $ = require("jquery"); @@ -462,7 +462,7 @@ $(function () { -},{"./actions.js":2,"./components/proxyapp.js":17,"./connection":19,"jquery":"jquery","react":"react","react-router":"react-router"}],4:[function(require,module,exports){ +},{"./actions.js":2,"./components/proxyapp.js":18,"./connection":20,"jquery":"jquery","react":"react","react-router":"react-router"}],4:[function(require,module,exports){ var React = require("react"); var ReactRouter = require("react-router"); var _ = require("lodash"); @@ -520,6 +520,11 @@ var SettingsState = { var ChildFocus = { contextTypes: { returnFocus: React.PropTypes.func + }, + returnFocus: function(){ + React.findDOMNode(this).blur(); + window.getSelection().removeAllRanges(); + this.context.returnFocus(); } }; @@ -681,6 +686,197 @@ module.exports = { },{"lodash":"lodash","react":"react","react-router":"react-router"}],5:[function(require,module,exports){ var React = require("react"); var common = require("./common.js"); +var utils = require("../utils.js"); + +var contentToHtml = function (content) { + return _.escape(content); +}; +var nodeToContent = function (node) { + return node.textContent; +}; + +/* +Basic Editor Functionality + */ +var EditorBase = React.createClass({displayName: "EditorBase", + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + contentToHtml: React.PropTypes.func, + nodeToContent: React.PropTypes.func, // content === nodeToContent( Node ) + submitOnEnter: React.PropTypes.bool, + className: React.PropTypes.string, + tag: React.PropTypes.string + }, + getDefaultProps: function () { + return { + contentToHtml: contentToHtml, + nodeToContent: nodeToContent, + submitOnEnter: true, + className: "", + tag: "div" + }; + }, + getInitialState: function () { + return { + editable: false + }; + }, + render: function () { + var className = "inline-input " + this.props.className; + var html = {__html: this.props.contentToHtml(this.props.content)}; + var Tag = this.props.tag; + return React.createElement(Tag, React.__spread({}, + this.props, + {tabIndex: "0", + className: className, + contentEditable: this.state.editable || undefined, // workaround: use undef instead of false to remove attr + onFocus: this.onFocus, + onBlur: this._stop, + onKeyDown: this.onKeyDown, + onInput: this.onInput, + dangerouslySetInnerHTML: html}) + ); + }, + onFocus: function (e) { + this.setState({editable: true}, function () { + React.findDOMNode(this).focus(); + var range = document.createRange(); + range.selectNodeContents(this.getDOMNode()); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + }); + this.props.onFocus && this.props.onFocus(e); + }, + stop: function () { + // a stop would cause a blur as a side-effect. + // but a blur event must trigger a stop as well. + // to fix this, make stop = blur and do the actual stop in the onBlur handler. + React.findDOMNode(this).blur(); + }, + _stop: function (e) { + window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur + var node = React.findDOMNode(this); + var content = this.props.nodeToContent(node); + this.setState({editable: false}); + this.props.onDone(content); + this.props.onBlur && this.props.onBlur(e); + }, + cancel: function () { + React.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); + this.stop(); + }, + onKeyDown: function (e) { + e.stopPropagation(); + switch (e.keyCode) { + case utils.Key.ESC: + e.preventDefault(); + this.cancel(); + break; + case utils.Key.ENTER: + if (this.props.submitOnEnter) { + e.preventDefault(); + this.stop(); + } + break; + default: + break; + } + }, + onInput: function () { + var node = React.findDOMNode(this); + var content = this.props.nodeToContent(node); + node.innerHTML = this.props.contentToHtml(content); + this.props.onInput && this.props.onInput(content); + } +}); + +/* +Add Validation to EditorBase + */ +var ValidateEditor = React.createClass({displayName: "ValidateEditor", + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + onInput: React.PropTypes.func, + isValid: React.PropTypes.func, + className: React.PropTypes.string, + }, + getInitialState: function(){ + return { + currentContent: this.props.content + }; + }, + componentWillReceiveProps: function(){ + this.setState({currentContent: this.props.content}); + }, + onInput: function(content){ + this.setState({currentContent: content}); + this.props.onInput && this.props.onInput(content); + }, + render: function () { + var className = this.props.className || ""; + if (this.props.isValid) { + if (this.props.isValid(this.state.currentContent)) { + className += " has-success"; + } else { + className += " has-warning" + } + } + return React.createElement(EditorBase, React.__spread({}, + this.props, + {ref: "editor", + className: className, + onDone: this.onDone, + onInput: this.onInput}) + ); + }, + onDone: function (content) { + if(this.props.isValid && !this.props.isValid(content)){ + this.refs.editor.cancel(); + content = this.props.content; + } + this.props.onDone(content); + } +}); + +/* +Text Editor with mitmweb-specific convenience features + */ +var ValueEditor = React.createClass({displayName: "ValueEditor", + mixins: [common.ChildFocus], + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + inline: React.PropTypes.bool, + }, + render: function () { + var tag = this.props.inline ? "span" : "div"; + return React.createElement(ValidateEditor, React.__spread({}, + this.props, + {onBlur: this.onBlur, + tag: tag}) + ); + }, + focus: function () { + React.findDOMNode(this).focus(); + }, + onBlur: function(e){ + if(!e.relatedTarget){ + this.returnFocus(); + } + this.props.onBlur && this.props.onBlur(e); + } +}); + +module.exports = { + ValueEditor: ValueEditor +}; + +},{"../utils.js":26,"./common.js":4,"react":"react"}],6:[function(require,module,exports){ +var React = require("react"); +var common = require("./common.js"); var Query = require("../actions.js").Query; var VirtualScrollMixin = require("./virtualscroll.js"); var views = require("../store/view.js"); @@ -829,7 +1025,7 @@ var EventLog = React.createClass({displayName: "EventLog", module.exports = EventLog; -},{"../actions.js":2,"../store/view.js":24,"./common.js":4,"./virtualscroll.js":18,"lodash":"lodash","react":"react"}],6:[function(require,module,exports){ +},{"../actions.js":2,"../store/view.js":25,"./common.js":4,"./virtualscroll.js":19,"lodash":"lodash","react":"react"}],7:[function(require,module,exports){ var React = require("react"); var RequestUtils = require("../flow/utils.js").RequestUtils; var ResponseUtils = require("../flow/utils.js").ResponseUtils; @@ -1032,7 +1228,7 @@ var all_columns = [ module.exports = all_columns; -},{"../flow/utils.js":22,"../utils.js":25,"react":"react"}],7:[function(require,module,exports){ +},{"../flow/utils.js":23,"../utils.js":26,"react":"react"}],8:[function(require,module,exports){ var React = require("react"); var common = require("./common.js"); var utils = require("../utils.js"); @@ -1222,7 +1418,7 @@ var FlowTable = React.createClass({displayName: "FlowTable", module.exports = FlowTable; -},{"../utils.js":25,"./common.js":4,"./flowtable-columns.js":6,"./virtualscroll.js":18,"lodash":"lodash","react":"react"}],8:[function(require,module,exports){ +},{"../utils.js":26,"./common.js":4,"./flowtable-columns.js":7,"./virtualscroll.js":19,"lodash":"lodash","react":"react"}],9:[function(require,module,exports){ var React = require("react"); var _ = require("lodash"); @@ -1461,7 +1657,7 @@ var ContentView = React.createClass({displayName: "ContentView", module.exports = ContentView; -},{"../../flow/utils.js":22,"../../utils.js":25,"lodash":"lodash","react":"react"}],9:[function(require,module,exports){ +},{"../../flow/utils.js":23,"../../utils.js":26,"lodash":"lodash","react":"react"}],10:[function(require,module,exports){ var React = require("react"); var _ = require("lodash"); @@ -1644,7 +1840,7 @@ var Details = React.createClass({displayName: "Details", module.exports = Details; -},{"../../utils.js":25,"lodash":"lodash","react":"react"}],10:[function(require,module,exports){ +},{"../../utils.js":26,"lodash":"lodash","react":"react"}],11:[function(require,module,exports){ var React = require("react"); var _ = require("lodash"); @@ -1773,7 +1969,7 @@ var FlowView = React.createClass({displayName: "FlowView", module.exports = FlowView; -},{"../common.js":4,"../prompt.js":16,"./details.js":9,"./messages.js":11,"./nav.js":12,"lodash":"lodash","react":"react"}],11:[function(require,module,exports){ +},{"../common.js":4,"../prompt.js":17,"./details.js":10,"./messages.js":12,"./nav.js":13,"lodash":"lodash","react":"react"}],12:[function(require,module,exports){ var React = require("react"); var _ = require("lodash"); @@ -1782,6 +1978,7 @@ var actions = require("../../actions.js"); var flowutils = require("../../flow/utils.js"); var utils = require("../../utils.js"); var ContentView = require("./contentview.js"); +var ValueEditor = require("../editor.js").ValueEditor; var Headers = React.createClass({displayName: "Headers", propTypes: { @@ -1839,16 +2036,16 @@ var Headers = React.createClass({displayName: "Headers", var rows = this.props.message.headers.map(function (header, i) { - var kEdit = React.createElement(HeaderInlineInput, { + var kEdit = React.createElement(HeaderEditor, { ref: i + "-key", content: header[0], - onChange: this.onChange.bind(null, i, 0), + onDone: this.onChange.bind(null, i, 0), onRemove: this.onRemove.bind(null, i, 0), onTab: this.onTab.bind(null, i, 0)}); - var vEdit = React.createElement(HeaderInlineInput, { + var vEdit = React.createElement(HeaderEditor, { ref: i + "-value", content: header[1], - onChange: this.onChange.bind(null, i, 1), + onDone: this.onChange.bind(null, i, 1), onRemove: this.onRemove.bind(null, i, 1), onTab: this.onTab.bind(null, i, 1)}); return ( @@ -1868,88 +2065,9 @@ var Headers = React.createClass({displayName: "Headers", } }); - -var InlineInput = React.createClass({displayName: "InlineInput", - mixins: [common.ChildFocus], - propTypes: { - content: React.PropTypes.string.isRequired, //must be string to match strict equality. - onChange: React.PropTypes.func.isRequired, - }, - getInitialState: function () { - return { - editable: false - }; - }, +var HeaderEditor = React.createClass({displayName: "HeaderEditor", render: function () { - var Tag = this.props.tag || "span"; - var className = "inline-input " + (this.props.className || ""); - var html = {__html: _.escape(this.props.content)}; - return React.createElement(Tag, React.__spread({}, - this.props, - {tabIndex: "0", - className: className, - contentEditable: this.state.editable || undefined, - onInput: this.onInput, - onFocus: this.onFocus, - onBlur: this.onBlur, - onKeyDown: this.onKeyDown, - dangerouslySetInnerHTML: html}) - ); - }, - onKeyDown: function (e) { - e.stopPropagation(); - switch (e.keyCode) { - case utils.Key.ESC: - this.blur(); - break; - case utils.Key.ENTER: - e.preventDefault(); - if (!e.ctrlKey) { - this.blur(); - } else { - this.props.onDone && this.props.onDone(); - } - break; - default: - this.props.onKeyDown && this.props.onKeyDown(e); - break; - } - }, - blur: function () { - this.getDOMNode().blur(); - window.getSelection().removeAllRanges(); - this.context.returnFocus && this.context.returnFocus(); - }, - focus: function () { - React.findDOMNode(this).focus(); - var range = document.createRange(); - range.selectNodeContents(this.getDOMNode()); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - }, - onFocus: function () { - this.setState({editable: true}, this.focus); - }, - onBlur: function (e) { - this.setState({editable: false}); - this.handleChange(); - this.props.onDone && this.props.onDone(); - }, - onInput: function () { - this.handleChange(); - }, - handleChange: function () { - var content = this.getDOMNode().textContent; - if (content !== this.props.content) { - this.props.onChange(content); - } - } -}); - -var HeaderInlineInput = React.createClass({displayName: "HeaderInlineInput", - render: function () { - return React.createElement(InlineInput, React.__spread({ref: "input"}, this.props, {onKeyDown: this.onKeyDown})); + return React.createElement(ValueEditor, React.__spread({ref: "input"}, this.props, {onKeyDown: this.onKeyDown, inline: true})); }, focus: function () { this.getDOMNode().focus(); @@ -1971,65 +2089,6 @@ var HeaderInlineInput = React.createClass({displayName: "HeaderInlineInput", } }); -var ValidateInlineInput = React.createClass({displayName: "ValidateInlineInput", - propTypes: { - onChange: React.PropTypes.func.isRequired, - isValid: React.PropTypes.func.isRequired, - immediate: React.PropTypes.bool - }, - getInitialState: function () { - return { - content: this.props.content, - originalContent: this.props.content - }; - }, - focus: function () { - this.getDOMNode().focus(); - }, - onChange: function (val) { - this.setState({ - content: val - }); - if (this.props.immediate && val !== this.state.originalContent && this.props.isValid(val)) { - this.props.onChange(val); - } - }, - onDone: function () { - if (this.state.content === this.state.originalContent) { - return true; - } - if (this.props.isValid(this.state.content)) { - this.props.onChange(this.state.content); - } else { - this.setState({ - content: this.state.originalContent - }); - } - }, - componentWillReceiveProps: function (nextProps) { - if (nextProps.content !== this.state.content) { - this.setState({ - content: nextProps.content, - originalContent: nextProps.content - }) - } - }, - render: function () { - var className = this.props.className || ""; - if (this.props.isValid(this.state.content)) { - className += " has-success"; - } else { - className += " has-warning" - } - return React.createElement(InlineInput, React.__spread({}, this.props, - {className: className, - content: this.state.content, - onChange: this.onChange, - onDone: this.onDone}) - ); - } -}); - var RequestLine = React.createClass({displayName: "RequestLine", render: function () { var flow = this.props.flow; @@ -2037,11 +2096,25 @@ var RequestLine = React.createClass({displayName: "RequestLine", var httpver = "HTTP/" + flow.request.httpversion.join("."); return React.createElement("div", {className: "first-line request-line"}, - React.createElement(InlineInput, {ref: "method", content: flow.request.method, onChange: this.onMethodChange}), + React.createElement(ValueEditor, { + ref: "method", + content: flow.request.method, + onDone: this.onMethodChange, + inline: true}), " ", - React.createElement(ValidateInlineInput, {ref: "url", content: url, onChange: this.onUrlChange, isValid: this.isValidUrl}), + React.createElement(ValueEditor, { + ref: "url", + content: url, + onDone: this.onUrlChange, + isValid: this.isValidUrl, + inline: true}), " ", - React.createElement(ValidateInlineInput, {ref: "httpVersion", immediate: true, content: httpver, onChange: this.onHttpVersionChange, isValid: flowutils.isValidHttpVersion}) + React.createElement(ValueEditor, { + ref: "httpVersion", + content: httpver, + onDone: this.onHttpVersionChange, + isValid: flowutils.isValidHttpVersion, + inline: true}) ) }, isValidUrl: function (url) { @@ -2076,12 +2149,25 @@ var ResponseLine = React.createClass({displayName: "ResponseLine", var flow = this.props.flow; var httpver = "HTTP/" + flow.response.httpversion.join("."); return React.createElement("div", {className: "first-line response-line"}, - React.createElement(ValidateInlineInput, {ref: "httpVersion", immediate: true, content: httpver, onChange: this.onHttpVersionChange, isValid: flowutils.isValidHttpVersion}), + React.createElement(ValueEditor, { + ref: "httpVersion", + content: httpver, + onDone: this.onHttpVersionChange, + isValid: flowutils.isValidHttpVersion, + inline: true}), " ", - React.createElement(ValidateInlineInput, {ref: "code", immediate: true, content: flow.response.code + "", onChange: this.onCodeChange, isValid: this.isValidCode}), + React.createElement(ValueEditor, { + ref: "code", + content: flow.response.code + "", + onDone: this.onCodeChange, + isValid: this.isValidCode, + inline: true}), " ", - React.createElement(InlineInput, {ref: "msg", content: flow.response.msg, onChange: this.onMsgChange}) - + React.createElement(ValueEditor, { + ref: "msg", + content: flow.response.msg, + onDone: this.onMsgChange, + inline: true}) ); }, isValidCode: function (code) { @@ -2137,7 +2223,7 @@ var Request = React.createClass({displayName: "Request", this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { @@ -2177,7 +2263,7 @@ var Response = React.createClass({displayName: "Response", this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { @@ -2211,7 +2297,7 @@ module.exports = { Error: Error }; -},{"../../actions.js":2,"../../flow/utils.js":22,"../../utils.js":25,"../common.js":4,"./contentview.js":8,"lodash":"lodash","react":"react"}],12:[function(require,module,exports){ +},{"../../actions.js":2,"../../flow/utils.js":23,"../../utils.js":26,"../common.js":4,"../editor.js":5,"./contentview.js":9,"lodash":"lodash","react":"react"}],13:[function(require,module,exports){ var React = require("react"); var actions = require("../../actions.js"); @@ -2274,7 +2360,7 @@ var Nav = React.createClass({displayName: "Nav", module.exports = Nav; -},{"../../actions.js":2,"react":"react"}],13:[function(require,module,exports){ +},{"../../actions.js":2,"react":"react"}],14:[function(require,module,exports){ var React = require("react"); var common = require("./common.js"); @@ -2295,7 +2381,7 @@ var Footer = React.createClass({displayName: "Footer", module.exports = Footer; -},{"./common.js":4,"react":"react"}],14:[function(require,module,exports){ +},{"./common.js":4,"react":"react"}],15:[function(require,module,exports){ var React = require("react"); var $ = require("jquery"); @@ -2417,7 +2503,7 @@ var FilterInput = React.createClass({displayName: "FilterInput", }, blur: function () { this.refs.input.getDOMNode().blur(); - this.context.returnFocus && this.context.returnFocus(); + this.returnFocus(); }, select: function () { this.refs.input.getDOMNode().select(); @@ -2696,7 +2782,7 @@ module.exports = { MainMenu: MainMenu }; -},{"../actions.js":2,"../filt/filt.js":21,"../utils.js":25,"./common.js":4,"jquery":"jquery","react":"react"}],15:[function(require,module,exports){ +},{"../actions.js":2,"../filt/filt.js":22,"../utils.js":26,"./common.js":4,"jquery":"jquery","react":"react"}],16:[function(require,module,exports){ var React = require("react"); var actions = require("../actions.js"); @@ -2943,7 +3029,7 @@ var MainView = React.createClass({displayName: "MainView", module.exports = MainView; -},{"../actions.js":2,"../filt/filt.js":21,"../store/view.js":24,"../utils.js":25,"./common.js":4,"./flowtable.js":7,"./flowview/index.js":10,"react":"react"}],16:[function(require,module,exports){ +},{"../actions.js":2,"../filt/filt.js":22,"../store/view.js":25,"../utils.js":26,"./common.js":4,"./flowtable.js":8,"./flowview/index.js":11,"react":"react"}],17:[function(require,module,exports){ var React = require("react"); var _ = require("lodash"); @@ -2980,7 +3066,7 @@ var Prompt = React.createClass({displayName: "Prompt", }, done: function (ret) { this.props.done(ret); - this.context.returnFocus && this.context.returnFocus(); + this.returnFocus(); }, getOptions: function () { var opts = []; @@ -3045,7 +3131,7 @@ var Prompt = React.createClass({displayName: "Prompt", module.exports = Prompt; -},{"../utils.js":25,"./common.js":4,"lodash":"lodash","react":"react"}],17:[function(require,module,exports){ +},{"../utils.js":26,"./common.js":4,"lodash":"lodash","react":"react"}],18:[function(require,module,exports){ var React = require("react"); var ReactRouter = require("react-router"); var _ = require("lodash"); @@ -3176,7 +3262,7 @@ module.exports = { routes: routes }; -},{"../actions.js":2,"../store/store.js":23,"../utils.js":25,"./common.js":4,"./eventlog.js":5,"./footer.js":13,"./header.js":14,"./mainview.js":15,"lodash":"lodash","react":"react","react-router":"react-router"}],18:[function(require,module,exports){ +},{"../actions.js":2,"../store/store.js":24,"../utils.js":26,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":16,"lodash":"lodash","react":"react","react-router":"react-router"}],19:[function(require,module,exports){ var React = require("react"); var VirtualScrollMixin = { @@ -3263,7 +3349,7 @@ var VirtualScrollMixin = { module.exports = VirtualScrollMixin; -},{"react":"react"}],19:[function(require,module,exports){ +},{"react":"react"}],20:[function(require,module,exports){ var actions = require("./actions.js"); var AppDispatcher = require("./dispatcher.js").AppDispatcher; @@ -3294,7 +3380,7 @@ function Connection(url) { module.exports = Connection; -},{"./actions.js":2,"./dispatcher.js":20}],20:[function(require,module,exports){ +},{"./actions.js":2,"./dispatcher.js":21}],21:[function(require,module,exports){ var flux = require("flux"); @@ -3318,7 +3404,7 @@ module.exports = { AppDispatcher: AppDispatcher }; -},{"flux":"flux"}],21:[function(require,module,exports){ +},{"flux":"flux"}],22:[function(require,module,exports){ module.exports = (function() { /* * Generated by PEG.js 0.8.0. @@ -5094,7 +5180,7 @@ module.exports = (function() { }; })(); -},{"../flow/utils.js":22}],22:[function(require,module,exports){ +},{"../flow/utils.js":23}],23:[function(require,module,exports){ var _ = require("lodash"); var $ = require("jquery"); @@ -5226,7 +5312,7 @@ module.exports = { isValidHttpVersion: isValidHttpVersion }; -},{"jquery":"jquery","lodash":"lodash"}],23:[function(require,module,exports){ +},{"jquery":"jquery","lodash":"lodash"}],24:[function(require,module,exports){ var _ = require("lodash"); var $ = require("jquery"); @@ -5409,7 +5495,7 @@ module.exports = { FlowStore: FlowStore }; -},{"../actions.js":2,"../dispatcher.js":20,"../utils.js":25,"events":1,"jquery":"jquery","lodash":"lodash"}],24:[function(require,module,exports){ +},{"../actions.js":2,"../dispatcher.js":21,"../utils.js":26,"events":1,"jquery":"jquery","lodash":"lodash"}],25:[function(require,module,exports){ var EventEmitter = require('events').EventEmitter; var _ = require("lodash"); @@ -5526,7 +5612,7 @@ module.exports = { StoreView: StoreView }; -},{"../utils.js":25,"events":1,"lodash":"lodash"}],25:[function(require,module,exports){ +},{"../utils.js":26,"events":1,"lodash":"lodash"}],26:[function(require,module,exports){ var $ = require("jquery"); var _ = require("lodash"); var actions = require("./actions.js"); diff --git a/libmproxy/web/static/vendor.js b/libmproxy/web/static/vendor.js index fbd6b1a48..1e83ac506 100644 --- a/libmproxy/web/static/vendor.js +++ b/libmproxy/web/static/vendor.js @@ -394,6 +394,422 @@ var invariant = function(condition, format, a, b, c, d, e, f) { module.exports = invariant; },{}],4:[function(require,module,exports){ +module.exports = require('./lib/'); + +},{"./lib/":5}],5:[function(require,module,exports){ +// Load modules + +var Stringify = require('./stringify'); +var Parse = require('./parse'); + + +// Declare internals + +var internals = {}; + + +module.exports = { + stringify: Stringify, + parse: Parse +}; + +},{"./parse":6,"./stringify":7}],6:[function(require,module,exports){ +// Load modules + +var Utils = require('./utils'); + + +// Declare internals + +var internals = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000 +}; + + +internals.parseValues = function (str, options) { + + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0, il = parts.length; i < il; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[Utils.decode(part)] = ''; + } + else { + var key = Utils.decode(part.slice(0, pos)); + var val = Utils.decode(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty(key)) { + continue; + } + + if (!obj.hasOwnProperty(key)) { + obj[key] = val; + } + else { + obj[key] = [].concat(obj[key]).concat(val); + } + } + } + + return obj; +}; + + +internals.parseObject = function (chain, val, options) { + + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj = {}; + if (root === '[]') { + obj = []; + obj = obj.concat(internals.parseObject(chain, val, options)); + } + else { + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + var indexString = '' + index; + if (!isNaN(index) && + root !== cleanRoot && + indexString === cleanRoot && + index >= 0 && + index <= options.arrayLimit) { + + obj = []; + obj[index] = internals.parseObject(chain, val, options); + } + else { + obj[cleanRoot] = internals.parseObject(chain, val, options); + } + } + + return obj; +}; + + +internals.parseKeys = function (key, val, options) { + + if (!key) { + return; + } + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Don't allow them to overwrite object prototype properties + + if (Object.prototype.hasOwnProperty(segment[1])) { + return; + } + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + keys.push(segment[1]); + } + + // Loop through children appending to the array until we hit depth + + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { + + ++i; + if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + keys.push(segment[1]); + } + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return internals.parseObject(keys, val, options); +}; + + +module.exports = function (str, options) { + + if (str === '' || + str === null || + typeof str === 'undefined') { + + return {}; + } + + options = options || {}; + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; + + var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; + var obj = {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + var newObj = internals.parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj); + } + + return Utils.compact(obj); +}; + +},{"./utils":8}],7:[function(require,module,exports){ +// Load modules + +var Utils = require('./utils'); + + +// Declare internals + +var internals = { + delimiter: '&', + arrayPrefixGenerators: { + brackets: function (prefix, key) { + return prefix + '[]'; + }, + indices: function (prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function (prefix, key) { + return prefix; + } + } +}; + + +internals.stringify = function (obj, prefix, generateArrayPrefix) { + + if (Utils.isBuffer(obj)) { + obj = obj.toString(); + } + else if (obj instanceof Date) { + obj = obj.toISOString(); + } + else if (obj === null) { + obj = ''; + } + + if (typeof obj === 'string' || + typeof obj === 'number' || + typeof obj === 'boolean') { + + return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys = Object.keys(obj); + for (var i = 0, il = objKeys.length; i < il; ++i) { + var key = objKeys[i]; + if (Array.isArray(obj)) { + values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix)); + } + else { + values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix)); + } + } + + return values; +}; + + +module.exports = function (obj, options) { + + options = options || {}; + var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; + + var keys = []; + + if (typeof obj !== 'object' || + obj === null) { + + return ''; + } + + var arrayFormat; + if (options.arrayFormat in internals.arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } + else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } + else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat]; + + var objKeys = Object.keys(obj); + for (var i = 0, il = objKeys.length; i < il; ++i) { + var key = objKeys[i]; + keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix)); + } + + return keys.join(delimiter); +}; + +},{"./utils":8}],8:[function(require,module,exports){ +// Load modules + + +// Declare internals + +var internals = {}; + + +exports.arrayToObject = function (source) { + + var obj = {}; + for (var i = 0, il = source.length; i < il; ++i) { + if (typeof source[i] !== 'undefined') { + + obj[i] = source[i]; + } + } + + return obj; +}; + + +exports.merge = function (target, source) { + + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } + else { + target[source] = true; + } + + return target; + } + + if (typeof target !== 'object') { + target = [target].concat(source); + return target; + } + + if (Array.isArray(target) && + !Array.isArray(source)) { + + target = exports.arrayToObject(target); + } + + var keys = Object.keys(source); + for (var k = 0, kl = keys.length; k < kl; ++k) { + var key = keys[k]; + var value = source[key]; + + if (!target[key]) { + target[key] = value; + } + else { + target[key] = exports.merge(target[key], value); + } + } + + return target; +}; + + +exports.decode = function (str) { + + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; + + +exports.compact = function (obj, refs) { + + if (typeof obj !== 'object' || + obj === null) { + + return obj; + } + + refs = refs || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0, il = obj.length; i < il; ++i) { + if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + obj[key] = exports.compact(obj[key], refs); + } + + return obj; +}; + + +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; + + +exports.isBuffer = function (obj) { + + if (obj === null || + typeof obj === 'undefined') { + + return false; + } + + return !!(obj.constructor && + obj.constructor.isBuffer && + obj.constructor.isBuffer(obj)); +}; + +},{}],9:[function(require,module,exports){ "use strict"; /** @@ -403,7 +819,7 @@ module.exports = invariant; function Cancellation() {} module.exports = Cancellation; -},{}],5:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); @@ -434,7 +850,7 @@ var History = { }; module.exports = History; -},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],6:[function(require,module,exports){ +},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],11:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -512,7 +928,7 @@ var Match = (function () { })(); module.exports = Match; -},{"./PathUtils":8}],7:[function(require,module,exports){ +},{"./PathUtils":13}],12:[function(require,module,exports){ "use strict"; var warning = require("react/lib/warning"); @@ -592,7 +1008,7 @@ var Navigation = { }; module.exports = Navigation; -},{"./PropTypes":9,"react/lib/warning":212}],8:[function(require,module,exports){ +},{"./PropTypes":14,"react/lib/warning":212}],13:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); @@ -746,7 +1162,7 @@ var PathUtils = { }; module.exports = PathUtils; -},{"object-assign":36,"qs":37,"react/lib/invariant":191}],9:[function(require,module,exports){ +},{"object-assign":41,"qs":4,"react/lib/invariant":191}],14:[function(require,module,exports){ "use strict"; var assign = require("react/lib/Object.assign"); @@ -778,7 +1194,7 @@ var PropTypes = assign({}, ReactPropTypes, { }); module.exports = PropTypes; -},{"./Route":11,"react":"react","react/lib/Object.assign":69}],10:[function(require,module,exports){ +},{"./Route":16,"react":"react","react/lib/Object.assign":69}],15:[function(require,module,exports){ "use strict"; /** @@ -791,7 +1207,7 @@ function Redirect(to, params, query) { } module.exports = Redirect; -},{}],11:[function(require,module,exports){ +},{}],16:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -999,7 +1415,7 @@ var Route = (function () { })(); module.exports = Route; -},{"./PathUtils":8,"react/lib/Object.assign":69,"react/lib/invariant":191,"react/lib/warning":212}],12:[function(require,module,exports){ +},{"./PathUtils":13,"react/lib/Object.assign":69,"react/lib/invariant":191,"react/lib/warning":212}],17:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); @@ -1075,7 +1491,7 @@ var ScrollHistory = { }; module.exports = ScrollHistory; -},{"./getWindowScrollPosition":27,"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],13:[function(require,module,exports){ +},{"./getWindowScrollPosition":32,"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],18:[function(require,module,exports){ "use strict"; var warning = require("react/lib/warning"); @@ -1159,7 +1575,7 @@ var State = { }; module.exports = State; -},{"./PropTypes":9,"react/lib/warning":212}],14:[function(require,module,exports){ +},{"./PropTypes":14,"react/lib/warning":212}],19:[function(require,module,exports){ "use strict"; /* jshint -W058 */ @@ -1235,7 +1651,7 @@ Transition.to = function (transition, routes, params, query, callback) { }; module.exports = Transition; -},{"./Cancellation":4,"./Redirect":10}],15:[function(require,module,exports){ +},{"./Cancellation":9,"./Redirect":15}],20:[function(require,module,exports){ "use strict"; /** @@ -1261,7 +1677,7 @@ var LocationActions = { }; module.exports = LocationActions; -},{}],16:[function(require,module,exports){ +},{}],21:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); @@ -1291,7 +1707,7 @@ var ImitateBrowserBehavior = { }; module.exports = ImitateBrowserBehavior; -},{"../actions/LocationActions":15}],17:[function(require,module,exports){ +},{"../actions/LocationActions":20}],22:[function(require,module,exports){ "use strict"; /** @@ -1307,7 +1723,7 @@ var ScrollToTopBehavior = { }; module.exports = ScrollToTopBehavior; -},{}],18:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -1347,7 +1763,7 @@ var ContextWrapper = (function (_React$Component) { })(React.Component); module.exports = ContextWrapper; -},{"react":"react"}],19:[function(require,module,exports){ +},{"react":"react"}],24:[function(require,module,exports){ "use strict"; var _inherits = function (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) subClass.__proto__ = superClass; }; @@ -1395,7 +1811,7 @@ DefaultRoute.defaultProps = { }; module.exports = DefaultRoute; -},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],20:[function(require,module,exports){ +},{"../PropTypes":14,"./Route":28,"./RouteHandler":29}],25:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -1534,7 +1950,7 @@ Link.defaultProps = { }; module.exports = Link; -},{"../PropTypes":9,"react":"react","react/lib/Object.assign":69}],21:[function(require,module,exports){ +},{"../PropTypes":14,"react":"react","react/lib/Object.assign":69}],26:[function(require,module,exports){ "use strict"; var _inherits = function (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) subClass.__proto__ = superClass; }; @@ -1583,7 +1999,7 @@ NotFoundRoute.defaultProps = { }; module.exports = NotFoundRoute; -},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],22:[function(require,module,exports){ +},{"../PropTypes":14,"./Route":28,"./RouteHandler":29}],27:[function(require,module,exports){ "use strict"; var _inherits = function (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) subClass.__proto__ = superClass; }; @@ -1627,7 +2043,7 @@ Redirect.propTypes = { Redirect.defaultProps = {}; module.exports = Redirect; -},{"../PropTypes":9,"./Route":23}],23:[function(require,module,exports){ +},{"../PropTypes":14,"./Route":28}],28:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -1720,7 +2136,7 @@ Route.defaultProps = { }; module.exports = Route; -},{"../PropTypes":9,"./RouteHandler":24,"react":"react","react/lib/invariant":191}],24:[function(require,module,exports){ +},{"../PropTypes":14,"./RouteHandler":29,"react":"react","react/lib/invariant":191}],29:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -1821,7 +2237,7 @@ RouteHandler.childContextTypes = { }; module.exports = RouteHandler; -},{"../PropTypes":9,"./ContextWrapper":18,"react":"react","react/lib/Object.assign":69}],25:[function(require,module,exports){ +},{"../PropTypes":14,"./ContextWrapper":23,"react":"react","react/lib/Object.assign":69}],30:[function(require,module,exports){ (function (process){ "use strict"; @@ -2338,7 +2754,7 @@ function createRouter(options) { module.exports = createRouter; }).call(this,require('_process')) -},{"./Cancellation":4,"./History":5,"./Match":6,"./PathUtils":8,"./PropTypes":9,"./Redirect":10,"./Route":11,"./ScrollHistory":12,"./Transition":14,"./actions/LocationActions":15,"./behaviors/ImitateBrowserBehavior":16,"./createRoutesFromReactChildren":26,"./isReactChildren":28,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./supportsHistory":35,"_process":1,"react":"react","react/lib/ExecutionEnvironment":62,"react/lib/invariant":191,"react/lib/warning":212}],26:[function(require,module,exports){ +},{"./Cancellation":9,"./History":10,"./Match":11,"./PathUtils":13,"./PropTypes":14,"./Redirect":15,"./Route":16,"./ScrollHistory":17,"./Transition":19,"./actions/LocationActions":20,"./behaviors/ImitateBrowserBehavior":21,"./createRoutesFromReactChildren":31,"./isReactChildren":33,"./locations/HashLocation":34,"./locations/HistoryLocation":35,"./locations/RefreshLocation":36,"./locations/StaticLocation":37,"./supportsHistory":40,"_process":1,"react":"react","react/lib/ExecutionEnvironment":62,"react/lib/invariant":191,"react/lib/warning":212}],31:[function(require,module,exports){ "use strict"; /* jshint -W084 */ @@ -2420,7 +2836,7 @@ function createRoutesFromReactChildren(children) { } module.exports = createRoutesFromReactChildren; -},{"./Route":11,"./components/DefaultRoute":19,"./components/NotFoundRoute":21,"./components/Redirect":22,"react":"react","react/lib/Object.assign":69,"react/lib/warning":212}],27:[function(require,module,exports){ +},{"./Route":16,"./components/DefaultRoute":24,"./components/NotFoundRoute":26,"./components/Redirect":27,"react":"react","react/lib/Object.assign":69,"react/lib/warning":212}],32:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); @@ -2439,7 +2855,7 @@ function getWindowScrollPosition() { } module.exports = getWindowScrollPosition; -},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],28:[function(require,module,exports){ +},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],33:[function(require,module,exports){ "use strict"; var React = require("react"); @@ -2453,7 +2869,7 @@ function isReactChildren(object) { } module.exports = isReactChildren; -},{"react":"react"}],29:[function(require,module,exports){ +},{"react":"react"}],34:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); @@ -2565,7 +2981,7 @@ var HashLocation = { }; module.exports = HashLocation; -},{"../History":5,"../actions/LocationActions":15}],30:[function(require,module,exports){ +},{"../History":10,"../actions/LocationActions":20}],35:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); @@ -2652,7 +3068,7 @@ var HistoryLocation = { }; module.exports = HistoryLocation; -},{"../History":5,"../actions/LocationActions":15}],31:[function(require,module,exports){ +},{"../History":10,"../actions/LocationActions":20}],36:[function(require,module,exports){ "use strict"; var HistoryLocation = require("./HistoryLocation"); @@ -2684,7 +3100,7 @@ var RefreshLocation = { }; module.exports = RefreshLocation; -},{"../History":5,"./HistoryLocation":30}],32:[function(require,module,exports){ +},{"../History":10,"./HistoryLocation":35}],37:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -2735,7 +3151,7 @@ StaticLocation.prototype.replace = throwCannotModify; StaticLocation.prototype.pop = throwCannotModify; module.exports = StaticLocation; -},{"react/lib/invariant":191}],33:[function(require,module,exports){ +},{"react/lib/invariant":191}],38:[function(require,module,exports){ "use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); @@ -2831,7 +3247,7 @@ var TestLocation = (function () { })(); module.exports = TestLocation; -},{"../History":5,"../actions/LocationActions":15,"react/lib/invariant":191}],34:[function(require,module,exports){ +},{"../History":10,"../actions/LocationActions":20,"react/lib/invariant":191}],39:[function(require,module,exports){ "use strict"; var createRouter = require("./createRouter"); @@ -2882,7 +3298,7 @@ function runRouter(routes, location, callback) { } module.exports = runRouter; -},{"./createRouter":25}],35:[function(require,module,exports){ +},{"./createRouter":30}],40:[function(require,module,exports){ "use strict"; function supportsHistory() { @@ -2899,7 +3315,7 @@ function supportsHistory() { } module.exports = supportsHistory; -},{}],36:[function(require,module,exports){ +},{}],41:[function(require,module,exports){ 'use strict'; function ToObject(val) { @@ -2927,422 +3343,6 @@ module.exports = Object.assign || function (target, source) { return to; }; -},{}],37:[function(require,module,exports){ -module.exports = require('./lib/'); - -},{"./lib/":38}],38:[function(require,module,exports){ -// Load modules - -var Stringify = require('./stringify'); -var Parse = require('./parse'); - - -// Declare internals - -var internals = {}; - - -module.exports = { - stringify: Stringify, - parse: Parse -}; - -},{"./parse":39,"./stringify":40}],39:[function(require,module,exports){ -// Load modules - -var Utils = require('./utils'); - - -// Declare internals - -var internals = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000 -}; - - -internals.parseValues = function (str, options) { - - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); - - for (var i = 0, il = parts.length; i < il; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; - - if (pos === -1) { - obj[Utils.decode(part)] = ''; - } - else { - var key = Utils.decode(part.slice(0, pos)); - var val = Utils.decode(part.slice(pos + 1)); - - if (Object.prototype.hasOwnProperty(key)) { - continue; - } - - if (!obj.hasOwnProperty(key)) { - obj[key] = val; - } - else { - obj[key] = [].concat(obj[key]).concat(val); - } - } - } - - return obj; -}; - - -internals.parseObject = function (chain, val, options) { - - if (!chain.length) { - return val; - } - - var root = chain.shift(); - - var obj = {}; - if (root === '[]') { - obj = []; - obj = obj.concat(internals.parseObject(chain, val, options)); - } - else { - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; - var index = parseInt(cleanRoot, 10); - var indexString = '' + index; - if (!isNaN(index) && - root !== cleanRoot && - indexString === cleanRoot && - index >= 0 && - index <= options.arrayLimit) { - - obj = []; - obj[index] = internals.parseObject(chain, val, options); - } - else { - obj[cleanRoot] = internals.parseObject(chain, val, options); - } - } - - return obj; -}; - - -internals.parseKeys = function (key, val, options) { - - if (!key) { - return; - } - - // The regex chunks - - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; - - // Get the parent - - var segment = parent.exec(key); - - // Don't allow them to overwrite object prototype properties - - if (Object.prototype.hasOwnProperty(segment[1])) { - return; - } - - // Stash the parent if it exists - - var keys = []; - if (segment[1]) { - keys.push(segment[1]); - } - - // Loop through children appending to the array until we hit depth - - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { - - ++i; - if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - keys.push(segment[1]); - } - } - - // If there's a remainder, just add whatever is left - - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } - - return internals.parseObject(keys, val, options); -}; - - -module.exports = function (str, options) { - - if (str === '' || - str === null || - typeof str === 'undefined') { - - return {}; - } - - options = options || {}; - options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; - - var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; - var obj = {}; - - // Iterate over the keys and setup the new object - - var keys = Object.keys(tempObj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - var newObj = internals.parseKeys(key, tempObj[key], options); - obj = Utils.merge(obj, newObj); - } - - return Utils.compact(obj); -}; - -},{"./utils":41}],40:[function(require,module,exports){ -// Load modules - -var Utils = require('./utils'); - - -// Declare internals - -var internals = { - delimiter: '&', - arrayPrefixGenerators: { - brackets: function (prefix, key) { - return prefix + '[]'; - }, - indices: function (prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function (prefix, key) { - return prefix; - } - } -}; - - -internals.stringify = function (obj, prefix, generateArrayPrefix) { - - if (Utils.isBuffer(obj)) { - obj = obj.toString(); - } - else if (obj instanceof Date) { - obj = obj.toISOString(); - } - else if (obj === null) { - obj = ''; - } - - if (typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean') { - - return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; - } - - var values = []; - - if (typeof obj === 'undefined') { - return values; - } - - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - if (Array.isArray(obj)) { - values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix)); - } - else { - values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix)); - } - } - - return values; -}; - - -module.exports = function (obj, options) { - - options = options || {}; - var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; - - var keys = []; - - if (typeof obj !== 'object' || - obj === null) { - - return ''; - } - - var arrayFormat; - if (options.arrayFormat in internals.arrayPrefixGenerators) { - arrayFormat = options.arrayFormat; - } - else if ('indices' in options) { - arrayFormat = options.indices ? 'indices' : 'repeat'; - } - else { - arrayFormat = 'indices'; - } - - var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat]; - - var objKeys = Object.keys(obj); - for (var i = 0, il = objKeys.length; i < il; ++i) { - var key = objKeys[i]; - keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix)); - } - - return keys.join(delimiter); -}; - -},{"./utils":41}],41:[function(require,module,exports){ -// Load modules - - -// Declare internals - -var internals = {}; - - -exports.arrayToObject = function (source) { - - var obj = {}; - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { - - obj[i] = source[i]; - } - } - - return obj; -}; - - -exports.merge = function (target, source) { - - if (!source) { - return target; - } - - if (typeof source !== 'object') { - if (Array.isArray(target)) { - target.push(source); - } - else { - target[source] = true; - } - - return target; - } - - if (typeof target !== 'object') { - target = [target].concat(source); - return target; - } - - if (Array.isArray(target) && - !Array.isArray(source)) { - - target = exports.arrayToObject(target); - } - - var keys = Object.keys(source); - for (var k = 0, kl = keys.length; k < kl; ++k) { - var key = keys[k]; - var value = source[key]; - - if (!target[key]) { - target[key] = value; - } - else { - target[key] = exports.merge(target[key], value); - } - } - - return target; -}; - - -exports.decode = function (str) { - - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } -}; - - -exports.compact = function (obj, refs) { - - if (typeof obj !== 'object' || - obj === null) { - - return obj; - } - - refs = refs || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; - } - - refs.push(obj); - - if (Array.isArray(obj)) { - var compacted = []; - - for (var i = 0, il = obj.length; i < il; ++i) { - if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } - - return compacted; - } - - var keys = Object.keys(obj); - for (i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - obj[key] = exports.compact(obj[key], refs); - } - - return obj; -}; - - -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; - - -exports.isBuffer = function (obj) { - - if (obj === null || - typeof obj === 'undefined') { - - return false; - } - - return !!(obj.constructor && - obj.constructor.isBuffer && - obj.constructor.isBuffer(obj)); -}; - },{}],42:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. @@ -34265,7 +34265,7 @@ return jQuery; (function (global){ /** * @license - * lodash 3.5.0 (Custom Build) + * lodash 3.6.0 (Custom Build) * Build: `lodash modern -d -o ./index.js` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.2 @@ -34278,7 +34278,7 @@ return jQuery; var undefined; /** Used as the semantic version number. */ - var VERSION = '3.5.0'; + var VERSION = '3.6.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -34288,8 +34288,8 @@ return jQuery; CURRY_RIGHT_FLAG = 16, PARTIAL_FLAG = 32, PARTIAL_RIGHT_FLAG = 64, - REARG_FLAG = 128, - ARY_FLAG = 256; + ARY_FLAG = 128, + REARG_FLAG = 256; /** Used as default options for `_.trunc`. */ var DEFAULT_TRUNC_LENGTH = 30, @@ -34353,18 +34353,18 @@ return jQuery; reInterpolate = /<%=([\s\S]+?)%>/g; /** - * Used to match ES template delimiters. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) - * for more details. + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + */ + var reComboMarks = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** + * Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ var reFlags = /\w*$/; - /** Used to detect named functions. */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - /** Used to detect hexadecimal string values. */ var reHexPrefix = /^0[xX]/; @@ -34378,16 +34378,13 @@ return jQuery; var reNoMatch = /($^)/; /** - * Used to match `RegExp` special characters. - * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special) - * for more details. + * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). + * In addition to special characters the forward slash is escaped to allow for + * easier `eval` use and `Function` compilation. */ var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, reHasRegExpChars = RegExp(reRegExpChars.source); - /** Used to detect functions containing a `this` reference. */ - var reThis = /\bthis\b/; - /** Used to match unescaped characters in compiled string literals. */ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; @@ -34418,7 +34415,7 @@ return jQuery; 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - 'window', 'WinRTError' + 'window' ]; /** Used to make template sourceURLs easier to identify. */ @@ -34527,8 +34524,11 @@ return jQuery; /** Detect free variable `global` from Node.js. */ var freeGlobal = freeExports && freeModule && typeof 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; + var freeWindow = objectTypes[typeof window] && window && window.Object && window; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; @@ -34539,7 +34539,7 @@ return jQuery; * The `this` value is used if it is the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || this; + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; /*--------------------------------------------------------------------------*/ @@ -34567,6 +34567,28 @@ return jQuery; 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; + } + /** * The base implementation of `_.indexOf` without support for binary searches. * @@ -34753,7 +34775,6 @@ return jQuery; /** * Gets the index at which the first occurrence of `NaN` is found in `array`. - * If `fromRight` is provided elements of `array` are iterated from right to left. * * @private * @param {Array} array The array to search. @@ -34782,7 +34803,7 @@ return jQuery; * @returns {boolean} Returns `true` if `value` is object-like, else `false`. */ function isObjectLike(value) { - return (value && typeof value == 'object') || false; + return !!value && typeof value == 'object'; } /** @@ -34904,19 +34925,19 @@ return jQuery; * @returns {Function} Returns a new `lodash` function. * @example * - * _.mixin({ 'add': function(a, b) { return a + b; } }); + * _.mixin({ 'foo': _.constant('foo') }); * * var lodash = _.runInContext(); - * lodash.mixin({ 'sub': function(a, b) { return a - b; } }); + * lodash.mixin({ 'bar': lodash.constant('bar') }); * - * _.isFunction(_.add); + * _.isFunction(_.foo); * // => true - * _.isFunction(_.sub); + * _.isFunction(_.bar); * // => false * - * lodash.isFunction(lodash.add); + * lodash.isFunction(lodash.foo); * // => false - * lodash.isFunction(lodash.sub); + * lodash.isFunction(lodash.bar); * // => true * * // using `context` to mock `Date#getTime` use in `_.now` @@ -34969,9 +34990,8 @@ return jQuery; var idCounter = 0; /** - * Used to resolve the `toStringTag` of values. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) - * for more details. + * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * of values. */ var objToString = objectProto.toString; @@ -35036,15 +35056,17 @@ return jQuery; var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; /** - * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * for more details. + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * of an array-like value. */ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap; + /** Used to lookup unminified function names. */ + var realNames = {}; + /*------------------------------------------------------------------------*/ /** @@ -35194,7 +35216,7 @@ return jQuery; * @memberOf _.support * @type boolean */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + support.funcDecomp = /\bthis\b/.test(function() { return this; }); /** * Detect if `Function#name` is supported (all but IE). @@ -35570,7 +35592,7 @@ return jQuery; /** * A specialized version of `_.forEach` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35591,7 +35613,7 @@ return jQuery; /** * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands or `this` binding. + * callback shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35611,7 +35633,7 @@ return jQuery; /** * A specialized version of `_.every` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35633,7 +35655,7 @@ return jQuery; /** * A specialized version of `_.filter` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35657,7 +35679,7 @@ return jQuery; /** * A specialized version of `_.map` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35719,7 +35741,7 @@ return jQuery; /** * A specialized version of `_.reduce` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35744,7 +35766,7 @@ return jQuery; /** * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands or `this` binding. + * callback shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35767,7 +35789,7 @@ return jQuery; /** * A specialized version of `_.some` for arrays without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array} array The array to iterate over. @@ -35787,6 +35809,23 @@ return jQuery; return false; } + /** + * A specialized version of `_.sum` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {number} Returns the sum. + */ + function arraySum(array) { + var length = array.length, + result = 0; + + while (length--) { + result += +array[length] || 0; + } + return result; + } + /** * Used by `_.defaults` to customize its `_.assign` use. * @@ -35901,26 +35940,6 @@ return jQuery; return object; } - /** - * The base implementation of `_.bindAll` without support for individual - * method name arguments. - * - * @private - * @param {Object} object The object to bind and assign the bound methods to. - * @param {string[]} methodNames The object method names to bind. - * @returns {Object} Returns `object`. - */ - function baseBindAll(object, methodNames) { - var index = -1, - length = methodNames.length; - - while (++index < length) { - var key = methodNames[index]; - object[key] = createWrapper(object[key], BIND_FLAG, object); - } - return object; - } - /** * The base implementation of `_.callback` which supports specifying the * number of arguments to provide to `func`. @@ -35934,9 +35953,9 @@ return jQuery; function baseCallback(func, thisArg, argCount) { var type = typeof func; if (type == 'function') { - return (typeof thisArg != 'undefined' && isBindable(func)) - ? bindCallback(func, thisArg, argCount) - : func; + return typeof thisArg == 'undefined' + ? func + : bindCallback(func, thisArg, argCount); } if (func == null) { return identity; @@ -36043,14 +36062,14 @@ return jQuery; * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The `arguments` object to slice and provide to `func`. + * @param {Object} args The arguments provide to `func`. * @returns {number} Returns the timer id. */ - function baseDelay(func, wait, args, fromIndex) { + function baseDelay(func, wait, args) { if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait); + return setTimeout(function() { func.apply(undefined, args); }, wait); } /** @@ -36109,21 +36128,7 @@ return jQuery; * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object|string} Returns `collection`. */ - function baseEach(collection, iteratee) { - var length = collection ? collection.length : 0; - if (!isLength(length)) { - return baseForOwn(collection, iteratee); - } - var index = -1, - iterable = toObject(collection); - - while (++index < length) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - } + var baseEach = createBaseEach(baseForOwn); /** * The base implementation of `_.forEachRight` without support for callback @@ -36134,23 +36139,11 @@ return jQuery; * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object|string} Returns `collection`. */ - function baseEachRight(collection, iteratee) { - var length = collection ? collection.length : 0; - if (!isLength(length)) { - return baseForOwnRight(collection, iteratee); - } - var iterable = toObject(collection); - while (length--) { - if (iteratee(iterable[length], length, iterable) === false) { - break; - } - } - return collection; - } + var baseEachRight = createBaseEach(baseForOwnRight, true); /** * The base implementation of `_.every` without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array|Object|string} collection The collection to iterate over. @@ -36199,7 +36192,7 @@ return jQuery; /** * The base implementation of `_.filter` without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Array|Object|string} collection The collection to iterate over. @@ -36248,11 +36241,10 @@ return jQuery; * @param {Array} array The array to flatten. * @param {boolean} isDeep Specify a deep flatten. * @param {boolean} isStrict Restrict flattening to arrays and `arguments` objects. - * @param {number} fromIndex The index to start from. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict, fromIndex) { - var index = fromIndex - 1, + function baseFlatten(array, isDeep, isStrict) { + var index = -1, length = array.length, resIndex = -1, result = []; @@ -36263,7 +36255,7 @@ return jQuery; if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) { if (isDeep) { // Recursively flatten arrays (susceptible to call stack limits). - value = baseFlatten(value, isDeep, isStrict, 0); + value = baseFlatten(value, isDeep, isStrict); } var valIndex = -1, valLength = value.length; @@ -36291,20 +36283,7 @@ return jQuery; * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseFor(object, iteratee, keysFunc) { - var index = -1, - iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (++index < length) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } + var baseFor = createBaseFor(); /** * This function is like `baseFor` except that it iterates over properties @@ -36316,19 +36295,7 @@ return jQuery; * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ - function baseForRight(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[length]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - } + var baseForRight = createBaseFor(true); /** * The base implementation of `_.forIn` without support for callback @@ -36393,30 +36360,6 @@ return jQuery; return result; } - /** - * The base implementation of `_.invoke` which requires additional arguments - * to be provided as an array of arguments rather than individually. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {Array} [args] The arguments to invoke the method with. - * @returns {Array} Returns the array of results. - */ - function baseInvoke(collection, methodName, args) { - var index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = isLength(length) ? Array(length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? methodName : (value != null && value[methodName]); - result[++index] = func ? func.apply(value, args) : undefined; - }); - return result; - } - /** * The base implementation of `_.isEqual` without support for `this` binding * `customizer` functions. @@ -36425,12 +36368,12 @@ return jQuery; * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {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, isWhere, stackA, stackB) { + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { // Exit early for identical values. if (value === other) { // Treat `+0` vs. `-0` as not equal. @@ -36445,7 +36388,7 @@ return jQuery; // Return `false` unless both values are `NaN`. return value !== value && other !== other; } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB); + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); } /** @@ -36458,12 +36401,12 @@ return jQuery; * @param {Object} other The other object to compare. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {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, isWhere, stackA, stackB) { + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = arrayTag, @@ -36485,21 +36428,27 @@ return jQuery; othIsArr = isTypedArray(other); } } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, + var objIsObj = (objTag == objectTag || (isLoose && objTag == funcTag)), + othIsObj = (othTag == objectTag || (isLoose && othTag == funcTag)), isSameTag = objTag == othTag; if (isSameTag && !(objIsArr || objIsObj)) { return equalByTag(object, other, objTag); } - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + if (isLoose) { + if (!isSameTag && !(objIsObj && othIsObj)) { + return false; + } + } else { + var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); - } - if (!isSameTag) { - return false; + if (valWrapped || othWrapped) { + return equalFunc(valWrapped ? object.value() : object, othWrapped ? 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. @@ -36516,7 +36465,7 @@ return jQuery; stackA.push(object); stackB.push(other); - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB); + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); stackA.pop(); stackB.pop(); @@ -36526,7 +36475,7 @@ return jQuery; /** * The base implementation of `_.isMatch` without support for callback - * shorthands or `this` binding. + * shorthands and `this` binding. * * @private * @param {Object} object The object to inspect. @@ -36537,30 +36486,27 @@ return jQuery; * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, props, values, strictCompareFlags, customizer) { - var length = props.length; - if (object == null) { - return !length; - } var index = -1, + length = props.length, noCustomizer = !customizer; while (++index < length) { if ((noCustomizer && strictCompareFlags[index]) ? values[index] !== object[props[index]] - : !hasOwnProperty.call(object, props[index]) + : !(props[index] in object) ) { return false; } } index = -1; while (++index < length) { - var key = props[index]; - if (noCustomizer && strictCompareFlags[index]) { - var result = hasOwnProperty.call(object, key); - } else { - var objValue = object[key], - srcValue = values[index]; + var key = props[index], + objValue = object[key], + srcValue = values[index]; + if (noCustomizer && strictCompareFlags[index]) { + var result = typeof objValue != 'undefined' || (key in object); + } else { result = customizer ? customizer(objValue, srcValue, key) : undefined; if (typeof result == 'undefined') { result = baseIsEqual(srcValue, objValue, customizer, true); @@ -36575,7 +36521,7 @@ return jQuery; /** * The base implementation of `_.map` without support for callback shorthands - * or `this` binding. + * and `this` binding. * * @private * @param {Array|Object|string} collection The collection to iterate over. @@ -36601,13 +36547,17 @@ return jQuery; var props = keys(source), length = props.length; + if (!length) { + return constant(true); + } if (length == 1) { var key = props[0], value = source[key]; if (isStrictComparable(value)) { return function(object) { - return object != null && object[key] === value && hasOwnProperty.call(object, key); + return object != null && object[key] === value && + (typeof value != 'undefined' || (key in toObject(object))); }; } } @@ -36620,7 +36570,7 @@ return jQuery; strictCompareFlags[length] = isStrictComparable(value); } return function(object) { - return baseIsMatch(object, props, values, strictCompareFlags); + return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); }; } @@ -36636,7 +36586,8 @@ return jQuery; function baseMatchesProperty(key, value) { if (isStrictComparable(value)) { return function(object) { - return object != null && object[key] === value; + return object != null && object[key] === value && + (typeof value != 'undefined' || (key in toObject(object))); }; } return function(object) { @@ -36716,7 +36667,7 @@ return jQuery; if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { result = isArray(value) ? value - : (value ? arrayCopy(value) : []); + : ((value && value.length) ? arrayCopy(value) : []); } else if (isPlainObject(srcValue) || isArguments(srcValue)) { result = isArguments(value) @@ -36753,30 +36704,6 @@ return jQuery; }; } - /** - * The base implementation of `_.pullAt` without support for individual - * index arguments. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - */ - function basePullAt(array, indexes) { - var length = indexes.length, - result = baseAt(array, indexes); - - indexes.sort(baseCompareAscending); - while (length--) { - var index = parseFloat(indexes[length]); - if (index != previous && isIndex(index)) { - var previous = index; - splice.call(array, index, 1); - } - } - return result; - } - /** * The base implementation of `_.random` without support for argument juggling * and returning floating-point numbers. @@ -36792,7 +36719,7 @@ return jQuery; /** * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands or `this` binding, which iterates over `collection` + * for callback shorthands and `this` binding, which iterates over `collection` * using the provided `eachFunc`. * * @private @@ -36859,7 +36786,7 @@ return jQuery; /** * The base implementation of `_.some` without support for callback shorthands - * or `this` binding. + * and `this` binding. * * @private * @param {Array|Object|string} collection The collection to iterate over. @@ -36926,6 +36853,23 @@ return jQuery; }); } + /** + * 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; + } + /** * The base implementation of `_.uniq` without support for callback shorthands * and `this` binding. @@ -36999,6 +36943,27 @@ return jQuery; return result; } + /** + * 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; + + 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)); + } + /** * The base implementation of `wrapperValue` which returns the result of * performing a sequence of actions on the unwrapped `value`, where each @@ -37007,7 +36972,7 @@ return jQuery; * @private * @param {*} value The unwrapped value. * @param {Array} actions Actions to peform to resolve the unwrapped value. - * @returns {*} Returns the resolved unwrapped value. + * @returns {*} Returns the resolved value. */ function baseWrapperValue(value, actions) { var result = value; @@ -37034,8 +36999,7 @@ return jQuery; * @private * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest, instead - * of the lowest, index at which a value should be inserted into `array`. + * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ @@ -37068,8 +37032,7 @@ return jQuery; * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [retHighest] Specify returning the highest, instead - * of the lowest, index at which a value should be inserted into `array`. + * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ @@ -37235,6 +37198,9 @@ return jQuery; * object composed from the results of running each element in the collection * through an iteratee. * + * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, + * and `_.partition`. + * * @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. @@ -37266,6 +37232,8 @@ return jQuery; * Creates a function that assigns properties of source object(s) to a given * destination object. * + * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. @@ -37305,6 +37273,56 @@ return jQuery; }; } + /** + * 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 ? collection.length : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * 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; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + /** * Creates a function that wraps `func` and invokes it with the `this` * binding of `thisArg`. @@ -37335,41 +37353,6 @@ return jQuery; return new SetCache(values); }; - /** - * Creates a function to compose other functions into a single function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new composer function. - */ - function createComposer(fromRight) { - return function() { - var length = arguments.length, - index = length, - fromIndex = fromRight ? (length - 1) : 0; - - if (!length) { - return function() { return arguments[0]; }; - } - var funcs = Array(length); - while (index--) { - funcs[index] = arguments[index]; - if (typeof funcs[index] != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - return function() { - var index = fromIndex, - result = funcs[index].apply(this, arguments); - - while ((fromRight ? index-- : ++index < length)) { - result = funcs[index].call(this, result); - } - return result; - }; - }; - } - /** * Creates a function that produces compound words out of the words in a * given string. @@ -37412,7 +37395,26 @@ return jQuery; } /** - * Creates a function that gets the extremum value of a collection. + * 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 = null; + } + var result = createWrapper(func, flag, null, null, null, null, null, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.max` or `_.min` function. * * @private * @param {Function} arrayFunc The function to get the extremum value from an array. @@ -37444,6 +37446,204 @@ return jQuery; }; } + /** + * 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); + } + } + + /** + * 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); + }; + } + + /** + * 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 length = arguments.length; + if (!length) { + return function() { return arguments[0]; }; + } + var wrapper, + 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); + } + var funcName = wrapper ? '' : getFuncName(func); + wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper; + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + funcName = getFuncName(func); + + var data = funcName == 'wrapper' ? getData(func) : null; + if (data && isLaziable(data[0])) { + 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; + if (wrapper && args.length == 1 && isArray(args[0])) { + return wrapper.plant(args[0]).value(); + } + var index = 0, + result = funcs[index].apply(this, args); + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * 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' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * 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' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * 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' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * 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 string && ((fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string)); + }; + } + + /** + * 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, null, partials, holders); + }); + return partialFunc; + } + + /** + * 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' && typeof 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. @@ -37507,7 +37707,12 @@ return jQuery; if (!isCurryBound) { bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); } - var result = createHybridWrapper(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity); + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } result.placeholder = placeholder; return result; } @@ -37529,9 +37734,8 @@ return jQuery; } /** - * Creates the pad required for `string` based on the given padding length. - * The `chars` string may be truncated if the number of padding characters - * exceeds the padding length. + * 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. @@ -37539,7 +37743,7 @@ return jQuery; * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the pad for `string`. */ - function createPad(string, length, chars) { + function createPadding(string, length, chars) { var strLength = string.length; length = +length; @@ -37588,6 +37792,22 @@ return jQuery; return wrapper; } + /** + * 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 func = getCallback(iteratee); + return (func === baseCallback && iteratee == null) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, func(iteratee, thisArg, 1), retHighest); + }; + } + /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. @@ -37630,10 +37850,10 @@ return jQuery; partials = holders = null; } - var data = !isBindKey && getData(func), + var data = isBindKey ? null : getData(func), newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - if (data && data !== true) { + if (data) { mergeData(newData, data); bitmask = newData[1]; arity = newData[9]; @@ -37662,18 +37882,18 @@ return jQuery; * @param {Array} other The other array to compare. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {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, isWhere, stackA, stackB) { + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { var index = -1, arrLength = array.length, othLength = other.length, result = true; - if (arrLength != othLength && !(isWhere && othLength > arrLength)) { + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { return false; } // Deep compare the contents, ignoring non-numeric properties. @@ -37683,23 +37903,23 @@ return jQuery; result = undefined; if (customizer) { - result = isWhere + result = isLoose ? customizer(othValue, arrValue, index) : customizer(arrValue, othValue, index); } if (typeof result == 'undefined') { // Recursively compare arrays (susceptible to call stack limits). - if (isWhere) { + if (isLoose) { var othIndex = othLength; while (othIndex--) { othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); if (result) { break; } } } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); } } } @@ -37755,26 +37975,26 @@ return jQuery; * @param {Object} other The other object to compare. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {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 equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) { + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { var objProps = keys(object), objLength = objProps.length, othProps = keys(other), othLength = othProps.length; - if (objLength != othLength && !isWhere) { + if (objLength != othLength && !isLoose) { return false; } - var hasCtor, + var skipCtor = isLoose, index = -1; while (++index < objLength) { var key = objProps[index], - result = hasOwnProperty.call(other, key); + result = isLoose ? key in other : hasOwnProperty.call(other, key); if (result) { var objValue = object[key], @@ -37782,21 +38002,21 @@ return jQuery; result = undefined; if (customizer) { - result = isWhere + result = isLoose ? customizer(othValue, objValue, key) : customizer(objValue, othValue, key); } if (typeof result == 'undefined') { // Recursively compare objects (susceptible to call stack limits). - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB); + result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); } } if (!result) { return false; } - hasCtor || (hasCtor = key == 'constructor'); + skipCtor || (skipCtor = key == 'constructor'); } - if (!hasCtor) { + if (!skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; @@ -37814,7 +38034,7 @@ return jQuery; /** * Gets the extremum value of `collection` invoking `iteratee` for each value * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments; (value, index, collection). + * The `iteratee` is invoked with three arguments: (value, index, collection). * * @private * @param {Array|Object|string} collection The collection to iterate over. @@ -37865,6 +38085,37 @@ return jQuery; return metaMap.get(func); }; + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + var getFuncName = (function() { + if (!support.funcNames) { + return constant(''); + } + if (constant.name == 'constant') { + return baseProperty('name'); + } + return function(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 @@ -37982,31 +38233,6 @@ return jQuery; return result; } - /** - * Checks if `func` is eligible for `this` binding. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is eligible, else `false`. - */ - function isBindable(func) { - var support = lodash.support, - result = !(support.funcNames ? func.name : support.funcDecomp); - - if (!result) { - var source = fnToString.call(func); - if (!support.funcNames) { - result = !reFuncName.test(source); - } - if (!result) { - // Check if `func` references the `this` keyword and store the result. - result = reThis.test(source) || isNative(func); - baseSetData(func, result); - } - } - return result; - } - /** * Checks if `value` is a valid array-like index. * @@ -38048,12 +38274,22 @@ return jQuery; return false; } + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + return !!funcName && func === lodash[funcName] && funcName in LazyWrapper.prototype; + } + /** * Checks if `value` is a valid array-like length. * - * **Note:** This function is based on ES `ToLength`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). * * @private * @param {*} value The value to check. @@ -38093,22 +38329,13 @@ return jQuery; function mergeData(data, source) { var bitmask = data[1], srcBitmask = source[1], - newBitmask = bitmask | srcBitmask; + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; - var arityFlags = ARY_FLAG | REARG_FLAG, - bindFlags = BIND_FLAG | BIND_KEY_FLAG, - comboFlags = arityFlags | bindFlags | CURRY_BOUND_FLAG | CURRY_RIGHT_FLAG; - - var isAry = bitmask & ARY_FLAG && !(srcBitmask & ARY_FLAG), - isRearg = bitmask & REARG_FLAG && !(srcBitmask & REARG_FLAG), - argPos = (isRearg ? data : source)[7], - ary = (isAry ? data : source)[8]; - - var isCommon = !(bitmask >= REARG_FLAG && srcBitmask > bindFlags) && - !(bitmask > bindFlags && srcBitmask >= REARG_FLAG); - - var isCombo = (newBitmask >= arityFlags && newBitmask <= comboFlags) && - (bitmask < REARG_FLAG || ((isRearg || isAry) && argPos.length <= ary)); + 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)) { @@ -38427,10 +38654,9 @@ return jQuery; * Creates an array excluding all values of the provided arrays using * `SameValueZero` for equality comparisons. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -38443,19 +38669,11 @@ return jQuery; * _.difference([1, 2, 3], [4, 2]); * // => [1, 3] */ - function difference() { - var args = arguments, - index = -1, - length = args.length; - - while (++index < length) { - var value = args[index]; - if (isArray(value) || isArguments(value)) { - break; - } - } - return baseDifference(value, baseFlatten(args, false, true, ++index)); - } + var difference = restParam(function(array, values) { + return (isArray(array) || isArguments(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); /** * Creates a slice of `array` with `n` elements dropped from the beginning. @@ -38531,7 +38749,7 @@ return jQuery; /** * 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). + * 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. @@ -38578,19 +38796,15 @@ return jQuery; * // => ['barney', 'fred', 'pebbles'] */ function dropRightWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - predicate = getCallback(predicate, thisArg, 3); - while (length-- && predicate(array[length], length, array)) {} - return baseSlice(array, 0, length + 1); + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; } /** * 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). + * 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. @@ -38637,14 +38851,9 @@ return jQuery; * // => ['barney', 'fred', 'pebbles'] */ function dropWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var index = -1; - predicate = getCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) {} - return baseSlice(array, index); + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; } /** @@ -38661,6 +38870,19 @@ return jQuery; * @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 fill(array, value, start, end) { var length = array ? array.length : 0; @@ -38676,7 +38898,7 @@ return jQuery; /** * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for, instead of the element itself. + * element `predicate` returns truthy for instead of the element itself. * * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. @@ -38722,18 +38944,7 @@ return jQuery; * _.findIndex(users, 'active'); * // => 2 */ - function findIndex(array, predicate, thisArg) { - var index = -1, - length = array ? array.length : 0; - - predicate = getCallback(predicate, thisArg, 3); - while (++index < length) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } + var findIndex = createFindIndex(); /** * This method is like `_.findIndex` except that it iterates over elements @@ -38783,16 +38994,7 @@ return jQuery; * _.findLastIndex(users, 'active'); * // => 0 */ - function findLastIndex(array, predicate, thisArg) { - var length = array ? array.length : 0; - predicate = getCallback(predicate, thisArg, 3); - while (length--) { - if (predicate(array[length], length, array)) { - return length; - } - } - return -1; - } + var findLastIndex = createFindIndex(true); /** * Gets the first element of `array`. @@ -38829,18 +39031,18 @@ return jQuery; * @example * * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]]; + * // => [1, 2, 3, [4]] * * // using `isDeep` * _.flatten([1, [2, 3, [4]]], true); - * // => [1, 2, 3, 4]; + * // => [1, 2, 3, 4] */ function flatten(array, isDeep, guard) { var length = array ? array.length : 0; if (guard && isIterateeCall(array, isDeep, guard)) { isDeep = false; } - return length ? baseFlatten(array, isDeep, false, 0) : []; + return length ? baseFlatten(array, isDeep) : []; } /** @@ -38854,11 +39056,11 @@ return jQuery; * @example * * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4]; + * // => [1, 2, 3, 4] */ function flattenDeep(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array, true, false, 0) : []; + return length ? baseFlatten(array, true) : []; } /** @@ -38867,10 +39069,9 @@ return jQuery; * it is used as the offset from the end of `array`. If `array` is sorted * providing `true` for `fromIndex` performs a faster binary search. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -38933,10 +39134,9 @@ return jQuery; * Creates an array of unique values in all provided arrays using `SameValueZero` * for equality comparisons. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -39064,10 +39264,10 @@ return jQuery; * comparisons. * * **Notes:** - * - Unlike `_.without`, this method mutates `array`. - * - `SameValueZero` comparisons are like strict equality comparisons, e.g. `===`, - * except that `NaN` matches `NaN`. See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * - Unlike `_.without`, this method mutates `array` + * - [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except + * that `NaN` matches `NaN` * * @static * @memberOf _ @@ -39130,14 +39330,28 @@ return jQuery; * console.log(evens); * // => [10, 20] */ - function pullAt(array) { - return basePullAt(array || [], baseFlatten(arguments, false, false, 1)); - } + var pullAt = restParam(function(array, indexes) { + array || (array = []); + indexes = baseFlatten(indexes); + + var length = indexes.length, + result = baseAt(array, indexes); + + indexes.sort(baseCompareAscending); + while (length--) { + var index = parseFloat(indexes[length]); + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return result; + }); /** * 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). + * `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. @@ -39241,14 +39455,14 @@ return jQuery; * to compute their sort ranking. The iteratee is bound to `thisArg` and * invoked with one argument; (value). * - * If a property name is provided for `predicate` the created `_.property` + * 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`. * @@ -39282,12 +39496,7 @@ return jQuery; * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); * // => 1 */ - function sortedIndex(array, value, iteratee, thisArg) { - var func = getCallback(iteratee); - return (func === baseCallback && iteratee == null) - ? binaryIndex(array, value) - : binaryIndexBy(array, value, func(iteratee, thisArg, 1)); - } + var sortedIndex = createSortedIndex(); /** * This method is like `_.sortedIndex` except that it returns the highest @@ -39309,12 +39518,7 @@ return jQuery; * _.sortedLastIndex([4, 4, 5, 5], 5); * // => 4 */ - function sortedLastIndex(array, value, iteratee, thisArg) { - var func = getCallback(iteratee); - return (func === baseCallback && iteratee == null) - ? binaryIndex(array, value, true) - : binaryIndexBy(array, value, func(iteratee, thisArg, 1), true); - } + var sortedLastIndex = createSortedIndex(true); /** * Creates a slice of `array` with `n` elements taken from the beginning. @@ -39390,7 +39594,7 @@ return jQuery; /** * 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). + * 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. @@ -39437,19 +39641,15 @@ return jQuery; * // => [] */ function takeRightWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - predicate = getCallback(predicate, thisArg, 3); - while (length-- && predicate(array[length], length, array)) {} - return baseSlice(array, length + 1); + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; } /** * 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). + * `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. @@ -39496,24 +39696,18 @@ return jQuery; * // => [] */ function takeWhile(array, predicate, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var index = -1; - predicate = getCallback(predicate, thisArg, 3); - while (++index < length && predicate(array[index], index, array)) {} - return baseSlice(array, 0, index); + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; } /** * Creates an array of unique values, in order, of the provided arrays using * `SameValueZero` for equality comparisons. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -39525,9 +39719,9 @@ return jQuery; * _.union([1, 2], [4, 2], [2, 1]); * // => [1, 2, 4] */ - function union() { - return baseUniq(baseFlatten(arguments, false, true, 0)); - } + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); /** * Creates a duplicate-value-free version of an array using `SameValueZero` @@ -39535,23 +39729,22 @@ return jQuery; * search algorithm for sorted arrays. If an iteratee function is provided it * is invoked for each value in the array to generate the criterion by which * uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked - * with three arguments; (value, index, array). + * with three arguments: (value, index, array). * - * 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:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -39633,10 +39826,9 @@ return jQuery; * Creates an array excluding all provided values using `SameValueZero` for * equality comparisons. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -39649,14 +39841,15 @@ return jQuery; * _.without([1, 2, 1, 3], 1, 2); * // => [3] */ - function without(array) { - return baseDifference(array, baseSlice(arguments, 1)); - } + var without = restParam(function(array, values) { + return (isArray(array) || isArguments(array)) + ? baseDifference(array, values) + : []; + }); /** - * Creates an array that is the symmetric difference of the provided arrays. - * See [Wikipedia](https://en.wikipedia.org/wiki/Symmetric_difference) for - * more details. + * Creates an array that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. * * @static * @memberOf _ @@ -39698,20 +39891,13 @@ return jQuery; * _.zip(['fred', 'barney'], [30, 40], [true, false]); * // => [['fred', 30, true], ['barney', 40, false]] */ - function zip() { - var length = arguments.length, - array = Array(length); - - while (length--) { - array[length] = arguments[length]; - } - return unzip(array); - } + var zip = restParam(unzip); /** - * Creates an object composed from arrays of property names and values. Provide - * either a single two dimensional array, e.g. `[[key1, value1], [key2, value2]]` - * or two arrays, one of property names and one of corresponding values. + * 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. * * @static * @memberOf _ @@ -39722,6 +39908,9 @@ return jQuery; * @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 } */ @@ -39818,13 +40007,14 @@ return jQuery; * @returns {*} Returns the result of `interceptor`. * @example * - * _([1, 2, 3]) - * .last() + * _(' abc ') + * .chain() + * .trim() * .thru(function(value) { * return [value]; * }) * .value(); - * // => [3] + * // => ['abc'] */ function thru(value, interceptor, thisArg) { return interceptor.call(thisArg, value); @@ -40014,32 +40204,32 @@ return jQuery; * _.at(['a', 'b', 'c'], [0, 2]); * // => ['a', 'c'] * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] */ - function at(collection) { + var at = restParam(function(collection, props) { var length = collection ? collection.length : 0; if (isLength(length)) { collection = toIterable(collection); } - return baseAt(collection, baseFlatten(arguments, false, false, 1)); - } + return baseAt(collection, baseFlatten(props)); + }); /** * 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; + * The `iteratee` is bound to `thisArg` and invoked with three arguments: * (value, index|key, collection). * - * If a property name is provided for `predicate` the created `_.property` + * 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`. * @@ -40072,7 +40262,7 @@ return jQuery; /** * Checks if `predicate` returns truthy for **all** elements of `collection`. - * The predicate is bound to `thisArg` and invoked with three arguments; + * 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` @@ -40120,6 +40310,9 @@ return jQuery; */ function every(collection, predicate, thisArg) { var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; + } if (typeof predicate != 'function' || typeof thisArg != 'undefined') { predicate = getCallback(predicate, thisArg, 3); } @@ -40129,7 +40322,7 @@ return jQuery; /** * 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). + * 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. @@ -40184,7 +40377,7 @@ return jQuery; /** * 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). + * 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. @@ -40231,14 +40424,7 @@ return jQuery; * _.result(_.find(users, 'active'), 'user'); * // => 'barney' */ - function find(collection, predicate, thisArg) { - if (isArray(collection)) { - var index = findIndex(collection, predicate, thisArg); - return index > -1 ? collection[index] : undefined; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFind(collection, predicate, baseEach); - } + var find = createFind(baseEach); /** * This method is like `_.find` except that it iterates over elements of @@ -40259,10 +40445,7 @@ return jQuery; * }); * // => 3 */ - function findLast(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(collection, predicate, baseEachRight); - } + var findLast = createFind(baseEachRight, true); /** * Performs a deep comparison between each element in `collection` and the @@ -40299,7 +40482,7 @@ return jQuery; /** * Iterates over elements of `collection` invoking `iteratee` for each element. - * The `iteratee` is bound to `thisArg` and invoked with three arguments; + * The `iteratee` is bound to `thisArg` and invoked with three arguments: * (value, index|key, collection). Iterator functions may exit iteration early * by explicitly returning `false`. * @@ -40327,11 +40510,7 @@ return jQuery; * }); * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ - function forEach(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEach(collection, iteratee) - : baseEach(collection, bindCallback(iteratee, thisArg, 3)); - } + var forEach = createForEach(arrayEach, baseEach); /** * This method is like `_.forEach` except that it iterates over elements of @@ -40349,30 +40528,26 @@ return jQuery; * * _([1, 2]).forEachRight(function(n) { * console.log(n); - * }).join(','); + * }).value(); * // => logs each value from right to left and returns the array */ - function forEachRight(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) - ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, bindCallback(iteratee, thisArg, 3)); - } + var forEachRight = createForEach(arrayEachRight, baseEachRight); /** * 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; + * The `iteratee` is bound to `thisArg` and invoked with three arguments: * (value, index|key, collection). * - * If a property name is provided for `predicate` the created `_.property` + * 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`. * @@ -40413,10 +40588,9 @@ return jQuery; * comparisons. If `fromIndex` is negative, it is used as the offset from * the end of `collection`. * - * **Note:** `SameValueZero` comparisons are like strict equality comparisons, - * e.g. `===`, except that `NaN` matches `NaN`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * for more details. + * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * comparisons are like strict equality comparisons, e.g. `===`, except that + * `NaN` matches `NaN`. * * @static * @memberOf _ @@ -40425,6 +40599,7 @@ return jQuery; * @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 * @@ -40440,7 +40615,7 @@ return jQuery; * _.includes('pebbles', 'eb'); * // => true */ - function includes(collection, target, fromIndex) { + function includes(collection, target, fromIndex, guard) { var length = collection ? collection.length : 0; if (!isLength(length)) { collection = values(collection); @@ -40449,10 +40624,10 @@ return jQuery; if (!length) { return false; } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } else { + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); } return (typeof collection == 'string' || !isArray(collection) && isString(collection)) ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) @@ -40463,17 +40638,17 @@ return jQuery; * 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; + * iteratee function is bound to `thisArg` and invoked with three arguments: * (value, index|key, collection). * - * If a property name is provided for `predicate` the created `_.property` + * 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`. * @@ -40531,23 +40706,32 @@ return jQuery; * _.invoke([123, 456], String.prototype.split, ''); * // => [['1', '2', '3'], ['4', '5', '6']] */ - function invoke(collection, methodName) { - return baseInvoke(collection, methodName, baseSlice(arguments, 2)); - } + var invoke = restParam(function(collection, methodName, args) { + var index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = isLength(length) ? Array(length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? methodName : (value != null && value[methodName]); + result[++index] = func ? func.apply(value, args) : undefined; + }); + return result; + }); /** * 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). + * arguments: (value, index|key, collection). * - * 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`. * @@ -40556,9 +40740,9 @@ return jQuery; * * The guarded methods are: * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, - * `dropRight`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, `slice`, - * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`, - * `trunc`, `random`, `range`, `sample`, `uniq`, and `words` + * `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, + * `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, + * `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, `uniq`, and `words` * * @static * @memberOf _ @@ -40601,7 +40785,7 @@ return jQuery; * 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). + * 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. @@ -40692,14 +40876,14 @@ return jQuery; * 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; + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: * (accumulator, value, index|key, collection). * * Many lodash methods are guarded to work as interatees for methods like * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: - * `assign`, `defaults`, `merge`, and `sortAllBy` + * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` * * @static * @memberOf _ @@ -40723,10 +40907,7 @@ return jQuery; * }, {}); * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) */ - function reduce(collection, iteratee, accumulator, thisArg) { - var func = isArray(collection) ? arrayReduce : baseReduce; - return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEach); - } + var reduce = createReduce(arrayReduce, baseEach); /** * This method is like `_.reduce` except that it iterates over elements of @@ -40750,10 +40931,7 @@ return jQuery; * }, []); * // => [4, 5, 2, 3, 0, 1] */ - function reduceRight(collection, iteratee, accumulator, thisArg) { - var func = isArray(collection) ? arrayReduceRight : baseReduce; - return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEachRight); - } + var reduceRight = createReduce(arrayReduceRight, baseEachRight); /** * The opposite of `_.filter`; this method returns the elements of `collection` @@ -40840,9 +41018,8 @@ return jQuery; } /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See [Wikipedia](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle) - * for more details. + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * * @static * @memberOf _ @@ -40900,7 +41077,7 @@ return jQuery; * 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). + * 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. @@ -40947,6 +41124,9 @@ return jQuery; */ function some(collection, predicate, thisArg) { var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; + } if (typeof predicate != 'function' || typeof thisArg != 'undefined') { predicate = getCallback(predicate, thisArg, 3); } @@ -40957,17 +41137,17 @@ return jQuery; * 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; + * The `iteratee` is bound to `thisArg` and invoked with three arguments: * (value, index|key, collection). * - * If a property name is provided for `predicate` the created `_.property` + * 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`. * @@ -41043,17 +41223,24 @@ return jQuery; * _.map(_.sortByAll(users, ['user', 'age']), _.values); * // => [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] */ - function sortByAll(collection) { + function sortByAll() { + var args = arguments, + collection = args[0], + guard = args[3], + index = 0, + length = args.length - 1; + if (collection == null) { return []; } - var args = arguments, - guard = args[3]; - - if (guard && isIterateeCall(args[1], args[2], guard)) { - args = [collection, args[1]]; + var props = Array(length); + while (index < length) { + props[index] = args[++index]; } - return baseSortByOrder(collection, baseFlatten(args, false, false, 1), []); + if (guard && isIterateeCall(args[1], args[2], guard)) { + props = args[1]; + } + return baseSortByOrder(collection, baseFlatten(props), []); } /** @@ -41272,7 +41459,7 @@ return jQuery; * @category Function * @param {Function} func The function to bind. * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [args] The arguments to be partially applied. + * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * @@ -41291,16 +41478,14 @@ return jQuery; * bound('hi'); * // => 'hi fred!' */ - function bind(func, thisArg) { + var bind = restParam(function(func, thisArg, partials) { var bitmask = BIND_FLAG; - if (arguments.length > 2) { - var partials = baseSlice(arguments, 2), - holders = replaceHolders(partials, bind.placeholder); - + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); bitmask |= PARTIAL_FLAG; } return createWrapper(func, bitmask, thisArg, partials, holders); - } + }); /** * Binds methods of an object to the object itself, overwriting the existing @@ -41330,13 +41515,18 @@ return jQuery; * jQuery('#docs').on('click', view.onClick); * // => logs 'clicked docs' when the element is clicked */ - function bindAll(object) { - return baseBindAll(object, - arguments.length > 1 - ? baseFlatten(arguments, false, false, 1) - : functions(object) - ); - } + 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 that invokes the method at `object[key]` and prepends @@ -41355,7 +41545,7 @@ return jQuery; * @category Function * @param {Object} object The object the method belongs to. * @param {string} key The key of the method. - * @param {...*} [args] The arguments to be partially applied. + * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * @@ -41382,16 +41572,14 @@ return jQuery; * bound('hi'); * // => 'hiya fred!' */ - function bindKey(object, key) { + var bindKey = restParam(function(object, key, partials) { var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (arguments.length > 2) { - var partials = baseSlice(arguments, 2), - holders = replaceHolders(partials, bindKey.placeholder); - + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); bitmask |= PARTIAL_FLAG; } return createWrapper(key, bitmask, object, partials, holders); - } + }); /** * Creates a function that accepts one or more arguments of `func` that when @@ -41433,14 +41621,7 @@ return jQuery; * curried(1)(_, 3)(2); * // => [1, 2, 3] */ - function curry(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_FLAG, null, null, null, null, null, arity); - result.placeholder = curry.placeholder; - return result; - } + var curry = createCurry(CURRY_FLAG); /** * This method is like `_.curry` except that arguments are applied to `func` @@ -41479,14 +41660,7 @@ return jQuery; * curried(3)(1, _)(2); * // => [1, 2, 3] */ - function curryRight(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, CURRY_RIGHT_FLAG, null, null, null, null, null, arity); - result.placeholder = curryRight.placeholder; - return result; - } + var curryRight = createCurry(CURRY_RIGHT_FLAG); /** * Creates a function that delays invoking `func` until after `wait` milliseconds @@ -41681,9 +41855,9 @@ return jQuery; * }, 'deferred'); * // logs 'deferred' after one or more milliseconds */ - function defer(func) { - return baseDelay(func, 1, arguments, 1); - } + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); /** * Invokes `func` after `wait` milliseconds. Any additional arguments are @@ -41703,9 +41877,9 @@ return jQuery; * }, 1000, 'later'); * // => logs 'later' after one second */ - function delay(func, wait) { - return baseDelay(func, wait, arguments, 2); - } + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); /** * Creates a function that returns the result of invoking the provided @@ -41727,7 +41901,7 @@ return jQuery; * addSquare(1, 2); * // => 9 */ - var flow = createComposer(); + var flow = createFlow(); /** * This method is like `_.flow` except that it creates a function that @@ -41749,7 +41923,7 @@ return jQuery; * addSquare(1, 2); * // => 9 */ - var flowRight = createComposer(true); + var flowRight = createFlow(true); /** * Creates a function that memoizes the result of `func`. If `resolver` is @@ -41761,10 +41935,8 @@ return jQuery; * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the ES `Map` method interface - * of `get`, `has`, and `set`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) - * for more details. + * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. * * @static * @memberOf _ @@ -41855,7 +42027,7 @@ return jQuery; /** * Creates a function that is restricted to invoking `func` once. Repeat calls * to the function return the value of the first call. The `func` is invoked - * with the `this` binding of the created function. + * with the `this` binding and arguments of the created function. * * @static * @memberOf _ @@ -41888,7 +42060,7 @@ return jQuery; * @memberOf _ * @category Function * @param {Function} func The function to partially apply arguments to. - * @param {...*} [args] The arguments to be partially applied. + * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * @@ -41905,12 +42077,7 @@ return jQuery; * greetFred('hi'); * // => 'hi fred' */ - function partial(func) { - var partials = baseSlice(arguments, 1), - holders = replaceHolders(partials, partial.placeholder); - - return createWrapper(func, PARTIAL_FLAG, null, partials, holders); - } + var partial = createPartial(PARTIAL_FLAG); /** * This method is like `_.partial` except that partially applied arguments @@ -41926,7 +42093,7 @@ return jQuery; * @memberOf _ * @category Function * @param {Function} func The function to partially apply arguments to. - * @param {...*} [args] The arguments to be partially applied. + * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * @@ -41943,12 +42110,7 @@ return jQuery; * sayHelloTo('fred'); * // => 'hello fred' */ - function partialRight(func) { - var partials = baseSlice(arguments, 1), - holders = replaceHolders(partials, partialRight.placeholder); - - return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders); - } + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); /** * Creates a function that invokes `func` with arguments arranged according @@ -41978,29 +42140,80 @@ return jQuery; * }, [1, 2, 3]); * // => [3, 6, 9] */ - function rearg(func) { - var indexes = baseFlatten(arguments, false, false, 1); - return createWrapper(func, REARG_FLAG, null, null, null, indexes); - } + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes)); + }); /** * Creates a function that invokes `func` with the `this` binding of the - * created function and the array of arguments provided to the created - * function much like [Function#apply](http://es5.github.io/#x15.3.4.3). + * 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); + } + start = nativeMax(typeof start == 'undefined' ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + 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); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * 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). + * + * **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 {*} Returns the new function. + * @returns {Function} Returns the new function. * @example * - * var spread = _.spread(function(who, what) { + * var say = _.spread(function(who, what) { * return who + ' says ' + what; * }); * - * spread(['Fred', 'hello']); - * // => 'Fred says hello' + * say(['fred', 'hello']); + * // => 'fred says hello' * * // with a Promise * var numbers = Promise.all([ @@ -42115,12 +42328,12 @@ return jQuery; * cloning is handled by the method instead. The `customizer` is bound to * `thisArg` and invoked with two argument; (value [, index|key, object]). * - * **Note:** This method is loosely based on the structured clone algorithm. + * **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. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) - * for more details. + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ @@ -42178,12 +42391,12 @@ return jQuery; * is handled by the method instead. The `customizer` is bound to `thisArg` * and invoked with two argument; (value [, index|key, object]). * - * **Note:** This method is loosely based on the structured clone algorithm. + * **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. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) - * for more details. + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ @@ -42240,7 +42453,7 @@ return jQuery; */ function isArguments(value) { var length = isObjectLike(value) ? value.length : undefined; - return (isLength(length) && objToString.call(value) == argsTag) || false; + return isLength(length) && objToString.call(value) == argsTag; } /** @@ -42260,7 +42473,7 @@ return jQuery; * // => false */ var isArray = nativeIsArray || function(value) { - return (isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag) || false; + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; }; /** @@ -42280,7 +42493,7 @@ return jQuery; * // => false */ function isBoolean(value) { - return (value === true || value === false || isObjectLike(value) && objToString.call(value) == boolTag) || false; + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); } /** @@ -42300,7 +42513,7 @@ return jQuery; * // => false */ function isDate(value) { - return (isObjectLike(value) && objToString.call(value) == dateTag) || false; + return isObjectLike(value) && objToString.call(value) == dateTag; } /** @@ -42320,13 +42533,13 @@ return jQuery; * // => false */ function isElement(value) { - return (value && value.nodeType === 1 && isObjectLike(value) && - (objToString.call(value).indexOf('Element') > -1)) || false; + return !!value && value.nodeType === 1 && isObjectLike(value) && + (objToString.call(value).indexOf('Element') > -1); } // Fallback for environments without DOM support. if (!support.dom) { isElement = function(value) { - return (value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value)) || false; + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); }; } @@ -42374,7 +42587,7 @@ return jQuery; * 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]). + * arguments: (value, other [, index|key]). * * **Note:** This method supports comparing arrays, booleans, `Date` objects, * numbers, `Object` objects, regexes, and strings. Objects are compared by @@ -42439,15 +42652,13 @@ return jQuery; * // => false */ function isError(value) { - return (isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag) || false; + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; } /** * Checks if `value` is a finite primitive number. * - * **Note:** This method is based on ES `Number.isFinite`. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite) - * for more details. + * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). * * @static * @memberOf _ @@ -42499,11 +42710,9 @@ return jQuery; }; /** - * Checks if `value` is the language type of `Object`. + * 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('')`) * - * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. - * * @static * @memberOf _ * @category Lang @@ -42524,7 +42733,7 @@ return jQuery; // Avoid a V8 JIT bug in Chrome 19-20. // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. var type = typeof value; - return type == 'function' || (value && type == 'object') || false; + return type == 'function' || (!!value && type == 'object'); } /** @@ -42532,7 +42741,7 @@ return jQuery; * `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). + * to `thisArg` and invoked with three arguments: (value, other, index|key). * * **Note:** This method supports comparing properties of arrays, booleans, * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions @@ -42570,13 +42779,19 @@ return jQuery; var props = keys(source), length = props.length; + if (!length) { + return true; + } + if (object == null) { + return false; + } customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); if (!customizer && length == 1) { var key = props[0], value = source[key]; if (isStrictComparable(value)) { - return object != null && value === object[key] && hasOwnProperty.call(object, key); + return value === object[key] && (typeof value != 'undefined' || (key in toObject(object))); } } var values = Array(length), @@ -42586,15 +42801,14 @@ return jQuery; value = values[length] = source[props[length]]; strictCompareFlags[length] = isStrictComparable(value); } - return baseIsMatch(object, props, values, strictCompareFlags, customizer); + return baseIsMatch(toObject(object), props, values, strictCompareFlags, customizer); } /** * Checks if `value` is `NaN`. * - * **Note:** This method is not the same as native `isNaN` which returns `true` - * for `undefined` and other non-numeric values. See the [ES5 spec](https://es5.github.io/#x15.1.2.4) - * for more details. + * **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. * * @static * @memberOf _ @@ -42644,7 +42858,7 @@ return jQuery; if (objToString.call(value) == funcTag) { return reNative.test(fnToString.call(value)); } - return (isObjectLike(value) && reHostCtor.test(value)) || false; + return isObjectLike(value) && reHostCtor.test(value); } /** @@ -42690,7 +42904,7 @@ return jQuery; * // => false */ function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag) || false; + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); } /** @@ -42772,7 +42986,7 @@ return jQuery; * // => false */ function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag) || false; + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); } /** @@ -42792,7 +43006,7 @@ return jQuery; * // => false */ function isTypedArray(value) { - return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false; + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; } /** @@ -42874,7 +43088,7 @@ return jQuery; * 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; + * The `customizer` is bound to `thisArg` and invoked with five arguments: * (objectValue, sourceValue, key, object, source). * * @static @@ -42959,18 +43173,18 @@ return jQuery; * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); * // => { 'user': 'barney', 'age': 36 } */ - function defaults(object) { + var defaults = restParam(function(args) { + var object = args[0]; if (object == null) { return object; } - var args = arrayCopy(arguments); args.push(assignDefaults); return assign.apply(undefined, args); - } + }); /** - * This method is like `_.findIndex` except that it returns the key of the - * first element `predicate` returns truthy for, instead of the element itself. + * 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` * style callback returns the property value of the given element. @@ -43016,10 +43230,7 @@ return jQuery; * _.findKey(users, 'active'); * // => 'barney' */ - function findKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwn, true); - } + var findKey = createFindKey(baseForOwn); /** * This method is like `_.findKey` except that it iterates over elements of @@ -43069,15 +43280,12 @@ return jQuery; * _.findLastKey(users, 'active'); * // => 'pebbles' */ - function findLastKey(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, baseForOwnRight, true); - } + var findLastKey = createFindKey(baseForOwnRight); /** * Iterates over own and inherited enumerable properties of an object invoking * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked - * with three arguments; (value, key, object). Iterator functions may exit + * with three arguments: (value, key, object). Iterator functions may exit * iteration early by explicitly returning `false`. * * @static @@ -43101,12 +43309,7 @@ return jQuery; * }); * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) */ - function forIn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseFor(object, iteratee, keysIn); - } + var forIn = createForIn(baseFor); /** * This method is like `_.forIn` except that it iterates over properties of @@ -43133,15 +43336,12 @@ return jQuery; * }); * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' */ - function forInRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keysIn); - } + var forInRight = createForIn(baseForRight); /** * Iterates over own enumerable properties of an object invoking `iteratee` * for each property. The `iteratee` is bound to `thisArg` and invoked with - * three arguments; (value, key, object). Iterator functions may exit iteration + * three arguments: (value, key, object). Iterator functions may exit iteration * early by explicitly returning `false`. * * @static @@ -43165,12 +43365,7 @@ return jQuery; * }); * // => logs 'a' and 'b' (iteration order is not guaranteed) */ - function forOwn(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return baseForOwn(object, iteratee); - } + var forOwn = createForOwn(baseForOwn); /** * This method is like `_.forOwn` except that it iterates over properties of @@ -43197,10 +43392,7 @@ return jQuery; * }); * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' */ - function forOwnRight(object, iteratee, thisArg) { - iteratee = bindCallback(iteratee, thisArg, 3); - return baseForRight(object, iteratee, keys); - } + var forOwnRight = createForOwn(baseForOwnRight); /** * Creates an array of function property names from all enumerable properties, @@ -43385,7 +43577,7 @@ return jQuery; /** * 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; + * iteratee function is bound to `thisArg` and invoked with three arguments: * (value, key, object). * * If a property name is provided for `iteratee` the created `_.property` @@ -43440,7 +43632,7 @@ return jQuery; * 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). + * with five arguments: (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ @@ -43489,7 +43681,7 @@ return jQuery; * Property names may be specified as individual arguments or as arrays of * property names. If `predicate` is provided it is invoked for each property * of `object` omitting the properties `predicate` returns truthy for. The - * predicate is bound to `thisArg` and invoked with three arguments; + * predicate is bound to `thisArg` and invoked with three arguments: * (value, key, object). * * @static @@ -43511,19 +43703,19 @@ return jQuery; * _.omit(object, _.isNumber); * // => { 'user': 'fred' } */ - function omit(object, predicate, thisArg) { + var omit = restParam(function(object, props) { if (object == null) { return {}; } - if (typeof predicate != 'function') { - var props = arrayMap(baseFlatten(arguments, false, false, 1), String); + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); return pickByArray(object, baseDifference(keysIn(object), props)); } - predicate = bindCallback(predicate, thisArg, 3); + 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`, @@ -43557,7 +43749,7 @@ return jQuery; * 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). + * bound to `thisArg` and invoked with three arguments: (value, key, object). * * @static * @memberOf _ @@ -43578,14 +43770,14 @@ return jQuery; * _.pick(object, _.isString); * // => { 'user': 'fred' } */ - function pick(object, predicate, thisArg) { + var pick = restParam(function(object, props) { if (object == null) { return {}; } - return typeof predicate == 'function' - ? pickByCallback(object, bindCallback(predicate, thisArg, 3)) - : pickByArray(object, baseFlatten(arguments, false, false, 1)); - } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); /** * Resolves the value of property `key` on `object`. If the value of `key` is @@ -43630,7 +43822,7 @@ return jQuery; * `accumulator` object which is the result of running each of its own enumerable * properties through `iteratee`, with each invocation potentially mutating * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked - * with four arguments; (accumulator, value, key, object). Iterator functions + * with four arguments: (accumulator, value, key, object). Iterator functions * may exit iteration early by explicitly returning `false`. * * @static @@ -43841,8 +44033,7 @@ return jQuery; /*------------------------------------------------------------------------*/ /** - * Converts `string` to camel case. - * See [Wikipedia](https://en.wikipedia.org/wiki/CamelCase) for more details. + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). * * @static * @memberOf _ @@ -43884,9 +44075,8 @@ return jQuery; } /** - * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. - * See [Wikipedia](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * for more details. + * 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 _ @@ -43900,7 +44090,7 @@ return jQuery; */ function deburr(string) { string = baseToString(string); - return string && string.replace(reLatin1, deburrLetter); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMarks, ''); } /** @@ -43955,9 +44145,8 @@ return jQuery; * [#108](https://html5sec.org/#108), and [#133](https://html5sec.org/#133) of * the [HTML5 Security Cheatsheet](https://html5sec.org/) for more details. * - * When working with HTML you should always quote attribute values to reduce - * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping) - * for more details. + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. * * @static * @memberOf _ @@ -43978,8 +44167,8 @@ return jQuery; } /** - * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", - * "+", "(", ")", "[", "]", "{" and "}" in `string`. + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. * * @static * @memberOf _ @@ -43989,7 +44178,7 @@ return jQuery; * @example * * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' */ function escapeRegExp(string) { string = baseToString(string); @@ -43999,9 +44188,7 @@ return jQuery; } /** - * Converts `string` to kebab case. - * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for - * more details. + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). * * @static * @memberOf _ @@ -44024,9 +44211,8 @@ return jQuery; }); /** - * Pads `string` on the left and right sides if it is shorter then the given - * padding length. The `chars` string may be truncated if the number of padding - * characters can't be evenly divided by the padding length. + * Pads `string` on the left and right sides if it is shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. * * @static * @memberOf _ @@ -44058,14 +44244,13 @@ return jQuery; leftLength = floor(mid), rightLength = ceil(mid); - chars = createPad('', rightLength, chars); + chars = createPadding('', rightLength, chars); return chars.slice(0, leftLength) + string + chars; } /** - * Pads `string` on the left side if it is shorter then the given padding - * length. The `chars` string may be truncated if the number of padding - * characters exceeds the padding length. + * Pads `string` on the left side if it is shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ @@ -44085,15 +44270,11 @@ return jQuery; * _.padLeft('abc', 3); * // => 'abc' */ - function padLeft(string, length, chars) { - string = baseToString(string); - return string && (createPad(string, length, chars) + string); - } + var padLeft = createPadDir(); /** - * Pads `string` on the right side if it is shorter then the given padding - * length. The `chars` string may be truncated if the number of padding - * characters exceeds the padding length. + * Pads `string` on the right side if it is shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ @@ -44113,18 +44294,15 @@ return jQuery; * _.padRight('abc', 3); * // => 'abc' */ - function padRight(string, length, chars) { - string = baseToString(string); - return string && (string + createPad(string, length, chars)); - } + var padRight = createPadDir(true); /** * Converts `string` to an integer of the specified radix. If `radix` is * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, * in which case a `radix` of `16` is used. * - * **Note:** This method aligns with the ES5 implementation of `parseInt`. - * See the [ES5 spec](https://es5.github.io/#E) for more details. + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. * * @static * @memberOf _ @@ -44204,8 +44382,7 @@ return jQuery; } /** - * Converts `string` to snake case. - * See [Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). * * @static * @memberOf _ @@ -44228,9 +44405,7 @@ return jQuery; }); /** - * Converts `string` to start case. - * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) - * for more details. + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static * @memberOf _ @@ -44289,9 +44464,9 @@ return jQuery; * properties may be accessed as free variables in the template. If a setting * object is provided it takes precedence over `_.templateSettings` values. * - * **Note:** In the development build `_.template` utilizes sourceURLs for easier debugging. - * See the [HTML5 Rocks article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for more details. + * **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). @@ -44503,7 +44678,7 @@ return jQuery; * // => 'abc' * * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar] + * // => ['foo', 'bar'] */ function trim(string, chars, guard) { var value = string; @@ -44611,7 +44786,7 @@ return jQuery; * 'length': 24, * 'separator': /,? +/ * }); - * //=> 'hi-diddly-ho there...' + * // => 'hi-diddly-ho there...' * * _.trunc('hi-diddly-ho there, neighborino', { * 'omission': ' [...]' @@ -44730,7 +44905,7 @@ return jQuery; * @static * @memberOf _ * @category Utility - * @param {*} func The function to attempt. + * @param {Function} func The function to attempt. * @returns {*} Returns the `func` result or error object. * @example * @@ -44743,20 +44918,13 @@ return jQuery; * elements = []; * } */ - function attempt() { - var func = arguments[0], - length = arguments.length, - args = Array(length ? (length - 1) : 0); - - while (--length > 0) { - args[length - 1] = arguments[length]; - } + var attempt = restParam(function(func, args) { try { return func.apply(undefined, args); } catch(e) { return isError(e) ? e : new Error(e); } - } + }); /** * Creates a function that invokes `func` with the `this` binding of `thisArg` @@ -44893,12 +45061,11 @@ return jQuery; * * var users = [ * { 'user': 'barney' }, - * { 'user': 'fred' }, - * { 'user': 'pebbles' } + * { 'user': 'fred' } * ]; * * _.find(users, _.matchesProperty('user', 'fred')); - * // => { 'user': 'fred', 'age': 40 } + * // => { 'user': 'fred' } */ function matchesProperty(key, value) { return baseMatchesProperty(key + '', baseClone(value, true)); @@ -44909,6 +45076,9 @@ return jQuery; * destination object. If `object` is a function then methods are added to * its prototype as well. * + * **Note:** Use `_.runInContext` to create a pristine `lodash` function + * for mixins to avoid conflicts caused by modifying the original. + * * @static * @memberOf _ * @category Utility @@ -44926,7 +45096,7 @@ return jQuery; * }); * } * - * // use `_.runInContext` to avoid potential conflicts (esp. in Node.js) + * // use `_.runInContext` to avoid conflicts (esp. in Node.js) * var _ = require('lodash').runInContext(); * * _.mixin({ 'vowels': vowels }); @@ -44976,12 +45146,10 @@ return jQuery; return function() { var chainAll = this.__chain__; if (chain || chainAll) { - var result = object(this.__wrapped__); - (result.__actions__ = arrayCopy(this.__actions__)).push({ - 'func': func, - 'args': arguments, - 'thisArg': object - }); + var result = object(this.__wrapped__), + actions = result.__actions__ = arrayCopy(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); result.__chain__ = chainAll; return result; } @@ -45048,7 +45216,7 @@ return jQuery; * var getName = _.property('user'); * * _.map(users, getName); - * // => ['fred', barney'] + * // => ['fred', 'barney'] * * _.pluck(_.sortBy(users, getName), 'user'); * // => ['barney', 'fred'] @@ -45058,7 +45226,7 @@ return jQuery; } /** - * The inverse of `_.property`; this method creates a function which returns + * The opposite of `_.property`; this method creates a function which returns * the property value of a given key on `object`. * * @static @@ -45236,16 +45404,16 @@ return jQuery; * `-Infinity` is returned. If an iteratee function is provided it is invoked * for each value in `collection` to generate the criterion by which the value * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). + * arguments: (value, index, collection). * - * 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`. * @@ -45272,11 +45440,11 @@ return jQuery; * _.max(users, function(chr) { * return chr.age; * }); - * // => { 'user': 'fred', 'age': 40 }; + * // => { 'user': 'fred', 'age': 40 } * * // using the `_.property` callback shorthand * _.max(users, 'age'); - * // => { 'user': 'fred', 'age': 40 }; + * // => { 'user': 'fred', 'age': 40 } */ var max = createExtremum(arrayMax); @@ -45285,16 +45453,16 @@ return jQuery; * `Infinity` is returned. If an iteratee function is provided it is invoked * for each value in `collection` to generate the criterion by which the value * is ranked. The `iteratee` is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). + * arguments: (value, index, collection). * - * 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`. * @@ -45321,11 +45489,11 @@ return jQuery; * _.min(users, function(chr) { * return chr.age; * }); - * // => { 'user': 'barney', 'age': 36 }; + * // => { 'user': 'barney', 'age': 36 } * * // using the `_.property` callback shorthand * _.min(users, 'age'); - * // => { 'user': 'barney', 'age': 36 }; + * // => { 'user': 'barney', 'age': 36 } */ var min = createExtremum(arrayMin, true); @@ -45336,26 +45504,45 @@ return jQuery; * @memberOf _ * @category Math * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {number} Returns the sum. * @example * - * _.sum([4, 6, 2]); - * // => 12 + * _.sum([4, 6]); + * // => 10 * - * _.sum({ 'a': 4, 'b': 6, 'c': 2 }); - * // => 12 + * _.sum({ 'a': 4, 'b': 6 }); + * // => 10 + * + * var objects = [ + * { 'n': 4 }, + * { 'n': 6 } + * ]; + * + * _.sum(objects, function(object) { + * return object.n; + * }); + * // => 10 + * + * // using the `_.property` callback shorthand + * _.sum(objects, 'n'); + * // => 10 */ - function sum(collection) { - if (!isArray(collection)) { - collection = toIterable(collection); + function sum(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; } - var length = collection.length, - result = 0; + var func = getCallback(), + noIteratee = iteratee == null; - while (length--) { - result += +collection[length] || 0; + if (!(func === baseCallback && noIteratee)) { + noIteratee = false; + iteratee = func(iteratee, thisArg, 3); } - return result; + return noIteratee + ? arraySum(isArray(collection) ? collection : toIterable(collection)) + : baseSum(collection, iteratee); } /*------------------------------------------------------------------------*/ @@ -45454,6 +45641,7 @@ return jQuery; lodash.reject = reject; lodash.remove = remove; lodash.rest = rest; + lodash.restParam = restParam; lodash.shuffle = shuffle; lodash.slice = slice; lodash.sortBy = sortBy; @@ -45745,8 +45933,11 @@ return jQuery; // Add `LazyWrapper` methods to `lodash.prototype`. baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var lodashFunc = lodash[methodName], - checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), + var lodashFunc = lodash[methodName]; + if (!lodashFunc) { + return; + } + var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), retUnwrapped = /^(?:first|last)$/.test(methodName); lodash.prototype[methodName] = function() { @@ -45805,6 +45996,19 @@ return jQuery; }; }); + // Map minified function names to their real names. + baseForOwn(LazyWrapper.prototype, function(func, methodName) { + var lodashFunc = lodash[methodName]; + if (lodashFunc) { + var key = lodashFunc.name, + names = realNames[key] || (realNames[key] = []); + + names.push({ 'name': methodName, 'func': lodashFunc }); + } + }); + + realNames[createHybridWrapper(null, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': null }]; + // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; LazyWrapper.prototype.reverse = lazyReverse; @@ -45894,7 +46098,7 @@ exports.createRedirect = require("./Route").createRedirect; exports.createRoutesFromReactChildren = require("./createRoutesFromReactChildren"); exports.create = require("./createRouter"); exports.run = require("./runRouter"); -},{"./History":5,"./Navigation":7,"./Route":11,"./State":13,"./behaviors/ImitateBrowserBehavior":16,"./behaviors/ScrollToTopBehavior":17,"./components/DefaultRoute":19,"./components/Link":20,"./components/NotFoundRoute":21,"./components/Redirect":22,"./components/Route":23,"./components/RouteHandler":24,"./createRouter":25,"./createRoutesFromReactChildren":26,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./locations/TestLocation":33,"./runRouter":34}],"react/addons":[function(require,module,exports){ +},{"./History":10,"./Navigation":12,"./Route":16,"./State":18,"./behaviors/ImitateBrowserBehavior":21,"./behaviors/ScrollToTopBehavior":22,"./components/DefaultRoute":24,"./components/Link":25,"./components/NotFoundRoute":26,"./components/Redirect":27,"./components/Route":28,"./components/RouteHandler":29,"./createRouter":30,"./createRoutesFromReactChildren":31,"./locations/HashLocation":34,"./locations/HistoryLocation":35,"./locations/RefreshLocation":36,"./locations/StaticLocation":37,"./locations/TestLocation":38,"./runRouter":39}],"react/addons":[function(require,module,exports){ module.exports = require('./lib/ReactWithAddons'); },{"./lib/ReactWithAddons":141}],"react":[function(require,module,exports){ diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js index b0aa09779..965ae9a76 100644 --- a/web/src/js/components/common.js +++ b/web/src/js/components/common.js @@ -55,6 +55,11 @@ var SettingsState = { var ChildFocus = { contextTypes: { returnFocus: React.PropTypes.func + }, + returnFocus: function(){ + React.findDOMNode(this).blur(); + window.getSelection().removeAllRanges(); + this.context.returnFocus(); } }; diff --git a/web/src/js/components/editor.js b/web/src/js/components/editor.js new file mode 100644 index 000000000..714a8e2a3 --- /dev/null +++ b/web/src/js/components/editor.js @@ -0,0 +1,189 @@ +var React = require("react"); +var common = require("./common.js"); +var utils = require("../utils.js"); + +var contentToHtml = function (content) { + return _.escape(content); +}; +var nodeToContent = function (node) { + return node.textContent; +}; + +/* +Basic Editor Functionality + */ +var EditorBase = React.createClass({ + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + contentToHtml: React.PropTypes.func, + nodeToContent: React.PropTypes.func, // content === nodeToContent( Node ) + submitOnEnter: React.PropTypes.bool, + className: React.PropTypes.string, + tag: React.PropTypes.string + }, + getDefaultProps: function () { + return { + contentToHtml: contentToHtml, + nodeToContent: nodeToContent, + submitOnEnter: true, + className: "", + tag: "div" + }; + }, + getInitialState: function () { + return { + editable: false + }; + }, + render: function () { + var className = "inline-input " + this.props.className; + var html = {__html: this.props.contentToHtml(this.props.content)}; + var Tag = this.props.tag; + return ; + }, + onFocus: function (e) { + this.setState({editable: true}, function () { + React.findDOMNode(this).focus(); + var range = document.createRange(); + range.selectNodeContents(this.getDOMNode()); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + }); + this.props.onFocus && this.props.onFocus(e); + }, + stop: function () { + // a stop would cause a blur as a side-effect. + // but a blur event must trigger a stop as well. + // to fix this, make stop = blur and do the actual stop in the onBlur handler. + React.findDOMNode(this).blur(); + }, + _stop: function (e) { + window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur + var node = React.findDOMNode(this); + var content = this.props.nodeToContent(node); + this.setState({editable: false}); + this.props.onDone(content); + this.props.onBlur && this.props.onBlur(e); + }, + cancel: function () { + React.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); + this.stop(); + }, + onKeyDown: function (e) { + e.stopPropagation(); + switch (e.keyCode) { + case utils.Key.ESC: + e.preventDefault(); + this.cancel(); + break; + case utils.Key.ENTER: + if (this.props.submitOnEnter) { + e.preventDefault(); + this.stop(); + } + break; + default: + break; + } + }, + onInput: function () { + var node = React.findDOMNode(this); + var content = this.props.nodeToContent(node); + node.innerHTML = this.props.contentToHtml(content); + this.props.onInput && this.props.onInput(content); + } +}); + +/* +Add Validation to EditorBase + */ +var ValidateEditor = React.createClass({ + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + onInput: React.PropTypes.func, + isValid: React.PropTypes.func, + className: React.PropTypes.string, + }, + getInitialState: function(){ + return { + currentContent: this.props.content + }; + }, + componentWillReceiveProps: function(){ + this.setState({currentContent: this.props.content}); + }, + onInput: function(content){ + this.setState({currentContent: content}); + this.props.onInput && this.props.onInput(content); + }, + render: function () { + var className = this.props.className || ""; + if (this.props.isValid) { + if (this.props.isValid(this.state.currentContent)) { + className += " has-success"; + } else { + className += " has-warning" + } + } + return ; + }, + onDone: function (content) { + if(this.props.isValid && !this.props.isValid(content)){ + this.refs.editor.cancel(); + content = this.props.content; + } + this.props.onDone(content); + } +}); + +/* +Text Editor with mitmweb-specific convenience features + */ +var ValueEditor = React.createClass({ + mixins: [common.ChildFocus], + propTypes: { + content: React.PropTypes.string.isRequired, + onDone: React.PropTypes.func.isRequired, + inline: React.PropTypes.bool, + }, + render: function () { + var tag = this.props.inline ? "span" : "div"; + return ; + }, + focus: function () { + React.findDOMNode(this).focus(); + }, + onBlur: function(e){ + if(!e.relatedTarget){ + this.returnFocus(); + } + this.props.onBlur && this.props.onBlur(e); + } +}); + +module.exports = { + ValueEditor: ValueEditor +}; \ No newline at end of file diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index cb166026a..fa75efbe4 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -6,6 +6,7 @@ var actions = require("../../actions.js"); var flowutils = require("../../flow/utils.js"); var utils = require("../../utils.js"); var ContentView = require("./contentview.js"); +var ValueEditor = require("../editor.js").ValueEditor; var Headers = React.createClass({ propTypes: { @@ -63,16 +64,16 @@ var Headers = React.createClass({ var rows = this.props.message.headers.map(function (header, i) { - var kEdit = ; - var vEdit = ; return ( @@ -92,88 +93,9 @@ var Headers = React.createClass({ } }); - -var InlineInput = React.createClass({ - mixins: [common.ChildFocus], - propTypes: { - content: React.PropTypes.string.isRequired, //must be string to match strict equality. - onChange: React.PropTypes.func.isRequired, - }, - getInitialState: function () { - return { - editable: false - }; - }, +var HeaderEditor = React.createClass({ render: function () { - var Tag = this.props.tag || "span"; - var className = "inline-input " + (this.props.className || ""); - var html = {__html: _.escape(this.props.content)}; - return ; - }, - onKeyDown: function (e) { - e.stopPropagation(); - switch (e.keyCode) { - case utils.Key.ESC: - this.blur(); - break; - case utils.Key.ENTER: - e.preventDefault(); - if (!e.ctrlKey) { - this.blur(); - } else { - this.props.onDone && this.props.onDone(); - } - break; - default: - this.props.onKeyDown && this.props.onKeyDown(e); - break; - } - }, - blur: function () { - this.getDOMNode().blur(); - window.getSelection().removeAllRanges(); - this.context.returnFocus && this.context.returnFocus(); - }, - focus: function () { - React.findDOMNode(this).focus(); - var range = document.createRange(); - range.selectNodeContents(this.getDOMNode()); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - }, - onFocus: function () { - this.setState({editable: true}, this.focus); - }, - onBlur: function (e) { - this.setState({editable: false}); - this.handleChange(); - this.props.onDone && this.props.onDone(); - }, - onInput: function () { - this.handleChange(); - }, - handleChange: function () { - var content = this.getDOMNode().textContent; - if (content !== this.props.content) { - this.props.onChange(content); - } - } -}); - -var HeaderInlineInput = React.createClass({ - render: function () { - return ; + return ; }, focus: function () { this.getDOMNode().focus(); @@ -195,65 +117,6 @@ var HeaderInlineInput = React.createClass({ } }); -var ValidateInlineInput = React.createClass({ - propTypes: { - onChange: React.PropTypes.func.isRequired, - isValid: React.PropTypes.func.isRequired, - immediate: React.PropTypes.bool - }, - getInitialState: function () { - return { - content: this.props.content, - originalContent: this.props.content - }; - }, - focus: function () { - this.getDOMNode().focus(); - }, - onChange: function (val) { - this.setState({ - content: val - }); - if (this.props.immediate && val !== this.state.originalContent && this.props.isValid(val)) { - this.props.onChange(val); - } - }, - onDone: function () { - if (this.state.content === this.state.originalContent) { - return true; - } - if (this.props.isValid(this.state.content)) { - this.props.onChange(this.state.content); - } else { - this.setState({ - content: this.state.originalContent - }); - } - }, - componentWillReceiveProps: function (nextProps) { - if (nextProps.content !== this.state.content) { - this.setState({ - content: nextProps.content, - originalContent: nextProps.content - }) - } - }, - render: function () { - var className = this.props.className || ""; - if (this.props.isValid(this.state.content)) { - className += " has-success"; - } else { - className += " has-warning" - } - return ; - } -}); - var RequestLine = React.createClass({ render: function () { var flow = this.props.flow; @@ -261,11 +124,25 @@ var RequestLine = React.createClass({ var httpver = "HTTP/" + flow.request.httpversion.join("."); return
- +   - +   - +
}, isValidUrl: function (url) { @@ -300,12 +177,25 @@ var ResponseLine = React.createClass({ var flow = this.props.flow; var httpver = "HTTP/" + flow.response.httpversion.join("."); return
- +   - +   - - +
; }, isValidCode: function (code) { @@ -361,7 +251,7 @@ var Request = React.createClass({ this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { @@ -401,7 +291,7 @@ var Response = React.createClass({ this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 225f5b9ff..998a41df1 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -119,7 +119,7 @@ var FilterInput = React.createClass({ }, blur: function () { this.refs.input.getDOMNode().blur(); - this.context.returnFocus && this.context.returnFocus(); + this.returnFocus(); }, select: function () { this.refs.input.getDOMNode().select(); diff --git a/web/src/js/components/prompt.js b/web/src/js/components/prompt.js index 229e82c85..121a1170a 100644 --- a/web/src/js/components/prompt.js +++ b/web/src/js/components/prompt.js @@ -34,7 +34,7 @@ var Prompt = React.createClass({ }, done: function (ret) { this.props.done(ret); - this.context.returnFocus && this.context.returnFocus(); + this.returnFocus(); }, getOptions: function () { var opts = []; From bb965b8e34095697da13f313673960feaee63b0f Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 1 May 2015 20:45:27 +0200 Subject: [PATCH 2/2] web: try harder to fix editor --- libmproxy/web/static/app.js | 9 +++++++-- web/src/js/components/editor.js | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libmproxy/web/static/app.js b/libmproxy/web/static/app.js index 3531174e6..b97671534 100644 --- a/libmproxy/web/static/app.js +++ b/libmproxy/web/static/app.js @@ -735,9 +735,15 @@ var EditorBase = React.createClass({displayName: "EditorBase", onBlur: this._stop, onKeyDown: this.onKeyDown, onInput: this.onInput, + onPaste: this.onPaste, dangerouslySetInnerHTML: html}) ); }, + onPaste: function(e){ + e.preventDefault(); + var content = e.clipboardData.getData("text/plain"); + document.execCommand("insertHTML", false, content); + }, onFocus: function (e) { this.setState({editable: true}, function () { React.findDOMNode(this).focus(); @@ -775,7 +781,7 @@ var EditorBase = React.createClass({displayName: "EditorBase", this.cancel(); break; case utils.Key.ENTER: - if (this.props.submitOnEnter) { + if (this.props.submitOnEnter && !e.shiftKey) { e.preventDefault(); this.stop(); } @@ -787,7 +793,6 @@ var EditorBase = React.createClass({displayName: "EditorBase", onInput: function () { var node = React.findDOMNode(this); var content = this.props.nodeToContent(node); - node.innerHTML = this.props.contentToHtml(content); this.props.onInput && this.props.onInput(content); } }); diff --git a/web/src/js/components/editor.js b/web/src/js/components/editor.js index 714a8e2a3..129fef08a 100644 --- a/web/src/js/components/editor.js +++ b/web/src/js/components/editor.js @@ -49,9 +49,15 @@ var EditorBase = React.createClass({ onBlur={this._stop} onKeyDown={this.onKeyDown} onInput={this.onInput} + onPaste={this.onPaste} dangerouslySetInnerHTML={html} />; }, + onPaste: function(e){ + e.preventDefault(); + var content = e.clipboardData.getData("text/plain"); + document.execCommand("insertHTML", false, content); + }, onFocus: function (e) { this.setState({editable: true}, function () { React.findDOMNode(this).focus(); @@ -89,7 +95,7 @@ var EditorBase = React.createClass({ this.cancel(); break; case utils.Key.ENTER: - if (this.props.submitOnEnter) { + if (this.props.submitOnEnter && !e.shiftKey) { e.preventDefault(); this.stop(); } @@ -101,7 +107,6 @@ var EditorBase = React.createClass({ onInput: function () { var node = React.findDOMNode(this); var content = this.props.nodeToContent(node); - node.innerHTML = this.props.contentToHtml(content); this.props.onInput && this.props.onInput(content); } });