From 3e6a74f4eea7c6722e8dff8564308560ff725aac Mon Sep 17 00:00:00 2001 From: Clemens Date: Sun, 29 May 2016 12:43:02 +0200 Subject: [PATCH 1/8] added ui --- web/src/js/components/header.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 643659c37..0df29f510 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -368,6 +368,18 @@ var FileMenu = React.createClass({ New +
  • + + + Open... + +
  • +
  • + + + Save... + +
  • From dfc033ab5f981eb97cda695e707acd590e5708e3 Mon Sep 17 00:00:00 2001 From: Clemens Date: Wed, 1 Jun 2016 00:52:37 +0200 Subject: [PATCH 2/8] added basic file up_download functionality (not finish yet) --- mitmproxy/web/__init__.py | 3 +++ mitmproxy/web/app.py | 23 +++++++++++++++++++++++ web/src/js/actions.js | 7 +++++++ web/src/js/components/header.js | 24 ++++++------------------ 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/mitmproxy/web/__init__.py b/mitmproxy/web/__init__.py index 80a658863..357718f15 100644 --- a/mitmproxy/web/__init__.py +++ b/mitmproxy/web/__init__.py @@ -87,6 +87,9 @@ class WebState(flow.State): data=[] ) + def load_flows(self, flows): + super(WebState, self).load_flows(flows) + class Options(object): attributes = [ diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index 43b2bad14..afeb7c001 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -8,6 +8,8 @@ import re import six import tornado.websocket +from six.moves import cStringIO as StringIO +from mitmproxy.flow import FlowWriter, FlowReader from mitmproxy import filt from mitmproxy import version @@ -159,6 +161,26 @@ class Flows(RequestHandler): data=[_strip_content(f.get_state()) for f in self.state.flows] )) +class DumpFlows(RequestHandler): + def get(self): + self.set_header("Content-Description", "File Transfer") + self.set_header("Cache-Control", "no-cache, no-store, must-revalidate") + self.set_header("Content-Disposition", "attachment; filename=flows") + self.set_header("Content-Type", "application/octet-stream") + self.set_header("Content-Transfer-Encoding", "binary") + + sio = StringIO() + fw = FlowWriter(sio) + for f in self.state.flows: + fw.add(f) + self.write(sio.getvalue()) + + sio.close() + + def post(self): + sio = StringIO(self.request.body) + self.state.load_flows(FlowReader(sio).stream()) + sio.close() class ClearAll(RequestHandler): @@ -356,6 +378,7 @@ class Application(tornado.web.Application): (r"/updates", ClientConnection), (r"/events", Events), (r"/flows", Flows), + (r"/flows/dump", DumpFlows), (r"/flows/accept", AcceptFlows), (r"/flows/(?P[0-9a-f\-]+)", FlowHandler), (r"/flows/(?P[0-9a-f\-]+)/accept", AcceptFlow), diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 6ded4c446..0f81d7a38 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -117,6 +117,13 @@ export var FlowActions = { }, clear: function(){ $.post("/clear"); + }, + download: () => window.location = "/flows/dump", + upload: (file) => { + var filereader = new FileReader(); + filereader.file = file; + filereader.onload = (e) => $.post("/flows/dump", e.target.result); + filereader.readAsBinaryString(file); } }; diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 0df29f510..4bb4622d3 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -345,11 +345,14 @@ var FileMenu = React.createClass({ }, handleOpenClick: function (e) { e.preventDefault(); - console.error("unimplemented: handleOpenClick"); + }, + handleOpenChange: function (e) { + e.preventDefault(); + FlowActions.upload(e.target.files[0]); }, handleSaveClick: function (e) { e.preventDefault(); - console.error("unimplemented: handleSaveClick"); + FlowActions.download(); }, handleShutdownClick: function (e) { e.preventDefault(); @@ -369,10 +372,7 @@ var FileMenu = React.createClass({
  • - - - Open... - +
  • @@ -388,18 +388,6 @@ var FileMenu = React.createClass({
  • {/* -
  • - - - Open - -
  • -
  • - - - Save - -
  • From cf544318ae7b59711f64166fe765c93ec8fb42c1 Mon Sep 17 00:00:00 2001 From: Clemens Date: Wed, 1 Jun 2016 23:12:09 +0200 Subject: [PATCH 3/8] basic file up and download working --- web/src/js/store/store.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js index e41b2eef7..4c4478d9d 100644 --- a/web/src/js/store/store.js +++ b/web/src/js/store/store.js @@ -118,7 +118,8 @@ _.extend(LiveStoreMixin.prototype, { this.handle_fetch(message.data); }.bind(this)) .fail(function () { - EventLogActions.add_event("Could not fetch " + this.type); + //EventLogActions.add_event("Could not fetch " + this.type); + console.log("Could not fetch " + this.type); // store.js:121 Uncaught ReferenceError: EventLogActions is not defined }.bind(this)); } }, From a219d3343081e13a005fc37e30a0bab83a773099 Mon Sep 17 00:00:00 2001 From: Clemens Date: Wed, 1 Jun 2016 23:12:49 +0200 Subject: [PATCH 4/8] basic file up and download working --- mitmproxy/web/app.py | 1 + web/src/js/actions.js | 2 +- web/src/js/components/header.js | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index afeb7c001..43949cc76 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -178,6 +178,7 @@ class DumpFlows(RequestHandler): sio.close() def post(self): + # self.state.clear() sio = StringIO(self.request.body) self.state.load_flows(FlowReader(sio).stream()) sio.close() diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 0f81d7a38..2f2479799 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -122,7 +122,7 @@ export var FlowActions = { upload: (file) => { var filereader = new FileReader(); filereader.file = file; - filereader.onload = (e) => $.post("/flows/dump", e.target.result); + filereader.onload = (e) => {$.post("/flows/dump", e.target.result); e.preventDefault();}; filereader.readAsBinaryString(file); } }; diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 4bb4622d3..859f2fcf0 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -344,11 +344,15 @@ var FileMenu = React.createClass({ } }, handleOpenClick: function (e) { + $('#uploadFileInput').trigger('click'); e.preventDefault(); }, - handleOpenChange: function (e) { + handleOpenFile: function (e) { + if (e.target.files.length > 0) { + FlowActions.upload(e.target.files[0]); + $('#uploadFileInput').val(""); + } e.preventDefault(); - FlowActions.upload(e.target.files[0]); }, handleSaveClick: function (e) { e.preventDefault(); @@ -372,7 +376,12 @@ var FileMenu = React.createClass({
  • - + + + Open... + + +
  • From 89fc438e324c359df8b387a39c9e8beab1df54d0 Mon Sep 17 00:00:00 2001 From: Clemens Date: Thu, 2 Jun 2016 15:12:42 +0200 Subject: [PATCH 5/8] change some pr issuses --- mitmproxy/web/app.py | 23 ++++++++++------------- web/src/js/actions.js | 11 ++++++++++- web/src/js/components/header.js | 6 +++--- web/src/js/store/store.js | 5 ++--- web/src/js/utils.js | 2 +- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index 43949cc76..50ee894b9 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -8,7 +8,7 @@ import re import six import tornado.websocket -from six.moves import cStringIO as StringIO +from io import BytesIO from mitmproxy.flow import FlowWriter, FlowReader from mitmproxy import filt @@ -163,25 +163,22 @@ class Flows(RequestHandler): class DumpFlows(RequestHandler): def get(self): - self.set_header("Content-Description", "File Transfer") - self.set_header("Cache-Control", "no-cache, no-store, must-revalidate") self.set_header("Content-Disposition", "attachment; filename=flows") self.set_header("Content-Type", "application/octet-stream") - self.set_header("Content-Transfer-Encoding", "binary") - sio = StringIO() - fw = FlowWriter(sio) + bio = BytesIO() + fw = FlowWriter(bio) for f in self.state.flows: fw.add(f) - self.write(sio.getvalue()) + self.write(bio.getvalue()) - sio.close() + bio.close() def post(self): - # self.state.clear() - sio = StringIO(self.request.body) - self.state.load_flows(FlowReader(sio).stream()) - sio.close() + self.state.clear() + bio = BytesIO(self.request.body) + self.state.load_flows(FlowReader(bio).stream()) + bio.close() class ClearAll(RequestHandler): @@ -393,7 +390,7 @@ class Application(tornado.web.Application): settings = dict( template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), - xsrf_cookies=True, + xsrf_cookies=False, cookie_secret=os.urandom(256), debug=debug, wauthenticator=wauthenticator, diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 2f2479799..5c6f0167b 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -1,6 +1,7 @@ import $ from "jquery"; import _ from "lodash"; import {AppDispatcher} from "./dispatcher.js"; +import {getCookie} from "./utils.js"; export var ActionTypes = { // Connection @@ -119,10 +120,18 @@ export var FlowActions = { $.post("/clear"); }, download: () => window.location = "/flows/dump", + upload: (file) => { + var xsrf = $.param({_xsrf: getCookie("_xsrf")}); + //console.log(xsrf); var filereader = new FileReader(); filereader.file = file; - filereader.onload = (e) => {$.post("/flows/dump", e.target.result); e.preventDefault();}; + filereader.onload = (e) => { + fetch("/flows/dump?"+xsrf, { + method: 'post', + body: e.currentTarget.result + }) + }; filereader.readAsBinaryString(file); } }; diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 859f2fcf0..adc8bb9b2 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -344,13 +344,13 @@ var FileMenu = React.createClass({ } }, handleOpenClick: function (e) { - $('#uploadFileInput').trigger('click'); + this.fileInput.click(); e.preventDefault(); }, handleOpenFile: function (e) { if (e.target.files.length > 0) { FlowActions.upload(e.target.files[0]); - $('#uploadFileInput').val(""); + this.fileInput.value = ""; } e.preventDefault(); }, @@ -380,7 +380,7 @@ var FileMenu = React.createClass({ Open... - + this.fileInput = ref} className="hidden" type="file" onChange={this.handleOpenFile}/>
  • diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js index 4c4478d9d..a16a0369c 100644 --- a/web/src/js/store/store.js +++ b/web/src/js/store/store.js @@ -2,7 +2,7 @@ import _ from "lodash"; import $ from "jquery"; import {EventEmitter} from 'events'; - +import { EventLogActions } from "../actions.js" import {ActionTypes, StoreCmds} from "../actions.js"; import {AppDispatcher} from "../dispatcher.js"; @@ -118,8 +118,7 @@ _.extend(LiveStoreMixin.prototype, { this.handle_fetch(message.data); }.bind(this)) .fail(function () { - //EventLogActions.add_event("Could not fetch " + this.type); - console.log("Could not fetch " + this.type); // store.js:121 Uncaught ReferenceError: EventLogActions is not defined + EventLogActions.add_event("Could not fetch " + this.type); }.bind(this)); } }, diff --git a/web/src/js/utils.js b/web/src/js/utils.js index 2627cf586..454bfe226 100644 --- a/web/src/js/utils.js +++ b/web/src/js/utils.js @@ -76,7 +76,7 @@ export function reverseString(s) { ) + end; } -function getCookie(name) { +export function getCookie(name) { var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b")); return r ? r[1] : undefined; } From 73e494770fe83b41f879d6f068f15c3056c943cf Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 2 Jun 2016 10:34:16 -0700 Subject: [PATCH 6/8] web: add fetchApi convenience method --- mitmproxy/web/__init__.py | 3 --- mitmproxy/web/app.py | 2 +- web/src/js/actions.js | 7 ++----- web/src/js/utils.js | 18 +++++++++++++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mitmproxy/web/__init__.py b/mitmproxy/web/__init__.py index 357718f15..80a658863 100644 --- a/mitmproxy/web/__init__.py +++ b/mitmproxy/web/__init__.py @@ -87,9 +87,6 @@ class WebState(flow.State): data=[] ) - def load_flows(self, flows): - super(WebState, self).load_flows(flows) - class Options(object): attributes = [ diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index 50ee894b9..af2f6e8c4 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -390,7 +390,7 @@ class Application(tornado.web.Application): settings = dict( template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), - xsrf_cookies=False, + xsrf_cookies=True, cookie_secret=os.urandom(256), debug=debug, wauthenticator=wauthenticator, diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 5c6f0167b..9325765b1 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -1,7 +1,6 @@ import $ from "jquery"; -import _ from "lodash"; import {AppDispatcher} from "./dispatcher.js"; -import {getCookie} from "./utils.js"; +import {fetchApi} from "./utils.js"; export var ActionTypes = { // Connection @@ -122,12 +121,10 @@ export var FlowActions = { download: () => window.location = "/flows/dump", upload: (file) => { - var xsrf = $.param({_xsrf: getCookie("_xsrf")}); - //console.log(xsrf); var filereader = new FileReader(); filereader.file = file; filereader.onload = (e) => { - fetch("/flows/dump?"+xsrf, { + fetchApi("/flows/dump", { method: 'post', body: e.currentTarget.result }) diff --git a/web/src/js/utils.js b/web/src/js/utils.js index 454bfe226..97737b201 100644 --- a/web/src/js/utils.js +++ b/web/src/js/utils.js @@ -76,11 +76,11 @@ export function reverseString(s) { ) + end; } -export function getCookie(name) { +function getCookie(name) { var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b")); return r ? r[1] : undefined; } -var xsrf = $.param({_xsrf: getCookie("_xsrf")}); +const xsrf = `_xsrf=${getCookie("_xsrf")}`; //Tornado XSRF Protection. $.ajaxPrefilter(function (options) { @@ -101,4 +101,16 @@ $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { console.error(thrownError, message, arguments); actions.EventLogActions.add_event(thrownError + ": " + message); alert(message); -}); \ No newline at end of file +}); + +export function fetchApi(url, options) { + if(url.indexOf("?") === -1){ + url += "?" + xsrf; + } else { + url += "&" + xsrf; + } + return fetch(url, { + ...options, + credentials: 'same-origin' + }); +} \ No newline at end of file From 9c6da08d00f2580c4513f04f1fef82eebb493248 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 2 Jun 2016 11:41:26 -0700 Subject: [PATCH 7/8] fix dumpfile upload --- mitmproxy/web/app.py | 3 +- mitmproxy/web/static/app.js | 75 ++++++++++++++++++++++++++++++++----- web/src/js/actions.js | 15 +++----- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index af2f6e8c4..594f1d3a1 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -176,7 +176,8 @@ class DumpFlows(RequestHandler): def post(self): self.state.clear() - bio = BytesIO(self.request.body) + content = self.request.files.values()[0][0]["body"] + bio = BytesIO(content) self.state.load_flows(FlowReader(bio).stream()) bio.close() diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index e02df55ab..12eea3e00 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -310,12 +310,10 @@ var _jquery = require("jquery"); var _jquery2 = _interopRequireDefault(_jquery); -var _lodash = require("lodash"); - -var _lodash2 = _interopRequireDefault(_lodash); - var _dispatcher = require("./dispatcher.js"); +var _utils = require("./utils.js"); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var ActionTypes = exports.ActionTypes = { @@ -433,6 +431,18 @@ var FlowActions = exports.FlowActions = { }, clear: function clear() { _jquery2.default.post("/clear"); + }, + download: function download() { + return window.location = "/flows/dump"; + }, + + upload: function upload(file) { + var data = new FormData(); + data.append('file', file); + (0, _utils.fetchApi)("/flows/dump", { + method: 'post', + body: data + }); } }; @@ -442,7 +452,7 @@ var Query = exports.Query = { SHOW_EVENTLOG: "e" }; -},{"./dispatcher.js":22,"jquery":"jquery","lodash":"lodash"}],3:[function(require,module,exports){ +},{"./dispatcher.js":22,"./utils.js":27,"jquery":"jquery"}],3:[function(require,module,exports){ "use strict"; var _react = require("react"); @@ -3513,18 +3523,27 @@ var FileMenu = _react2.default.createClass({ } }, handleOpenClick: function handleOpenClick(e) { + this.fileInput.click(); + e.preventDefault(); + }, + handleOpenFile: function handleOpenFile(e) { + if (e.target.files.length > 0) { + _actions.FlowActions.upload(e.target.files[0]); + this.fileInput.value = ""; + } e.preventDefault(); - console.error("unimplemented: handleOpenClick"); }, handleSaveClick: function handleSaveClick(e) { e.preventDefault(); - console.error("unimplemented: handleSaveClick"); + _actions.FlowActions.download(); }, handleShutdownClick: function handleShutdownClick(e) { e.preventDefault(); console.error("unimplemented: handleShutdownClick"); }, render: function render() { + var _this = this; + var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : ""); return _react2.default.createElement( @@ -3548,6 +3567,29 @@ var FileMenu = _react2.default.createClass({ "New" ) ), + _react2.default.createElement( + "li", + null, + _react2.default.createElement( + "a", + { href: "#", onClick: this.handleOpenClick }, + _react2.default.createElement("i", { className: "fa fa-fw fa-folder-open" }), + "Open..." + ), + _react2.default.createElement("input", { ref: function ref(_ref) { + return _this.fileInput = _ref; + }, className: "hidden", type: "file", onChange: this.handleOpenFile }) + ), + _react2.default.createElement( + "li", + null, + _react2.default.createElement( + "a", + { href: "#", onClick: this.handleSaveClick }, + _react2.default.createElement("i", { className: "fa fa-fw fa-floppy-o" }), + "Save..." + ) + ), _react2.default.createElement("li", { role: "presentation", className: "divider" }), _react2.default.createElement( "li", @@ -6602,7 +6644,7 @@ _lodash2.default.extend(LiveStoreMixin.prototype, { this._fetchxhr = _jquery2.default.getJSON("/" + this.type).done(function (message) { this.handle_fetch(message.data); }.bind(this)).fail(function () { - EventLogActions.add_event("Could not fetch " + this.type); + _actions.EventLogActions.add_event("Could not fetch " + this.type); }.bind(this)); } }, @@ -6792,7 +6834,11 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.formatTimeStamp = exports.formatTimeDelta = exports.formatSize = exports.Key = undefined; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + exports.reverseString = reverseString; +exports.fetchApi = fetchApi; var _jquery = require("jquery"); @@ -6877,7 +6923,7 @@ function getCookie(name) { var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b")); return r ? r[1] : undefined; } -var xsrf = _jquery2.default.param({ _xsrf: getCookie("_xsrf") }); +var xsrf = "_xsrf=" + getCookie("_xsrf"); //Tornado XSRF Protection. _jquery2.default.ajaxPrefilter(function (options) { @@ -6900,6 +6946,17 @@ _jquery2.default.ajaxPrefilter(function (options) { alert(message); }); +function fetchApi(url, options) { + if (url.indexOf("?") === -1) { + url += "?" + xsrf; + } else { + url += "&" + xsrf; + } + return fetch(url, _extends({}, options, { + credentials: 'same-origin' + })); +} + },{"./actions.js":2,"jquery":"jquery","lodash":"lodash","react":"react"}]},{},[3]) diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 9325765b1..c77cdf734 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -121,15 +121,12 @@ export var FlowActions = { download: () => window.location = "/flows/dump", upload: (file) => { - var filereader = new FileReader(); - filereader.file = file; - filereader.onload = (e) => { - fetchApi("/flows/dump", { - method: 'post', - body: e.currentTarget.result - }) - }; - filereader.readAsBinaryString(file); + let data = new FormData(); + data.append('file', file); + fetchApi("/flows/dump", { + method: 'post', + body: data + }) } }; From 5e7fa349a94fcc204e88523cfb4c61d24b9838bc Mon Sep 17 00:00:00 2001 From: Clemens Date: Thu, 2 Jun 2016 21:01:22 +0200 Subject: [PATCH 8/8] final review done, nothing to change -> ready to merge --- mitmproxy/web/app.py | 3 +- mitmproxy/web/static/vendor.js | 3454 ++++++++++++++++++-------------- 2 files changed, 1937 insertions(+), 1520 deletions(-) diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index 594f1d3a1..dce85df38 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -170,12 +170,13 @@ class DumpFlows(RequestHandler): fw = FlowWriter(bio) for f in self.state.flows: fw.add(f) - self.write(bio.getvalue()) + self.write(bio.getvalue()) bio.close() def post(self): self.state.clear() + content = self.request.files.values()[0][0]["body"] bio = BytesIO(content) self.state.load_flows(FlowReader(bio).stream()) diff --git a/mitmproxy/web/static/vendor.js b/mitmproxy/web/static/vendor.js index efe6f2b4e..f3a960ccb 100644 --- a/mitmproxy/web/static/vendor.js +++ b/mitmproxy/web/static/vendor.js @@ -764,7 +764,11 @@ function createBrowserHistory() { var useRefresh = !isSupported || forceRefresh; function getCurrentLocation(historyState) { - historyState = historyState || window.history.state || {}; + try { + historyState = historyState || window.history.state || {}; + } catch (e) { + historyState = {}; + } var path = _DOMUtils.getWindowPath(); var _historyState = historyState; @@ -2116,13 +2120,15 @@ var KNOWN_STATICS = { }; module.exports = function hoistNonReactStatics(targetComponent, sourceComponent) { - var keys = Object.getOwnPropertyNames(sourceComponent); - for (var i=0; i plugins (like Flash Player) will read + // nodes immediately upon insertion into the DOM, so + // must also be populated prior to insertion into the DOM. + if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) { insertTreeChildren(tree); parentNode.insertBefore(tree.node, referenceNode); } else { @@ -7823,12 +7882,17 @@ function queueText(tree, text) { } } +function toString() { + return this.node.nodeName; +} + function DOMLazyTree(node) { return { node: node, children: [], html: null, - text: null + text: null, + toString: toString }; } @@ -7839,7 +7903,7 @@ DOMLazyTree.queueHTML = queueHTML; DOMLazyTree.queueText = queueText; module.exports = DOMLazyTree; -},{"./createMicrosoftUnsafeLocalFunction":178,"./setTextContent":200}],75:[function(require,module,exports){ +},{"./DOMNamespaces":75,"./createMicrosoftUnsafeLocalFunction":178,"./setTextContent":200}],75:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -8093,8 +8157,9 @@ module.exports = DOMProperty; 'use strict'; var DOMProperty = require('./DOMProperty'); +var ReactDOMComponentTree = require('./ReactDOMComponentTree'); var ReactDOMInstrumentation = require('./ReactDOMInstrumentation'); -var ReactPerf = require('./ReactPerf'); +var ReactInstrumentation = require('./ReactInstrumentation'); var quoteAttributeValueForBrowser = require('./quoteAttributeValueForBrowser'); var warning = require('fbjs/lib/warning'); @@ -8202,9 +8267,6 @@ var DOMPropertyOperations = { * @param {*} value */ setValueForProperty: function (node, name, value) { - if (process.env.NODE_ENV !== 'production') { - ReactDOMInstrumentation.debugTool.onSetValueForProperty(node, name, value); - } var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; @@ -8212,6 +8274,7 @@ var DOMPropertyOperations = { mutationMethod(node, value); } else if (shouldIgnoreValue(propertyInfo, value)) { this.deleteValueForProperty(node, name); + return; } else if (propertyInfo.mustUseProperty) { var propName = propertyInfo.propertyName; // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the @@ -8236,6 +8299,14 @@ var DOMPropertyOperations = { } } else if (DOMProperty.isCustomAttribute(name)) { DOMPropertyOperations.setValueForAttribute(node, name, value); + return; + } + + if (process.env.NODE_ENV !== 'production') { + ReactDOMInstrumentation.debugTool.onSetValueForProperty(node, name, value); + var payload = {}; + payload[name] = value; + ReactInstrumentation.debugTool.onNativeOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'update attribute', payload); } }, @@ -8248,6 +8319,12 @@ var DOMPropertyOperations = { } else { node.setAttribute(name, '' + value); } + + if (process.env.NODE_ENV !== 'production') { + var payload = {}; + payload[name] = value; + ReactInstrumentation.debugTool.onNativeOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'update attribute', payload); + } }, /** @@ -8257,9 +8334,6 @@ var DOMPropertyOperations = { * @param {string} name */ deleteValueForProperty: function (node, name) { - if (process.env.NODE_ENV !== 'production') { - ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name); - } var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; @@ -8281,20 +8355,19 @@ var DOMPropertyOperations = { } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); } + + if (process.env.NODE_ENV !== 'production') { + ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name); + ReactInstrumentation.debugTool.onNativeOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'remove attribute', name); + } } }; -ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', { - setValueForProperty: 'setValueForProperty', - setValueForAttribute: 'setValueForAttribute', - deleteValueForProperty: 'deleteValueForProperty' -}); - module.exports = DOMPropertyOperations; }).call(this,require('_process')) -},{"./DOMProperty":76,"./ReactDOMInstrumentation":114,"./ReactPerf":147,"./quoteAttributeValueForBrowser":197,"_process":29,"fbjs/lib/warning":229}],78:[function(require,module,exports){ +},{"./DOMProperty":76,"./ReactDOMComponentTree":107,"./ReactDOMInstrumentation":115,"./ReactInstrumentation":136,"./quoteAttributeValueForBrowser":197,"_process":29,"fbjs/lib/warning":229}],78:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -8627,7 +8700,7 @@ var EnterLeaveEventPlugin = { }; module.exports = EnterLeaveEventPlugin; -},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":106,"./SyntheticMouseEvent":168,"fbjs/lib/keyOf":223}],82:[function(require,module,exports){ +},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":107,"./SyntheticMouseEvent":168,"fbjs/lib/keyOf":223}],82:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -8964,7 +9037,7 @@ var EventPluginHub = { module.exports = EventPluginHub; }).call(this,require('_process')) -},{"./EventPluginRegistry":84,"./EventPluginUtils":85,"./ReactErrorUtils":130,"./accumulateInto":175,"./forEachAccumulated":183,"_process":29,"fbjs/lib/invariant":219}],84:[function(require,module,exports){ +},{"./EventPluginRegistry":84,"./EventPluginUtils":85,"./ReactErrorUtils":129,"./accumulateInto":175,"./forEachAccumulated":183,"_process":29,"fbjs/lib/invariant":219}],84:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -9440,7 +9513,7 @@ var EventPluginUtils = { module.exports = EventPluginUtils; }).call(this,require('_process')) -},{"./EventConstants":82,"./ReactErrorUtils":130,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],86:[function(require,module,exports){ +},{"./EventConstants":82,"./ReactErrorUtils":129,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],86:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -10083,7 +10156,7 @@ var LinkedValueUtils = { module.exports = LinkedValueUtils; }).call(this,require('_process')) -},{"./ReactPropTypeLocations":149,"./ReactPropTypes":150,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],91:[function(require,module,exports){ +},{"./ReactPropTypeLocations":148,"./ReactPropTypes":149,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],91:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -10297,7 +10370,7 @@ var React = { module.exports = React; }).call(this,require('_process')) -},{"./ReactChildren":95,"./ReactClass":96,"./ReactComponent":97,"./ReactDOMFactories":110,"./ReactElement":127,"./ReactElementValidator":128,"./ReactPropTypes":150,"./ReactVersion":156,"./onlyChild":196,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],93:[function(require,module,exports){ +},{"./ReactChildren":95,"./ReactClass":96,"./ReactComponent":97,"./ReactDOMFactories":111,"./ReactElement":126,"./ReactElementValidator":127,"./ReactPropTypes":149,"./ReactVersion":156,"./onlyChild":196,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],93:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -10615,7 +10688,7 @@ var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { }); module.exports = ReactBrowserEventEmitter; -},{"./EventConstants":82,"./EventPluginRegistry":84,"./ReactEventEmitterMixin":131,"./ViewportMetrics":174,"./getVendorPrefixedEventName":192,"./isEventSupported":194,"object-assign":28}],94:[function(require,module,exports){ +},{"./EventConstants":82,"./EventPluginRegistry":84,"./ReactEventEmitterMixin":130,"./ViewportMetrics":174,"./getVendorPrefixedEventName":192,"./isEventSupported":194,"object-assign":28}],94:[function(require,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -10744,7 +10817,7 @@ var ReactChildReconciler = { module.exports = ReactChildReconciler; }).call(this,require('_process')) -},{"./KeyEscapeUtils":89,"./ReactReconciler":152,"./instantiateReactComponent":193,"./shouldUpdateReactComponent":201,"./traverseAllChildren":202,"_process":29,"fbjs/lib/warning":229}],95:[function(require,module,exports){ +},{"./KeyEscapeUtils":89,"./ReactReconciler":151,"./instantiateReactComponent":193,"./shouldUpdateReactComponent":201,"./traverseAllChildren":202,"_process":29,"fbjs/lib/warning":229}],95:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -10802,6 +10875,8 @@ function forEachSingleChild(bookKeeping, child, name) { /** * Iterates through children that are typically specified as `props.children`. * + * See https://facebook.github.io/react/docs/top-level-api.html#react.children.foreach + * * The provided forEachFunc(child, index) will be called for each * leaf child. * @@ -10877,7 +10952,9 @@ function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { /** * Maps children that are typically specified as `props.children`. * - * The provided mapFunction(child, index) will be called for each + * See https://facebook.github.io/react/docs/top-level-api.html#react.children.map + * + * The provided mapFunction(child, key, index) will be called for each * leaf child. * * @param {?*} children Children tree container. @@ -10902,6 +10979,8 @@ function forEachSingleChildDummy(traverseContext, child, name) { * Count the number of children that are typically specified as * `props.children`. * + * See https://facebook.github.io/react/docs/top-level-api.html#react.children.count + * * @param {?*} children Children tree container. * @return {number} The number of children. */ @@ -10912,6 +10991,8 @@ function countChildren(children, context) { /** * Flatten a children object (typically specified as `props.children`) and * return an array with appropriately re-keyed children. + * + * See https://facebook.github.io/react/docs/top-level-api.html#react.children.toarray */ function toArray(children) { var result = []; @@ -10928,7 +11009,7 @@ var ReactChildren = { }; module.exports = ReactChildren; -},{"./PooledClass":91,"./ReactElement":127,"./traverseAllChildren":202,"fbjs/lib/emptyFunction":211}],96:[function(require,module,exports){ +},{"./PooledClass":91,"./ReactElement":126,"./traverseAllChildren":202,"fbjs/lib/emptyFunction":211}],96:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -11559,6 +11640,7 @@ var ReactClass = { /** * Creates a composite component class given a class specification. + * See https://facebook.github.io/react/docs/top-level-api.html#react.createclass * * @param {object} spec Class specification (which must define `render`). * @return {function} Component constructor function. @@ -11655,7 +11737,7 @@ var ReactClass = { module.exports = ReactClass; }).call(this,require('_process')) -},{"./ReactComponent":97,"./ReactElement":127,"./ReactNoopUpdateQueue":145,"./ReactPropTypeLocationNames":148,"./ReactPropTypeLocations":149,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/keyMirror":222,"fbjs/lib/keyOf":223,"fbjs/lib/warning":229,"object-assign":28}],97:[function(require,module,exports){ +},{"./ReactComponent":97,"./ReactElement":126,"./ReactNoopUpdateQueue":145,"./ReactPropTypeLocationNames":147,"./ReactPropTypeLocations":148,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/keyMirror":222,"fbjs/lib/keyOf":223,"fbjs/lib/warning":229,"object-assign":28}],97:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -11780,7 +11862,7 @@ if (process.env.NODE_ENV !== 'production') { module.exports = ReactComponent; }).call(this,require('_process')) -},{"./ReactInstrumentation":137,"./ReactNoopUpdateQueue":145,"./canDefineProperty":177,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],98:[function(require,module,exports){ +},{"./ReactInstrumentation":136,"./ReactNoopUpdateQueue":145,"./canDefineProperty":177,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],98:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -11796,7 +11878,6 @@ module.exports = ReactComponent; var DOMChildrenOperations = require('./DOMChildrenOperations'); var ReactDOMIDOperations = require('./ReactDOMIDOperations'); -var ReactPerf = require('./ReactPerf'); /** * Abstracts away all functionality of the reconciler that requires knowledge of @@ -11820,12 +11901,8 @@ var ReactComponentBrowserEnvironment = { }; -ReactPerf.measureMethods(ReactComponentBrowserEnvironment, 'ReactComponentBrowserEnvironment', { - replaceNodeWithMarkup: 'replaceNodeWithMarkup' -}); - module.exports = ReactComponentBrowserEnvironment; -},{"./DOMChildrenOperations":73,"./ReactDOMIDOperations":112,"./ReactPerf":147}],99:[function(require,module,exports){ +},{"./DOMChildrenOperations":73,"./ReactDOMIDOperations":113}],99:[function(require,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -11882,6 +11959,155 @@ module.exports = ReactComponentEnvironment; },{"_process":29,"fbjs/lib/invariant":219}],100:[function(require,module,exports){ (function (process){ +/** + * Copyright 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponentTreeDevtool + */ + +'use strict'; + +var invariant = require('fbjs/lib/invariant'); + +var tree = {}; +var rootIDs = []; + +function updateTree(id, update) { + if (!tree[id]) { + tree[id] = { + parentID: null, + ownerID: null, + text: null, + childIDs: [], + displayName: 'Unknown', + isMounted: false, + updateCount: 0 + }; + } + update(tree[id]); +} + +function purgeDeep(id) { + var item = tree[id]; + if (item) { + var childIDs = item.childIDs; + + delete tree[id]; + childIDs.forEach(purgeDeep); + } +} + +var ReactComponentTreeDevtool = { + onSetDisplayName: function (id, displayName) { + updateTree(id, function (item) { + return item.displayName = displayName; + }); + }, + onSetChildren: function (id, nextChildIDs) { + updateTree(id, function (item) { + var prevChildIDs = item.childIDs; + item.childIDs = nextChildIDs; + + nextChildIDs.forEach(function (nextChildID) { + var nextChild = tree[nextChildID]; + !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected devtool events to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0; + !(nextChild.displayName != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetDisplayName() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0; + !(nextChild.childIDs != null || nextChild.text != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() or onSetText() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0; + !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0; + + if (prevChildIDs.indexOf(nextChildID) === -1) { + nextChild.parentID = id; + } + }); + }); + }, + onSetOwner: function (id, ownerID) { + updateTree(id, function (item) { + return item.ownerID = ownerID; + }); + }, + onSetText: function (id, text) { + updateTree(id, function (item) { + return item.text = text; + }); + }, + onMountComponent: function (id) { + updateTree(id, function (item) { + return item.isMounted = true; + }); + }, + onMountRootComponent: function (id) { + rootIDs.push(id); + }, + onUpdateComponent: function (id) { + updateTree(id, function (item) { + return item.updateCount++; + }); + }, + onUnmountComponent: function (id) { + updateTree(id, function (item) { + return item.isMounted = false; + }); + rootIDs = rootIDs.filter(function (rootID) { + return rootID !== id; + }); + }, + purgeUnmountedComponents: function () { + if (ReactComponentTreeDevtool._preventPurging) { + // Should only be used for testing. + return; + } + + Object.keys(tree).filter(function (id) { + return !tree[id].isMounted; + }).forEach(purgeDeep); + }, + isMounted: function (id) { + var item = tree[id]; + return item ? item.isMounted : false; + }, + getChildIDs: function (id) { + var item = tree[id]; + return item ? item.childIDs : []; + }, + getDisplayName: function (id) { + var item = tree[id]; + return item ? item.displayName : 'Unknown'; + }, + getOwnerID: function (id) { + var item = tree[id]; + return item ? item.ownerID : null; + }, + getParentID: function (id) { + var item = tree[id]; + return item ? item.parentID : null; + }, + getText: function (id) { + var item = tree[id]; + return item ? item.text : null; + }, + getUpdateCount: function (id) { + var item = tree[id]; + return item ? item.updateCount : 0; + }, + getRootIDs: function () { + return rootIDs; + }, + getRegisteredIDs: function () { + return Object.keys(tree); + } +}; + +module.exports = ReactComponentTreeDevtool; +}).call(this,require('_process')) + +},{"_process":29,"fbjs/lib/invariant":219}],101:[function(require,module,exports){ +(function (process){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -11904,7 +12130,6 @@ var ReactErrorUtils = require('./ReactErrorUtils'); var ReactInstanceMap = require('./ReactInstanceMap'); var ReactInstrumentation = require('./ReactInstrumentation'); var ReactNodeTypes = require('./ReactNodeTypes'); -var ReactPerf = require('./ReactPerf'); var ReactPropTypeLocations = require('./ReactPropTypeLocations'); var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); var ReactReconciler = require('./ReactReconciler'); @@ -11940,6 +12165,28 @@ function warnIfInvalidElement(Component, element) { } } +function invokeComponentDidMountWithTimer() { + var publicInstance = this._instance; + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentDidMount'); + } + publicInstance.componentDidMount(); + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentDidMount'); + } +} + +function invokeComponentDidUpdateWithTimer(prevProps, prevState, prevContext) { + var publicInstance = this._instance; + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentDidUpdate'); + } + publicInstance.componentDidUpdate(prevProps, prevState, prevContext); + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentDidUpdate'); + } +} + function shouldConstruct(Component) { return Component.prototype && Component.prototype.isReactComponent; } @@ -11999,6 +12246,7 @@ var ReactCompositeComponentMixin = { this._nativeContainerInfo = null; // See ReactUpdateQueue + this._updateBatchNumber = null; this._pendingElement = null; this._pendingStateQueue = null; this._pendingReplaceState = false; @@ -12107,7 +12355,11 @@ var ReactCompositeComponentMixin = { } if (inst.componentDidMount) { - transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); + if (process.env.NODE_ENV !== 'production') { + transaction.getReactMountReady().enqueue(invokeComponentDidMountWithTimer, this); + } else { + transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); + } } return markup; @@ -12128,11 +12380,35 @@ var ReactCompositeComponentMixin = { _constructComponentWithoutOwner: function (publicProps, publicContext) { var Component = this._currentElement.type; + var instanceOrElement; if (shouldConstruct(Component)) { - return new Component(publicProps, publicContext, ReactUpdateQueue); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'ctor'); + } + } + instanceOrElement = new Component(publicProps, publicContext, ReactUpdateQueue); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'ctor'); + } + } } else { - return Component(publicProps, publicContext, ReactUpdateQueue); + // This can still be an instance in case of factory components + // but we'll count this as time spent rendering as the more common case. + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'render'); + } + } + instanceOrElement = Component(publicProps, publicContext, ReactUpdateQueue); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'render'); + } + } } + return instanceOrElement; }, performInitialMountWithErrorHandling: function (renderedElement, nativeParent, nativeContainerInfo, transaction, context) { @@ -12162,7 +12438,17 @@ var ReactCompositeComponentMixin = { performInitialMount: function (renderedElement, nativeParent, nativeContainerInfo, transaction, context) { var inst = this._instance; if (inst.componentWillMount) { + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentWillMount'); + } + } inst.componentWillMount(); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentWillMount'); + } + } // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingStateQueue` without triggering a re-render. if (this._pendingStateQueue) { @@ -12180,6 +12466,12 @@ var ReactCompositeComponentMixin = { var markup = ReactReconciler.mountComponent(this._renderedComponent, transaction, nativeParent, nativeContainerInfo, this._processChildContext(context)); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onSetChildren(this._debugID, this._renderedComponent._debugID !== 0 ? [this._renderedComponent._debugID] : []); + } + } + return markup; }, @@ -12201,12 +12493,22 @@ var ReactCompositeComponentMixin = { if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) { inst._calledComponentWillUnmount = true; + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentWillUnmount'); + } + } if (safely) { var name = this.getName() + '.componentWillUnmount()'; ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst)); } else { inst.componentWillUnmount(); } + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentWillUnmount'); + } + } } if (this._renderedComponent) { @@ -12389,10 +12691,10 @@ var ReactCompositeComponentMixin = { performUpdateIfNecessary: function (transaction) { if (this._pendingElement != null) { ReactReconciler.receiveComponent(this, this._pendingElement, transaction, this._context); - } - - if (this._pendingStateQueue !== null || this._pendingForceUpdate) { + } else if (this._pendingStateQueue !== null || this._pendingForceUpdate) { this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context); + } else { + this._updateBatchNumber = null; } }, @@ -12439,17 +12741,41 @@ var ReactCompositeComponentMixin = { // _pendingStateQueue which will ensure that any state updates gets // immediately reconciled instead of waiting for the next batch. if (willReceive && inst.componentWillReceiveProps) { + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentWillReceiveProps'); + } + } inst.componentWillReceiveProps(nextProps, nextContext); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentWillReceiveProps'); + } + } } var nextState = this._processPendingState(nextProps, nextContext); + var shouldUpdate = true; - var shouldUpdate = this._pendingForceUpdate || !inst.shouldComponentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext); + if (!this._pendingForceUpdate && inst.shouldComponentUpdate) { + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'shouldComponentUpdate'); + } + } + shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'shouldComponentUpdate'); + } + } + } if (process.env.NODE_ENV !== 'production') { process.env.NODE_ENV !== 'production' ? warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : void 0; } + this._updateBatchNumber = null; if (shouldUpdate) { this._pendingForceUpdate = false; // Will set `this.props`, `this.state` and `this.context`. @@ -12515,7 +12841,17 @@ var ReactCompositeComponentMixin = { } if (inst.componentWillUpdate) { + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'componentWillUpdate'); + } + } inst.componentWillUpdate(nextProps, nextState, nextContext); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'componentWillUpdate'); + } + } } this._currentElement = nextElement; @@ -12527,7 +12863,11 @@ var ReactCompositeComponentMixin = { this._updateRenderedComponent(transaction, unmaskedContext); if (hasComponentDidUpdate) { - transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); + if (process.env.NODE_ENV !== 'production') { + transaction.getReactMountReady().enqueue(invokeComponentDidUpdateWithTimer.bind(this, prevProps, prevState, prevContext), this); + } else { + transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); + } } }, @@ -12549,8 +12889,16 @@ var ReactCompositeComponentMixin = { this._renderedNodeType = ReactNodeTypes.getType(nextRenderedElement); this._renderedComponent = this._instantiateReactComponent(nextRenderedElement); + var nextMarkup = ReactReconciler.mountComponent(this._renderedComponent, transaction, this._nativeParent, this._nativeContainerInfo, this._processChildContext(context)); - this._replaceNodeWithMarkup(oldNativeNode, nextMarkup); + + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onSetChildren(this._debugID, this._renderedComponent._debugID !== 0 ? [this._renderedComponent._debugID] : []); + } + } + + this._replaceNodeWithMarkup(oldNativeNode, nextMarkup, prevComponentInstance); } }, @@ -12559,8 +12907,8 @@ var ReactCompositeComponentMixin = { * * @protected */ - _replaceNodeWithMarkup: function (oldNativeNode, nextMarkup) { - ReactComponentEnvironment.replaceNodeWithMarkup(oldNativeNode, nextMarkup); + _replaceNodeWithMarkup: function (oldNativeNode, nextMarkup, prevInstance) { + ReactComponentEnvironment.replaceNodeWithMarkup(oldNativeNode, nextMarkup, prevInstance); }, /** @@ -12568,7 +12916,19 @@ var ReactCompositeComponentMixin = { */ _renderValidatedComponentWithoutOwnerOrContext: function () { var inst = this._instance; + + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'render'); + } + } var renderedComponent = inst.render(); + if (process.env.NODE_ENV !== 'production') { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'render'); + } + } + if (process.env.NODE_ENV !== 'production') { // We allow auto-mocks to proceed as if they're returning null. if (renderedComponent === undefined && inst.render._isMockFunction) { @@ -12595,6 +12955,7 @@ var ReactCompositeComponentMixin = { !( // TODO: An `isValidNode` function would probably be more appropriate renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : invariant(false) : void 0; + return renderedComponent; }, @@ -12663,12 +13024,6 @@ var ReactCompositeComponentMixin = { }; -ReactPerf.measureMethods(ReactCompositeComponentMixin, 'ReactCompositeComponent', { - mountComponent: 'mountComponent', - updateComponent: 'updateComponent', - _renderValidatedComponent: '_renderValidatedComponent' -}); - var ReactCompositeComponent = { Mixin: ReactCompositeComponentMixin @@ -12678,7 +13033,7 @@ var ReactCompositeComponent = { module.exports = ReactCompositeComponent; }).call(this,require('_process')) -},{"./ReactComponentEnvironment":99,"./ReactCurrentOwner":101,"./ReactElement":127,"./ReactErrorUtils":130,"./ReactInstanceMap":136,"./ReactInstrumentation":137,"./ReactNodeTypes":144,"./ReactPerf":147,"./ReactPropTypeLocationNames":148,"./ReactPropTypeLocations":149,"./ReactReconciler":152,"./ReactUpdateQueue":154,"./shouldUpdateReactComponent":201,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],101:[function(require,module,exports){ +},{"./ReactComponentEnvironment":99,"./ReactCurrentOwner":102,"./ReactElement":126,"./ReactErrorUtils":129,"./ReactInstanceMap":135,"./ReactInstrumentation":136,"./ReactNodeTypes":144,"./ReactPropTypeLocationNames":147,"./ReactPropTypeLocations":148,"./ReactReconciler":151,"./ReactUpdateQueue":154,"./shouldUpdateReactComponent":201,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],102:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -12710,7 +13065,7 @@ var ReactCurrentOwner = { }; module.exports = ReactCurrentOwner; -},{}],102:[function(require,module,exports){ +},{}],103:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -12730,7 +13085,6 @@ module.exports = ReactCurrentOwner; var ReactDOMComponentTree = require('./ReactDOMComponentTree'); var ReactDefaultInjection = require('./ReactDefaultInjection'); var ReactMount = require('./ReactMount'); -var ReactPerf = require('./ReactPerf'); var ReactReconciler = require('./ReactReconciler'); var ReactUpdates = require('./ReactUpdates'); var ReactVersion = require('./ReactVersion'); @@ -12742,11 +13096,9 @@ var warning = require('fbjs/lib/warning'); ReactDefaultInjection.inject(); -var render = ReactPerf.measure('React', 'render', ReactMount.render); - var React = { findDOMNode: findDOMNode, - render: render, + render: ReactMount.render, unmountComponentAtNode: ReactMount.unmountComponentAtNode, version: ReactVersion, @@ -12818,7 +13170,7 @@ if (process.env.NODE_ENV !== 'production') { module.exports = React; }).call(this,require('_process')) -},{"./ReactDOMComponentTree":106,"./ReactDefaultInjection":124,"./ReactMount":140,"./ReactPerf":147,"./ReactReconciler":152,"./ReactUpdates":155,"./ReactVersion":156,"./findDOMNode":181,"./getNativeComponentFromComposite":189,"./renderSubtreeIntoContainer":198,"_process":29,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/warning":229}],103:[function(require,module,exports){ +},{"./ReactDOMComponentTree":107,"./ReactDefaultInjection":125,"./ReactMount":139,"./ReactReconciler":151,"./ReactUpdates":155,"./ReactVersion":156,"./findDOMNode":181,"./getNativeComponentFromComposite":189,"./renderSubtreeIntoContainer":198,"_process":29,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/warning":229}],104:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -12843,7 +13195,7 @@ var ReactDOMButton = { }; module.exports = ReactDOMButton; -},{"./DisabledInputUtils":80}],104:[function(require,module,exports){ +},{"./DisabledInputUtils":80}],105:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -12880,9 +13232,11 @@ var ReactDOMInput = require('./ReactDOMInput'); var ReactDOMOption = require('./ReactDOMOption'); var ReactDOMSelect = require('./ReactDOMSelect'); var ReactDOMTextarea = require('./ReactDOMTextarea'); +var ReactInstrumentation = require('./ReactInstrumentation'); var ReactMultiChild = require('./ReactMultiChild'); -var ReactPerf = require('./ReactPerf'); +var ReactServerRenderingTransaction = require('./ReactServerRenderingTransaction'); +var emptyFunction = require('fbjs/lib/emptyFunction'); var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); var invariant = require('fbjs/lib/invariant'); var isEventSupported = require('./isEventSupported'); @@ -13001,6 +13355,9 @@ function assertValidProps(component, props) { } function enqueuePutListener(inst, registrationName, listener, transaction) { + if (transaction instanceof ReactServerRenderingTransaction) { + return; + } if (process.env.NODE_ENV !== 'production') { // IE8 has no API for event capturing and the `onScroll` event doesn't // bubble. @@ -13009,10 +13366,6 @@ function enqueuePutListener(inst, registrationName, listener, transaction) { var containerInfo = inst._nativeContainerInfo; var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE; var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument; - if (!doc) { - // Server rendering. - return; - } listenTo(registrationName, doc); transaction.getReactMountReady().enqueue(putListener, { inst: inst, @@ -13031,6 +13384,19 @@ function optionPostMount() { ReactDOMOption.postMountWrapper(inst); } +var setContentChildForInstrumentation = emptyFunction; +if (process.env.NODE_ENV !== 'production') { + setContentChildForInstrumentation = function (contentToUse) { + var debugID = this._debugID; + var contentDebugID = debugID + '#text'; + this._contentDebugID = contentDebugID; + ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text'); + ReactInstrumentation.debugTool.onSetText(contentDebugID, '' + contentToUse); + ReactInstrumentation.debugTool.onMountComponent(contentDebugID); + ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]); + }; +} + // There are so many media events, it makes sense to just // maintain a list rather than create a `trapBubbledEvent` for each var mediaEvents = { @@ -13191,6 +13557,7 @@ function ReactDOMComponent(element) { this._flags = 0; if (process.env.NODE_ENV !== 'production') { this._ancestorInfo = null; + this._contentDebugID = null; } } @@ -13306,7 +13673,7 @@ ReactDOMComponent.Mixin = { div.innerHTML = '<' + type + '>'; el = div.removeChild(div.firstChild); } else { - el = ownerDocument.createElement(this._currentElement.type); + el = ownerDocument.createElement(this._currentElement.type, props.is || null); } } else { el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type); @@ -13436,6 +13803,9 @@ ReactDOMComponent.Mixin = { if (contentToUse != null) { // TODO: Validate that text is allowed as a child of this node ret = escapeTextContentForBrowser(contentToUse); + if (process.env.NODE_ENV !== 'production') { + setContentChildForInstrumentation.call(this, contentToUse); + } } else if (childrenToUse != null) { var mountImages = this.mountChildren(childrenToUse, transaction, context); ret = mountImages.join(''); @@ -13470,6 +13840,9 @@ ReactDOMComponent.Mixin = { var childrenToUse = contentToUse != null ? null : props.children; if (contentToUse != null) { // TODO: Validate that text is allowed as a child of this node + if (process.env.NODE_ENV !== 'production') { + setContentChildForInstrumentation.call(this, contentToUse); + } DOMLazyTree.queueText(lazyTree, contentToUse); } else if (childrenToUse != null) { var mountImages = this.mountChildren(childrenToUse, transaction, context); @@ -13678,17 +14051,34 @@ ReactDOMComponent.Mixin = { this.updateChildren(null, transaction, context); } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { this.updateTextContent(''); + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); + } } if (nextContent != null) { if (lastContent !== nextContent) { this.updateTextContent('' + nextContent); + if (process.env.NODE_ENV !== 'production') { + this._contentDebugID = this._debugID + '#text'; + setContentChildForInstrumentation.call(this, nextContent); + } } } else if (nextHtml != null) { if (lastHtml !== nextHtml) { this.updateMarkup('' + nextHtml); } + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); + } } else if (nextChildren != null) { + if (process.env.NODE_ENV !== 'production') { + if (this._contentDebugID) { + ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID); + this._contentDebugID = null; + } + } + this.updateChildren(nextChildren, transaction, context); } }, @@ -13738,6 +14128,13 @@ ReactDOMComponent.Mixin = { this._rootNodeID = null; this._domID = null; this._wrapperState = null; + + if (process.env.NODE_ENV !== 'production') { + if (this._contentDebugID) { + ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID); + this._contentDebugID = null; + } + } }, getPublicInstance: function () { @@ -13746,17 +14143,12 @@ ReactDOMComponent.Mixin = { }; -ReactPerf.measureMethods(ReactDOMComponent.Mixin, 'ReactDOMComponent', { - mountComponent: 'mountComponent', - receiveComponent: 'receiveComponent' -}); - _assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); module.exports = ReactDOMComponent; }).call(this,require('_process')) -},{"./AutoFocusUtils":67,"./CSSPropertyOperations":70,"./DOMLazyTree":74,"./DOMNamespaces":75,"./DOMProperty":76,"./DOMPropertyOperations":77,"./EventConstants":82,"./EventPluginHub":83,"./EventPluginRegistry":84,"./ReactBrowserEventEmitter":93,"./ReactComponentBrowserEnvironment":98,"./ReactDOMButton":103,"./ReactDOMComponentFlags":105,"./ReactDOMComponentTree":106,"./ReactDOMInput":113,"./ReactDOMOption":115,"./ReactDOMSelect":116,"./ReactDOMTextarea":119,"./ReactMultiChild":141,"./ReactPerf":147,"./escapeTextContentForBrowser":180,"./isEventSupported":194,"./validateDOMNesting":203,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/keyOf":223,"fbjs/lib/shallowEqual":228,"fbjs/lib/warning":229,"object-assign":28}],105:[function(require,module,exports){ +},{"./AutoFocusUtils":67,"./CSSPropertyOperations":70,"./DOMLazyTree":74,"./DOMNamespaces":75,"./DOMProperty":76,"./DOMPropertyOperations":77,"./EventConstants":82,"./EventPluginHub":83,"./EventPluginRegistry":84,"./ReactBrowserEventEmitter":93,"./ReactComponentBrowserEnvironment":98,"./ReactDOMButton":104,"./ReactDOMComponentFlags":106,"./ReactDOMComponentTree":107,"./ReactDOMInput":114,"./ReactDOMOption":116,"./ReactDOMSelect":117,"./ReactDOMTextarea":120,"./ReactInstrumentation":136,"./ReactMultiChild":140,"./ReactServerRenderingTransaction":153,"./escapeTextContentForBrowser":180,"./isEventSupported":194,"./validateDOMNesting":203,"_process":29,"fbjs/lib/emptyFunction":211,"fbjs/lib/invariant":219,"fbjs/lib/keyOf":223,"fbjs/lib/shallowEqual":228,"fbjs/lib/warning":229,"object-assign":28}],106:[function(require,module,exports){ /** * Copyright 2015-present, Facebook, Inc. * All rights reserved. @@ -13775,7 +14167,7 @@ var ReactDOMComponentFlags = { }; module.exports = ReactDOMComponentFlags; -},{}],106:[function(require,module,exports){ +},{}],107:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -13965,7 +14357,7 @@ var ReactDOMComponentTree = { module.exports = ReactDOMComponentTree; }).call(this,require('_process')) -},{"./DOMProperty":76,"./ReactDOMComponentFlags":105,"_process":29,"fbjs/lib/invariant":219}],107:[function(require,module,exports){ +},{"./DOMProperty":76,"./ReactDOMComponentFlags":106,"_process":29,"fbjs/lib/invariant":219}],108:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14002,7 +14394,7 @@ function ReactDOMContainerInfo(topLevelWrapper, node) { module.exports = ReactDOMContainerInfo; }).call(this,require('_process')) -},{"./validateDOMNesting":203,"_process":29}],108:[function(require,module,exports){ +},{"./validateDOMNesting":203,"_process":29}],109:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14067,7 +14459,7 @@ ReactDOMDebugTool.addDevtool(ReactDOMUnknownPropertyDevtool); module.exports = ReactDOMDebugTool; }).call(this,require('_process')) -},{"./ReactDOMUnknownPropertyDevtool":121,"_process":29,"fbjs/lib/warning":229}],109:[function(require,module,exports){ +},{"./ReactDOMUnknownPropertyDevtool":122,"_process":29,"fbjs/lib/warning":229}],110:[function(require,module,exports){ /** * Copyright 2014-present, Facebook, Inc. * All rights reserved. @@ -14128,7 +14520,7 @@ _assign(ReactDOMEmptyComponent.prototype, { }); module.exports = ReactDOMEmptyComponent; -},{"./DOMLazyTree":74,"./ReactDOMComponentTree":106,"object-assign":28}],110:[function(require,module,exports){ +},{"./DOMLazyTree":74,"./ReactDOMComponentTree":107,"object-assign":28}],111:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14308,7 +14700,7 @@ var ReactDOMFactories = mapObject({ module.exports = ReactDOMFactories; }).call(this,require('_process')) -},{"./ReactElement":127,"./ReactElementValidator":128,"_process":29,"fbjs/lib/mapObject":224}],111:[function(require,module,exports){ +},{"./ReactElement":126,"./ReactElementValidator":127,"_process":29,"fbjs/lib/mapObject":224}],112:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14327,7 +14719,7 @@ var ReactDOMFeatureFlags = { }; module.exports = ReactDOMFeatureFlags; -},{}],112:[function(require,module,exports){ +},{}],113:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14343,7 +14735,6 @@ module.exports = ReactDOMFeatureFlags; var DOMChildrenOperations = require('./DOMChildrenOperations'); var ReactDOMComponentTree = require('./ReactDOMComponentTree'); -var ReactPerf = require('./ReactPerf'); /** * Operations used to process updates to DOM nodes. @@ -14362,12 +14753,8 @@ var ReactDOMIDOperations = { } }; -ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { - dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' -}); - module.exports = ReactDOMIDOperations; -},{"./DOMChildrenOperations":73,"./ReactDOMComponentTree":106,"./ReactPerf":147}],113:[function(require,module,exports){ +},{"./DOMChildrenOperations":73,"./ReactDOMComponentTree":107}],114:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14456,6 +14843,8 @@ var ReactDOMInput = { if (process.env.NODE_ENV !== 'production') { LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); + var owner = inst._currentElement._owner; + if (props.valueLink !== undefined && !didWarnValueLink) { process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; didWarnValueLink = true; @@ -14465,11 +14854,11 @@ var ReactDOMInput = { didWarnCheckedLink = true; } if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; + process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; didWarnCheckedDefaultChecked = true; } if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - process.env.NODE_ENV !== 'production' ? warning(false, 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; + process.env.NODE_ENV !== 'production' ? warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; didWarnValueDefaultValue = true; } warnIfValueIsNull(props); @@ -14500,7 +14889,7 @@ var ReactDOMInput = { var owner = inst._currentElement._owner; if ((initialValue || !inst._wrapperState.controlled) && controlled && !didWarnUncontrolledToControlled) { - process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing a uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; + process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; didWarnUncontrolledToControlled = true; } if (inst._wrapperState.controlled && (defaultValue || !controlled) && !didWarnControlledToUncontrolled) { @@ -14575,7 +14964,7 @@ function _handleChange(event) { module.exports = ReactDOMInput; }).call(this,require('_process')) -},{"./DOMPropertyOperations":77,"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":106,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],114:[function(require,module,exports){ +},{"./DOMPropertyOperations":77,"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":107,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],115:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -14592,7 +14981,7 @@ module.exports = ReactDOMInput; var ReactDOMDebugTool = require('./ReactDOMDebugTool'); module.exports = { debugTool: ReactDOMDebugTool }; -},{"./ReactDOMDebugTool":108}],115:[function(require,module,exports){ +},{"./ReactDOMDebugTool":109}],116:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14705,7 +15094,7 @@ var ReactDOMOption = { module.exports = ReactDOMOption; }).call(this,require('_process')) -},{"./ReactChildren":95,"./ReactDOMComponentTree":106,"./ReactDOMSelect":116,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],116:[function(require,module,exports){ +},{"./ReactChildren":95,"./ReactDOMComponentTree":107,"./ReactDOMSelect":117,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],117:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -14922,7 +15311,7 @@ function _handleChange(event) { module.exports = ReactDOMSelect; }).call(this,require('_process')) -},{"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":106,"./ReactUpdates":155,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],117:[function(require,module,exports){ +},{"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":107,"./ReactUpdates":155,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],118:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15135,7 +15524,7 @@ var ReactDOMSelection = { }; module.exports = ReactDOMSelection; -},{"./getNodeForCharacterOffset":190,"./getTextContentAccessor":191,"fbjs/lib/ExecutionEnvironment":205}],118:[function(require,module,exports){ +},{"./getNodeForCharacterOffset":190,"./getTextContentAccessor":191,"fbjs/lib/ExecutionEnvironment":205}],119:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -15155,7 +15544,7 @@ var _assign = require('object-assign'); var DOMChildrenOperations = require('./DOMChildrenOperations'); var DOMLazyTree = require('./DOMLazyTree'); var ReactDOMComponentTree = require('./ReactDOMComponentTree'); -var ReactPerf = require('./ReactPerf'); +var ReactInstrumentation = require('./ReactInstrumentation'); var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); var invariant = require('fbjs/lib/invariant'); @@ -15203,6 +15592,8 @@ _assign(ReactDOMTextComponent.prototype, { */ mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) { if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText); + var parentInfo; if (nativeParent != null) { parentInfo = nativeParent._ancestorInfo; @@ -15266,6 +15657,10 @@ _assign(ReactDOMTextComponent.prototype, { this._stringText = nextStringText; var commentNodes = this.getNativeNode(); DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText); + + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onSetText(this._debugID, nextStringText); + } } } }, @@ -15300,15 +15695,10 @@ _assign(ReactDOMTextComponent.prototype, { }); -ReactPerf.measureMethods(ReactDOMTextComponent.prototype, 'ReactDOMTextComponent', { - mountComponent: 'mountComponent', - receiveComponent: 'receiveComponent' -}); - module.exports = ReactDOMTextComponent; }).call(this,require('_process')) -},{"./DOMChildrenOperations":73,"./DOMLazyTree":74,"./ReactDOMComponentTree":106,"./ReactPerf":147,"./escapeTextContentForBrowser":180,"./validateDOMNesting":203,"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],119:[function(require,module,exports){ +},{"./DOMChildrenOperations":73,"./DOMLazyTree":74,"./ReactDOMComponentTree":107,"./ReactInstrumentation":136,"./escapeTextContentForBrowser":180,"./validateDOMNesting":203,"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],120:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -15454,7 +15844,7 @@ function _handleChange(event) { module.exports = ReactDOMTextarea; }).call(this,require('_process')) -},{"./DOMPropertyOperations":77,"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":106,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],120:[function(require,module,exports){ +},{"./DOMPropertyOperations":77,"./DisabledInputUtils":80,"./LinkedValueUtils":90,"./ReactDOMComponentTree":107,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],121:[function(require,module,exports){ (function (process){ /** * Copyright 2015-present, Facebook, Inc. @@ -15592,7 +15982,7 @@ module.exports = { }; }).call(this,require('_process')) -},{"_process":29,"fbjs/lib/invariant":219}],121:[function(require,module,exports){ +},{"_process":29,"fbjs/lib/invariant":219}],122:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -15660,7 +16050,7 @@ var ReactDOMUnknownPropertyDevtool = { module.exports = ReactDOMUnknownPropertyDevtool; }).call(this,require('_process')) -},{"./DOMProperty":76,"./EventPluginRegistry":84,"_process":29,"fbjs/lib/warning":229}],122:[function(require,module,exports){ +},{"./DOMProperty":76,"./EventPluginRegistry":84,"_process":29,"fbjs/lib/warning":229}],123:[function(require,module,exports){ (function (process){ /** * Copyright 2016-present, Facebook, Inc. @@ -15675,7 +16065,9 @@ module.exports = ReactDOMUnknownPropertyDevtool; 'use strict'; -var ReactInvalidSetStateWarningDevTool = require('./ReactInvalidSetStateWarningDevTool'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); + +var performanceNow = require('fbjs/lib/performanceNow'); var warning = require('fbjs/lib/warning'); var eventHandlers = []; @@ -15696,6 +16088,70 @@ function emitEvent(handlerFunctionName, arg1, arg2, arg3, arg4, arg5) { } } +var isProfiling = false; +var flushHistory = []; +var currentFlushNesting = 0; +var currentFlushMeasurements = null; +var currentFlushStartTime = null; +var currentTimerDebugID = null; +var currentTimerStartTime = null; +var currentTimerType = null; + +function clearHistory() { + ReactComponentTreeDevtool.purgeUnmountedComponents(); + ReactNativeOperationHistoryDevtool.clearHistory(); +} + +function getTreeSnapshot(registeredIDs) { + return registeredIDs.reduce(function (tree, id) { + var ownerID = ReactComponentTreeDevtool.getOwnerID(id); + var parentID = ReactComponentTreeDevtool.getParentID(id); + tree[id] = { + displayName: ReactComponentTreeDevtool.getDisplayName(id), + text: ReactComponentTreeDevtool.getText(id), + updateCount: ReactComponentTreeDevtool.getUpdateCount(id), + childIDs: ReactComponentTreeDevtool.getChildIDs(id), + // Text nodes don't have owners but this is close enough. + ownerID: ownerID || ReactComponentTreeDevtool.getOwnerID(parentID), + parentID: parentID + }; + return tree; + }, {}); +} + +function resetMeasurements() { + if (process.env.NODE_ENV !== 'production') { + var previousStartTime = currentFlushStartTime; + var previousMeasurements = currentFlushMeasurements || []; + var previousOperations = ReactNativeOperationHistoryDevtool.getHistory(); + + if (!isProfiling || currentFlushNesting === 0) { + currentFlushStartTime = null; + currentFlushMeasurements = null; + clearHistory(); + return; + } + + if (previousMeasurements.length || previousOperations.length) { + var registeredIDs = ReactComponentTreeDevtool.getRegisteredIDs(); + flushHistory.push({ + duration: performanceNow() - previousStartTime, + measurements: previousMeasurements || [], + operations: previousOperations || [], + treeSnapshot: getTreeSnapshot(registeredIDs) + }); + } + + clearHistory(); + currentFlushStartTime = performanceNow(); + currentFlushMeasurements = []; + } +} + +function checkDebugID(debugID) { + process.env.NODE_ENV !== 'production' ? warning(debugID, 'ReactDebugTool: debugID may not be empty.') : void 0; +} + var ReactDebugTool = { addDevtool: function (devtool) { eventHandlers.push(devtool); @@ -15708,35 +16164,147 @@ var ReactDebugTool = { } } }, + beginProfiling: function () { + if (process.env.NODE_ENV !== 'production') { + if (isProfiling) { + return; + } + + isProfiling = true; + flushHistory.length = 0; + resetMeasurements(); + } + }, + endProfiling: function () { + if (process.env.NODE_ENV !== 'production') { + if (!isProfiling) { + return; + } + + isProfiling = false; + resetMeasurements(); + } + }, + getFlushHistory: function () { + if (process.env.NODE_ENV !== 'production') { + return flushHistory; + } + }, + onBeginFlush: function () { + if (process.env.NODE_ENV !== 'production') { + currentFlushNesting++; + resetMeasurements(); + } + emitEvent('onBeginFlush'); + }, + onEndFlush: function () { + if (process.env.NODE_ENV !== 'production') { + resetMeasurements(); + currentFlushNesting--; + } + emitEvent('onEndFlush'); + }, + onBeginLifeCycleTimer: function (debugID, timerType) { + checkDebugID(debugID); + emitEvent('onBeginLifeCycleTimer', debugID, timerType); + if (process.env.NODE_ENV !== 'production') { + if (isProfiling && currentFlushNesting > 0) { + process.env.NODE_ENV !== 'production' ? warning(!currentTimerType, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; + currentTimerStartTime = performanceNow(); + currentTimerDebugID = debugID; + currentTimerType = timerType; + } + } + }, + onEndLifeCycleTimer: function (debugID, timerType) { + checkDebugID(debugID); + if (process.env.NODE_ENV !== 'production') { + if (isProfiling && currentFlushNesting > 0) { + process.env.NODE_ENV !== 'production' ? warning(currentTimerType === timerType, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; + currentFlushMeasurements.push({ + timerType: timerType, + instanceID: debugID, + duration: performanceNow() - currentTimerStartTime + }); + currentTimerStartTime = null; + currentTimerDebugID = null; + currentTimerType = null; + } + } + emitEvent('onEndLifeCycleTimer', debugID, timerType); + }, + onBeginReconcilerTimer: function (debugID, timerType) { + checkDebugID(debugID); + emitEvent('onBeginReconcilerTimer', debugID, timerType); + }, + onEndReconcilerTimer: function (debugID, timerType) { + checkDebugID(debugID); + emitEvent('onEndReconcilerTimer', debugID, timerType); + }, onBeginProcessingChildContext: function () { emitEvent('onBeginProcessingChildContext'); }, onEndProcessingChildContext: function () { emitEvent('onEndProcessingChildContext'); }, + onNativeOperation: function (debugID, type, payload) { + checkDebugID(debugID); + emitEvent('onNativeOperation', debugID, type, payload); + }, onSetState: function () { emitEvent('onSetState'); }, - onMountRootComponent: function (internalInstance) { - emitEvent('onMountRootComponent', internalInstance); + onSetDisplayName: function (debugID, displayName) { + checkDebugID(debugID); + emitEvent('onSetDisplayName', debugID, displayName); }, - onMountComponent: function (internalInstance) { - emitEvent('onMountComponent', internalInstance); + onSetChildren: function (debugID, childDebugIDs) { + checkDebugID(debugID); + emitEvent('onSetChildren', debugID, childDebugIDs); }, - onUpdateComponent: function (internalInstance) { - emitEvent('onUpdateComponent', internalInstance); + onSetOwner: function (debugID, ownerDebugID) { + checkDebugID(debugID); + emitEvent('onSetOwner', debugID, ownerDebugID); }, - onUnmountComponent: function (internalInstance) { - emitEvent('onUnmountComponent', internalInstance); + onSetText: function (debugID, text) { + checkDebugID(debugID); + emitEvent('onSetText', debugID, text); + }, + onMountRootComponent: function (debugID) { + checkDebugID(debugID); + emitEvent('onMountRootComponent', debugID); + }, + onMountComponent: function (debugID) { + checkDebugID(debugID); + emitEvent('onMountComponent', debugID); + }, + onUpdateComponent: function (debugID) { + checkDebugID(debugID); + emitEvent('onUpdateComponent', debugID); + }, + onUnmountComponent: function (debugID) { + checkDebugID(debugID); + emitEvent('onUnmountComponent', debugID); } }; -ReactDebugTool.addDevtool(ReactInvalidSetStateWarningDevTool); +if (process.env.NODE_ENV !== 'production') { + var ReactInvalidSetStateWarningDevTool = require('./ReactInvalidSetStateWarningDevTool'); + var ReactNativeOperationHistoryDevtool = require('./ReactNativeOperationHistoryDevtool'); + var ReactComponentTreeDevtool = require('./ReactComponentTreeDevtool'); + ReactDebugTool.addDevtool(ReactInvalidSetStateWarningDevTool); + ReactDebugTool.addDevtool(ReactComponentTreeDevtool); + ReactDebugTool.addDevtool(ReactNativeOperationHistoryDevtool); + var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; + if (/[?&]react_perf\b/.test(url)) { + ReactDebugTool.beginProfiling(); + } +} module.exports = ReactDebugTool; }).call(this,require('_process')) -},{"./ReactInvalidSetStateWarningDevTool":138,"_process":29,"fbjs/lib/warning":229}],123:[function(require,module,exports){ +},{"./ReactComponentTreeDevtool":100,"./ReactInvalidSetStateWarningDevTool":137,"./ReactNativeOperationHistoryDevtool":143,"_process":29,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/performanceNow":227,"fbjs/lib/warning":229}],124:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15805,8 +16373,7 @@ var ReactDefaultBatchingStrategy = { }; module.exports = ReactDefaultBatchingStrategy; -},{"./ReactUpdates":155,"./Transaction":173,"fbjs/lib/emptyFunction":211,"object-assign":28}],124:[function(require,module,exports){ -(function (process){ +},{"./ReactUpdates":155,"./Transaction":173,"fbjs/lib/emptyFunction":211,"object-assign":28}],125:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -15824,7 +16391,6 @@ var BeforeInputEventPlugin = require('./BeforeInputEventPlugin'); var ChangeEventPlugin = require('./ChangeEventPlugin'); var DefaultEventPluginOrder = require('./DefaultEventPluginOrder'); var EnterLeaveEventPlugin = require('./EnterLeaveEventPlugin'); -var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var HTMLDOMPropertyConfig = require('./HTMLDOMPropertyConfig'); var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment'); var ReactDOMComponent = require('./ReactDOMComponent'); @@ -15887,553 +16453,12 @@ function inject() { ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); - - if (process.env.NODE_ENV !== 'production') { - var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; - if (/[?&]react_perf\b/.test(url)) { - var ReactDefaultPerf = require('./ReactDefaultPerf'); - ReactDefaultPerf.start(); - } - } } module.exports = { inject: inject }; -}).call(this,require('_process')) - -},{"./BeforeInputEventPlugin":68,"./ChangeEventPlugin":72,"./DefaultEventPluginOrder":79,"./EnterLeaveEventPlugin":81,"./HTMLDOMPropertyConfig":88,"./ReactComponentBrowserEnvironment":98,"./ReactDOMComponent":104,"./ReactDOMComponentTree":106,"./ReactDOMEmptyComponent":109,"./ReactDOMTextComponent":118,"./ReactDOMTreeTraversal":120,"./ReactDefaultBatchingStrategy":123,"./ReactDefaultPerf":125,"./ReactEventListener":132,"./ReactInjection":134,"./ReactReconcileTransaction":151,"./SVGDOMPropertyConfig":157,"./SelectEventPlugin":158,"./SimpleEventPlugin":159,"_process":29,"fbjs/lib/ExecutionEnvironment":205}],125:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerf - */ - -'use strict'; - -var DOMProperty = require('./DOMProperty'); -var ReactDOMComponentTree = require('./ReactDOMComponentTree'); -var ReactDefaultPerfAnalysis = require('./ReactDefaultPerfAnalysis'); -var ReactMount = require('./ReactMount'); -var ReactPerf = require('./ReactPerf'); - -var performanceNow = require('fbjs/lib/performanceNow'); -var warning = require('fbjs/lib/warning'); - -function roundFloat(val) { - return Math.floor(val * 100) / 100; -} - -function addValue(obj, key, val) { - obj[key] = (obj[key] || 0) + val; -} - -// Composite/text components don't have any built-in ID: we have to make our own -var compositeIDMap; -var compositeIDCounter = 17000; -function getIDOfComposite(inst) { - if (!compositeIDMap) { - compositeIDMap = new WeakMap(); - } - if (compositeIDMap.has(inst)) { - return compositeIDMap.get(inst); - } else { - var id = compositeIDCounter++; - compositeIDMap.set(inst, id); - return id; - } -} - -function getID(inst) { - if (inst.hasOwnProperty('_rootNodeID')) { - return inst._rootNodeID; - } else { - return getIDOfComposite(inst); - } -} - -function stripComplexValues(key, value) { - if (typeof value !== 'object' || Array.isArray(value) || value == null) { - return value; - } - var prototype = Object.getPrototypeOf(value); - if (!prototype || prototype === Object.prototype) { - return value; - } - return ''; -} - -// This implementation of ReactPerf is going away some time mid 15.x. -// While we plan to keep most of the API, the actual format of measurements -// will change dramatically. To signal this, we wrap them into an opaque-ish -// object to discourage reaching into it until the API stabilizes. -function wrapLegacyMeasurements(measurements) { - return { __unstable_this_format_will_change: measurements }; -} -function unwrapLegacyMeasurements(measurements) { - return measurements && measurements.__unstable_this_format_will_change || measurements; -} - -var warnedAboutPrintDOM = false; -var warnedAboutGetMeasurementsSummaryMap = false; - -var ReactDefaultPerf = { - _allMeasurements: [], // last item in the list is the current one - _mountStack: [0], - _compositeStack: [], - _injected: false, - - start: function () { - if (!ReactDefaultPerf._injected) { - ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); - } - - ReactDefaultPerf._allMeasurements.length = 0; - ReactPerf.enableMeasure = true; - }, - - stop: function () { - ReactPerf.enableMeasure = false; - }, - - getLastMeasurements: function () { - return wrapLegacyMeasurements(ReactDefaultPerf._allMeasurements); - }, - - printExclusive: function (measurements) { - measurements = unwrapLegacyMeasurements(measurements || ReactDefaultPerf._allMeasurements); - var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); - console.table(summary.map(function (item) { - return { - 'Component class name': item.componentName, - 'Total inclusive time (ms)': roundFloat(item.inclusive), - 'Exclusive mount time (ms)': roundFloat(item.exclusive), - 'Exclusive render time (ms)': roundFloat(item.render), - 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count), - 'Render time per instance (ms)': roundFloat(item.render / item.count), - 'Instances': item.count - }; - })); - // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct - // number. - }, - - printInclusive: function (measurements) { - measurements = unwrapLegacyMeasurements(measurements || ReactDefaultPerf._allMeasurements); - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); - console.table(summary.map(function (item) { - return { - 'Owner > component': item.componentName, - 'Inclusive time (ms)': roundFloat(item.time), - 'Instances': item.count - }; - })); - console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); - }, - - getMeasurementsSummaryMap: function (measurements) { - process.env.NODE_ENV !== 'production' ? warning(warnedAboutGetMeasurementsSummaryMap, '`ReactPerf.getMeasurementsSummaryMap(...)` is deprecated. Use ' + '`ReactPerf.getWasted(...)` instead.') : void 0; - warnedAboutGetMeasurementsSummaryMap = true; - return ReactDefaultPerf.getWasted(measurements); - }, - - getWasted: function (measurements) { - measurements = unwrapLegacyMeasurements(measurements); - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements, true); - return summary.map(function (item) { - return { - 'Owner > component': item.componentName, - 'Wasted time (ms)': item.time, - 'Instances': item.count - }; - }); - }, - - printWasted: function (measurements) { - measurements = unwrapLegacyMeasurements(measurements || ReactDefaultPerf._allMeasurements); - console.table(ReactDefaultPerf.getWasted(measurements)); - console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); - }, - - printDOM: function (measurements) { - process.env.NODE_ENV !== 'production' ? warning(warnedAboutPrintDOM, '`ReactPerf.printDOM(...)` is deprecated. Use ' + '`ReactPerf.printOperations(...)` instead.') : void 0; - warnedAboutPrintDOM = true; - return ReactDefaultPerf.printOperations(measurements); - }, - - printOperations: function (measurements) { - measurements = unwrapLegacyMeasurements(measurements || ReactDefaultPerf._allMeasurements); - var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); - console.table(summary.map(function (item) { - var result = {}; - result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; - result.type = item.type; - result.args = JSON.stringify(item.args, stripComplexValues); - return result; - })); - console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'); - }, - - _recordWrite: function (id, fnName, totalTime, args) { - // TODO: totalTime isn't that useful since it doesn't count paints/reflows - var entry = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]; - var writes = entry.writes; - writes[id] = writes[id] || []; - writes[id].push({ - type: fnName, - time: totalTime, - args: args - }); - }, - - measure: function (moduleName, fnName, func) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var totalTime; - var rv; - var start; - - var entry = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]; - - if (fnName === '_renderNewRootComponent' || fnName === 'flushBatchedUpdates') { - // A "measurement" is a set of metrics recorded for each flush. We want - // to group the metrics for a given flush together so we can look at the - // components that rendered and the DOM operations that actually - // happened to determine the amount of "wasted work" performed. - ReactDefaultPerf._allMeasurements.push(entry = { - exclusive: {}, - inclusive: {}, - render: {}, - counts: {}, - writes: {}, - displayNames: {}, - hierarchy: {}, - totalTime: 0, - created: {} - }); - start = performanceNow(); - rv = func.apply(this, args); - entry.totalTime = performanceNow() - start; - return rv; - } else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactDOMIDOperations' || moduleName === 'CSSPropertyOperations' || moduleName === 'DOMChildrenOperations' || moduleName === 'DOMPropertyOperations' || moduleName === 'ReactComponentBrowserEnvironment') { - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (fnName === '_mountImageIntoNode') { - ReactDefaultPerf._recordWrite('', fnName, totalTime, args[0]); - } else if (fnName === 'dangerouslyProcessChildrenUpdates') { - // special format - args[1].forEach(function (update) { - var writeArgs = {}; - if (update.fromIndex !== null) { - writeArgs.fromIndex = update.fromIndex; - } - if (update.toIndex !== null) { - writeArgs.toIndex = update.toIndex; - } - if (update.content !== null) { - writeArgs.content = update.content; - } - ReactDefaultPerf._recordWrite(args[0]._rootNodeID, update.type, totalTime, writeArgs); - }); - } else { - // basic format - var id = args[0]; - if (moduleName === 'EventPluginHub') { - id = id._rootNodeID; - } else if (fnName === 'replaceNodeWithMarkup') { - // Old node is already unmounted; can't get its instance - id = ReactDOMComponentTree.getInstanceFromNode(args[1].node)._rootNodeID; - } else if (fnName === 'replaceDelimitedText') { - id = getID(ReactDOMComponentTree.getInstanceFromNode(args[0])); - } else if (typeof id === 'object') { - id = getID(ReactDOMComponentTree.getInstanceFromNode(args[0])); - } - ReactDefaultPerf._recordWrite(id, fnName, totalTime, Array.prototype.slice.call(args, 1)); - } - return rv; - } else if (moduleName === 'ReactCompositeComponent' && (fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()? - fnName === '_renderValidatedComponent')) { - - if (this._currentElement.type === ReactMount.TopLevelWrapper) { - return func.apply(this, args); - } - - var rootNodeID = getIDOfComposite(this); - var isRender = fnName === '_renderValidatedComponent'; - var isMount = fnName === 'mountComponent'; - - var mountStack = ReactDefaultPerf._mountStack; - - if (isRender) { - addValue(entry.counts, rootNodeID, 1); - } else if (isMount) { - entry.created[rootNodeID] = true; - mountStack.push(0); - } - - ReactDefaultPerf._compositeStack.push(rootNodeID); - - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - ReactDefaultPerf._compositeStack.pop(); - - if (isRender) { - addValue(entry.render, rootNodeID, totalTime); - } else if (isMount) { - var subMountTime = mountStack.pop(); - mountStack[mountStack.length - 1] += totalTime; - addValue(entry.exclusive, rootNodeID, totalTime - subMountTime); - addValue(entry.inclusive, rootNodeID, totalTime); - } else { - addValue(entry.inclusive, rootNodeID, totalTime); - } - - entry.displayNames[rootNodeID] = { - current: this.getName(), - owner: this._currentElement._owner ? this._currentElement._owner.getName() : '' - }; - - return rv; - } else if ((moduleName === 'ReactDOMComponent' || moduleName === 'ReactDOMTextComponent') && (fnName === 'mountComponent' || fnName === 'receiveComponent')) { - - rv = func.apply(this, args); - entry.hierarchy[getID(this)] = ReactDefaultPerf._compositeStack.slice(); - return rv; - } else { - return func.apply(this, args); - } - }; - } -}; - -module.exports = ReactDefaultPerf; -}).call(this,require('_process')) - -},{"./DOMProperty":76,"./ReactDOMComponentTree":106,"./ReactDefaultPerfAnalysis":126,"./ReactMount":140,"./ReactPerf":147,"_process":29,"fbjs/lib/performanceNow":227,"fbjs/lib/warning":229}],126:[function(require,module,exports){ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDefaultPerfAnalysis - */ - -'use strict'; - -// Don't try to save users less than 1.2ms (a number I made up) - -var _assign = require('object-assign'); - -var DONT_CARE_THRESHOLD = 1.2; -var DOM_OPERATION_TYPES = { - '_mountImageIntoNode': 'set innerHTML', - INSERT_MARKUP: 'set innerHTML', - MOVE_EXISTING: 'move', - REMOVE_NODE: 'remove', - SET_MARKUP: 'set innerHTML', - TEXT_CONTENT: 'set textContent', - 'setValueForProperty': 'update attribute', - 'setValueForAttribute': 'update attribute', - 'deleteValueForProperty': 'remove attribute', - 'setValueForStyles': 'update styles', - 'replaceNodeWithMarkup': 'replace', - 'replaceDelimitedText': 'replace' -}; - -function getTotalTime(measurements) { - // TODO: return number of DOM ops? could be misleading. - // TODO: measure dropped frames after reconcile? - // TODO: log total time of each reconcile and the top-level component - // class that triggered it. - var totalTime = 0; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - totalTime += measurement.totalTime; - } - return totalTime; -} - -function getDOMSummary(measurements) { - var items = []; - measurements.forEach(function (measurement) { - Object.keys(measurement.writes).forEach(function (id) { - measurement.writes[id].forEach(function (write) { - items.push({ - id: id, - type: DOM_OPERATION_TYPES[write.type] || write.type, - args: write.args - }); - }); - }); - }); - return items; -} - -function getExclusiveSummary(measurements) { - var candidates = {}; - var displayName; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = _assign({}, measurement.exclusive, measurement.inclusive); - - for (var id in allIDs) { - displayName = measurement.displayNames[id].current; - - candidates[displayName] = candidates[displayName] || { - componentName: displayName, - inclusive: 0, - exclusive: 0, - render: 0, - count: 0 - }; - if (measurement.render[id]) { - candidates[displayName].render += measurement.render[id]; - } - if (measurement.exclusive[id]) { - candidates[displayName].exclusive += measurement.exclusive[id]; - } - if (measurement.inclusive[id]) { - candidates[displayName].inclusive += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[displayName].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (displayName in candidates) { - if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { - arr.push(candidates[displayName]); - } - } - - arr.sort(function (a, b) { - return b.exclusive - a.exclusive; - }); - - return arr; -} - -function getInclusiveSummary(measurements, onlyClean) { - var candidates = {}; - var inclusiveKey; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = _assign({}, measurement.exclusive, measurement.inclusive); - var cleanComponents; - - if (onlyClean) { - cleanComponents = getUnchangedComponents(measurement); - } - - for (var id in allIDs) { - if (onlyClean && !cleanComponents[id]) { - continue; - } - - var displayName = measurement.displayNames[id]; - - // Inclusive time is not useful for many components without knowing where - // they are instantiated. So we aggregate inclusive time with both the - // owner and current displayName as the key. - inclusiveKey = displayName.owner + ' > ' + displayName.current; - - candidates[inclusiveKey] = candidates[inclusiveKey] || { - componentName: inclusiveKey, - time: 0, - count: 0 - }; - - if (measurement.inclusive[id]) { - candidates[inclusiveKey].time += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[inclusiveKey].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (inclusiveKey in candidates) { - if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { - arr.push(candidates[inclusiveKey]); - } - } - - arr.sort(function (a, b) { - return b.time - a.time; - }); - - return arr; -} - -function getUnchangedComponents(measurement) { - // For a given reconcile, look at which components did not actually - // render anything to the DOM and return a mapping of their ID to - // the amount of time it took to render the entire subtree. - var cleanComponents = {}; - var writes = measurement.writes; - var hierarchy = measurement.hierarchy; - var dirtyComposites = {}; - Object.keys(writes).forEach(function (id) { - writes[id].forEach(function (write) { - // Root mounting (innerHTML set) is recorded with an ID of '' - if (id !== '' && hierarchy.hasOwnProperty(id)) { - hierarchy[id].forEach(function (c) { - return dirtyComposites[c] = true; - }); - } - }); - }); - var allIDs = _assign({}, measurement.exclusive, measurement.inclusive); - - for (var id in allIDs) { - var isDirty = false; - // See if any of the DOM operations applied to this component's subtree. - if (dirtyComposites[id]) { - isDirty = true; - } - // check if component newly created - if (measurement.created[id]) { - isDirty = true; - } - if (!isDirty && measurement.counts[id] > 0) { - cleanComponents[id] = true; - } - } - return cleanComponents; -} - -var ReactDefaultPerfAnalysis = { - getExclusiveSummary: getExclusiveSummary, - getInclusiveSummary: getInclusiveSummary, - getDOMSummary: getDOMSummary, - getTotalTime: getTotalTime -}; - -module.exports = ReactDefaultPerfAnalysis; -},{"object-assign":28}],127:[function(require,module,exports){ +},{"./BeforeInputEventPlugin":68,"./ChangeEventPlugin":72,"./DefaultEventPluginOrder":79,"./EnterLeaveEventPlugin":81,"./HTMLDOMPropertyConfig":88,"./ReactComponentBrowserEnvironment":98,"./ReactDOMComponent":105,"./ReactDOMComponentTree":107,"./ReactDOMEmptyComponent":110,"./ReactDOMTextComponent":119,"./ReactDOMTreeTraversal":121,"./ReactDefaultBatchingStrategy":124,"./ReactEventListener":131,"./ReactInjection":133,"./ReactReconcileTransaction":150,"./SVGDOMPropertyConfig":157,"./SelectEventPlugin":158,"./SimpleEventPlugin":159}],126:[function(require,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -16550,6 +16575,10 @@ var ReactElement = function (type, key, ref, self, source, owner, props) { return element; }; +/** + * Create and return a new ReactElement of the given type. + * See https://facebook.github.io/react/docs/top-level-api.html#react.createelement + */ ReactElement.createElement = function (type, config, children) { var propName; @@ -16563,6 +16592,11 @@ ReactElement.createElement = function (type, config, children) { if (config != null) { if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning( + /* eslint-disable no-proto */ + config.__proto__ == null || config.__proto__ === Object.prototype, + /* eslint-enable no-proto */ + 'React.createElement(...): Expected props argument to be a plain object. ' + 'Properties defined in its prototype chain will be ignored.') : void 0; ref = !config.hasOwnProperty('ref') || Object.getOwnPropertyDescriptor(config, 'ref').get ? null : config.ref; key = !config.hasOwnProperty('key') || Object.getOwnPropertyDescriptor(config, 'key').get ? null : '' + config.key; } else { @@ -16634,6 +16668,10 @@ ReactElement.createElement = function (type, config, children) { return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); }; +/** + * Return a function that produces ReactElements of a given type. + * See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory + */ ReactElement.createFactory = function (type) { var factory = ReactElement.createElement.bind(null, type); // Expose the type on the factory and the prototype so that it can be @@ -16651,6 +16689,10 @@ ReactElement.cloneAndReplaceKey = function (oldElement, newKey) { return newElement; }; +/** + * Clone and return a new ReactElement using element as the starting point. + * See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement + */ ReactElement.cloneElement = function (element, config, children) { var propName; @@ -16671,6 +16713,13 @@ ReactElement.cloneElement = function (element, config, children) { var owner = element._owner; if (config != null) { + if (process.env.NODE_ENV !== 'production') { + process.env.NODE_ENV !== 'production' ? warning( + /* eslint-disable no-proto */ + config.__proto__ == null || config.__proto__ === Object.prototype, + /* eslint-enable no-proto */ + 'React.cloneElement(...): Expected props argument to be a plain object. ' + 'Properties defined in its prototype chain will be ignored.') : void 0; + } if (config.ref !== undefined) { // Silently steal the ref from the parent. ref = config.ref; @@ -16713,6 +16762,8 @@ ReactElement.cloneElement = function (element, config, children) { }; /** + * Verifies the object is a ReactElement. + * See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement * @param {?object} object * @return {boolean} True if `object` is a valid component. * @final @@ -16724,7 +16775,7 @@ ReactElement.isValidElement = function (object) { module.exports = ReactElement; }).call(this,require('_process')) -},{"./ReactCurrentOwner":101,"./canDefineProperty":177,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],128:[function(require,module,exports){ +},{"./ReactCurrentOwner":102,"./canDefineProperty":177,"_process":29,"fbjs/lib/warning":229,"object-assign":28}],127:[function(require,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -17009,7 +17060,7 @@ var ReactElementValidator = { module.exports = ReactElementValidator; }).call(this,require('_process')) -},{"./ReactCurrentOwner":101,"./ReactElement":127,"./ReactPropTypeLocationNames":148,"./ReactPropTypeLocations":149,"./canDefineProperty":177,"./getIteratorFn":188,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],129:[function(require,module,exports){ +},{"./ReactCurrentOwner":102,"./ReactElement":126,"./ReactPropTypeLocationNames":147,"./ReactPropTypeLocations":148,"./canDefineProperty":177,"./getIteratorFn":188,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],128:[function(require,module,exports){ /** * Copyright 2014-present, Facebook, Inc. * All rights reserved. @@ -17040,7 +17091,7 @@ var ReactEmptyComponent = { ReactEmptyComponent.injection = ReactEmptyComponentInjection; module.exports = ReactEmptyComponent; -},{}],130:[function(require,module,exports){ +},{}],129:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -17120,7 +17171,7 @@ if (process.env.NODE_ENV !== 'production') { module.exports = ReactErrorUtils; }).call(this,require('_process')) -},{"_process":29}],131:[function(require,module,exports){ +},{"_process":29}],130:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17154,7 +17205,7 @@ var ReactEventEmitterMixin = { }; module.exports = ReactEventEmitterMixin; -},{"./EventPluginHub":83}],132:[function(require,module,exports){ +},{"./EventPluginHub":83}],131:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17312,7 +17363,7 @@ var ReactEventListener = { }; module.exports = ReactEventListener; -},{"./PooledClass":91,"./ReactDOMComponentTree":106,"./ReactUpdates":155,"./getEventTarget":187,"fbjs/lib/EventListener":204,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/getUnboundedScrollPosition":216,"object-assign":28}],133:[function(require,module,exports){ +},{"./PooledClass":91,"./ReactDOMComponentTree":107,"./ReactUpdates":155,"./getEventTarget":187,"fbjs/lib/EventListener":204,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/getUnboundedScrollPosition":216,"object-assign":28}],132:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17334,7 +17385,7 @@ var ReactFeatureFlags = { }; module.exports = ReactFeatureFlags; -},{}],134:[function(require,module,exports){ +},{}],133:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17356,7 +17407,6 @@ var ReactClass = require('./ReactClass'); var ReactEmptyComponent = require('./ReactEmptyComponent'); var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); var ReactNativeComponent = require('./ReactNativeComponent'); -var ReactPerf = require('./ReactPerf'); var ReactUpdates = require('./ReactUpdates'); var ReactInjection = { @@ -17368,12 +17418,11 @@ var ReactInjection = { EventPluginUtils: EventPluginUtils.injection, EventEmitter: ReactBrowserEventEmitter.injection, NativeComponent: ReactNativeComponent.injection, - Perf: ReactPerf.injection, Updates: ReactUpdates.injection }; module.exports = ReactInjection; -},{"./DOMProperty":76,"./EventPluginHub":83,"./EventPluginUtils":85,"./ReactBrowserEventEmitter":93,"./ReactClass":96,"./ReactComponentEnvironment":99,"./ReactEmptyComponent":129,"./ReactNativeComponent":143,"./ReactPerf":147,"./ReactUpdates":155}],135:[function(require,module,exports){ +},{"./DOMProperty":76,"./EventPluginHub":83,"./EventPluginUtils":85,"./ReactBrowserEventEmitter":93,"./ReactClass":96,"./ReactComponentEnvironment":99,"./ReactEmptyComponent":128,"./ReactNativeComponent":142,"./ReactUpdates":155}],134:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17498,7 +17547,7 @@ var ReactInputSelection = { }; module.exports = ReactInputSelection; -},{"./ReactDOMSelection":117,"fbjs/lib/containsNode":208,"fbjs/lib/focusNode":213,"fbjs/lib/getActiveElement":214}],136:[function(require,module,exports){ +},{"./ReactDOMSelection":118,"fbjs/lib/containsNode":208,"fbjs/lib/focusNode":213,"fbjs/lib/getActiveElement":214}],135:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17547,7 +17596,7 @@ var ReactInstanceMap = { }; module.exports = ReactInstanceMap; -},{}],137:[function(require,module,exports){ +},{}],136:[function(require,module,exports){ /** * Copyright 2016-present, Facebook, Inc. * All rights reserved. @@ -17564,7 +17613,7 @@ module.exports = ReactInstanceMap; var ReactDebugTool = require('./ReactDebugTool'); module.exports = { debugTool: ReactDebugTool }; -},{"./ReactDebugTool":122}],138:[function(require,module,exports){ +},{"./ReactDebugTool":123}],137:[function(require,module,exports){ (function (process){ /** * Copyright 2016-present, Facebook, Inc. @@ -17604,7 +17653,7 @@ var ReactInvalidSetStateWarningDevTool = { module.exports = ReactInvalidSetStateWarningDevTool; }).call(this,require('_process')) -},{"_process":29,"fbjs/lib/warning":229}],139:[function(require,module,exports){ +},{"_process":29,"fbjs/lib/warning":229}],138:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -17655,7 +17704,7 @@ var ReactMarkupChecksum = { }; module.exports = ReactMarkupChecksum; -},{"./adler32":176}],140:[function(require,module,exports){ +},{"./adler32":176}],139:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -17681,7 +17730,6 @@ var ReactElement = require('./ReactElement'); var ReactFeatureFlags = require('./ReactFeatureFlags'); var ReactInstrumentation = require('./ReactInstrumentation'); var ReactMarkupChecksum = require('./ReactMarkupChecksum'); -var ReactPerf = require('./ReactPerf'); var ReactReconciler = require('./ReactReconciler'); var ReactUpdateQueue = require('./ReactUpdateQueue'); var ReactUpdates = require('./ReactUpdates'); @@ -17919,6 +17967,10 @@ var ReactMount = { * @return {ReactComponent} nextComponent */ _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onBeginFlush(); + } + // Various parts of our code (such as ReactCompositeComponent's // _renderValidatedComponent) assume that calls to render aren't nested; // verify that that's the case. @@ -17929,6 +17981,12 @@ var ReactMount = { ReactBrowserEventEmitter.ensureScrollValueMonitoring(); var componentInstance = instantiateReactComponent(nextElement); + if (process.env.NODE_ENV !== 'production') { + // Mute future events from the top level wrapper. + // It is an implementation detail that devtools should not know about. + componentInstance._debugID = 0; + } + // The initial render is synchronous but any updates that happen during // rendering, in componentWillMount or componentDidMount, will be batched // according to the current batching strategy. @@ -17939,7 +17997,9 @@ var ReactMount = { instancesByReactRootID[wrapperID] = componentInstance; if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onMountRootComponent(componentInstance); + // The instance here is TopLevelWrapper so we report mount for its child. + ReactInstrumentation.debugTool.onMountRootComponent(componentInstance._renderedComponent._debugID); + ReactInstrumentation.debugTool.onEndFlush(); } return componentInstance; @@ -18019,6 +18079,7 @@ var ReactMount = { /** * Renders a React component into the DOM in the supplied `container`. + * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render * * If the React component was previously rendered into `container`, this will * perform an update on it and only mutate the DOM as necessary to reflect the @@ -18035,6 +18096,7 @@ var ReactMount = { /** * Unmounts and destroys the React component rendered in the `container`. + * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode * * @param {DOMElement} container DOM element containing a React component. * @return {boolean} True if a component was found in and unmounted from @@ -18126,18 +18188,20 @@ var ReactMount = { setInnerHTML(container, markup); ReactDOMComponentTree.precacheNode(instance, container.firstChild); } + + if (process.env.NODE_ENV !== 'production') { + var nativeNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild); + if (nativeNode._debugID !== 0) { + ReactInstrumentation.debugTool.onNativeOperation(nativeNode._debugID, 'mount', markup.toString()); + } + } } }; -ReactPerf.measureMethods(ReactMount, 'ReactMount', { - _renderNewRootComponent: '_renderNewRootComponent', - _mountImageIntoNode: '_mountImageIntoNode' -}); - module.exports = ReactMount; }).call(this,require('_process')) -},{"./DOMLazyTree":74,"./DOMProperty":76,"./ReactBrowserEventEmitter":93,"./ReactCurrentOwner":101,"./ReactDOMComponentTree":106,"./ReactDOMContainerInfo":107,"./ReactDOMFeatureFlags":111,"./ReactElement":127,"./ReactFeatureFlags":133,"./ReactInstrumentation":137,"./ReactMarkupChecksum":139,"./ReactPerf":147,"./ReactReconciler":152,"./ReactUpdateQueue":154,"./ReactUpdates":155,"./instantiateReactComponent":193,"./setInnerHTML":199,"./shouldUpdateReactComponent":201,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],141:[function(require,module,exports){ +},{"./DOMLazyTree":74,"./DOMProperty":76,"./ReactBrowserEventEmitter":93,"./ReactCurrentOwner":102,"./ReactDOMComponentTree":107,"./ReactDOMContainerInfo":108,"./ReactDOMFeatureFlags":112,"./ReactElement":126,"./ReactFeatureFlags":132,"./ReactInstrumentation":136,"./ReactMarkupChecksum":138,"./ReactReconciler":151,"./ReactUpdateQueue":154,"./ReactUpdates":155,"./instantiateReactComponent":193,"./setInnerHTML":199,"./shouldUpdateReactComponent":201,"_process":29,"fbjs/lib/emptyObject":212,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],140:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -18153,12 +18217,14 @@ module.exports = ReactMount; 'use strict'; var ReactComponentEnvironment = require('./ReactComponentEnvironment'); +var ReactInstrumentation = require('./ReactInstrumentation'); var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes'); var ReactCurrentOwner = require('./ReactCurrentOwner'); var ReactReconciler = require('./ReactReconciler'); var ReactChildReconciler = require('./ReactChildReconciler'); +var emptyFunction = require('fbjs/lib/emptyFunction'); var flattenChildren = require('./flattenChildren'); var invariant = require('fbjs/lib/invariant'); @@ -18275,6 +18341,15 @@ function processQueue(inst, updateQueue) { ReactComponentEnvironment.processChildrenUpdates(inst, updateQueue); } +var setChildrenForInstrumentation = emptyFunction; +if (process.env.NODE_ENV !== 'production') { + setChildrenForInstrumentation = function (children) { + ReactInstrumentation.debugTool.onSetChildren(this._debugID, children ? Object.keys(children).map(function (key) { + return children[key]._debugID; + }) : []); + }; +} + /** * ReactMultiChild are capable of reconciling multiple children. * @@ -18336,6 +18411,7 @@ var ReactMultiChild = { mountChildren: function (nestedChildren, transaction, context) { var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context); this._renderedChildren = children; + var mountImages = []; var index = 0; for (var name in children) { @@ -18346,6 +18422,11 @@ var ReactMultiChild = { mountImages.push(mountImage); } } + + if (process.env.NODE_ENV !== 'production') { + setChildrenForInstrumentation.call(this, children); + } + return mountImages; }, @@ -18452,6 +18533,10 @@ var ReactMultiChild = { processQueue(this, updates); } this._renderedChildren = nextChildren; + + if (process.env.NODE_ENV !== 'production') { + setChildrenForInstrumentation.call(this, nextChildren); + } }, /** @@ -18543,7 +18628,7 @@ var ReactMultiChild = { module.exports = ReactMultiChild; }).call(this,require('_process')) -},{"./ReactChildReconciler":94,"./ReactComponentEnvironment":99,"./ReactCurrentOwner":101,"./ReactMultiChildUpdateTypes":142,"./ReactReconciler":152,"./flattenChildren":182,"_process":29,"fbjs/lib/invariant":219}],142:[function(require,module,exports){ +},{"./ReactChildReconciler":94,"./ReactComponentEnvironment":99,"./ReactCurrentOwner":102,"./ReactInstrumentation":136,"./ReactMultiChildUpdateTypes":141,"./ReactReconciler":151,"./flattenChildren":182,"_process":29,"fbjs/lib/emptyFunction":211,"fbjs/lib/invariant":219}],141:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -18576,7 +18661,7 @@ var ReactMultiChildUpdateTypes = keyMirror({ }); module.exports = ReactMultiChildUpdateTypes; -},{"fbjs/lib/keyMirror":222}],143:[function(require,module,exports){ +},{"fbjs/lib/keyMirror":222}],142:[function(require,module,exports){ (function (process){ /** * Copyright 2014-present, Facebook, Inc. @@ -18675,7 +18760,45 @@ var ReactNativeComponent = { module.exports = ReactNativeComponent; }).call(this,require('_process')) -},{"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],144:[function(require,module,exports){ +},{"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],143:[function(require,module,exports){ +/** + * Copyright 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactNativeOperationHistoryDevtool + */ + +'use strict'; + +var history = []; + +var ReactNativeOperationHistoryDevtool = { + onNativeOperation: function (debugID, type, payload) { + history.push({ + instanceID: debugID, + type: type, + payload: payload + }); + }, + clearHistory: function () { + if (ReactNativeOperationHistoryDevtool._preventClearing) { + // Should only be used for tests. + return; + } + + history = []; + }, + getHistory: function () { + return history; + } +}; + +module.exports = ReactNativeOperationHistoryDevtool; +},{}],144:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -18716,7 +18839,7 @@ var ReactNodeTypes = { module.exports = ReactNodeTypes; }).call(this,require('_process')) -},{"./ReactElement":127,"_process":29,"fbjs/lib/invariant":219}],145:[function(require,module,exports){ +},{"./ReactElement":126,"_process":29,"fbjs/lib/invariant":219}],145:[function(require,module,exports){ (function (process){ /** * Copyright 2015-present, Facebook, Inc. @@ -18913,106 +19036,6 @@ module.exports = ReactOwner; },{"_process":29,"fbjs/lib/invariant":219}],147:[function(require,module,exports){ (function (process){ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPerf - */ - -'use strict'; - -/** - * ReactPerf is a general AOP system designed to measure performance. This - * module only has the hooks: see ReactDefaultPerf for the analysis tool. - */ - -var ReactPerf = { - /** - * Boolean to enable/disable measurement. Set to false by default to prevent - * accidental logging and perf loss. - */ - enableMeasure: false, - - /** - * Holds onto the measure function in use. By default, don't measure - * anything, but we'll override this if we inject a measure function. - */ - storedMeasure: _noMeasure, - - /** - * @param {object} object - * @param {string} objectName - * @param {object} methodNames - */ - measureMethods: function (object, objectName, methodNames) { - if (process.env.NODE_ENV !== 'production') { - for (var key in methodNames) { - if (!methodNames.hasOwnProperty(key)) { - continue; - } - object[key] = ReactPerf.measure(objectName, methodNames[key], object[key]); - } - } - }, - - /** - * Use this to wrap methods you want to measure. Zero overhead in production. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ - measure: function (objName, fnName, func) { - if (process.env.NODE_ENV !== 'production') { - var measuredFunc = null; - var wrapper = function () { - if (ReactPerf.enableMeasure) { - if (!measuredFunc) { - measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); - } - return measuredFunc.apply(this, arguments); - } - return func.apply(this, arguments); - }; - wrapper.displayName = objName + '_' + fnName; - return wrapper; - } - return func; - }, - - injection: { - /** - * @param {function} measure - */ - injectMeasure: function (measure) { - ReactPerf.storedMeasure = measure; - } - } -}; - -/** - * Simply passes through the measured function, without measuring it. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ -function _noMeasure(objName, fnName, func) { - return func; -} - -module.exports = ReactPerf; -}).call(this,require('_process')) - -},{"_process":29}],148:[function(require,module,exports){ -(function (process){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -19039,7 +19062,7 @@ if (process.env.NODE_ENV !== 'production') { module.exports = ReactPropTypeLocationNames; }).call(this,require('_process')) -},{"_process":29}],149:[function(require,module,exports){ +},{"_process":29}],148:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -19062,7 +19085,7 @@ var ReactPropTypeLocations = keyMirror({ }); module.exports = ReactPropTypeLocations; -},{"fbjs/lib/keyMirror":222}],150:[function(require,module,exports){ +},{"fbjs/lib/keyMirror":222}],149:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -19443,7 +19466,7 @@ function getClassName(propValue) { } module.exports = ReactPropTypes; -},{"./ReactElement":127,"./ReactPropTypeLocationNames":148,"./getIteratorFn":188,"fbjs/lib/emptyFunction":211}],151:[function(require,module,exports){ +},{"./ReactElement":126,"./ReactPropTypeLocationNames":147,"./getIteratorFn":188,"fbjs/lib/emptyFunction":211}],150:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -19606,7 +19629,7 @@ _assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin); PooledClass.addPoolingTo(ReactReconcileTransaction); module.exports = ReactReconcileTransaction; -},{"./CallbackQueue":71,"./PooledClass":91,"./ReactBrowserEventEmitter":93,"./ReactInputSelection":135,"./Transaction":173,"object-assign":28}],152:[function(require,module,exports){ +},{"./CallbackQueue":71,"./PooledClass":91,"./ReactBrowserEventEmitter":93,"./ReactInputSelection":134,"./Transaction":173,"object-assign":28}],151:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -19624,6 +19647,8 @@ module.exports = ReactReconcileTransaction; var ReactRef = require('./ReactRef'); var ReactInstrumentation = require('./ReactInstrumentation'); +var invariant = require('fbjs/lib/invariant'); + /** * Helper to call ReactRef.attachRefs with this composite component, split out * to avoid allocations in the transaction mount-ready queue. @@ -19646,12 +19671,20 @@ var ReactReconciler = { * @internal */ mountComponent: function (internalInstance, transaction, nativeParent, nativeContainerInfo, context) { + if (process.env.NODE_ENV !== 'production') { + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'mountComponent'); + } + } var markup = internalInstance.mountComponent(transaction, nativeParent, nativeContainerInfo, context); if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { transaction.getReactMountReady().enqueue(attachRefs, internalInstance); } if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onMountComponent(internalInstance); + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'mountComponent'); + ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID); + } } return markup; }, @@ -19671,10 +19704,18 @@ var ReactReconciler = { * @internal */ unmountComponent: function (internalInstance, safely) { + if (process.env.NODE_ENV !== 'production') { + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'unmountComponent'); + } + } ReactRef.detachRefs(internalInstance, internalInstance._currentElement); internalInstance.unmountComponent(safely); if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onUnmountComponent(internalInstance); + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'unmountComponent'); + ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID); + } } }, @@ -19704,6 +19745,12 @@ var ReactReconciler = { return; } + if (process.env.NODE_ENV !== 'production') { + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'receiveComponent'); + } + } + var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); if (refsChanged) { @@ -19717,7 +19764,10 @@ var ReactReconciler = { } if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance); + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'receiveComponent'); + ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); + } } }, @@ -19728,10 +19778,24 @@ var ReactReconciler = { * @param {ReactReconcileTransaction} transaction * @internal */ - performUpdateIfNecessary: function (internalInstance, transaction) { + performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) { + if (internalInstance._updateBatchNumber !== updateBatchNumber) { + // The component's enqueued batch number should always be the current + // batch or the following one. + !(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : invariant(false) : void 0; + return; + } + if (process.env.NODE_ENV !== 'production') { + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'performUpdateIfNecessary'); + } + } internalInstance.performUpdateIfNecessary(transaction); if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onUpdateComponent(internalInstance); + if (internalInstance._debugID !== 0) { + ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'performUpdateIfNecessary'); + ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); + } } } @@ -19740,7 +19804,7 @@ var ReactReconciler = { module.exports = ReactReconciler; }).call(this,require('_process')) -},{"./ReactInstrumentation":137,"./ReactRef":153,"_process":29}],153:[function(require,module,exports){ +},{"./ReactInstrumentation":136,"./ReactRef":152,"_process":29,"fbjs/lib/invariant":219}],152:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -19819,7 +19883,81 @@ ReactRef.detachRefs = function (instance, element) { }; module.exports = ReactRef; -},{"./ReactOwner":146}],154:[function(require,module,exports){ +},{"./ReactOwner":146}],153:[function(require,module,exports){ +/** + * Copyright 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactServerRenderingTransaction + */ + +'use strict'; + +var _assign = require('object-assign'); + +var PooledClass = require('./PooledClass'); +var Transaction = require('./Transaction'); + +/** + * Executed within the scope of the `Transaction` instance. Consider these as + * being member methods, but with an implied ordering while being isolated from + * each other. + */ +var TRANSACTION_WRAPPERS = []; + +var noopCallbackQueue = { + enqueue: function () {} +}; + +/** + * @class ReactServerRenderingTransaction + * @param {boolean} renderToStaticMarkup + */ +function ReactServerRenderingTransaction(renderToStaticMarkup) { + this.reinitializeTransaction(); + this.renderToStaticMarkup = renderToStaticMarkup; + this.useCreateElement = false; +} + +var Mixin = { + /** + * @see Transaction + * @abstract + * @final + * @return {array} Empty list of operation wrap procedures. + */ + getTransactionWrappers: function () { + return TRANSACTION_WRAPPERS; + }, + + /** + * @return {object} The queue to collect `onDOMReady` callbacks with. + */ + getReactMountReady: function () { + return noopCallbackQueue; + }, + + /** + * `PooledClass` looks for this, and will invoke this before allowing this + * instance to be reused. + */ + destructor: function () {}, + + checkpoint: function () {}, + + rollback: function () {} +}; + +_assign(ReactServerRenderingTransaction.prototype, Transaction.Mixin, Mixin); + +PooledClass.addPoolingTo(ReactServerRenderingTransaction); + +module.exports = ReactServerRenderingTransaction; +},{"./PooledClass":91,"./Transaction":173,"object-assign":28}],154:[function(require,module,exports){ (function (process){ /** * Copyright 2015-present, Facebook, Inc. @@ -20038,7 +20176,7 @@ var ReactUpdateQueue = { module.exports = ReactUpdateQueue; }).call(this,require('_process')) -},{"./ReactCurrentOwner":101,"./ReactInstanceMap":136,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],155:[function(require,module,exports){ +},{"./ReactCurrentOwner":102,"./ReactInstanceMap":135,"./ReactUpdates":155,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],155:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -20058,13 +20196,14 @@ var _assign = require('object-assign'); var CallbackQueue = require('./CallbackQueue'); var PooledClass = require('./PooledClass'); var ReactFeatureFlags = require('./ReactFeatureFlags'); -var ReactPerf = require('./ReactPerf'); +var ReactInstrumentation = require('./ReactInstrumentation'); var ReactReconciler = require('./ReactReconciler'); var Transaction = require('./Transaction'); var invariant = require('fbjs/lib/invariant'); var dirtyComponents = []; +var updateBatchNumber = 0; var asapCallbackQueue = CallbackQueue.getPooled(); var asapEnqueued = false; @@ -20159,6 +20298,13 @@ function runBatchedUpdates(transaction) { // them before their children by sorting the array. dirtyComponents.sort(mountOrderComparator); + // Any updates enqueued while reconciling must be performed after this entire + // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and + // C, B could update twice in a single batch if C's render enqueues an update + // to B (since B would have already updated, we should skip it, and the only + // way we can know to do so is by checking the batch counter). + updateBatchNumber++; + for (var i = 0; i < len; i++) { // If a component is unmounted before pending changes apply, it will still // be here, but we assume that it has cleared its _pendingCallbacks and @@ -20182,7 +20328,7 @@ function runBatchedUpdates(transaction) { console.time(markerName); } - ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction); + ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); if (markerName) { console.timeEnd(markerName); @@ -20197,6 +20343,10 @@ function runBatchedUpdates(transaction) { } var flushBatchedUpdates = function () { + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onBeginFlush(); + } + // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents // array and perform any updates enqueued by mount-ready handlers (i.e., // componentDidUpdate) but we need to check here too in order to catch @@ -20216,8 +20366,11 @@ var flushBatchedUpdates = function () { CallbackQueue.release(queue); } } + + if (process.env.NODE_ENV !== 'production') { + ReactInstrumentation.debugTool.onEndFlush(); + } }; -flushBatchedUpdates = ReactPerf.measure('ReactUpdates', 'flushBatchedUpdates', flushBatchedUpdates); /** * Mark a component as needing a rerender, adding an optional callback to a @@ -20238,6 +20391,9 @@ function enqueueUpdate(component) { } dirtyComponents.push(component); + if (component._updateBatchNumber == null) { + component._updateBatchNumber = updateBatchNumber + 1; + } } /** @@ -20283,7 +20439,7 @@ var ReactUpdates = { module.exports = ReactUpdates; }).call(this,require('_process')) -},{"./CallbackQueue":71,"./PooledClass":91,"./ReactFeatureFlags":133,"./ReactPerf":147,"./ReactReconciler":152,"./Transaction":173,"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],156:[function(require,module,exports){ +},{"./CallbackQueue":71,"./PooledClass":91,"./ReactFeatureFlags":132,"./ReactInstrumentation":136,"./ReactReconciler":151,"./Transaction":173,"_process":29,"fbjs/lib/invariant":219,"object-assign":28}],156:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -20297,7 +20453,7 @@ module.exports = ReactUpdates; 'use strict'; -module.exports = '15.0.2'; +module.exports = '15.1.0'; },{}],157:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. @@ -20796,7 +20952,7 @@ var SelectEventPlugin = { }; module.exports = SelectEventPlugin; -},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":106,"./ReactInputSelection":135,"./SyntheticEvent":164,"./isTextInputElement":195,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/getActiveElement":214,"fbjs/lib/keyOf":223,"fbjs/lib/shallowEqual":228}],159:[function(require,module,exports){ +},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":107,"./ReactInputSelection":134,"./SyntheticEvent":164,"./isTextInputElement":195,"fbjs/lib/ExecutionEnvironment":205,"fbjs/lib/getActiveElement":214,"fbjs/lib/keyOf":223,"fbjs/lib/shallowEqual":228}],159:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -21427,7 +21583,7 @@ var SimpleEventPlugin = { module.exports = SimpleEventPlugin; }).call(this,require('_process')) -},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":106,"./SyntheticAnimationEvent":160,"./SyntheticClipboardEvent":161,"./SyntheticDragEvent":163,"./SyntheticEvent":164,"./SyntheticFocusEvent":165,"./SyntheticKeyboardEvent":167,"./SyntheticMouseEvent":168,"./SyntheticTouchEvent":169,"./SyntheticTransitionEvent":170,"./SyntheticUIEvent":171,"./SyntheticWheelEvent":172,"./getEventCharCode":184,"_process":29,"fbjs/lib/EventListener":204,"fbjs/lib/emptyFunction":211,"fbjs/lib/invariant":219,"fbjs/lib/keyOf":223}],160:[function(require,module,exports){ +},{"./EventConstants":82,"./EventPropagators":86,"./ReactDOMComponentTree":107,"./SyntheticAnimationEvent":160,"./SyntheticClipboardEvent":161,"./SyntheticDragEvent":163,"./SyntheticEvent":164,"./SyntheticFocusEvent":165,"./SyntheticKeyboardEvent":167,"./SyntheticMouseEvent":168,"./SyntheticTouchEvent":169,"./SyntheticTransitionEvent":170,"./SyntheticUIEvent":171,"./SyntheticWheelEvent":172,"./getEventCharCode":184,"_process":29,"fbjs/lib/EventListener":204,"fbjs/lib/emptyFunction":211,"fbjs/lib/invariant":219,"fbjs/lib/keyOf":223}],160:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -22856,6 +23012,8 @@ var warning = require('fbjs/lib/warning'); /** * Returns the DOM node rendered by this element. * + * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode + * * @param {ReactComponent|DOMElement} componentOrElement * @return {?DOMElement} The root node of this element. */ @@ -22890,7 +23048,7 @@ function findDOMNode(componentOrElement) { module.exports = findDOMNode; }).call(this,require('_process')) -},{"./ReactCurrentOwner":101,"./ReactDOMComponentTree":106,"./ReactInstanceMap":136,"./getNativeComponentFromComposite":189,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],182:[function(require,module,exports){ +},{"./ReactCurrentOwner":102,"./ReactDOMComponentTree":107,"./ReactInstanceMap":135,"./getNativeComponentFromComposite":189,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],182:[function(require,module,exports){ (function (process){ /** * Copyright 2013-present, Facebook, Inc. @@ -23511,6 +23669,7 @@ var _assign = require('object-assign'); var ReactCompositeComponent = require('./ReactCompositeComponent'); var ReactEmptyComponent = require('./ReactEmptyComponent'); var ReactNativeComponent = require('./ReactNativeComponent'); +var ReactInstrumentation = require('./ReactInstrumentation'); var invariant = require('fbjs/lib/invariant'); var warning = require('fbjs/lib/warning'); @@ -23533,6 +23692,21 @@ function getDeclarationErrorAddendum(owner) { return ''; } +function getDisplayName(instance) { + var element = instance._currentElement; + if (element == null) { + return '#empty'; + } else if (typeof element === 'string' || typeof element === 'number') { + return '#text'; + } else if (typeof element.type === 'string') { + return element.type; + } else if (instance.getName) { + return instance.getName() || 'Unknown'; + } else { + return element.type.displayName || element.type.name || 'Unknown'; + } +} + /** * Check if the type reference is a known internal type. I.e. not a user * provided composite type. @@ -23544,6 +23718,8 @@ function isInternalComponentType(type) { return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function'; } +var nextDebugID = 1; + /** * Given a ReactNode, create an instance that will actually be mounted. * @@ -23554,7 +23730,8 @@ function isInternalComponentType(type) { function instantiateReactComponent(node) { var instance; - if (node === null || node === false) { + var isEmpty = node === null || node === false; + if (isEmpty) { instance = ReactEmptyComponent.create(instantiateReactComponent); } else if (typeof node === 'object') { var element = node; @@ -23592,6 +23769,20 @@ function instantiateReactComponent(node) { instance._warnedAboutRefsInRender = false; } + if (process.env.NODE_ENV !== 'production') { + var debugID = isEmpty ? 0 : nextDebugID++; + instance._debugID = debugID; + + if (debugID !== 0) { + var displayName = getDisplayName(instance); + ReactInstrumentation.debugTool.onSetDisplayName(debugID, displayName); + var owner = node && node._owner; + if (owner) { + ReactInstrumentation.debugTool.onSetOwner(debugID, owner._debugID); + } + } + } + // Internal instances should fully constructed at this point, so they should // not get any new fields added to them at this point. if (process.env.NODE_ENV !== 'production') { @@ -23606,7 +23797,7 @@ function instantiateReactComponent(node) { module.exports = instantiateReactComponent; }).call(this,require('_process')) -},{"./ReactCompositeComponent":100,"./ReactEmptyComponent":129,"./ReactNativeComponent":143,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],194:[function(require,module,exports){ +},{"./ReactCompositeComponent":101,"./ReactEmptyComponent":128,"./ReactInstrumentation":136,"./ReactNativeComponent":142,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229,"object-assign":28}],194:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -23729,10 +23920,13 @@ var invariant = require('fbjs/lib/invariant'); /** * Returns the first child in a collection of children and verifies that there - * is only one child in the collection. The current implementation of this - * function assumes that a single child gets passed without a wrapper, but the - * purpose of this helper function is to abstract away the particular structure - * of children. + * is only one child in the collection. + * + * See https://facebook.github.io/react/docs/top-level-api.html#react.children.only + * + * The current implementation of this function assumes that a single child gets + * passed without a wrapper, but the purpose of this helper function is to + * abstract away the particular structure of children. * * @param {?object} children Child collection structure. * @return {ReactElement} The first and only `ReactElement` contained in the @@ -23746,7 +23940,7 @@ function onlyChild(children) { module.exports = onlyChild; }).call(this,require('_process')) -},{"./ReactElement":127,"_process":29,"fbjs/lib/invariant":219}],197:[function(require,module,exports){ +},{"./ReactElement":126,"_process":29,"fbjs/lib/invariant":219}],197:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -23790,7 +23984,7 @@ module.exports = quoteAttributeValueForBrowser; var ReactMount = require('./ReactMount'); module.exports = ReactMount.renderSubtreeIntoContainer; -},{"./ReactMount":140}],199:[function(require,module,exports){ +},{"./ReactMount":139}],199:[function(require,module,exports){ /** * Copyright 2013-present, Facebook, Inc. * All rights reserved. @@ -24119,7 +24313,7 @@ function traverseAllChildren(children, callback, traverseContext) { module.exports = traverseAllChildren; }).call(this,require('_process')) -},{"./KeyEscapeUtils":89,"./ReactCurrentOwner":101,"./ReactElement":127,"./getIteratorFn":188,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],203:[function(require,module,exports){ +},{"./KeyEscapeUtils":89,"./ReactCurrentOwner":102,"./ReactElement":126,"./getIteratorFn":188,"_process":29,"fbjs/lib/invariant":219,"fbjs/lib/warning":229}],203:[function(require,module,exports){ (function (process){ /** * Copyright 2015-present, Facebook, Inc. @@ -24529,18 +24723,18 @@ var EventListener = { * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ - listen: function (target, eventType, callback) { + listen: function listen(target, eventType, callback) { if (target.addEventListener) { target.addEventListener(eventType, callback, false); return { - remove: function () { + remove: function remove() { target.removeEventListener(eventType, callback, false); } }; } else if (target.attachEvent) { target.attachEvent('on' + eventType, callback); return { - remove: function () { + remove: function remove() { target.detachEvent('on' + eventType, callback); } }; @@ -24555,11 +24749,11 @@ var EventListener = { * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ - capture: function (target, eventType, callback) { + capture: function capture(target, eventType, callback) { if (target.addEventListener) { target.addEventListener(eventType, callback, true); return { - remove: function () { + remove: function remove() { target.removeEventListener(eventType, callback, true); } }; @@ -24573,7 +24767,7 @@ var EventListener = { } }, - registerDefault: function () {} + registerDefault: function registerDefault() {} }; module.exports = EventListener; @@ -24698,7 +24892,7 @@ module.exports = camelizeStyleName; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @typechecks + * */ var isTextNode = require('./isTextNode'); @@ -24707,10 +24901,6 @@ var isTextNode = require('./isTextNode'); /** * Checks if a given DOM node contains or is another DOM node. - * - * @param {?DOMNode} outerNode Outer DOM node. - * @param {?DOMNode} innerNode Inner DOM node. - * @return {boolean} True if `outerNode` contains or is `innerNode`. */ function containsNode(outerNode, innerNode) { if (!outerNode || !innerNode) { @@ -24721,7 +24911,7 @@ function containsNode(outerNode, innerNode) { return false; } else if (isTextNode(innerNode)) { return containsNode(outerNode, innerNode.parentNode); - } else if (outerNode.contains) { + } else if ('contains' in outerNode) { return outerNode.contains(innerNode); } else if (outerNode.compareDocumentPosition) { return !!(outerNode.compareDocumentPosition(innerNode) & 16); @@ -24959,6 +25149,7 @@ module.exports = createNodesFromMarkup; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * + * */ function makeEmptyFunction(arg) { @@ -24972,7 +25163,7 @@ function makeEmptyFunction(arg) { * primarily useful idiomatically for overridable function endpoints which * always need to be callable, since JS lacks a null-call idiom ala Cocoa. */ -function emptyFunction() {} +var emptyFunction = function emptyFunction() {}; emptyFunction.thatReturns = makeEmptyFunction; emptyFunction.thatReturnsFalse = makeEmptyFunction(false); @@ -25416,7 +25607,7 @@ var invariant = require('./invariant'); * @param {object} obj * @return {object} */ -var keyMirror = function (obj) { +var keyMirror = function keyMirror(obj) { var ret = {}; var key; !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : void 0; @@ -25455,7 +25646,7 @@ module.exports = keyMirror; * 'xa12' in that case. Resolve keys you want to use once at startup time, then * reuse those resolutions. */ -var keyOf = function (oneKeyObj) { +var keyOf = function keyOf(oneKeyObj) { var key; for (key in oneKeyObj) { if (!oneKeyObj.hasOwnProperty(key)) { @@ -25527,6 +25718,7 @@ module.exports = mapObject; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * + * * @typechecks static-only */ @@ -25534,9 +25726,6 @@ module.exports = mapObject; /** * Memoizes the return value of a function that accepts one string argument. - * - * @param {function} callback - * @return {function} */ function memoizeStringOnly(callback) { @@ -25597,11 +25786,11 @@ var performanceNow; * because of Facebook's testing infrastructure. */ if (performance.now) { - performanceNow = function () { + performanceNow = function performanceNow() { return performance.now(); }; } else { - performanceNow = function () { + performanceNow = function performanceNow() { return Date.now(); }; } @@ -25700,7 +25889,7 @@ var emptyFunction = require('./emptyFunction'); var warning = emptyFunction; if (process.env.NODE_ENV !== 'production') { - warning = function (condition, format) { + warning = function warning(condition, format) { for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } @@ -25871,7 +26060,7 @@ module.exports.Dispatcher = require('./lib/Dispatcher'); },{"./lib/Dispatcher":5}],"jquery":[function(require,module,exports){ /*! - * jQuery JavaScript Library v2.2.3 + * jQuery JavaScript Library v2.2.4 * http://jquery.com/ * * Includes Sizzle.js @@ -25881,7 +26070,7 @@ module.exports.Dispatcher = require('./lib/Dispatcher'); * Released under the MIT license * http://jquery.org/license * - * Date: 2016-04-05T19:26Z + * Date: 2016-05-20T17:23Z */ (function( global, factory ) { @@ -25937,7 +26126,7 @@ var support = {}; var - version = "2.2.3", + version = "2.2.4", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -30878,13 +31067,14 @@ jQuery.Event.prototype = { isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, + isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; - if ( e ) { + if ( e && !this.isSimulated ) { e.preventDefault(); } }, @@ -30893,7 +31083,7 @@ jQuery.Event.prototype = { this.isPropagationStopped = returnTrue; - if ( e ) { + if ( e && !this.isSimulated ) { e.stopPropagation(); } }, @@ -30902,7 +31092,7 @@ jQuery.Event.prototype = { this.isImmediatePropagationStopped = returnTrue; - if ( e ) { + if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } @@ -31833,19 +32023,6 @@ function getWidthOrHeight( elem, name, extra ) { styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - // Support: IE11 only - // In IE 11 fullscreen elements inside of an iframe have - // 100x too small dimensions (gh-1764). - if ( document.msFullscreenElement && window.top !== window ) { - - // Support: IE11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - if ( elem.getClientRects().length ) { - val = Math.round( elem.getBoundingClientRect()[ name ] * 100 ); - } - } - // Some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 @@ -33736,6 +33913,7 @@ jQuery.extend( jQuery.event, { }, // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), @@ -33743,27 +33921,10 @@ jQuery.extend( jQuery.event, { { type: type, isSimulated: true - - // Previously, `originalEvent: {}` was set here, so stopPropagation call - // would not be triggered on donor event, since in our own - // jQuery.event.stopPropagation function we had a check for existence of - // originalEvent.stopPropagation method, so, consequently it would be a noop. - // - // But now, this "simulate" function is used only for events - // for which stopPropagation() is noop, so there is no need for that anymore. - // - // For the 1.x branch though, guard for "click" and "submit" - // events is still used, but was moved to jQuery.event.stopPropagation function - // because `originalEvent` should point to the original event for the constancy - // with other events and for more focused logic } ); jQuery.event.trigger( e, null, elem ); - - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } } } ); @@ -35717,8 +35878,7 @@ return jQuery; (function (global){ /** * @license - * lodash 4.11.2 (Custom Build) - * Build: `lodash -d -o ./foo/lodash.js` + * lodash * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 @@ -35730,7 +35890,7 @@ return jQuery; var undefined; /** Used as the semantic version number. */ - var VERSION = '4.11.2'; + var VERSION = '4.13.1'; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; @@ -35834,7 +35994,7 @@ return jQuery; /** Used to match property names within property paths. */ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g; /** * Used to match `RegExp` @@ -35967,7 +36127,7 @@ return jQuery; 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', 'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + '_', 'isFinite', 'parseInt', 'setTimeout' ]; /** Used to make template sourceURLs easier to identify. */ @@ -36046,12 +36206,6 @@ return jQuery; '`': '`' }; - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { '\\': '\\', @@ -36067,41 +36221,25 @@ return jQuery; freeParseInt = parseInt; /** Detect free variable `exports`. */ - var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) - ? exports - : undefined; + var freeExports = typeof exports == 'object' && exports; /** Detect free variable `module`. */ - var freeModule = (objectTypes[typeof module] && module && !module.nodeType) - ? module - : undefined; + var freeModule = freeExports && typeof module == 'object' && module; /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = (freeModule && freeModule.exports === freeExports) - ? freeExports - : undefined; + var moduleExports = freeModule && freeModule.exports === freeExports; /** Detect free variable `global` from Node.js. */ - var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + var freeGlobal = checkGlobal(typeof global == 'object' && global); /** Detect free variable `self`. */ - var freeSelf = checkGlobal(objectTypes[typeof self] && self); - - /** Detect free variable `window`. */ - var freeWindow = checkGlobal(objectTypes[typeof window] && window); + var freeSelf = checkGlobal(typeof self == 'object' && self); /** Detect `this` as the global object. */ - var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + var thisGlobal = checkGlobal(typeof this == 'object' && this); - /** - * Used as a reference to the global object. - * - * The `this` value is used if it's the global object to avoid Greasemonkey's - * restricted `window` object, otherwise the `window` object is used. - */ - var root = freeGlobal || - ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || - freeSelf || thisGlobal || Function('return this')(); + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || thisGlobal || Function('return this')(); /*--------------------------------------------------------------------------*/ @@ -36157,7 +36295,7 @@ return jQuery; * A specialized version of `baseAggregator` for arrays. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. @@ -36165,7 +36303,7 @@ return jQuery; */ function arrayAggregator(array, setter, iteratee, accumulator) { var index = -1, - length = array.length; + length = array ? array.length : 0; while (++index < length) { var value = array[index]; @@ -36174,42 +36312,18 @@ return jQuery; return accumulator; } - /** - * Creates a new array concatenating `array` with `other`. - * - * @private - * @param {Array} array The first array to concatenate. - * @param {Array} other The second array to concatenate. - * @returns {Array} Returns the new concatenated array. - */ - function arrayConcat(array, other) { - var index = -1, - length = array.length, - othIndex = -1, - othLength = other.length, - result = Array(length + othLength); - - while (++index < length) { - result[index] = array[index]; - } - while (++othIndex < othLength) { - result[index++] = other[othIndex]; - } - return result; - } - /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, - length = array.length; + length = array ? array.length : 0; while (++index < length) { if (iteratee(array[index], index, array) === false) { @@ -36224,12 +36338,12 @@ return jQuery; * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEachRight(array, iteratee) { - var length = array.length; + var length = array ? array.length : 0; while (length--) { if (iteratee(array[length], length, array) === false) { @@ -36244,14 +36358,14 @@ return jQuery; * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. */ function arrayEvery(array, predicate) { var index = -1, - length = array.length; + length = array ? array.length : 0; while (++index < length) { if (!predicate(array[index], index, array)) { @@ -36266,13 +36380,13 @@ return jQuery; * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, - length = array.length, + length = array ? array.length : 0, resIndex = 0, result = []; @@ -36290,26 +36404,27 @@ return jQuery; * specifying an index to search from. * * @private - * @param {Array} array The array to search. + * @param {Array} [array] The array to search. * @param {*} target The value to search for. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludes(array, value) { - return !!array.length && baseIndexOf(array, value, 0) > -1; + var length = array ? array.length : 0; + return !!length && baseIndexOf(array, value, 0) > -1; } /** * This function is like `arrayIncludes` except that it accepts a comparator. * * @private - * @param {Array} array The array to search. + * @param {Array} [array] The array to search. * @param {*} target The value to search for. * @param {Function} comparator The comparator invoked per element. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludesWith(array, value, comparator) { var index = -1, - length = array.length; + length = array ? array.length : 0; while (++index < length) { if (comparator(value, array[index])) { @@ -36324,13 +36439,13 @@ return jQuery; * shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, - length = array.length, + length = array ? array.length : 0, result = Array(length); while (++index < length) { @@ -36363,7 +36478,7 @@ return jQuery; * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the first element of `array` as @@ -36372,7 +36487,7 @@ return jQuery; */ function arrayReduce(array, iteratee, accumulator, initAccum) { var index = -1, - length = array.length; + length = array ? array.length : 0; if (initAccum && length) { accumulator = array[++index]; @@ -36388,7 +36503,7 @@ return jQuery; * iteratee shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the last element of `array` as @@ -36396,7 +36511,7 @@ return jQuery; * @returns {*} Returns the accumulated value. */ function arrayReduceRight(array, iteratee, accumulator, initAccum) { - var length = array.length; + var length = array ? array.length : 0; if (initAccum && length) { accumulator = array[--length]; } @@ -36411,14 +36526,14 @@ return jQuery; * shorthands. * * @private - * @param {Array} array The array to iterate over. + * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, - length = array.length; + length = array ? array.length : 0; while (++index < length) { if (predicate(array[index], index, array)) { @@ -36429,23 +36544,21 @@ return jQuery; } /** - * The base implementation of methods like `_.find` and `_.findKey`, without - * support for iteratee shorthands, which iterates over `collection` using - * `eachFunc`. + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. * * @private * @param {Array|Object} collection The collection to search. * @param {Function} predicate The function invoked per iteration. * @param {Function} eachFunc The function to iterate over `collection`. - * @param {boolean} [retKey] Specify returning the key of the found element - * instead of the element itself. * @returns {*} Returns the found element or its key, else `undefined`. */ - function baseFind(collection, predicate, eachFunc, retKey) { + function baseFindKey(collection, predicate, eachFunc) { var result; eachFunc(collection, function(value, key, collection) { if (predicate(value, key, collection)) { - result = retKey ? key : value; + result = key; return false; } }); @@ -36459,12 +36572,13 @@ return jQuery; * @private * @param {Array} array The array to search. * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {number} Returns the index of the matched value, else `-1`. */ - function baseFindIndex(array, predicate, fromRight) { + function baseFindIndex(array, predicate, fromIndex, fromRight) { var length = array.length, - index = fromRight ? length : -1; + index = fromIndex + (fromRight ? 1 : -1); while ((fromRight ? index-- : ++index < length)) { if (predicate(array[index], index, array)) { @@ -36625,7 +36739,7 @@ return jQuery; * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. - * @returns {Object} Returns the new array of key-value pairs. + * @returns {Object} Returns the key-value pairs. */ function baseToPairs(object, props) { return arrayMap(props, function(key) { @@ -36638,7 +36752,7 @@ return jQuery; * * @private * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { @@ -36662,6 +36776,18 @@ return jQuery; }); } + /** + * Checks if a cache value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + /** * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol * that is not found in the character symbols. @@ -36759,6 +36885,18 @@ return jQuery; return '\\' + stringEscapes[chr]; } + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + /** * Gets the index at which the first occurrence of `NaN` is found in `array`. * @@ -36770,7 +36908,7 @@ return jQuery; */ function indexOfNaN(array, fromIndex, fromRight) { var length = array.length, - index = fromIndex + (fromRight ? 0 : -1); + index = fromIndex + (fromRight ? 1 : -1); while ((fromRight ? index-- : ++index < length)) { var other = array[index]; @@ -36818,11 +36956,11 @@ return jQuery; } /** - * Converts `map` to an array. + * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. - * @returns {Array} Returns the converted array. + * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, @@ -36860,11 +36998,11 @@ return jQuery; } /** - * Converts `set` to an array. + * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. - * @returns {Array} Returns the converted array. + * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, @@ -36876,6 +37014,23 @@ return jQuery; return result; } + /** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ + function setToPairs(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = [value, value]; + }); + return result; + } + /** * Gets the number of symbols in `string`. * @@ -36944,10 +37099,10 @@ return jQuery; * lodash.isFunction(lodash.bar); * // => true * - * // Use `context` to mock `Date#getTime` use in `_.now`. - * var mock = _.runInContext({ + * // Use `context` to stub `Date#getTime` use in `_.now`. + * var stubbed = _.runInContext({ * 'Date': function() { - * return { 'getTime': getTimeMock }; + * return { 'getTime': stubGetTime }; * } * }); * @@ -36969,6 +37124,15 @@ return jQuery; objectProto = context.Object.prototype, stringProto = context.String.prototype; + /** Used to detect overreaching core-js shims. */ + var coreJsData = context['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + /** Used to resolve the decompiled source of functions. */ var funcToString = context.Function.prototype.toString; @@ -37002,15 +37166,16 @@ return jQuery; Reflect = context.Reflect, Symbol = context.Symbol, Uint8Array = context.Uint8Array, - clearTimeout = context.clearTimeout, enumerate = Reflect ? Reflect.enumerate : undefined, getOwnPropertySymbols = Object.getOwnPropertySymbols, iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, splice = arrayProto.splice; + /** Built-in method references that are mockable. */ + var setTimeout = function(func, wait) { return context.setTimeout.call(root, func, wait); }; + /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeCeil = Math.ceil, nativeFloor = Math.floor, @@ -37129,22 +37294,24 @@ return jQuery; * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, - * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, - * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, - * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, - * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, - * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, - * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, - * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, - * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`, - * `noConflict`, `noop`, `now`, `nth`, `pad`, `padEnd`, `padStart`, `parseInt`, - * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`, - * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, - * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, - * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`, - * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`, - * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, - * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words` + * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, + * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, + * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, + * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` * * @name _ * @constructor @@ -37403,64 +37570,212 @@ return jQuery; * * @private * @constructor - * @returns {Object} Returns the new hash object. + * @param {Array} [entries] The key-value pairs to cache. */ - function Hash() {} + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } /** * Removes `key` and its value from the hash. * * @private + * @name delete + * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ - function hashDelete(hash, key) { - return hashHas(hash, key) && delete hash[key]; + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; } /** * Gets the hash value for `key`. * * @private - * @param {Object} hash The hash to query. + * @name get + * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ - function hashGet(hash, key) { + function hashGet(key) { + var data = this.__data__; if (nativeCreate) { - var result = hash[key]; + var result = data[key]; return result === HASH_UNDEFINED ? undefined : result; } - return hasOwnProperty.call(hash, key) ? hash[key] : undefined; + return hasOwnProperty.call(data, key) ? data[key] : undefined; } /** * Checks if a hash value for `key` exists. * * @private - * @param {Object} hash The hash to query. + * @name has + * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ - function hashHas(hash, key) { - return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); } /** * Sets the hash `key` to `value`. * * @private - * @param {Object} hash The hash to modify. + * @name set + * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. */ - function hashSet(hash, key, value) { - hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; } - // Avoid inheriting from `Object.prototype` when possible. - Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; /*------------------------------------------------------------------------*/ @@ -37469,15 +37784,15 @@ return jQuery; * * @private * @constructor - * @param {Array} [values] The values to cache. + * @param {Array} [entries] The key-value pairs to cache. */ - function MapCache(values) { + function MapCache(entries) { var index = -1, - length = values ? values.length : 0; + length = entries ? entries.length : 0; this.clear(); while (++index < length) { - var entry = values[index]; + var entry = entries[index]; this.set(entry[0], entry[1]); } } @@ -37489,10 +37804,10 @@ return jQuery; * @name clear * @memberOf MapCache */ - function mapClear() { + function mapCacheClear() { this.__data__ = { 'hash': new Hash, - 'map': Map ? new Map : [], + 'map': new (Map || ListCache), 'string': new Hash }; } @@ -37506,12 +37821,8 @@ return jQuery; * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ - function mapDelete(key) { - var data = this.__data__; - if (isKeyable(key)) { - return hashDelete(typeof key == 'string' ? data.string : data.hash, key); - } - return Map ? data.map['delete'](key) : assocDelete(data.map, key); + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); } /** @@ -37523,12 +37834,8 @@ return jQuery; * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ - function mapGet(key) { - var data = this.__data__; - if (isKeyable(key)) { - return hashGet(typeof key == 'string' ? data.string : data.hash, key); - } - return Map ? data.map.get(key) : assocGet(data.map, key); + function mapCacheGet(key) { + return getMapData(this, key).get(key); } /** @@ -37540,12 +37847,8 @@ return jQuery; * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ - function mapHas(key) { - var data = this.__data__; - if (isKeyable(key)) { - return hashHas(typeof key == 'string' ? data.string : data.hash, key); - } - return Map ? data.map.has(key) : assocHas(data.map, key); + function mapCacheHas(key) { + return getMapData(this, key).has(key); } /** @@ -37558,30 +37861,23 @@ return jQuery; * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ - function mapSet(key, value) { - var data = this.__data__; - if (isKeyable(key)) { - hashSet(typeof key == 'string' ? data.string : data.hash, key, value); - } else if (Map) { - data.map.set(key, value); - } else { - assocSet(data.map, key, value); - } + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); return this; } // Add methods to `MapCache`. - MapCache.prototype.clear = mapClear; - MapCache.prototype['delete'] = mapDelete; - MapCache.prototype.get = mapGet; - MapCache.prototype.has = mapHas; - MapCache.prototype.set = mapSet; + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; /*------------------------------------------------------------------------*/ /** * - * Creates a set cache object to store unique values. + * Creates an array cache object to store unique values. * * @private * @constructor @@ -37593,52 +37889,41 @@ return jQuery; this.__data__ = new MapCache; while (++index < length) { - this.push(values[index]); + this.add(values[index]); } } /** - * Checks if `value` is in `cache`. + * Adds `value` to the array cache. * * @private - * @param {Object} cache The set cache to search. + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache * @param {*} value The value to search for. * @returns {number} Returns `true` if `value` is found, else `false`. */ - function cacheHas(cache, value) { - var map = cache.__data__; - if (isKeyable(value)) { - var data = map.__data__, - hash = typeof value == 'string' ? data.string : data.hash; - - return hash[value] === HASH_UNDEFINED; - } - return map.has(value); - } - - /** - * Adds `value` to the set cache. - * - * @private - * @name push - * @memberOf SetCache - * @param {*} value The value to cache. - */ - function cachePush(value) { - var map = this.__data__; - if (isKeyable(value)) { - var data = map.__data__, - hash = typeof value == 'string' ? data.string : data.hash; - - hash[value] = HASH_UNDEFINED; - } - else { - map.set(value, HASH_UNDEFINED); - } + function setCacheHas(value) { + return this.__data__.has(value); } // Add methods to `SetCache`. - SetCache.prototype.push = cachePush; + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; /*------------------------------------------------------------------------*/ @@ -37647,17 +37932,10 @@ return jQuery; * * @private * @constructor - * @param {Array} [values] The values to cache. + * @param {Array} [entries] The key-value pairs to cache. */ - function Stack(values) { - var index = -1, - length = values ? values.length : 0; - - this.clear(); - while (++index < length) { - var entry = values[index]; - this.set(entry[0], entry[1]); - } + function Stack(entries) { + this.__data__ = new ListCache(entries); } /** @@ -37668,7 +37946,7 @@ return jQuery; * @memberOf Stack */ function stackClear() { - this.__data__ = { 'array': [], 'map': null }; + this.__data__ = new ListCache; } /** @@ -37681,10 +37959,7 @@ return jQuery; * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { - var data = this.__data__, - array = data.array; - - return array ? assocDelete(array, key) : data.map['delete'](key); + return this.__data__['delete'](key); } /** @@ -37697,10 +37972,7 @@ return jQuery; * @returns {*} Returns the entry value. */ function stackGet(key) { - var data = this.__data__, - array = data.array; - - return array ? assocGet(array, key) : data.map.get(key); + return this.__data__.get(key); } /** @@ -37713,10 +37985,7 @@ return jQuery; * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { - var data = this.__data__, - array = data.array; - - return array ? assocHas(array, key) : data.map.has(key); + return this.__data__.has(key); } /** @@ -37730,21 +37999,11 @@ return jQuery; * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { - var data = this.__data__, - array = data.array; - - if (array) { - if (array.length < (LARGE_ARRAY_SIZE - 1)) { - assocSet(array, key, value); - } else { - data.array = null; - data.map = new MapCache(array); - } - } - var map = data.map; - if (map) { - map.set(key, value); + var cache = this.__data__; + if (cache instanceof ListCache && cache.__data__.length == LARGE_ARRAY_SIZE) { + cache = this.__data__ = new MapCache(cache.__data__); } + cache.set(key, value); return this; } @@ -37757,90 +38016,6 @@ return jQuery; /*------------------------------------------------------------------------*/ - /** - * Removes `key` and its value from the associative array. - * - * @private - * @param {Array} array The array to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function assocDelete(array, key) { - var index = assocIndexOf(array, key); - if (index < 0) { - return false; - } - var lastIndex = array.length - 1; - if (index == lastIndex) { - array.pop(); - } else { - splice.call(array, index, 1); - } - return true; - } - - /** - * Gets the associative array value for `key`. - * - * @private - * @param {Array} array The array to query. - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function assocGet(array, key) { - var index = assocIndexOf(array, key); - return index < 0 ? undefined : array[index][1]; - } - - /** - * Checks if an associative array value for `key` exists. - * - * @private - * @param {Array} array The array to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function assocHas(array, key) { - return assocIndexOf(array, key) > -1; - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to search. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** - * Sets the associative array `key` to `value`. - * - * @private - * @param {Array} array The array to modify. - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - */ - function assocSet(array, key, value) { - var index = assocIndexOf(array, key); - if (index < 0) { - array.push([key, value]); - } else { - array[index][1] = value; - } - } - - /*------------------------------------------------------------------------*/ - /** * Used by `_.defaults` to customize its `_.assignIn` use. * @@ -37893,6 +38068,24 @@ return jQuery; } } + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + /** * Aggregates elements of `collection` on `accumulator` with keys transformed * by `iteratee` and values set by `setter`. @@ -37930,7 +38123,7 @@ return jQuery; * @private * @param {Object} object The object to iterate over. * @param {string[]} paths The property paths of elements to pick. - * @returns {Array} Returns the new array of picked elements. + * @returns {Array} Returns the picked elements. */ function baseAt(object, paths) { var index = -1, @@ -38045,7 +38238,7 @@ return jQuery; * * @private * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. */ function baseConforms(source) { var props = keys(source), @@ -38358,7 +38551,7 @@ return jQuery; * @private * @param {Object} object The object to inspect. * @param {Array} props The property names to filter. - * @returns {Array} Returns the new array of filtered property names. + * @returns {Array} Returns the function names. */ function baseFunctions(object, props) { return arrayFilter(props, function(key) { @@ -38399,9 +38592,7 @@ return jQuery; */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); - return isArray(object) - ? result - : arrayPush(result, symbolsFunc(object)); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } /** @@ -38421,7 +38612,7 @@ return jQuery; * The base implementation of `_.has` without support for deep paths. * * @private - * @param {Object} object The object to query. + * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ @@ -38429,20 +38620,21 @@ return jQuery; // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, // that are composed entirely of index properties, return `false` for // `hasOwnProperty` checks of them. - return hasOwnProperty.call(object, key) || - (typeof object == 'object' && key in object && getPrototype(object) === null); + return object != null && + (hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototype(object) === null)); } /** * The base implementation of `_.hasIn` without support for deep paths. * * @private - * @param {Object} object The object to query. + * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHasIn(object, key) { - return key in Object(object); + return object != null && key in Object(object); } /** @@ -38696,6 +38888,22 @@ return jQuery; return true; } + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + /** * The base implementation of `_.iteratee`. * @@ -38793,7 +39001,7 @@ return jQuery; * * @private * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. */ function baseMatches(source) { var matchData = getMatchData(source); @@ -38811,7 +39019,7 @@ return jQuery; * @private * @param {string} path The path of the property to get. * @param {*} srcValue The value to match. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { @@ -39026,7 +39234,7 @@ return jQuery; * * @private * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { @@ -39039,7 +39247,7 @@ return jQuery; * * @private * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new accessor function. */ function basePropertyDeep(path) { return function(object) { @@ -39064,6 +39272,9 @@ return jQuery; length = values.length, seen = array; + if (array === values) { + values = copyArray(values); + } if (iteratee) { seen = arrayMap(array, baseUnary(iteratee)); } @@ -39140,7 +39351,7 @@ return jQuery; * @param {number} end The end of the range. * @param {number} step The value to increment or decrement by. * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the new array of numbers. + * @returns {Array} Returns the range of numbers. */ function baseRange(start, end, step, fromRight) { var index = -1, @@ -39854,7 +40065,7 @@ return jQuery; * placeholders, and provided arguments into a single array of arguments. * * @private - * @param {Array|Object} args The provided arguments. + * @param {Array} args The provided arguments. * @param {Array} partials The arguments to prepend to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. @@ -39889,7 +40100,7 @@ return jQuery; * is tailored for `_.partialRight`. * * @private - * @param {Array|Object} args The provided arguments. + * @param {Array} args The provided arguments. * @param {Array} partials The arguments to append to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. @@ -40011,7 +40222,7 @@ return jQuery; customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; - customizer = typeof customizer == 'function' + customizer = (assigner.length > 3 && typeof customizer == 'function') ? (length--, customizer) : undefined; @@ -40110,7 +40321,7 @@ return jQuery; * * @private * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new case function. */ function createCaseFirst(methodName) { return function(string) { @@ -40195,7 +40406,7 @@ return jQuery; var length = arguments.length, args = Array(length), index = length, - placeholder = getPlaceholder(wrapper); + placeholder = getHolder(wrapper); while (index--) { args[index] = arguments[index]; @@ -40216,6 +40427,31 @@ return jQuery; return wrapper; } + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + predicate = getIteratee(predicate, 3); + if (!isArrayLike(collection)) { + var props = keys(collection); + } + var index = findIndexFunc(props || collection, function(value, key) { + if (props) { + key = value; + value = iterable[key]; + } + return predicate(value, key, iterable); + }, fromIndex); + return index > -1 ? collection[props ? props[index] : index] : undefined; + }; + } + /** * Creates a `_.flow` or `_.flowRight` function. * @@ -40310,14 +40546,14 @@ return jQuery; function wrapper() { var length = arguments.length, - index = length, - args = Array(length); + args = Array(length), + index = length; while (index--) { args[index] = arguments[index]; } if (isCurried) { - var placeholder = getPlaceholder(wrapper), + var placeholder = getHolder(wrapper), holdersCount = countHolders(args, placeholder); } if (partials) { @@ -40406,7 +40642,7 @@ return jQuery; * * @private * @param {Function} arrayFunc The function to iterate over iteratees. - * @returns {Function} Returns the new invoker function. + * @returns {Function} Returns the new over function. */ function createOver(arrayFunc) { return rest(function(iteratees) { @@ -40579,7 +40815,7 @@ return jQuery; var func = Math[methodName]; return function(number, precision) { number = toNumber(number); - precision = toInteger(precision); + precision = nativeMin(toInteger(precision), 292); if (precision) { // Shift with exponential notation to avoid floating-point issues. // See [MDN](https://mdn.io/round#Examples) for more details. @@ -40604,6 +40840,26 @@ return jQuery; return new Set(values); }; + /** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ + function createToPairs(keysFunc) { + return function(object) { + var tag = getTag(object); + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } + return baseToPairs(object, keysFunc(object)); + }; + } + /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. @@ -40621,6 +40877,7 @@ return jQuery; * 64 - `_.partialRight` * 128 - `_.rearg` * 256 - `_.ary` + * 512 - `_.flip` * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to be partially applied. * @param {Array} [holders] The `partials` placeholder indexes. @@ -40699,9 +40956,7 @@ return jQuery; * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { - var index = -1, - isPartial = bitmask & PARTIAL_COMPARE_FLAG, - isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, arrLength = array.length, othLength = other.length; @@ -40713,7 +40968,10 @@ return jQuery; if (stacked) { return stacked == other; } - var result = true; + var index = -1, + result = true, + seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined; + stack.set(array, other); // Ignore non-index properties. @@ -40734,10 +40992,12 @@ return jQuery; break; } // Recursively compare arrays (susceptible to call stack limits). - if (isUnordered) { - if (!arraySome(other, function(othValue) { - return arrValue === othValue || - equalFunc(arrValue, othValue, customizer, bitmask, stack); + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!seen.has(othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + return seen.add(othIndex); + } })) { result = false; break; @@ -40971,6 +41231,18 @@ return jQuery; return result; } + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + /** * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, * this function returns the custom method, otherwise it returns `baseIteratee`. @@ -41001,6 +41273,21 @@ return jQuery; */ var getLength = baseProperty('length'); + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + /** * Gets the property names, values, and compare flags of `object`. * @@ -41009,11 +41296,14 @@ return jQuery; * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { - var result = toPairs(object), + var result = keys(object), length = result.length; while (length--) { - result[length][2] = isStrictComparable(result[length][1]); + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; } return result; } @@ -41027,20 +41317,8 @@ return jQuery; * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { - var value = object[key]; - return isNative(value) ? value : undefined; - } - - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getPlaceholder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; } /** @@ -41069,9 +41347,7 @@ return jQuery; // Fallback for IE < 11. if (!getOwnPropertySymbols) { - getSymbols = function() { - return []; - }; + getSymbols = stubArray; } /** @@ -41292,7 +41568,7 @@ return jQuery; * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. */ function isFlattenable(value) { - return isArrayLikeObject(value) && (isArray(value) || isArguments(value)); + return isArray(value) || isArguments(value); } /** @@ -41403,6 +41679,26 @@ return jQuery; return !!data && func === data[0]; } + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ + var isMaskable = coreJsData ? isFunction : stubFalse; + /** * Checks if `value` is likely a prototype object. * @@ -41436,7 +41732,7 @@ return jQuery; * @private * @param {string} key The key of the property to get. * @param {*} srcValue The value to match. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. */ function matchesStrictComparable(key, srcValue) { return function(object) { @@ -41688,7 +41984,7 @@ return jQuery; * @param {Array} array The array to process. * @param {number} [size=1] The length of each chunk * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array containing chunks. + * @returns {Array} Returns the new array of chunks. * @example * * _.chunk(['a', 'b', 'c', 'd'], 2); @@ -41771,16 +42067,16 @@ return jQuery; */ function concat() { var length = arguments.length, - array = castArray(arguments[0]); + args = Array(length ? length - 1 : 0), + array = arguments[0], + index = length; - if (length < 2) { - return length ? copyArray(array) : []; + while (index--) { + args[index - 1] = arguments[index]; } - var args = Array(length - 1); - while (length--) { - args[length - 1] = arguments[length]; - } - return arrayConcat(array, baseFlatten(args, 1)); + return length + ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)) + : []; } /** @@ -41799,8 +42095,8 @@ return jQuery; * @see _.without, _.xor * @example * - * _.difference([3, 2, 1], [4, 2]); - * // => [3, 1] + * _.difference([2, 1], [2, 3]); + * // => [1] */ var difference = rest(function(array, values) { return isArrayLikeObject(array) @@ -41825,8 +42121,8 @@ return jQuery; * @returns {Array} Returns the new array of filtered values. * @example * - * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); - * // => [3.1, 1.3] + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] * * // The `_.property` iteratee shorthand. * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); @@ -42078,6 +42374,7 @@ return jQuery; * @param {Array} array The array to search. * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * @@ -42102,10 +42399,16 @@ return jQuery; * _.findIndex(users, 'active'); * // => 2 */ - function findIndex(array, predicate) { - return (array && array.length) - ? baseFindIndex(array, getIteratee(predicate, 3)) - : -1; + function findIndex(array, predicate, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, getIteratee(predicate, 3), index); } /** @@ -42119,6 +42422,7 @@ return jQuery; * @param {Array} array The array to search. * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * @@ -42143,10 +42447,19 @@ return jQuery; * _.findLastIndex(users, 'active'); * // => 0 */ - function findLastIndex(array, predicate) { - return (array && array.length) - ? baseFindIndex(array, getIteratee(predicate, 3), true) - : -1; + function findLastIndex(array, predicate, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, getIteratee(predicate, 3), index, true); } /** @@ -42293,11 +42606,11 @@ return jQuery; if (!length) { return -1; } - fromIndex = toInteger(fromIndex); - if (fromIndex < 0) { - fromIndex = nativeMax(length + fromIndex, 0); + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); } - return baseIndexOf(array, value, fromIndex); + return baseIndexOf(array, value, index); } /** @@ -42332,7 +42645,7 @@ return jQuery; * @returns {Array} Returns the new array of intersecting values. * @example * - * _.intersection([2, 1], [4, 2], [1, 2]); + * _.intersection([2, 1], [2, 3]); * // => [2] */ var intersection = rest(function(arrays) { @@ -42358,7 +42671,7 @@ return jQuery; * @returns {Array} Returns the new array of intersecting values. * @example * - * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [2.1] * * // The `_.property` iteratee shorthand. @@ -42488,7 +42801,7 @@ return jQuery; ) + 1; } if (value !== value) { - return indexOfNaN(array, index, true); + return indexOfNaN(array, index - 1, true); } while (index--) { if (array[index] === value) { @@ -42499,8 +42812,8 @@ return jQuery; } /** - * Gets the nth element of `array`. If `n` is negative, the nth element - * from the end is returned. + * Gets the element at index `n` of `array`. If `n` is negative, the nth + * element from the end is returned. * * @static * @memberOf _ @@ -42540,11 +42853,11 @@ return jQuery; * @returns {Array} Returns `array`. * @example * - * var array = [1, 2, 3, 1, 2, 3]; + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * - * _.pull(array, 2, 3); + * _.pull(array, 'a', 'c'); * console.log(array); - * // => [1, 1] + * // => ['b', 'b'] */ var pull = rest(pullAll); @@ -42562,11 +42875,11 @@ return jQuery; * @returns {Array} Returns `array`. * @example * - * var array = [1, 2, 3, 1, 2, 3]; + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * - * _.pullAll(array, [2, 3]); + * _.pullAll(array, ['a', 'c']); * console.log(array); - * // => [1, 1] + * // => ['b', 'b'] */ function pullAll(array, values) { return (array && array.length && values && values.length) @@ -42648,14 +42961,14 @@ return jQuery; * @returns {Array} Returns the new array of removed elements. * @example * - * var array = [5, 10, 15, 20]; - * var evens = _.pullAt(array, 1, 3); + * var array = ['a', 'b', 'c', 'd']; + * var pulled = _.pullAt(array, [1, 3]); * * console.log(array); - * // => [5, 15] + * // => ['a', 'c'] * - * console.log(evens); - * // => [10, 20] + * console.log(pulled); + * // => ['b', 'd'] */ var pullAt = rest(function(array, indexes) { indexes = baseFlatten(indexes, 1); @@ -42795,9 +43108,6 @@ return jQuery; * * _.sortedIndex([30, 50], 40); * // => 1 - * - * _.sortedIndex([4, 5], 4); - * // => 0 */ function sortedIndex(array, value) { return baseSortedIndex(array, value); @@ -42820,13 +43130,13 @@ return jQuery; * into `array`. * @example * - * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; + * var objects = [{ 'x': 4 }, { 'x': 5 }]; * - * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); - * // => 1 + * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 0 * * // The `_.property` iteratee shorthand. - * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); * // => 0 */ function sortedIndexBy(array, value, iteratee) { @@ -42846,8 +43156,8 @@ return jQuery; * @returns {number} Returns the index of the matched value, else `-1`. * @example * - * _.sortedIndexOf([1, 1, 2, 2], 2); - * // => 2 + * _.sortedIndexOf([4, 5, 5, 5, 6], 5); + * // => 1 */ function sortedIndexOf(array, value) { var length = array ? array.length : 0; @@ -42875,8 +43185,8 @@ return jQuery; * into `array`. * @example * - * _.sortedLastIndex([4, 5], 4); - * // => 1 + * _.sortedLastIndex([4, 5, 5, 5, 6], 5); + * // => 4 */ function sortedLastIndex(array, value) { return baseSortedIndex(array, value, true); @@ -42899,8 +43209,13 @@ return jQuery; * into `array`. * @example * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 1 + * * // The `_.property` iteratee shorthand. - * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); * // => 1 */ function sortedLastIndexBy(array, value, iteratee) { @@ -42920,7 +43235,7 @@ return jQuery; * @returns {number} Returns the index of the matched value, else `-1`. * @example * - * _.sortedLastIndexOf([1, 1, 2, 2], 2); + * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); * // => 3 */ function sortedLastIndexOf(array, value) { @@ -43160,8 +43475,8 @@ return jQuery; * @returns {Array} Returns the new array of combined values. * @example * - * _.union([2, 1], [4, 2], [1, 2]); - * // => [2, 1, 4] + * _.union([2], [1, 2]); + * // => [2, 1] */ var union = rest(function(arrays) { return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); @@ -43183,8 +43498,8 @@ return jQuery; * @returns {Array} Returns the new array of combined values. * @example * - * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); - * // => [2.1, 1.2, 4.3] + * _.unionBy([2.1], [1.2, 2.3], Math.floor); + * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); @@ -43291,7 +43606,7 @@ return jQuery; * @returns {Array} Returns the new duplicate free array. * @example * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.uniqWith(objects, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] @@ -43380,13 +43695,13 @@ return jQuery; * @memberOf _ * @since 0.1.0 * @category Array - * @param {Array} array The array to filter. + * @param {Array} array The array to inspect. * @param {...*} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.xor * @example * - * _.without([1, 2, 1, 3], 1, 2); + * _.without([2, 1, 2, 3], 1, 2); * // => [3] */ var without = rest(function(array, values) { @@ -43406,12 +43721,12 @@ return jQuery; * @since 2.4.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of values. + * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.without * @example * - * _.xor([2, 1], [4, 2]); - * // => [1, 4] + * _.xor([2, 1], [2, 3]); + * // => [1, 3] */ var xor = rest(function(arrays) { return baseXor(arrayFilter(arrays, isArrayLikeObject)); @@ -43430,11 +43745,11 @@ return jQuery; * @param {...Array} [arrays] The arrays to inspect. * @param {Array|Function|Object|string} [iteratee=_.identity] * The iteratee invoked per element. - * @returns {Array} Returns the new array of values. + * @returns {Array} Returns the new array of filtered values. * @example * - * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); - * // => [1.2, 4.3] + * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2, 3.4] * * // The `_.property` iteratee shorthand. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); @@ -43459,7 +43774,7 @@ return jQuery; * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of values. + * @returns {Array} Returns the new array of filtered values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; @@ -43667,9 +43982,6 @@ return jQuery; * * _(object).at(['a[0].b.c', 'a[1]']).value(); * // => [3, 4] - * - * _(['a', 'b', 'c']).at(0, 2).value(); - * // => ['a', 'c'] */ var wrapperAt = rest(function(paths) { paths = baseFlatten(paths, 1); @@ -43932,6 +44244,7 @@ return jQuery; * _.countBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': 1, '6': 2 } * + * // The `_.property` iteratee shorthand. * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ @@ -44037,6 +44350,7 @@ return jQuery; * @param {Array|Object} collection The collection to search. * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * @@ -44061,14 +44375,7 @@ return jQuery; * _.find(users, 'active'); * // => object for 'barney' */ - function find(collection, predicate) { - predicate = getIteratee(predicate, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, baseEach); - } + var find = createFind(findIndex); /** * This method is like `_.find` except that it iterates over elements of @@ -44081,6 +44388,7 @@ return jQuery; * @param {Array|Object} collection The collection to search. * @param {Array|Function|Object|string} [predicate=_.identity] * The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * @@ -44089,14 +44397,7 @@ return jQuery; * }); * // => 3 */ - function findLast(collection, predicate) { - predicate = getIteratee(predicate, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate, true); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, baseEachRight); - } + var findLast = createFind(findLastIndex); /** * Creates a flattened array of values by running each element in `collection` @@ -44207,9 +44508,8 @@ return jQuery; * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forEach(collection, iteratee) { - return (typeof iteratee == 'function' && isArray(collection)) - ? arrayEach(collection, iteratee) - : baseEach(collection, getIteratee(iteratee)); + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, getIteratee(iteratee, 3)); } /** @@ -44233,9 +44533,8 @@ return jQuery; * // => Logs `2` then `1`. */ function forEachRight(collection, iteratee) { - return (typeof iteratee == 'function' && isArray(collection)) - ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, getIteratee(iteratee)); + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, getIteratee(iteratee, 3)); } /** @@ -44855,7 +45154,6 @@ return jQuery; * @static * @memberOf _ * @since 2.4.0 - * @type {Function} * @category Date * @returns {number} Returns the timestamp. * @example @@ -44863,9 +45161,11 @@ return jQuery; * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred function to be invoked. + * // => Logs the number of milliseconds it took for the deferred invocation. */ - var now = Date.now; + function now() { + return Date.now(); + } /*------------------------------------------------------------------------*/ @@ -44916,7 +45216,7 @@ return jQuery; * @param {Function} func The function to cap arguments for. * @param {number} [n=func.length] The arity cap. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.ary(parseInt, 1)); @@ -44969,7 +45269,7 @@ return jQuery; * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for partially applied arguments. * - * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" * property of bound functions. * * @static @@ -45000,7 +45300,7 @@ return jQuery; var bind = rest(function(func, thisArg, partials) { var bitmask = BIND_FLAG; if (partials.length) { - var holders = replaceHolders(partials, getPlaceholder(bind)); + var holders = replaceHolders(partials, getHolder(bind)); bitmask |= PARTIAL_FLAG; } return createWrapper(func, bitmask, thisArg, partials, holders); @@ -45054,7 +45354,7 @@ return jQuery; var bindKey = rest(function(object, key, partials) { var bitmask = BIND_FLAG | BIND_KEY_FLAG; if (partials.length) { - var holders = replaceHolders(partials, getPlaceholder(bindKey)); + var holders = replaceHolders(partials, getHolder(bindKey)); bitmask |= PARTIAL_FLAG; } return createWrapper(key, bitmask, object, partials, holders); @@ -45209,7 +45509,7 @@ return jQuery; maxWait, result, timerId, - lastCallTime = 0, + lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, @@ -45260,7 +45560,7 @@ return jQuery; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. - return (!lastCallTime || (timeSinceLastCall >= wait) || + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } @@ -45274,7 +45574,6 @@ return jQuery; } function trailingEdge(time) { - clearTimeout(timerId); timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been @@ -45287,11 +45586,8 @@ return jQuery; } function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastCallTime = lastInvokeTime = 0; - lastArgs = lastThis = timerId = undefined; + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { @@ -45312,7 +45608,6 @@ return jQuery; } if (maxing) { // Handle invocations in a tight loop. - clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } @@ -45380,7 +45675,7 @@ return jQuery; * @since 4.0.0 * @category Function * @param {Function} func The function to flip arguments for. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new flipped function. * @example * * var flipped = _.flip(function() { @@ -45413,7 +45708,7 @@ return jQuery; * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoizing function. + * @returns {Function} Returns the new memoized function. * @example * * var object = { 'a': 1, 'b': 2 }; @@ -45471,7 +45766,7 @@ return jQuery; * @since 3.0.0 * @category Function * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new negated function. * @example * * function isEven(n) { @@ -45536,7 +45831,7 @@ return jQuery; * * var func = _.overArgs(function(x, y) { * return [x, y]; - * }, square, doubled); + * }, [square, doubled]); * * func(9, 3); * // => [81, 6] @@ -45595,7 +45890,7 @@ return jQuery; * // => 'hi fred' */ var partial = rest(function(func, partials) { - var holders = replaceHolders(partials, getPlaceholder(partial)); + var holders = replaceHolders(partials, getHolder(partial)); return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders); }); @@ -45632,7 +45927,7 @@ return jQuery; * // => 'hello fred' */ var partialRight = rest(function(func, partials) { - var holders = replaceHolders(partials, getPlaceholder(partialRight)); + var holders = replaceHolders(partials, getHolder(partialRight)); return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); }); @@ -45653,7 +45948,7 @@ return jQuery; * * var rearged = _.rearg(function(a, b, c) { * return [a, b, c]; - * }, 2, 0, 1); + * }, [2, 0, 1]); * * rearged('b', 'c', 'a') * // => ['a', 'b', 'c'] @@ -45834,7 +46129,7 @@ return jQuery; * @since 4.0.0 * @category Function * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.unary(parseInt)); @@ -46292,7 +46587,7 @@ return jQuery; * _.isBuffer(new Uint8Array(2)); * // => false */ - var isBuffer = !Buffer ? constant(false) : function(value) { + var isBuffer = !Buffer ? stubFalse : function(value) { return value instanceof Buffer; }; @@ -46510,14 +46805,14 @@ return jQuery; * _.isFinite(3); * // => true * - * _.isFinite(Number.MAX_VALUE); - * // => true - * - * _.isFinite(3.14); + * _.isFinite(Number.MIN_VALUE); * // => true * * _.isFinite(Infinity); * // => false + * + * _.isFinite('3'); + * // => false */ function isFinite(value) { return typeof value == 'number' && nativeIsFinite(value); @@ -46792,7 +47087,15 @@ return jQuery; } /** - * Checks if `value` is a native function. + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the + * presence of the `core-js` package because `core-js` circumvents this kind + * of detection. Despite multiple requests, the `core-js` maintainer has made + * it clear: any attempt to fix the detection will be obstructed. As a result, + * we're left with little choice but to throw an error. Unfortunately, this + * also affects packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on `core-js`. * * @static * @memberOf _ @@ -46810,11 +47113,10 @@ return jQuery; * // => false */ function isNative(value) { - if (!isObject(value)) { - return false; + if (isMaskable(value)) { + throw new Error('This method is not supported with `core-js`. Try https://github.com/es-shims.'); } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return baseIsNative(value); } /** @@ -47238,10 +47540,45 @@ return jQuery; return func(value); } + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + /** * Converts `value` to an integer. * - * **Note:** This function is loosely based on + * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). * * @static @@ -47252,7 +47589,7 @@ return jQuery; * @returns {number} Returns the converted integer. * @example * - * _.toInteger(3); + * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); @@ -47261,20 +47598,14 @@ return jQuery; * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * - * _.toInteger('3'); + * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - var remainder = value % 1; - return value === value ? (remainder ? value - remainder : value) : 0; + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; } /** @@ -47292,7 +47623,7 @@ return jQuery; * @returns {number} Returns the converted integer. * @example * - * _.toLength(3); + * _.toLength(3.2); * // => 3 * * _.toLength(Number.MIN_VALUE); @@ -47301,7 +47632,7 @@ return jQuery; * _.toLength(Infinity); * // => 4294967295 * - * _.toLength('3'); + * _.toLength('3.2'); * // => 3 */ function toLength(value) { @@ -47319,8 +47650,8 @@ return jQuery; * @returns {number} Returns the number. * @example * - * _.toNumber(3); - * // => 3 + * _.toNumber(3.2); + * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 @@ -47328,8 +47659,8 @@ return jQuery; * _.toNumber(Infinity); * // => Infinity * - * _.toNumber('3'); - * // => 3 + * _.toNumber('3.2'); + * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { @@ -47392,7 +47723,7 @@ return jQuery; * @returns {number} Returns the converted integer. * @example * - * _.toSafeInteger(3); + * _.toSafeInteger(3.2); * // => 3 * * _.toSafeInteger(Number.MIN_VALUE); @@ -47401,7 +47732,7 @@ return jQuery; * _.toSafeInteger(Infinity); * // => 9007199254740991 * - * _.toSafeInteger('3'); + * _.toSafeInteger('3.2'); * // => 3 */ function toSafeInteger(value) { @@ -47594,16 +47925,13 @@ return jQuery; * @category Object * @param {Object} object The object to iterate over. * @param {...(string|string[])} [paths] The property paths of elements to pick. - * @returns {Array} Returns the new array of picked elements. + * @returns {Array} Returns the picked values. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; * * _.at(object, ['a[0].b.c', 'a[1]']); * // => [3, 4] - * - * _.at(['a', 'b', 'c'], 0, 2); - * // => ['a', 'c'] */ var at = rest(function(object, paths) { return baseAt(object, baseFlatten(paths, 1)); @@ -47736,7 +48064,7 @@ return jQuery; * // => 'barney' */ function findKey(object, predicate) { - return baseFind(object, getIteratee(predicate, 3), baseForOwn, true); + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); } /** @@ -47776,7 +48104,7 @@ return jQuery; * // => 'pebbles' */ function findLastKey(object, predicate) { - return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); } /** @@ -47810,7 +48138,7 @@ return jQuery; function forIn(object, iteratee) { return object == null ? object - : baseFor(object, getIteratee(iteratee), keysIn); + : baseFor(object, getIteratee(iteratee, 3), keysIn); } /** @@ -47842,7 +48170,7 @@ return jQuery; function forInRight(object, iteratee) { return object == null ? object - : baseForRight(object, getIteratee(iteratee), keysIn); + : baseForRight(object, getIteratee(iteratee, 3), keysIn); } /** @@ -47874,7 +48202,7 @@ return jQuery; * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forOwn(object, iteratee) { - return object && baseForOwn(object, getIteratee(iteratee)); + return object && baseForOwn(object, getIteratee(iteratee, 3)); } /** @@ -47904,7 +48232,7 @@ return jQuery; * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. */ function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, getIteratee(iteratee)); + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); } /** @@ -47916,7 +48244,7 @@ return jQuery; * @memberOf _ * @category Object * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of property names. + * @returns {Array} Returns the function names. * @see _.functionsIn * @example * @@ -47943,7 +48271,7 @@ return jQuery; * @since 4.0.0 * @category Object * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of property names. + * @returns {Array} Returns the function names. * @see _.functions * @example * @@ -48296,7 +48624,7 @@ return jQuery; * inherited enumerable string keyed properties of source objects into the * destination object. Source properties that resolve to `undefined` are * skipped if a destination value exists. Array and plain object properties - * are merged recursively.Other objects and value types are overridden by + * are merged recursively. Other objects and value types are overridden by * assignment. Source objects are applied from left to right. Subsequent * sources overwrite property assignments of previous sources. * @@ -48581,7 +48909,8 @@ return jQuery; /** * Creates an array of own enumerable string keyed-value pairs for `object` - * which can be consumed by `_.fromPairs`. + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. * * @static * @memberOf _ @@ -48589,7 +48918,7 @@ return jQuery; * @alias entries * @category Object * @param {Object} object The object to query. - * @returns {Array} Returns the new array of key-value pairs. + * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { @@ -48602,13 +48931,12 @@ return jQuery; * _.toPairs(new Foo); * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) */ - function toPairs(object) { - return baseToPairs(object, keys(object)); - } + var toPairs = createToPairs(keys); /** * Creates an array of own and inherited enumerable string keyed-value pairs - * for `object` which can be consumed by `_.fromPairs`. + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. * * @static * @memberOf _ @@ -48616,7 +48944,7 @@ return jQuery; * @alias entriesIn * @category Object * @param {Object} object The object to query. - * @returns {Array} Returns the new array of key-value pairs. + * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { @@ -48627,25 +48955,24 @@ return jQuery; * Foo.prototype.c = 3; * * _.toPairsIn(new Foo); - * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) */ - function toPairsIn(object) { - return baseToPairs(object, keysIn(object)); - } + var toPairsIn = createToPairs(keysIn); /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. The iteratee is invoked - * with four arguments: (accumulator, value, key, object). Iteratee functions - * may exit iteration early by explicitly returning `false`. + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 1.3.0 * @category Object - * @param {Array|Object} object The object to iterate over. + * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The custom accumulator value. * @returns {*} Returns the accumulated value. @@ -49067,7 +49394,7 @@ return jQuery; * @category String * @param {string} [string=''] The string to search. * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search from. + * @param {number} [position=string.length] The position to search up to. * @returns {boolean} Returns `true` if `string` ends with `target`, * else `false`. * @example @@ -49461,7 +49788,7 @@ return jQuery; * @param {string} [string=''] The string to split. * @param {RegExp|string} separator The separator pattern to split by. * @param {number} [limit] The length to truncate results to. - * @returns {Array} Returns the new array of string segments. + * @returns {Array} Returns the string segments. * @example * * _.split('a-b-c', '-', 2); @@ -49606,12 +49933,6 @@ return jQuery; * compiled({ 'user': 'pebbles' }); * // => 'hello pebbles!' * - * // Use custom template delimiters. - * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; - * var compiled = _.template('hello {{ user }}!'); - * compiled({ 'user': 'mustache' }); - * // => 'hello mustache!' - * * // Use backslashes to treat delimiters as plain text. * var compiled = _.template('<%= "\\<%- value %\\>" %>'); * compiled({ 'value': 'ignored' }); @@ -49637,9 +49958,15 @@ return jQuery; * // return __p; * // } * + * // Use custom template delimiters. + * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; + * var compiled = _.template('hello {{ user }}!'); + * compiled({ 'user': 'mustache' }); + * // => 'hello mustache!' + * * // Use the `source` property to inline compiled templates for meaningful * // line numbers in error messages and stack traces. - * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ + * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\ * var JST = {\ * "main": ' + _.template(mainText).source + '\ * };\ @@ -50152,7 +50479,7 @@ return jQuery; * } * }; * - * _.bindAll(view, 'onClick'); + * _.bindAll(view, ['onClick']); * jQuery(element).on('click', view.onClick); * // => Logs 'clicked docs' when clicked. */ @@ -50175,7 +50502,7 @@ return jQuery; * @since 4.0.0 * @category Util * @param {Array} pairs The predicate-function pairs. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new composite function. * @example * * var func = _.cond([ @@ -50225,7 +50552,7 @@ return jQuery; * @since 4.0.0 * @category Util * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. * @example * * var users = [ @@ -50233,7 +50560,7 @@ return jQuery; * { 'user': 'fred', 'age': 40 } * ]; * - * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); + * _.filter(users, _.conforms({ 'age': function(n) { return n > 38; } })); * // => [{ 'user': 'fred', 'age': 40 }] */ function conforms(source) { @@ -50248,13 +50575,15 @@ return jQuery; * @since 2.4.0 * @category Util * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new constant function. * @example * - * var object = { 'user': 'fred' }; - * var getter = _.constant(object); + * var objects = _.times(2, _.constant({ 'a': 1 })); * - * getter() === object; + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); * // => true */ function constant(value) { @@ -50273,7 +50602,7 @@ return jQuery; * @since 3.0.0 * @category Util * @param {...(Function|Function[])} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new composite function. * @see _.flowRight * @example * @@ -50281,7 +50610,7 @@ return jQuery; * return n * n; * } * - * var addSquare = _.flow(_.add, square); + * var addSquare = _.flow([_.add, square]); * addSquare(1, 2); * // => 9 */ @@ -50296,7 +50625,7 @@ return jQuery; * @memberOf _ * @category Util * @param {...(Function|Function[])} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new composite function. * @see _.flow * @example * @@ -50304,7 +50633,7 @@ return jQuery; * return n * n; * } * - * var addSquare = _.flowRight(square, _.add); + * var addSquare = _.flowRight([square, _.add]); * addSquare(1, 2); * // => 9 */ @@ -50323,7 +50652,7 @@ return jQuery; * * var object = { 'user': 'fred' }; * - * _.identity(object) === object; + * console.log(_.identity(object) === object); * // => true */ function identity(value) { @@ -50389,7 +50718,7 @@ return jQuery; * @since 3.0.0 * @category Util * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. * @example * * var users = [ @@ -50417,7 +50746,7 @@ return jQuery; * @category Util * @param {Array|string} path The path of the property to get. * @param {*} srcValue The value to match. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new spec function. * @example * * var users = [ @@ -50442,7 +50771,7 @@ return jQuery; * @category Util * @param {Array|string} path The path of the method to invoke. * @param {...*} [args] The arguments to invoke the method with. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new invoker function. * @example * * var objects = [ @@ -50473,7 +50802,7 @@ return jQuery; * @category Util * @param {Object} object The object to query. * @param {...*} [args] The arguments to invoke the method with. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new invoker function. * @example * * var array = _.times(3, _.constant), @@ -50584,8 +50913,7 @@ return jQuery; } /** - * A no-operation function that returns `undefined` regardless of the - * arguments it receives. + * A method that returns `undefined`. * * @static * @memberOf _ @@ -50593,17 +50921,15 @@ return jQuery; * @category Util * @example * - * var object = { 'user': 'fred' }; - * - * _.noop(object) === undefined; - * // => true + * _.times(2, _.noop); + * // => [undefined, undefined] */ function noop() { // No operation performed. } /** - * Creates a function that returns its nth argument. If `n` is negative, + * Creates a function that gets the argument at index `n`. If `n` is negative, * the nth argument from the end is returned. * * @static @@ -50611,7 +50937,7 @@ return jQuery; * @since 4.0.0 * @category Util * @param {number} [n=0] The index of the argument to return. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new pass-thru function. * @example * * var func = _.nthArg(1); @@ -50642,7 +50968,7 @@ return jQuery; * @returns {Function} Returns the new function. * @example * - * var func = _.over(Math.max, Math.min); + * var func = _.over([Math.max, Math.min]); * * func(1, 2, 3, 4); * // => [4, 1] @@ -50662,7 +50988,7 @@ return jQuery; * @returns {Function} Returns the new function. * @example * - * var func = _.overEvery(Boolean, isFinite); + * var func = _.overEvery([Boolean, isFinite]); * * func('1'); * // => true @@ -50688,7 +51014,7 @@ return jQuery; * @returns {Function} Returns the new function. * @example * - * var func = _.overSome(Boolean, isFinite); + * var func = _.overSome([Boolean, isFinite]); * * func('1'); * // => true @@ -50709,7 +51035,7 @@ return jQuery; * @since 2.4.0 * @category Util * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new accessor function. * @example * * var objects = [ @@ -50736,7 +51062,7 @@ return jQuery; * @since 3.0.0 * @category Util * @param {Object} object The object to query. - * @returns {Function} Returns the new function. + * @returns {Function} Returns the new accessor function. * @example * * var array = [0, 1, 2], @@ -50770,7 +51096,7 @@ return jQuery; * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the new array of numbers. + * @returns {Array} Returns the range of numbers. * @see _.inRange, _.rangeRight * @example * @@ -50808,7 +51134,7 @@ return jQuery; * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the new array of numbers. + * @returns {Array} Returns the range of numbers. * @see _.inRange, _.range * @example * @@ -50835,6 +51161,101 @@ return jQuery; */ var rangeRight = createRange(true); + /** + * A method that returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * A method that returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** + * A method that returns a new empty object. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Object} Returns the new empty object. + * @example + * + * var objects = _.times(2, _.stubObject); + * + * console.log(objects); + * // => [{}, {}] + * + * console.log(objects[0] === objects[1]); + * // => false + */ + function stubObject() { + return {}; + } + + /** + * A method that returns an empty string. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {string} Returns the empty string. + * @example + * + * _.times(2, _.stubString); + * // => ['', ''] + */ + function stubString() { + return ''; + } + + /** + * A method that returns `true`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `true`. + * @example + * + * _.times(2, _.stubTrue); + * // => [true, true] + */ + function stubTrue() { + return true; + } + /** * Invokes the iteratee `n` times, returning an array of the results of * each invocation. The iteratee is invoked with one argument; (index). @@ -50851,8 +51272,8 @@ return jQuery; * _.times(3, String); * // => ['0', '1', '2'] * - * _.times(4, _.constant(true)); - * // => [true, true, true, true] + * _.times(4, _.constant(0)); + * // => [0, 0, 0, 0] */ function times(n, iteratee) { n = toInteger(n); @@ -50888,15 +51309,6 @@ return jQuery; * * _.toPath('a[0].b.c'); * // => ['a', '0', 'b', 'c'] - * - * var path = ['a', 'b', 'c'], - * newPath = _.toPath(path); - * - * console.log(newPath); - * // => ['a', 'b', 'c'] - * - * console.log(path === newPath); - * // => false */ function toPath(value) { if (isArray(value)) { @@ -51535,6 +51947,11 @@ return jQuery; lodash.meanBy = meanBy; lodash.min = min; lodash.minBy = minBy; + lodash.stubArray = stubArray; + lodash.stubFalse = stubFalse; + lodash.stubObject = stubObject; + lodash.stubString = stubString; + lodash.stubTrue = stubTrue; lodash.multiply = multiply; lodash.nth = nth; lodash.noConflict = noConflict; @@ -51569,6 +51986,7 @@ return jQuery; lodash.sumBy = sumBy; lodash.template = template; lodash.times = times; + lodash.toFinite = toFinite; lodash.toInteger = toInteger; lodash.toLength = toLength; lodash.toLower = toLower; @@ -51840,7 +52258,7 @@ return jQuery; // also prevents errors in cases where Lodash is loaded by a script tag in the // presence of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch // for more details. Use `_.noConflict` to remove Lodash from the global object. - (freeWindow || freeSelf || {})._ = _; + (freeSelf || {})._ = _; // Some AMD build optimizers like r.js check for condition patterns like the following: if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { @@ -51851,11 +52269,9 @@ return jQuery; }); } // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - else if (freeExports && freeModule) { + else if (freeModule) { // Export for Node.js. - if (moduleExports) { - (freeModule.exports = _)._ = _; - } + (freeModule.exports = _)._ = _; // Export for CommonJS support. freeExports._ = _; } @@ -51872,7 +52288,7 @@ return jQuery; module.exports = require('react/lib/ReactDOM'); -},{"react/lib/ReactDOM":102}],"react-router":[function(require,module,exports){ +},{"react/lib/ReactDOM":103}],"react-router":[function(require,module,exports){ 'use strict'; exports.__esModule = true;