From e00306657e66f05b419c201e854e729f3f7fb77c Mon Sep 17 00:00:00 2001 From: Chris Blanchard Date: Sun, 26 Jul 2015 12:54:35 +0100 Subject: [PATCH] Added cool stuff --- config/socketio.js | 2 + lib/ensl/client.js | 1 + lib/react/app.jsx | 226 +- lib/user/user.js | 3 +- public/css/app.css | 4 - public/images/commander.png | Bin 0 -> 16614 bytes public/js/app.js | 224 +- public/js/react-0.13.3.js | 19602 ++++++++++++++++++++++++++++++++++ views/partials/head.hbs | 2 +- 9 files changed, 19933 insertions(+), 131 deletions(-) create mode 100644 public/images/commander.png create mode 100644 public/js/react-0.13.3.js diff --git a/config/socketio.js b/config/socketio.js index a13c348..f179d0e 100644 --- a/config/socketio.js +++ b/config/socketio.js @@ -7,6 +7,8 @@ var chatController = require("../lib/chat/controller"); var gatherController = require("../lib/gather/controller"); var userController = require("../lib/user/controller"); +var createUser = require("../spec/helpers/index.js").createUser; + module.exports = function (io) { var rootNamespace = io.of('/') diff --git a/lib/ensl/client.js b/lib/ensl/client.js index f45ee47..f2d3a34 100644 --- a/lib/ensl/client.js +++ b/lib/ensl/client.js @@ -14,6 +14,7 @@ function EnslClient (options) { EnslClient.prototype.getUserById = function (options, callback) { var id = options.id; var url = this.baseUrl + "/api/v1/users/" + id; + request({ url: url, json: true diff --git a/lib/react/app.jsx b/lib/react/app.jsx index db5bcb0..b5799a6 100644 --- a/lib/react/app.jsx +++ b/lib/react/app.jsx @@ -56,16 +56,6 @@ var UserLogin = React.createClass({ } }) -var UserLine = React.createClass({ - render: function () { - return ( -
  • - {this.props.user.username} -
  • - ); - } -}); - var UserMenu = React.createClass({ getDefaultProps: function () { return { @@ -85,7 +75,7 @@ var UserMenu = React.createClass({ render: function () { var users = this.props.users.map(function (user) { return ( - +
  • {user.username}
  • ); }); return ( @@ -128,7 +118,7 @@ var Chatroom = React.createClass({ socket.emit("message:refresh", {}); self.timer = setInterval(function () { - self.refs.messages.refreshTime(); + if (self.refs.messages) self.refs.messages.refreshTime(); }, TIMER_INTERVAL); }, @@ -243,6 +233,93 @@ var MessageBar = React.createClass({ } }); +var JoinGatherButton = React.createClass({ + joinGather: function (e) { + e.preventDefault(); + socket.emit("gather:join", {}); + }, + render: function () { + var message = this.props.buttonName || "Join Gather"; + var buttonClass = "btn btn-primary"; + if (this.props.buttonClass) { + buttonClass += " " + this.props.buttonClass; + } + return () + } +}); + +var GatherProgress = React.createClass({ + gatheringProgress: function () { + var num = this.props.gather.gatherers.length; + var den = 12; + return { + num: num, + den: den, + message: num + " / " + den + }; + }, + electionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.leaderVote) acc++; + return acc; + }, 0); + var den = 12; + return { + num: num, + den: den, + message: den - num + " more votes required" + }; + }, + selectionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.team !== "lobby") acc++; + return acc; + }, 0); + var den = 12; + + return { + num: num, + den: den, + message: num + " out of " + den + " players assigned" + }; + }, + render: function () { + var progress; + var gatherState = this.props.gather.state; + if (gatherState === 'gathering' && this.props.gather.gatherers.length) { + progress = this.gatheringProgress(); + } else if (gatherState === 'election') { + progress = this.electionProgress(); + } else if (gatherState === 'selection') { + progress = this.selectionProgress(); + } + if (progress) { + var style = { + width: Math.round((progress.num / progress.den * 100)) + "%" + }; + return ( +
    +

    Gather Progress

    +
    +
    + {progress.message} +
    +
    +
    + ); + } else { + return false; + } + } +}); + var Gather = React.createClass({ getDefaultProps: function () { return { @@ -266,93 +343,116 @@ var Gather = React.createClass({ }); }); }, - joinGather: function (e) { - e.preventDefault(); - socket.emit("gather:join", {}); + stateDescription: function () { + switch(this.props.gather.state) { + case "gathering": + return "Waiting for more gatherers"; + case "election": + return "Currently voting for team leaders"; + case "selection": + return "Waiting for leaders to picking teams"; + case "done": + return "Gather completed"; + default: + return "Initialising gather"; + } }, leaveGather: function (e) { e.preventDefault(); socket.emit("gather:leave", {}); }, + inviteToGather: function (e) { + e.preventDefault(); + }, render: function () { var joinButton; if (this.joinedGather()) { - joinButton = (); + className="btn btn-danger">Leave Gather); } else { - joinButton = (); + joinButton = (
  • ); + } + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (
  • ); } return (
    - Current Gather - {this.props.gather.gatherers.length} + NS2 Gather + {this.props.gather.gatherers.length} +
    + {this.stateDescription()}
    -
    -
    +
    - {joinButton} +
      + {inviteButton} + {joinButton} +
    ); } }); -// var GatherState = React.createClass({ -// getDefaultProps: function () { -// return { -// "state": "none" -// } -// }, -// stateDescription: function () { -// switch(this.props.date) { -// case "gathering": -// return "Waiting on more players to join" -// } -// }, -// render: function () { -//
    -//

    {this.displayState}

    -//
    -// } -// }) +var LeaderPoll = React.createClass({ + render: function () { + return ( +
    +
    + ); + } +}); var Gatherers = React.createClass({ render: function () { var gatherers = this.props.gatherers.map(function (gatherer) { var lifeforms = ( gatherer.user.ability.lifeforms.map(function (lifeform) { - return {lifeform}; + return ({lifeform}); }) ); - var division = ({gatherer.user.ability.division}) + var division = ({gatherer.user.ability.division}); + var commBadge; + if (gatherer.user.ability.commander) { + commBadge = (Commander) + } return ( - - {gatherer.user.username} - {division} - {lifeforms} + + {commBadge} + {gatherer.user.username} + {division}  + {lifeforms}  ); }) - return ( - - - - - - - - - - {gatherers} - -
    PlayerAbilityLife Forms
    - ); + if (this.props.gatherers.length) { + return ( +
    +
    +
    +
    Roster
    +
    + + + {gatherers} + +
    +
    +
    + ); + } else { + return (
    ); + } } }); diff --git a/lib/user/user.js b/lib/user/user.js index 613dab5..409e7fb 100644 --- a/lib/user/user.js +++ b/lib/user/user.js @@ -20,7 +20,8 @@ // }; this.ability = { division: "Div " + (Math.floor(Math.random() * 4) + 1), - lifeforms: [["Lerk", "Onos", "Fade"][Math.floor(Math.random() * 3)]] + lifeforms: [["Lerk", "Onos", "Fade"][Math.floor(Math.random() * 3)]], + commander: true } } diff --git a/public/css/app.css b/public/css/app.css index d9f2db1..750a8af 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -19,8 +19,4 @@ .signin { margin: 0px 10px; -} - -.gatherer-table { - padding: 20px; } \ No newline at end of file diff --git a/public/images/commander.png b/public/images/commander.png new file mode 100644 index 0000000000000000000000000000000000000000..609e602dba92d722002cc8c80f805fb21d6ceb6a GIT binary patch literal 16614 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 G`hNiUq(GPe literal 0 HcmV?d00001 diff --git a/public/js/app.js b/public/js/app.js index c3b88f7..074f30a 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -56,16 +56,6 @@ var UserLogin = React.createClass({displayName: "UserLogin", } }) -var UserLine = React.createClass({displayName: "UserLine", - render: function () { - return ( - React.createElement("li", null, - React.createElement("a", {href: "#"}, this.props.user.username) - ) - ); - } -}); - var UserMenu = React.createClass({displayName: "UserMenu", getDefaultProps: function () { return { @@ -85,7 +75,7 @@ var UserMenu = React.createClass({displayName: "UserMenu", render: function () { var users = this.props.users.map(function (user) { return ( - React.createElement(UserLine, {user: user}) + React.createElement("li", {key: user.id}, React.createElement("a", {href: "#"}, user.username)) ); }); return ( @@ -128,7 +118,7 @@ var Chatroom = React.createClass({displayName: "Chatroom", socket.emit("message:refresh", {}); self.timer = setInterval(function () { - self.refs.messages.refreshTime(); + if (self.refs.messages) self.refs.messages.refreshTime(); }, TIMER_INTERVAL); }, @@ -243,6 +233,93 @@ var MessageBar = React.createClass({displayName: "MessageBar", } }); +var JoinGatherButton = React.createClass({displayName: "JoinGatherButton", + joinGather: function (e) { + e.preventDefault(); + socket.emit("gather:join", {}); + }, + render: function () { + var message = this.props.buttonName || "Join Gather"; + var buttonClass = "btn btn-primary"; + if (this.props.buttonClass) { + buttonClass += " " + this.props.buttonClass; + } + return (React.createElement("button", { + onClick: this.joinGather, + className: buttonClass}, message)) + } +}); + +var GatherProgress = React.createClass({displayName: "GatherProgress", + gatheringProgress: function () { + var num = this.props.gather.gatherers.length; + var den = 12; + return { + num: num, + den: den, + message: num + " / " + den + }; + }, + electionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.leaderVote) acc++; + return acc; + }, 0); + var den = 12; + return { + num: num, + den: den, + message: den - num + " more votes required" + }; + }, + selectionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.team !== "lobby") acc++; + return acc; + }, 0); + var den = 12; + + return { + num: num, + den: den, + message: num + " out of " + den + " players assigned" + }; + }, + render: function () { + var progress; + var gatherState = this.props.gather.state; + if (gatherState === 'gathering' && this.props.gather.gatherers.length) { + progress = this.gatheringProgress(); + } else if (gatherState === 'election') { + progress = this.electionProgress(); + } else if (gatherState === 'selection') { + progress = this.selectionProgress(); + } + if (progress) { + var style = { + width: Math.round((progress.num / progress.den * 100)) + "%" + }; + return ( + React.createElement("div", {className: "panel-body"}, + React.createElement("p", null, "Gather Progress"), + React.createElement("div", {className: "progress"}, + React.createElement("div", {className: "progress-bar progress-bar-striped active", + "data-role": "progressbar", + "data-aria-valuenow": progress.num, + "data-aria-valuemin": "0", + "data-aria-valuemax": progress.den, + style: style}, + progress.message + ) + ) + ) + ); + } else { + return false; + } + } +}); + var Gather = React.createClass({displayName: "Gather", getDefaultProps: function () { return { @@ -266,93 +343,116 @@ var Gather = React.createClass({displayName: "Gather", }); }); }, - joinGather: function (e) { - e.preventDefault(); - socket.emit("gather:join", {}); + stateDescription: function () { + switch(this.props.gather.state) { + case "gathering": + return "Waiting for more gatherers"; + case "election": + return "Currently voting for team leaders"; + case "selection": + return "Waiting for leaders to picking teams"; + case "done": + return "Gather completed"; + default: + return "Initialising gather"; + } }, leaveGather: function (e) { e.preventDefault(); socket.emit("gather:leave", {}); }, + inviteToGather: function (e) { + e.preventDefault(); + }, render: function () { var joinButton; if (this.joinedGather()) { - joinButton = (React.createElement("button", { + joinButton = (React.createElement("li", null, React.createElement("button", { onClick: this.leaveGather, - className: "btn btn-danger"}, "Leave Gather")); + className: "btn btn-danger"}, "Leave Gather"))); } else { - joinButton = (React.createElement("button", { - onClick: this.joinGather, - className: "btn btn-primary"}, "Join Gather")); + joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); + } + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.inviteToGather, + className: "btn btn-primary"}, "Invite to Gather"))); } return ( React.createElement("div", {className: "panel panel-default"}, React.createElement("div", {className: "panel-heading"}, - "Current Gather", - React.createElement("span", {className: "badge add-left"}, " ", this.props.gather.gatherers.length, " ") + React.createElement("strong", null, "NS2 Gather "), + React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length), + React.createElement("br", null), + this.stateDescription() ), React.createElement(Gatherers, {gatherers: this.props.gather.gatherers}), - React.createElement("div", {className: "panel-body"} - ), + React.createElement(GatherProgress, {gather: this.props.gather}), React.createElement("div", {className: "panel-footer text-right"}, - joinButton + React.createElement("ul", {className: "list-inline"}, + inviteButton, + joinButton + ) ) ) ); } }); -// var GatherState = React.createClass({ -// getDefaultProps: function () { -// return { -// "state": "none" -// } -// }, -// stateDescription: function () { -// switch(this.props.date) { -// case "gathering": -// return "Waiting on more players to join" -// } -// }, -// render: function () { -//
    -//

    {this.displayState}

    -//
    -// } -// }) +var LeaderPoll = React.createClass({displayName: "LeaderPoll", + render: function () { + return ( + React.createElement("div", {className: "panel-body"} + ) + ); + } +}); var Gatherers = React.createClass({displayName: "Gatherers", render: function () { var gatherers = this.props.gatherers.map(function (gatherer) { var lifeforms = ( gatherer.user.ability.lifeforms.map(function (lifeform) { - return React.createElement("span", {className: "label label-default"}, lifeform); + return (React.createElement("span", {className: "label label-default"}, lifeform)); }) ); - var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)) + var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)); + var commBadge; + if (gatherer.user.ability.commander) { + commBadge = (React.createElement("img", {src: "/images/commander.png", + alt: "Commander", + height: "20", + width: "20"})) + } return ( - React.createElement("tr", null, - React.createElement("td", null, gatherer.user.username), - React.createElement("td", null, division), - React.createElement("td", null, lifeforms) + React.createElement("tr", {key: gatherer.user.id}, + React.createElement("td", {className: "col-md-1"}, commBadge), + React.createElement("td", {className: "col-md-5"}, gatherer.user.username), + React.createElement("td", {className: "col-md-3"}, division, " "), + React.createElement("td", {className: "col-md-3"}, lifeforms, " ") ) ); }) - return ( - React.createElement("table", {className: "table table-striped gatherer-table"}, - React.createElement("thead", null, - React.createElement("tr", null, - React.createElement("th", null, "Player"), - React.createElement("th", null, "Ability"), - React.createElement("th", null, "Life Forms") + if (this.props.gatherers.length) { + return ( + React.createElement("div", {className: "panel-body"}, + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + React.createElement("h5", {className: "panel-title"}, "Roster") + ), + React.createElement("table", {className: "table roster-table"}, + React.createElement("tbody", null, + gatherers + ) + ) ) - ), - React.createElement("tbody", null, - gatherers ) - ) - ); + ); + } else { + return (React.createElement("div", {className: "panel-body text-center"}, React.createElement(JoinGatherButton, {buttonClass: "btn-lg", buttonName: "Start a Gather"}))); + } } }); @@ -383,4 +483,4 @@ initialiseComponents(); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsQ0FBQyxZQUFZOztBQUVkLFlBQVksQ0FBQzs7QUFFYixJQUFJLGlDQUFpQywyQkFBQTtDQUNwQyxNQUFNLEVBQUUsWUFBWTtFQUNuQjtHQUNDLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUE7SUFDSCxvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLElBQUEsRUFBSSxDQUFDLEdBQUksQ0FBQSxFQUFBO0tBQ1gsb0JBQUEsR0FBRSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxtQkFBb0IsQ0FBSSxDQUFBLEVBQUEsU0FBQSxFQUFBLENBQUE7QUFBQSxLQUNyQyxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGdCQUFpQixDQUFBLEVBQUEsR0FBQSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLEdBQVEsQ0FBQTtJQUN6RCxDQUFBO0dBQ0EsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLCtCQUErQix5QkFBQTtDQUNsQyxXQUFXLEVBQUUsVUFBVSxFQUFFLEVBQUU7RUFDMUIsRUFBRSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7RUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtHQUM5QixFQUFFLEVBQUUsRUFBRTtHQUNOLENBQUMsQ0FBQztFQUNIO0NBQ0QsWUFBWSxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQzFCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0VBQ2hFLElBQUksQ0FBQyxFQUFFLEVBQUUsT0FBTztFQUNoQixLQUFLLENB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QVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztDQUNoRSxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLE1BQU0sRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUM5RCxDQUFDLENBQUM7O0FBRUYsb0JBQW9CLEVBQUUsQ0FBQztBQUN2QjtBQUNBOztBQUVBLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiJChmdW5jdGlvbiAoKSB7XG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgVXNlckNvdW50ZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8bGk+XG5cdFx0XHRcdDxhIGhyZWY9XCIjXCI+XG5cdFx0XHRcdFx0PGkgY2xhc3NOYW1lPVwiZmEgZmEtdXNlcnMgZmEtZndcIj48L2k+IE9ubGluZSBcblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJiYWRnZSBhZGQtbGVmdFwiPiB7dGhpcy5wcm9wcy5jb3VudH0gPC9zcGFuPlxuXHRcdFx0XHQ8L2E+XG5cdFx0XHQ8L2xpPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgVXNlckxvZ2luID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRhdXRob3JpemVJZDogZnVuY3Rpb24gKGlkKSB7XG5cdFx0aWQgPSBwYXJzZUludChpZCwgMTApO1xuXHRcdHNvY2tldC5lbWl0KFwidXNlcnM6YXV0aG9yaXplXCIsIHtcblx0XHRcdGlkOiBpZFxuXHRcdH0pO1xuXHR9LFxuXHRoYW5kbGVTdWJtaXQ6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHZhciBpZCA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5hdXRob3JpemVfaWQpLnZhbHVlLnRyaW0oKTtcblx0XHRpZiAoIWlkKSByZXR1cm47XG5cdFx0UmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmF1dGhvcml6ZV9pZCkudmFsdWUgPSAnJztcblx0XHR0aGlzLmF1dGhvcml6ZUlkKGlkKTtcblx0XHRyZXR1cm47XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8Zm9ybSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXR9ID5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cCBzaWduaW5cIj5cblx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRpZD1cImJ0bi1pbnB1dFwiIFxuXHRcdFx0XHRcdFx0dHlwZT1cInRleHRcIiBcblx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImZvcm0tY29udHJvbFwiIFxuXHRcdFx0XHRcdFx0cmVmPVwiYXV0aG9yaXplX2lkXCJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiQ2hvb3NlIGFuIElELi4uXCIgLz5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cC1idG5cIj5cblx0XHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdFx0dHlwZT1cInN1Ym1pdFwiIFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJidG4gYnRuLXByaW1hcnlcIiBcblx0XHRcdFx0XHRcdFx0aWQ9XCJidG4tY2hhdFwiIFxuXHRcdFx0XHRcdFx0XHR2YWx1ZT1cIkxvZ2luXCIgLz5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInNpZ25pblwiPlxuXHRcdFx0XHQ8cCBjbGFzc05hbWU9XCJ0ZXh0LWNlbnRlclwiPjxzbWFsbD5KdXN0IGEgdGVtcG9yYXJ5IG1lYXN1cmUgdW50aWwgZ2VudWluZSBhdXRoZW50aWNhdGlvbiBpcyBpbXBsZW1lbnRlZDwvc21hbGw+PC9wPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZm9ybT5cblx0XHQpO1xuXHR9XG59KVxuXG52YXIgVXNlckxpbmUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8bGk+XG5cdFx0XHRcdDxhIGhyZWY9XCIjXCI+e3RoaXMucHJvcHMudXNlci51c2VybmFtZX08L2E+XG5cdFx0XHQ8L2xpPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgVXNlck1lbnUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRjb3VudDogMCxcblx0XHRcdHVzZXJzOiBbXVxuXHRcdH07XG5cdH0sXG5cdGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiAoKSB7XG5cdFx0c29ja2V0Lm9uKCd1c2VyQ291bnQnLCB0aGlzLnVwZGF0ZVVzZXJzKTtcblx0fSxcblx0dXBkYXRlVXNlcnM6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0dGhpcy5zZXRQcm9wcyh7XG5cdFx0XHRjb3VudDogZGF0YS5jb3VudCxcblx0XHRcdHVzZXJzOiBkYXRhLnVzZXJzXG5cdFx0fSk7XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciB1c2VycyA9IHRoaXMucHJvcHMudXNlcnMubWFwKGZ1bmN0aW9uICh1c2VyKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8VXNlckxpbmUgdXNlcj17dXNlcn0gLz5cblx0XHRcdCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIChcblx0XHRcdDx1bCBjbGFzc05hbWU9XCJuYXZcIiBpZD1cInNpZGUtbWVudVwiPlxuXHRcdFx0XHQ8VXNlckNvdW50ZXIgey4uLnRoaXMucHJvcHN9IC8+XG5cdFx0XHRcdHt1c2Vyc31cblx0XHRcdFx0PGxpPjxiciAvPjxVc2VyTG9naW4gLz48YnIgLz48L2xpPlxuXHRcdFx0PC91bD5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIENoYXRyb29tID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aGlzdG9yeTogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgVElNRVJfSU5URVJWQUwgPSA2MDAwMDsgLy8gRXZlcnkgbWludXRlXG5cblx0XHRzb2NrZXQub24oXCJtZXNzYWdlOm5ld1wiLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0dmFyIGhpc3RvcnkgPSBzZWxmLnByb3BzLmhpc3Rvcnk7XG5cdFx0XHRoaXN0b3J5LnB1c2goZGF0YSk7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogaGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBNZXNzYWdlIEhpc3RvcnkgUmV0cmlldmVkXG5cdFx0c29ja2V0Lm9uKFwibWVzc2FnZTpyZWZyZXNoXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogZGF0YS5jaGF0SGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6cmVmcmVzaFwiLCB7fSk7XG5cblx0XHRzZWxmLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuXHRcdFx0c2VsZi5yZWZzLm1lc3NhZ2VzLnJlZnJlc2hUaW1lKCk7XG5cdFx0fSwgVElNRVJfSU5URVJWQUwpO1xuXHR9LFxuXG5cdGNvbXBvbmVudERpZFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHRjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xuXHR9LFxuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcblx0XHRzb2NrZXQuZW1pdChcIm5ld01lc3NhZ2VcIiwge21lc3NhZ2U6IG1lc3NhZ2V9KTtcblx0fSxcblx0c2Nyb2xsVG9Cb3R0b206IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbm9kZSA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5tZXNzYWdlQ29udGFpbmVyKTtcblx0ICBub2RlLnNjcm9sbFRvcCA9IG5vZGUuc2Nyb2xsSGVpZ2h0O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbWVzc2FnZXMgPSB0aGlzLnByb3BzLmhpc3RvcnkubWFwKGZ1bmN0aW9uIChtZXNzYWdlKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8Q2hhdE1lc3NhZ2UgXG5cdFx0XHRcdFx0YXZhdGFyPXttZXNzYWdlLmF1dGhvci5hdmF0YXJ9IFxuXHRcdFx0XHRcdHVzZXJuYW1lPXttZXNzYWdlLmF1dGhvci51c2VybmFtZX1cblx0XHRcdFx0XHRjb250ZW50PXttZXNzYWdlLmNvbnRlbnR9XG5cdFx0XHRcdFx0cmVmPVwibWVzc2FnZXNcIlxuXHRcdFx0XHRcdGNyZWF0ZWRBdD17bWVzc2FnZS5jcmVhdGVkQXR9IC8+XG5cdFx0XHQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+R2F0aGVyIENoYXQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoYXRcIiBpZD1cImNoYXRtZXNzYWdlc1wiIHJlZj1cIm1lc3NhZ2VDb250YWluZXJcIj5cblx0XHRcdFx0XHRcdHttZXNzYWdlc31cblx0XHRcdFx0XHQ8L3VsPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1mb290ZXJcIj5cblx0XHRcdFx0XHQ8TWVzc2FnZUJhciAvPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ2hhdE1lc3NhZ2UgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHR0aW1lQWdvOiAkLnRpbWVhZ28odGhpcy5wcm9wcy5jcmVhdGVkQXQpXG5cdFx0fVxuXHR9LFxuXHRyZWZyZXNoVGltZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRzZWxmLnNldFN0YXRlKHtcblx0XHRcdHRpbWVBZ286ICQudGltZWFnbyhzZWxmLnByb3BzLmNyZWF0ZWRBdClcblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxsaSBjbGFzc05hbWU9XCJsZWZ0IGNsZWFyZml4XCI+XG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImNoYXQtaW1nIHB1bGwtbGVmdFwiPlxuXHRcdFx0XHRcdFx0PGltZyBcblx0XHRcdFx0XHRcdFx0c3JjPXt0aGlzLnByb3BzLmF2YXRhcn0gXG5cdFx0XHRcdFx0XHRcdGFsdD1cIlVzZXIgQXZhdGFyXCIgXG5cdFx0XHRcdFx0XHRcdGhlaWdodD1cIjQwXCJcblx0XHRcdFx0XHRcdFx0d2lkdGg9XCI0MFwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImltZy1jaXJjbGVcIiAvPlxuXHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY2hhdC1ib2R5IGNsZWFyZml4XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJoZWFkZXJcIj5cblx0XHRcdFx0XHRcdDxzdHJvbmcgY2xhc3NOYW1lPVwicHJpbWFyeS1mb250XCI+e3RoaXMucHJvcHMudXNlcm5hbWV9PC9zdHJvbmc+XG5cdFx0XHRcdFx0XHQ8c21hbGwgY2xhc3NOYW1lPVwicHVsbC1yaWdodCB0ZXh0LW11dGVkXCI+XG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLWNsb2NrLW8gZmEtZndcIj48L2k+IHt0aGlzLnN0YXRlLnRpbWVBZ299XG5cdFx0XHRcdFx0XHQ8L3NtYWxsPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxwPnt0aGlzLnByb3BzLmNvbnRlbnR9PC9wPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbGk+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBNZXNzYWdlQmFyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKGNvbnRlbnQpIHtcblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6bmV3XCIsIHtcblx0XHRcdGNvbnRlbnQ6IGNvbnRlbnRcblx0XHR9KTtcblx0fSxcblx0aGFuZGxlU3VibWl0OiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR2YXIgY29udGVudCA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5jb250ZW50KS52YWx1ZS50cmltKCk7XG5cdFx0aWYgKCFjb250ZW50KSByZXR1cm47XG5cdFx0UmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmNvbnRlbnQpLnZhbHVlID0gJyc7XG5cdFx0dGhpcy5zZW5kTWVzc2FnZShjb250ZW50KTtcblx0XHRyZXR1cm47XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8Zm9ybSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXR9ID5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cFwiPlxuXHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdGlkPVwiYnRuLWlucHV0XCIgXG5cdFx0XHRcdFx0XHR0eXBlPVwidGV4dFwiIFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiZm9ybS1jb250cm9sXCIgXG5cdFx0XHRcdFx0XHRyZWY9XCJjb250ZW50XCJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiQmUgcG9saXRlIHBsZWFzZS4uLlwiIC8+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAtYnRuXCI+XG5cdFx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRcdHR5cGU9XCJzdWJtaXRcIiBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCIgXG5cdFx0XHRcdFx0XHRcdGlkPVwiYnRuLWNoYXRcIiBcblx0XHRcdFx0XHRcdFx0dmFsdWU9XCJTZW5kXCIgLz5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9mb3JtPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgR2F0aGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Z2F0aGVyOiB7XG5cdFx0XHRcdGdhdGhlcmVyczogW11cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGpvaW5lZEdhdGhlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRyZXR1cm4gdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnNvbWUoZnVuY3Rpb24gKGdhdGhlcmVyKSB7XG5cdFx0XHRyZXR1cm4gZ2F0aGVyZXIudXNlci5pZCA9PT0gc2VsZi5wcm9wcy51c2VyLmlkO1xuXHRcdH0pO1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRzb2NrZXQub24oXCJnYXRoZXI6cmVmcmVzaFwiLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0c2VsZi5zZXRQcm9wcyh7XG5cdFx0XHRcdGdhdGhlcjogZGF0YS5nYXRoZXIsXG5cdFx0XHRcdHVzZXI6IGRhdGEudXNlclxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH0sXG5cdGpvaW5HYXRoZXI6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHNvY2tldC5lbWl0KFwiZ2F0aGVyOmpvaW5cIiwge30pO1xuXHR9LFxuXHRsZWF2ZUdhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0c29ja2V0LmVtaXQoXCJnYXRoZXI6bGVhdmVcIiwge30pO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgam9pbkJ1dHRvbjtcblx0XHRpZiAodGhpcy5qb2luZWRHYXRoZXIoKSkge1xuXHRcdFx0am9pbkJ1dHRvbiA9ICg8YnV0dG9uIFxuXHRcdFx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLmxlYXZlR2F0aGVyfSBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1kYW5nZXJcIj5MZWF2ZSBHYXRoZXI8L2J1dHRvbj4pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqb2luQnV0dG9uID0gKDxidXR0b24gXG5cdFx0XHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMuam9pbkdhdGhlcn0gXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4tcHJpbWFyeVwiPkpvaW4gR2F0aGVyPC9idXR0b24+KTtcblx0XHR9XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwgcGFuZWwtZGVmYXVsdFwiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWhlYWRpbmdcIj5cblx0XHRcdFx0XHRDdXJyZW50IEdhdGhlciBcblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJiYWRnZSBhZGQtbGVmdFwiPiB7dGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmxlbmd0aH0gPC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PEdhdGhlcmVycyBnYXRoZXJlcnM9e3RoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVyc30gLz5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWZvb3RlciB0ZXh0LXJpZ2h0XCI+XG5cdFx0XHRcdFx0e2pvaW5CdXR0b259XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cbi8vIHZhciBHYXRoZXJTdGF0ZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbi8vIFx0Z2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiAoKSB7XG4vLyBcdFx0cmV0dXJuIHtcbi8vIFx0XHRcdFwic3RhdGVcIjogXCJub25lXCJcbi8vIFx0XHR9XG4vLyBcdH0sXG4vLyBcdHN0YXRlRGVzY3JpcHRpb246IGZ1bmN0aW9uICgpIHtcbi8vIFx0XHRzd2l0Y2godGhpcy5wcm9wcy5kYXRlKSB7XG4vLyBcdFx0XHRjYXNlIFwiZ2F0aGVyaW5nXCI6XG4vLyBcdFx0XHRcdHJldHVybiBcIldhaXRpbmcgb24gbW9yZSBwbGF5ZXJzIHRvIGpvaW5cIlxuLy8gXHRcdH1cbi8vIFx0fSxcbi8vIFx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4vLyBcdFx0PGRpdiBjbGFzc05hbWU9XCJ3ZWxsXCI+XG4vLyBcdFx0XHQ8cD57dGhpcy5kaXNwbGF5U3RhdGV9PC9wPlxuLy8gXHRcdDwvZGl2PlxuLy8gXHR9XG4vLyB9KVxuXG52YXIgR2F0aGVyZXJzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgZ2F0aGVyZXJzID0gdGhpcy5wcm9wcy5nYXRoZXJlcnMubWFwKGZ1bmN0aW9uIChnYXRoZXJlcikge1xuXHRcdFx0dmFyIGxpZmVmb3JtcyA9IChcblx0XHRcdFx0Z2F0aGVyZXIudXNlci5hYmlsaXR5LmxpZmVmb3Jtcy5tYXAoZnVuY3Rpb24gKGxpZmVmb3JtKSB7XG5cdFx0XHRcdFx0cmV0dXJuIDxzcGFuIGNsYXNzTmFtZT1cImxhYmVsIGxhYmVsLWRlZmF1bHRcIj57bGlmZWZvcm19PC9zcGFuPjtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0XHR2YXIgZGl2aXNpb24gPSAoPHNwYW4gY2xhc3NOYW1lPVwibGFiZWwgbGFiZWwtcHJpbWFyeVwiPntnYXRoZXJlci51c2VyLmFiaWxpdHkuZGl2aXNpb259PC9zcGFuPilcblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PHRyPlxuXHRcdFx0XHRcdDx0ZD57Z2F0aGVyZXIudXNlci51c2VybmFtZX08L3RkPlxuXHRcdFx0XHRcdDx0ZD57ZGl2aXNpb259PC90ZD5cblx0XHRcdFx0XHQ8dGQ+e2xpZmVmb3Jtc308L3RkPlxuXHRcdFx0XHQ8L3RyPlxuXHRcdFx0KTtcblx0XHR9KVxuXHRcdHJldHVybiAoXG5cdFx0XHQ8dGFibGUgY2xhc3NOYW1lPVwidGFibGUgdGFibGUtc3RyaXBlZCBnYXRoZXJlci10YWJsZVwiPlxuXHRcdFx0XHQ8dGhlYWQ+XG5cdFx0XHRcdFx0PHRyPlxuXHRcdFx0XHRcdFx0PHRoPlBsYXllcjwvdGg+XG5cdFx0XHRcdFx0XHQ8dGg+QWJpbGl0eTwvdGg+XG5cdFx0XHRcdFx0XHQ8dGg+TGlmZSBGb3JtczwvdGg+XG5cdFx0XHRcdFx0PC90cj5cblx0XHRcdFx0PC90aGVhZD5cblx0XHRcdFx0PHRib2R5PlxuXHRcdFx0XHRcdHtnYXRoZXJlcnN9XG5cdFx0XHRcdDwvdGJvZHk+XG5cdFx0XHQ8L3RhYmxlPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgc29ja2V0O1xuXG5mdW5jdGlvbiBpbml0aWFsaXNlQ29tcG9uZW50cyAoKSB7XG5cdHZhciBzb2NrZXRVcmwgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyB3aW5kb3cubG9jYXRpb24uaG9zdDtcblx0c29ja2V0ID0gaW8oc29ja2V0VXJsKVxuXHRcdC5vbihcImNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJDb25uZWN0ZWRcIik7XG5cdFx0fSlcblx0XHQub24oXCJyZWNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJSZWNvbm5lY3RlZFwiKTtcblx0XHR9KVxuXHRcdC5vbihcImRpc2Nvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJEaXNjb25uZWN0ZWRcIilcblx0XHR9KTtcblxuXHRSZWFjdC5yZW5kZXIoPFVzZXJNZW51IC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZS1tZW51JykpO1xuXHRSZWFjdC5yZW5kZXIoPENoYXRyb29tIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hhdHJvb20nKSk7XG5cdFJlYWN0LnJlbmRlcig8R2F0aGVyIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ2F0aGVycycpKTtcbn07XG5cbmluaXRpYWxpc2VDb21wb25lbnRzKCk7XG5cblxuXG59KTtcblxuIl19 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsQ0FBQyxZQUFZOztBQUVkLFlBQVksQ0FBQzs7QUFFYixJQUFJLGlDQUFpQywyQkFBQTtDQUNwQyxNQUFNLEVBQUUsWUFBWTtFQUNuQjtHQUNDLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUE7SUFDSCxvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLElBQUEsRUFBSSxDQUFDLEdBQUksQ0FBQSxFQUFBO0tBQ1gsb0JBQUEsR0FBRSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxtQkFBb0IsQ0FBSSxDQUFBLEVBQUEsU0FBQSxFQUFBLENBQUE7QUFBQSxLQUNyQyxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGdCQUFpQixDQUFBLEVBQUEsR0FBQSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLEdBQVEsQ0FBQTtJQUN6RCxDQUFBO0dBQ0EsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLCtCQUErQix5QkFBQTtDQUNsQyxXQUFXLEVBQUUsVUFBVSxFQUFFLEVBQUU7RUFDMUIsRUFBRSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7RUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtHQUM5QixFQUFFLEVBQUUsRUFBRTtHQUNOLENBQUMsQ0FBQztFQUNIO0NBQ0QsWUFBWSxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQzFCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0VBQ2hFLElBQUksQ0FBQyxFQUFFLEVBQUUsT0FBTztFQUNoQixLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztFQUNyRCxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQ3JCLE9BQU87RUFDUDtDQUNELE1BQU0sRUFBRSxZQUFZO0VBQ25CO0dBQ0Msb0JBQUEsTUFBSyxFQUFBLENBQUEsQ0FBQyxRQUFBLEVBQVEsQ0FBRSxJQUFJLENBQUMsWUFBYSxDQUFFLENBQUEsRUFBQTtJQUNuQyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLG9CQUFxQixDQUFBLEVBQUE7S0FDbkMsb0JBQUEsT0FBTSxFQUFBLENBQUE7TUFDTCxFQUFBLEVBQUUsQ0FBQyxXQUFBLEVBQVc7TUFDZCxJQUFBLEVBQUksQ0FBQyxNQUFBLEVBQU07TUFDWCxTQUFBLEVBQVMsQ0FBQyxjQUFBLEVBQWM7TUFDeEIsR0FBQSxFQUFHLENBQUMsY0FBQSxFQUFjO01BQ2xCLFdBQUEsRUFBVyxDQUFDLGlCQUFpQixDQUFBLENBQUcsQ0FBQSxFQUFBO0tBQ2pDLG9CQUFBLE1BQUssRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsaUJBQWtCLENBQUEsRUFBQTtNQUNqQyxvQkFBQSxPQUFNLEVBQUEsQ0FBQTtPQUNMLElBQUEsRUFBSSxDQUFDLFFBQUEsRUFBUTtPQUNiLFNBQUEsRUFBUyxDQUFDLGlCQUFBLEVBQWlCO09BQzNCLEVBQUEsRUFBRSxDQUFDLFVBQUEsRUFBVTtPQUNiLEtBQUEsRUFBSyxDQUFDLE9BQU8sQ0FBQSxDQUFHLENBQUE7S0FDWCxDQUFBO0lBQ0YsQ0FBQSxFQUFBO0lBQ04sb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxRQUFTLENBQUEsRUFBQTtJQUN4QixvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGFBQWMsQ0FBQSxFQUFBLG9CQUFBLE9BQU0sRUFBQSxJQUFDLEVBQUEsc0VBQTRFLENBQUksQ0FBQTtJQUM1RyxDQUFBO0dBQ0EsQ0FBQTtJQUNOO0VBQ0Y7QUFDRixDQUFDLENBQUM7O0FBRUYsSUFBSSw4QkFBOEIsd0JBQUE7Q0FDakMsZUFBZSxFQUFFLFlBQVk7RUFDNUIsT0FBTztHQUNOLEtBQUssRUFBRSxDQUFDO0dBQ1IsS0FBSyxFQUFFLEVBQUU7R0FDVCxDQUFDO0VBQ0Y7Q0FDRCxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztFQUN6QztDQUNELFdBQVcsRUFBRSxVQUFVLElBQUksRUFBRTtFQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDO0dBQ2IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0dBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztHQUNqQixDQUFDLENBQUM7RUFDSDtDQUNELE1BQU0sRUFBRSxZQUFZO0VBQ25CLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRTtHQUNoRDtJQUNDLG9CQUFBLElBQUcsRUFBQSxDQUFBLENBQUMsR0FBQSxFQUFHLENBQUUsSUFBSSxDQUFDLEVBQUksQ0FBQSxFQUFBLG9CQUFBLEdBQUUsRUFBQSxDQUFBLENBQUMsSUFBQSxFQUFJLENBQUMsR0FBSSxDQUFBLEVBQUMsSUFBSSxDQUFDLFFBQWEsQ0FBSyxDQUFBO0tBQ3JEO0dBQ0YsQ0FBQyxDQUFDO0VBQ0g7R0FDQyxvQkFBQSxJQUFHLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLEtBQUEsRUFBSyxDQUFDLEVBQUEsRUFBRSxDQUFDLFdBQVksQ0FBQSxFQUFBO0lBQ2xDLG9CQUFDLFdBQVcsRUFBQSxnQkFBQSxHQUFBLENBQUUsR0FBRyxJQUFJLENBQUMsS0FBTSxDQUFBLENBQUcsQ0FBQSxFQUFBO0lBQzlCLEtBQUssRUFBQztJQUNQLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUEsb0JBQUEsSUFBRyxFQUFBLElBQUEsQ0FBRyxDQUFBLEVBQUEsb0JBQUMsU0FBUyxFQUFBLElBQUEsQ0FBRyxDQUFBLEVBQUEsb0JBQUEsSUFBRyxFQUFBLElBQUEsQ0FBRyxDQUFLLENBQUE7R0FDOUIsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLDhCQUE4Qix3QkFBQTtDQUNqQyxlQUFlLEVBQUUsWUFBWTtFQUM1QixPQUFPO0dBQ04sT0FBTyxFQUFFLEVBQUU7R0FDWCxDQUFDO0VBQ0Y7Q0FDRCxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztBQUNsQixFQUFFLElBQUksY0FBYyxHQUFHLEtBQUssQ0FBQzs7RUFFM0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxJQUFJLEVBQUU7R0FDeEMsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7R0FDakMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztHQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ2IsT0FBTyxFQUFFLE9BQU87SUFDaEIsQ0FBQyxDQUFDO0dBQ0gsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ3pCLEdBQUcsQ0FBQyxDQUFDO0FBQ0w7O0VBRUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxVQUFVLElBQUksRUFBRTtHQUM1QyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXO0lBQ3pCLENBQUMsQ0FBQztHQUNILElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUN6QixHQUFHLENBQUMsQ0FBQzs7QUFFTCxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDLENBQUM7O0VBRW5DLElBQUksQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLFlBQVk7R0FDcEMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztHQUN6RCxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQ3JCLEVBQUU7O0NBRUQsbUJBQW1CLEVBQUUsWUFBWTtFQUNoQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0VBQzFCO0NBQ0QsV0FBVyxFQUFFLFVBQVUsT0FBTyxFQUFFO0VBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7RUFDOUM7Q0FDRCxjQUFjLEVBQUUsWUFBWTtFQUMzQixJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztHQUN4RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7RUFDcEM7Q0FDRCxNQUFNLEVBQUUsWUFBWTtFQUNuQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxPQUFPLEVBQUU7R0FDeEQ7SUFDQyxvQkFBQyxXQUFXLEVBQUEsQ0FBQTtLQUNYLE1BQUEsRUFBTSxDQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFDO0tBQzlCLFFBQUEsRUFBUSxDQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFDO0tBQ2xDLE9BQUEsRUFBTyxDQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUM7S0FDekIsR0FBQSxFQUFHLENBQUMsVUFBQSxFQUFVO0tBQ2QsU0FBQSxFQUFTLENBQUUsT0FBTyxDQUFDLFNBQVUsQ0FBQSxDQUFHLENBQUE7S0FDaEM7R0FDRixDQUFDLENBQUM7RUFDSDtHQUNDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMscUJBQXNCLENBQUEsRUFBQTtJQUNwQyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGVBQWdCLENBQUEsRUFBQSxhQUFpQixDQUFBLEVBQUE7SUFDaEQsb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxZQUFhLENBQUEsRUFBQTtLQUMzQixvQkFBQSxJQUFHLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLE1BQUEsRUFBTSxDQUFDLEVBQUEsRUFBRSxDQUFDLGNBQUEsRUFBYyxDQUFDLEdBQUEsRUFBRyxDQUFDLGtCQUFtQixDQUFBLEVBQUE7TUFDNUQsUUFBUztLQUNOLENBQUE7SUFDQSxDQUFBLEVBQUE7SUFDTixvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGNBQWUsQ0FBQSxFQUFBO0tBQzdCLG9CQUFDLFVBQVUsRUFBQSxJQUFBLENBQUcsQ0FBQTtJQUNULENBQUE7R0FDRCxDQUFBO0lBQ0w7RUFDRjtBQUNGLENBQUMsQ0FBQyxDQUFDOztBQUVILElBQUksaUNBQWlDLDJCQUFBO0NBQ3BDLGVBQWUsRUFBRSxZQUFZO0VBQzVCLE9BQU87R0FDTixPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztHQUN4QztFQUNEO0NBQ0QsV0FBVyxFQUFFLFlBQVk7RUFDeEIsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDO0VBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUM7R0FDYixPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztHQUN4QyxDQUFDLENBQUM7RUFDSDtDQUNELE1BQU0sRUFBRSxZQUFZO0VBQ25CO0dBQ0Msb0JBQUEsSUFBRyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxlQUFnQixDQUFBLEVBQUE7SUFDN0Isb0JBQUEsTUFBSyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxvQkFBcUIsQ0FBQSxFQUFBO01BQ25DLG9CQUFBLEtBQUksRUFBQSxDQUFBO09BQ0gsR0FBQSxFQUFHLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUM7T0FDdkIsR0FBQSxFQUFHLENBQUMsYUFBQSxFQUFhO09BQ2pCLE1BQUEsRUFBTSxDQUFDLElBQUEsRUFBSTtPQUNYLEtBQUEsRUFBSyxDQUFDLElBQUEsRUFBSTtPQUNWLFNBQUEsRUFBUyxDQUFDLFlBQVksQ0FBQSxDQUFHLENBQUE7SUFDckIsQ0FBQSxFQUFBO0lBQ1Asb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxvQkFBcUIsQ0FBQSxFQUFBO0tBQ25DLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsUUFBUyxDQUFBLEVBQUE7TUFDdkIsb0JBQUEsUUFBTyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxjQUFlLENBQUEsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQWtCLENBQUEsRUFBQTtNQUMvRCxvQkFBQSxPQUFNLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLHVCQUF3QixDQUFBLEVBQUE7T0FDeEMsb0JBQUEsR0FBRSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxxQkFBc0IsQ0FBSSxDQUFBLEVBQUEsR0FBQSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBUTtNQUNyRCxDQUFBO0tBQ0gsQ0FBQSxFQUFBO0tBQ04sb0JBQUEsR0FBRSxFQUFBLElBQUMsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQVksQ0FBQTtJQUN0QixDQUFBO0dBQ0YsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLGdDQUFnQywwQkFBQTtDQUNuQyxXQUFXLEVBQUUsVUFBVSxPQUFPLEVBQUU7RUFDL0IsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7R0FDMUIsT0FBTyxFQUFFLE9BQU87R0FDaEIsQ0FBQyxDQUFDO0VBQ0g7Q0FDRCxZQUFZLEVBQUUsVUFBVSxDQUFDLEVBQUU7RUFDMUIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0VBQ25CLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7RUFDaEUsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPO0VBQ3JCLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO0VBQ2hELElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7RUFDMUIsT0FBTztFQUNQO0NBQ0QsTUFBTSxFQUFFLFlBQVk7RUFDbkI7R0FDQyxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFFBQUEsRUFBUSxDQUFFLElBQUksQ0FBQyxZQUFhLENBQUUsQ0FBQSxFQUFBO0lBQ25DLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsYUFBYyxDQUFBLEVBQUE7S0FDNUIsb0JBQUEsT0FBTSxFQUFBLENBQUE7TUFDTCxFQUFBLEVBQUUsQ0FBQyxXQUFBLEVBQVc7TUFDZCxJQUFBLEVBQUksQ0FBQyxNQUFBLEVBQU07TUFDWCxTQUFBLEVBQVMsQ0FBQyxjQUFBLEVBQWM7TUFDeEIsR0FBQSxFQUFHLENBQUMsU0FBQSxFQUFTO01BQ2IsV0FBQSxFQUFXLENBQUMscUJBQXFCLENBQUEsQ0FBRyxDQUFBLEVBQUE7S0FDckMsb0JBQUEsTUFBSyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxpQkFBa0IsQ0FBQSxFQUFBO01BQ2pDLG9CQUFBLE9BQU0sRUFBQSxDQUFBO09BQ0wsSUFBQSxFQUFJLENBQUMsUUFBQSxFQUFRO09BQ2IsU0FBQSxFQUFTLENBQUMsaUJBQUEsRUFBaUI7T0FDM0IsRUFBQSxFQUFFLENBQUMsVUFBQSxFQUFVO09BQ2IsS0FBQSxFQUFLLENBQUMsTUFBTSxDQUFBLENBQUcsQ0FBQTtLQUNWLENBQUE7SUFDRixDQUFBO0dBQ0EsQ0FBQTtJQUNOO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLHNDQUFzQyxnQ0FBQTtDQUN6QyxVQUFVLEVBQUUsVUFBVSxDQUFDLEVBQUU7RUFDeEIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0VBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0VBQy9CO0NBQ0QsTUFBTSxFQUFFLFlBQVk7RUFDbkIsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksYUFBYSxDQUFDO0VBQ3JELElBQUksV0FBVyxHQUFHLGlCQUFpQixDQUFDO0VBQ3BDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUU7R0FDM0IsV0FBVyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztHQUM1QztFQUNELFFBQVEsb0JBQUEsUUFBTyxFQUFBLENBQUE7T0FDVixPQUFBLEVBQU8sQ0FBRSxJQUFJLENBQUMsVUFBVSxFQUFDO09BQ3pCLFNBQUEsRUFBUyxDQUFFLFdBQWEsQ0FBQSxFQUFDLE9BQWlCLENBQUEsQ0FBQztFQUNoRDtBQUNGLENBQUMsQ0FBQyxDQUFDOztBQUVILElBQUksb0NBQW9DLDhCQUFBO0NBQ3ZDLGlCQUFpQixFQUFFLFlBQVk7RUFDOUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztFQUM3QyxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7RUFDYixPQUFPO0dBQ04sR0FBRyxFQUFFLEdBQUc7R0FDUixHQUFHLEVBQUUsR0FBRztHQUNSLE9BQU8sRUFBRSxHQUFHLEdBQUcsS0FBSyxHQUFHLEdBQUc7R0FDMUIsQ0FBQztFQUNGO0NBQ0QsZ0JBQWdCLEVBQUUsWUFBWTtFQUM3QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLFFBQVEsRUFBRTtHQUNyRSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDL0IsT0FBTyxHQUFHLENBQUM7R0FDWCxFQUFFLENBQUMsQ0FBQyxDQUFDO0VBQ04sSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO0VBQ2IsT0FBTztHQUNOLEdBQUcsRUFBRSxHQUFHO0dBQ1IsR0FBRyxFQUFFLEdBQUc7R0FDUixPQUFPLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxzQkFBc0I7R0FDM0MsQ0FBQztFQUNGO0NBQ0QsaUJBQWlCLEVBQUUsWUFBWTtFQUM5QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLFFBQVEsRUFBRTtHQUNyRSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3JDLE9BQU8sR0FBRyxDQUFDO0dBQ1gsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNSLEVBQUUsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDOztFQUViLE9BQU87R0FDTixHQUFHLEVBQUUsR0FBRztHQUNSLEdBQUcsRUFBRSxHQUFHO0dBQ1IsT0FBTyxFQUFFLEdBQUcsR0FBRyxVQUFVLEdBQUcsR0FBRyxHQUFHLG1CQUFtQjtHQUNyRCxDQUFDO0VBQ0Y7Q0FDRCxNQUFNLEVBQUUsWUFBWTtFQUNuQixJQUFJLFFBQVEsQ0FBQztFQUNiLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztFQUMxQyxJQUFJLFdBQVcsS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtHQUN0RSxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7R0FDcEMsTUFBTSxJQUFJLFdBQVcsS0FBSyxVQUFVLEVBQUU7R0FDdEMsUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0dBQ25DLE1BQU0sSUFBSSxXQUFXLEtBQUssV0FBVyxFQUFFO0dBQ3ZDLFFBQVEsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztHQUNwQztFQUNELElBQUksUUFBUSxFQUFFO0dBQ2IsSUFBSSxLQUFLLEdBQUc7SUFDWCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRztJQUM1RCxDQUFDO0dBQ0Y7SUFDQyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLFlBQWEsQ0FBQSxFQUFBO0tBQzNCLG9CQUFBLEdBQUUsRUFBQSxJQUFDLEVBQUEsaUJBQW1CLENBQUEsRUFBQTtLQUN0QixvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLFVBQVcsQ0FBQSxFQUFBO09BQ3hCLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsMENBQUEsRUFBMEM7UUFDeEQsV0FBQSxFQUFTLENBQUMsYUFBQSxFQUFhO1FBQ3ZCLG9CQUFBLEVBQWtCLENBQUUsUUFBUSxDQUFDLEdBQUcsRUFBQztRQUNqQyxvQkFBQSxFQUFrQixDQUFDLEdBQUEsRUFBRztRQUN0QixvQkFBQSxFQUFrQixDQUFFLFFBQVEsQ0FBQyxHQUFHLEVBQUM7UUFDakMsS0FBQSxFQUFLLENBQUUsS0FBTyxDQUFBLEVBQUE7U0FDWixRQUFRLENBQUMsT0FBUTtPQUNkLENBQUE7TUFDRCxDQUFBO0lBQ0YsQ0FBQTtLQUNMO0dBQ0YsTUFBTTtHQUNOLE9BQU8sS0FBSyxDQUFDO0dBQ2I7RUFDRDtBQUNGLENBQUMsQ0FBQyxDQUFDOztBQUVILElBQUksNEJBQTRCLHNCQUFBO0NBQy9CLGVBQWUsRUFBRSxZQUFZO0VBQzVCLE9BQU87R0FDTixNQUFNLEVBQUU7SUFDUCxTQUFTLEVBQUUsRUFBRTtJQUNiO0dBQ0Q7RUFDRDtDQUNELFlBQVksRUFBRSxZQUFZO0VBQ3pCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztFQUNoQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxRQUFRLEVBQUU7R0FDM0QsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7R0FDL0MsQ0FBQyxDQUFDO0VBQ0g7Q0FDRCxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztFQUNoQixNQUFNLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLFVBQVUsSUFBSSxFQUFFO0dBQzNDLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDYixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07SUFDbkIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0lBQ2YsQ0FBQyxDQUFDO0dBQ0gsQ0FBQyxDQUFDO0VBQ0g7Q0FDRCxnQkFBZ0IsRUFBRSxZQUFZO0VBQzdCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSztHQUM3QixLQUFLLFdBQVc7SUFDZixPQUFPLDRCQUE0QixDQUFDO0dBQ3JDLEtBQUssVUFBVTtJQUNkLE9BQU8sbUNBQW1DLENBQUM7R0FDNUMsS0FBSyxXQUFXO0lBQ2YsT0FBTyxzQ0FBc0MsQ0FBQztHQUMvQyxLQUFLLE1BQU07SUFDVixPQUFPLGtCQUFrQixDQUFDO0dBQzNCO0lBQ0MsT0FBTyxxQkFBcUIsQ0FBQztHQUM5QjtFQUNEO0NBQ0QsV0FBVyxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQ3pCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztFQUNoQztDQUNELGNBQWMsRUFBRSxVQUFVLENBQUMsRUFBRTtFQUM1QixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7RUFDbkI7Q0FDRCxNQUFNLEVBQUUsWUFBWTtFQUNuQixJQUFJLFVBQVUsQ0FBQztFQUNmLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxFQUFFO0dBQ3hCLFVBQVUsSUFBSSxvQkFBQSxJQUFHLEVBQUEsSUFBQyxFQUFBLG9CQUFBLFFBQU8sRUFBQSxDQUFBO09BQ3JCLE9BQUEsRUFBTyxDQUFFLElBQUksQ0FBQyxXQUFXLEVBQUM7T0FDMUIsU0FBQSxFQUFTLENBQUMsZ0JBQWlCLENBQUEsRUFBQSxjQUFxQixDQUFLLENBQUEsQ0FBQyxDQUFDO0dBQzNELE1BQU07R0FDTixVQUFVLElBQUksb0JBQUEsSUFBRyxFQUFBLElBQUMsRUFBQSxvQkFBQyxnQkFBZ0IsRUFBQSxJQUFBLENBQUcsQ0FBSyxDQUFBLENBQUMsQ0FBQztHQUM3QztFQUNELElBQUksWUFBWSxDQUFDO0VBQ2pCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLFdBQVcsRUFBRTtHQUM1QyxZQUFZLElBQUksb0JBQUEsSUFBRyxFQUFBLElBQUMsRUFBQSxvQkFBQSxRQUFPLEVBQUEsQ0FBQTtPQUN2QixPQUFBLEVBQU8sQ0FBRSxJQUFJLENBQUMsY0FBYyxFQUFDO09BQzdCLFNBQUEsRUFBUyxDQUFDLGlCQUFrQixDQUFBLEVBQUEsa0JBQXlCLENBQUssQ0FBQSxDQUFDLENBQUM7R0FDaEU7RUFDRDtHQUNDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMscUJBQXNCLENBQUEsRUFBQTtJQUNwQyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGVBQWdCLENBQUEsRUFBQTtLQUM5QixvQkFBQSxRQUFPLEVBQUEsSUFBQyxFQUFBLGFBQW9CLENBQUEsRUFBQTtLQUM1QixvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGdCQUFpQixDQUFBLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQWMsQ0FBQSxFQUFBO0tBQzVFLG9CQUFBLElBQUcsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFBO0tBQ0wsSUFBSSxDQUFDLGdCQUFnQixFQUFHO0lBQ3BCLENBQUEsRUFBQTtJQUNOLG9CQUFDLFNBQVMsRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBVSxDQUFBLENBQUcsQ0FBQSxFQUFBO0lBQ3JELG9CQUFDLGNBQWMsRUFBQSxDQUFBLENBQUMsTUFBQSxFQUFNLENBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFPLENBQUEsQ0FBRyxDQUFBLEVBQUE7SUFDN0Msb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyx5QkFBMEIsQ0FBQSxFQUFBO0tBQ3hDLG9CQUFBLElBQUcsRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsYUFBYyxDQUFBLEVBQUE7TUFDMUIsWUFBWSxFQUFDO01BQ2IsVUFBVztLQUNSLENBQUE7SUFDQSxDQUFBO0dBQ0QsQ0FBQTtJQUNMO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLGdDQUFnQywwQkFBQTtDQUNuQyxNQUFNLEVBQUUsWUFBWTtFQUNuQjtHQUNDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsWUFBYSxDQUFBO0dBQ3RCLENBQUE7SUFDTDtFQUNGO0FBQ0YsQ0FBQyxDQUFDLENBQUM7O0FBRUgsSUFBSSwrQkFBK0IseUJBQUE7Q0FDbEMsTUFBTSxFQUFFLFlBQVk7RUFDbkIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsUUFBUSxFQUFFO0dBQzVELElBQUksU0FBUztJQUNaLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxRQUFRLEVBQUU7S0FDdkQsUUFBUSxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLHFCQUFzQixDQUFBLEVBQUMsUUFBZ0IsQ0FBQSxFQUFFO0tBQ2pFLENBQUM7SUFDRixDQUFDO0dBQ0YsSUFBSSxRQUFRLElBQUksb0JBQUEsTUFBSyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxxQkFBc0IsQ0FBQSxFQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQWdCLENBQUEsQ0FBQyxDQUFDO0dBQy9GLElBQUksU0FBUyxDQUFDO0dBQ2QsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7SUFDcEMsU0FBUyxJQUFJLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsR0FBQSxFQUFHLENBQUMsdUJBQUEsRUFBdUI7T0FDMUMsR0FBQSxFQUFHLENBQUMsV0FBQSxFQUFXO09BQ2YsTUFBQSxFQUFNLENBQUMsSUFBQSxFQUFJO09BQ1gsS0FBQSxFQUFLLENBQUMsSUFBSSxDQUFBLENBQUcsQ0FBQSxDQUFDO0FBQ3JCLElBQUk7O0dBRUQ7SUFDQyxvQkFBQSxJQUFHLEVBQUEsQ0FBQSxDQUFDLEdBQUEsRUFBRyxDQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBSSxDQUFBLEVBQUE7S0FDMUIsb0JBQUEsSUFBRyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxVQUFXLENBQUEsRUFBQyxTQUFlLENBQUEsRUFBQTtLQUN6QyxvQkFBQSxJQUFHLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLFVBQVcsQ0FBQSxFQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBYyxDQUFBLEVBQUE7S0FDdEQsb0JBQUEsSUFBRyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxVQUFXLENBQUEsRUFBQyxRQUFRLEVBQUMsR0FBVyxDQUFBLEVBQUE7S0FDOUMsb0JBQUEsSUFBRyxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxVQUFXLENBQUEsRUFBQyxTQUFTLEVBQUMsR0FBVyxDQUFBO0lBQzNDLENBQUE7S0FDSjtHQUNGLENBQUM7RUFDRixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtHQUNoQztJQUNDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsWUFBYSxDQUFBLEVBQUE7S0FDM0Isb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxxQkFBc0IsQ0FBQSxFQUFBO01BQ3BDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsZUFBZ0IsQ0FBQSxFQUFBO09BQzlCLG9CQUFBLElBQUcsRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsYUFBYyxDQUFBLEVBQUEsUUFBVyxDQUFBO01BQ2xDLENBQUEsRUFBQTtNQUNOLG9CQUFBLE9BQU0sRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsb0JBQXFCLENBQUEsRUFBQTtPQUNyQyxvQkFBQSxPQUFNLEVBQUEsSUFBQyxFQUFBO1FBQ0wsU0FBVTtPQUNKLENBQUE7TUFDRCxDQUFBO0tBQ0gsQ0FBQTtJQUNELENBQUE7S0FDTDtHQUNGLE1BQU07R0FDTixRQUFRLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsd0JBQXlCLENBQUEsRUFBQSxvQkFBQyxnQkFBZ0IsRUFBQSxDQUFBLENBQUMsV0FBQSxFQUFXLENBQUMsUUFBQSxFQUFRLENBQUMsVUFBQSxFQUFVLENBQUMsZ0JBQWdCLENBQUEsQ0FBRyxDQUFNLENBQUEsRUFBRTtHQUM3SDtFQUNEO0FBQ0YsQ0FBQyxDQUFDLENBQUM7O0FBRUgsSUFBSSxNQUFNLENBQUM7O0FBRVgsU0FBUyxvQkFBb0IsSUFBSTtDQUNoQyxJQUFJLFNBQVMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Q0FDdkUsTUFBTSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUM7R0FDcEIsRUFBRSxDQUFDLFNBQVMsRUFBRSxZQUFZO0dBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7R0FDekIsQ0FBQztHQUNELEVBQUUsQ0FBQyxXQUFXLEVBQUUsWUFBWTtHQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0dBQzNCLENBQUM7R0FDRCxFQUFFLENBQUMsWUFBWSxFQUFFLFlBQVk7R0FDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7QUFDOUIsR0FBRyxDQUFDLENBQUM7O0NBRUosS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxRQUFRLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7Q0FDakUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxRQUFRLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7Q0FDaEUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxNQUFNLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDOUQsQ0FBQyxDQUFDOztBQUVGLG9CQUFvQixFQUFFLENBQUM7QUFDdkI7QUFDQTs7QUFFQSxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiQoZnVuY3Rpb24gKCkge1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIFVzZXJDb3VudGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGxpPlxuXHRcdFx0XHQ8YSBocmVmPVwiI1wiPlxuXHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLXVzZXJzIGZhLWZ3XCI+PC9pPiBPbmxpbmUgXG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiYmFkZ2UgYWRkLWxlZnRcIj4ge3RoaXMucHJvcHMuY291bnR9IDwvc3Bhbj5cblx0XHRcdFx0PC9hPlxuXHRcdFx0PC9saT5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIFVzZXJMb2dpbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0YXV0aG9yaXplSWQ6IGZ1bmN0aW9uIChpZCkge1xuXHRcdGlkID0gcGFyc2VJbnQoaWQsIDEwKTtcblx0XHRzb2NrZXQuZW1pdChcInVzZXJzOmF1dGhvcml6ZVwiLCB7XG5cdFx0XHRpZDogaWRcblx0XHR9KTtcblx0fSxcblx0aGFuZGxlU3VibWl0OiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR2YXIgaWQgPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuYXV0aG9yaXplX2lkKS52YWx1ZS50cmltKCk7XG5cdFx0aWYgKCFpZCkgcmV0dXJuO1xuXHRcdFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5hdXRob3JpemVfaWQpLnZhbHVlID0gJyc7XG5cdFx0dGhpcy5hdXRob3JpemVJZChpZCk7XG5cdFx0cmV0dXJuO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGZvcm0gb25TdWJtaXQ9e3RoaXMuaGFuZGxlU3VibWl0fSA+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAgc2lnbmluXCI+XG5cdFx0XHRcdFx0PGlucHV0IFxuXHRcdFx0XHRcdFx0aWQ9XCJidG4taW5wdXRcIiBcblx0XHRcdFx0XHRcdHR5cGU9XCJ0ZXh0XCIgXG5cdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJmb3JtLWNvbnRyb2xcIiBcblx0XHRcdFx0XHRcdHJlZj1cImF1dGhvcml6ZV9pZFwiXG5cdFx0XHRcdFx0XHRwbGFjZWhvbGRlcj1cIkNob29zZSBhbiBJRC4uLlwiIC8+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAtYnRuXCI+XG5cdFx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRcdHR5cGU9XCJzdWJtaXRcIiBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCIgXG5cdFx0XHRcdFx0XHRcdGlkPVwiYnRuLWNoYXRcIiBcblx0XHRcdFx0XHRcdFx0dmFsdWU9XCJMb2dpblwiIC8+XG5cdFx0XHRcdFx0PC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJzaWduaW5cIj5cblx0XHRcdFx0PHAgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIj48c21hbGw+SnVzdCBhIHRlbXBvcmFyeSBtZWFzdXJlIHVudGlsIGdlbnVpbmUgYXV0aGVudGljYXRpb24gaXMgaW1wbGVtZW50ZWQ8L3NtYWxsPjwvcD5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Zvcm0+XG5cdFx0KTtcblx0fVxufSlcblxudmFyIFVzZXJNZW51ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y291bnQ6IDAsXG5cdFx0XHR1c2VyczogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHNvY2tldC5vbigndXNlckNvdW50JywgdGhpcy51cGRhdGVVc2Vycyk7XG5cdH0sXG5cdHVwZGF0ZVVzZXJzOiBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdHRoaXMuc2V0UHJvcHMoe1xuXHRcdFx0Y291bnQ6IGRhdGEuY291bnQsXG5cdFx0XHR1c2VyczogZGF0YS51c2Vyc1xuXHRcdH0pO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgdXNlcnMgPSB0aGlzLnByb3BzLnVzZXJzLm1hcChmdW5jdGlvbiAodXNlcikge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGxpIGtleT17dXNlci5pZH0+PGEgaHJlZj1cIiNcIj57dXNlci51c2VybmFtZX08L2E+PC9saT5cblx0XHRcdCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIChcblx0XHRcdDx1bCBjbGFzc05hbWU9XCJuYXZcIiBpZD1cInNpZGUtbWVudVwiPlxuXHRcdFx0XHQ8VXNlckNvdW50ZXIgey4uLnRoaXMucHJvcHN9IC8+XG5cdFx0XHRcdHt1c2Vyc31cblx0XHRcdFx0PGxpPjxiciAvPjxVc2VyTG9naW4gLz48YnIgLz48L2xpPlxuXHRcdFx0PC91bD5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIENoYXRyb29tID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aGlzdG9yeTogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgVElNRVJfSU5URVJWQUwgPSA2MDAwMDsgLy8gRXZlcnkgbWludXRlXG5cblx0XHRzb2NrZXQub24oXCJtZXNzYWdlOm5ld1wiLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0dmFyIGhpc3RvcnkgPSBzZWxmLnByb3BzLmhpc3Rvcnk7XG5cdFx0XHRoaXN0b3J5LnB1c2goZGF0YSk7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogaGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBNZXNzYWdlIEhpc3RvcnkgUmV0cmlldmVkXG5cdFx0c29ja2V0Lm9uKFwibWVzc2FnZTpyZWZyZXNoXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogZGF0YS5jaGF0SGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6cmVmcmVzaFwiLCB7fSk7XG5cblx0XHRzZWxmLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHNlbGYucmVmcy5tZXNzYWdlcykgc2VsZi5yZWZzLm1lc3NhZ2VzLnJlZnJlc2hUaW1lKCk7XG5cdFx0fSwgVElNRVJfSU5URVJWQUwpO1xuXHR9LFxuXG5cdGNvbXBvbmVudERpZFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHRjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xuXHR9LFxuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcblx0XHRzb2NrZXQuZW1pdChcIm5ld01lc3NhZ2VcIiwge21lc3NhZ2U6IG1lc3NhZ2V9KTtcblx0fSxcblx0c2Nyb2xsVG9Cb3R0b206IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbm9kZSA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5tZXNzYWdlQ29udGFpbmVyKTtcblx0ICBub2RlLnNjcm9sbFRvcCA9IG5vZGUuc2Nyb2xsSGVpZ2h0O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbWVzc2FnZXMgPSB0aGlzLnByb3BzLmhpc3RvcnkubWFwKGZ1bmN0aW9uIChtZXNzYWdlKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8Q2hhdE1lc3NhZ2UgXG5cdFx0XHRcdFx0YXZhdGFyPXttZXNzYWdlLmF1dGhvci5hdmF0YXJ9IFxuXHRcdFx0XHRcdHVzZXJuYW1lPXttZXNzYWdlLmF1dGhvci51c2VybmFtZX1cblx0XHRcdFx0XHRjb250ZW50PXttZXNzYWdlLmNvbnRlbnR9XG5cdFx0XHRcdFx0cmVmPVwibWVzc2FnZXNcIlxuXHRcdFx0XHRcdGNyZWF0ZWRBdD17bWVzc2FnZS5jcmVhdGVkQXR9IC8+XG5cdFx0XHQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+R2F0aGVyIENoYXQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoYXRcIiBpZD1cImNoYXRtZXNzYWdlc1wiIHJlZj1cIm1lc3NhZ2VDb250YWluZXJcIj5cblx0XHRcdFx0XHRcdHttZXNzYWdlc31cblx0XHRcdFx0XHQ8L3VsPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1mb290ZXJcIj5cblx0XHRcdFx0XHQ8TWVzc2FnZUJhciAvPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ2hhdE1lc3NhZ2UgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHR0aW1lQWdvOiAkLnRpbWVhZ28odGhpcy5wcm9wcy5jcmVhdGVkQXQpXG5cdFx0fVxuXHR9LFxuXHRyZWZyZXNoVGltZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRzZWxmLnNldFN0YXRlKHtcblx0XHRcdHRpbWVBZ286ICQudGltZWFnbyhzZWxmLnByb3BzLmNyZWF0ZWRBdClcblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxsaSBjbGFzc05hbWU9XCJsZWZ0IGNsZWFyZml4XCI+XG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImNoYXQtaW1nIHB1bGwtbGVmdFwiPlxuXHRcdFx0XHRcdFx0PGltZyBcblx0XHRcdFx0XHRcdFx0c3JjPXt0aGlzLnByb3BzLmF2YXRhcn0gXG5cdFx0XHRcdFx0XHRcdGFsdD1cIlVzZXIgQXZhdGFyXCIgXG5cdFx0XHRcdFx0XHRcdGhlaWdodD1cIjQwXCJcblx0XHRcdFx0XHRcdFx0d2lkdGg9XCI0MFwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImltZy1jaXJjbGVcIiAvPlxuXHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY2hhdC1ib2R5IGNsZWFyZml4XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJoZWFkZXJcIj5cblx0XHRcdFx0XHRcdDxzdHJvbmcgY2xhc3NOYW1lPVwicHJpbWFyeS1mb250XCI+e3RoaXMucHJvcHMudXNlcm5hbWV9PC9zdHJvbmc+XG5cdFx0XHRcdFx0XHQ8c21hbGwgY2xhc3NOYW1lPVwicHVsbC1yaWdodCB0ZXh0LW11dGVkXCI+XG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLWNsb2NrLW8gZmEtZndcIj48L2k+IHt0aGlzLnN0YXRlLnRpbWVBZ299XG5cdFx0XHRcdFx0XHQ8L3NtYWxsPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxwPnt0aGlzLnByb3BzLmNvbnRlbnR9PC9wPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbGk+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBNZXNzYWdlQmFyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKGNvbnRlbnQpIHtcblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6bmV3XCIsIHtcblx0XHRcdGNvbnRlbnQ6IGNvbnRlbnRcblx0XHR9KTtcblx0fSxcblx0aGFuZGxlU3VibWl0OiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR2YXIgY29udGVudCA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5jb250ZW50KS52YWx1ZS50cmltKCk7XG5cdFx0aWYgKCFjb250ZW50KSByZXR1cm47XG5cdFx0UmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmNvbnRlbnQpLnZhbHVlID0gJyc7XG5cdFx0dGhpcy5zZW5kTWVzc2FnZShjb250ZW50KTtcblx0XHRyZXR1cm47XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8Zm9ybSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXR9ID5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cFwiPlxuXHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdGlkPVwiYnRuLWlucHV0XCIgXG5cdFx0XHRcdFx0XHR0eXBlPVwidGV4dFwiIFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiZm9ybS1jb250cm9sXCIgXG5cdFx0XHRcdFx0XHRyZWY9XCJjb250ZW50XCJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiQmUgcG9saXRlIHBsZWFzZS4uLlwiIC8+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAtYnRuXCI+XG5cdFx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRcdHR5cGU9XCJzdWJtaXRcIiBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCIgXG5cdFx0XHRcdFx0XHRcdGlkPVwiYnRuLWNoYXRcIiBcblx0XHRcdFx0XHRcdFx0dmFsdWU9XCJTZW5kXCIgLz5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9mb3JtPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgSm9pbkdhdGhlckJ1dHRvbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0am9pbkdhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0c29ja2V0LmVtaXQoXCJnYXRoZXI6am9pblwiLCB7fSk7XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBtZXNzYWdlID0gdGhpcy5wcm9wcy5idXR0b25OYW1lIHx8IFwiSm9pbiBHYXRoZXJcIjtcblx0XHR2YXIgYnV0dG9uQ2xhc3MgPSBcImJ0biBidG4tcHJpbWFyeVwiO1xuXHRcdGlmICh0aGlzLnByb3BzLmJ1dHRvbkNsYXNzKSB7XG5cdFx0XHRidXR0b25DbGFzcyArPSBcIiBcIiArIHRoaXMucHJvcHMuYnV0dG9uQ2xhc3M7XG5cdFx0fVxuXHRcdHJldHVybiAoPGJ1dHRvbiBcblx0XHRcdFx0XHRcdFx0b25DbGljaz17dGhpcy5qb2luR2F0aGVyfSBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPXtidXR0b25DbGFzc30+e21lc3NhZ2V9PC9idXR0b24+KVxuXHR9XG59KTtcblxudmFyIEdhdGhlclByb2dyZXNzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnYXRoZXJpbmdQcm9ncmVzczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBudW0gPSB0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMubGVuZ3RoO1xuXHRcdHZhciBkZW4gPSAxMjtcblx0XHRyZXR1cm4ge1xuXHRcdFx0bnVtOiBudW0sXG5cdFx0XHRkZW46IGRlbixcblx0XHRcdG1lc3NhZ2U6IG51bSArIFwiIC8gXCIgKyBkZW5cblx0XHR9O1xuXHR9LFxuXHRlbGVjdGlvblByb2dyZXNzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG51bSA9IHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgZ2F0aGVyZXIpIHtcblx0XHRcdGlmIChnYXRoZXJlci5sZWFkZXJWb3RlKSBhY2MrKztcblx0XHRcdHJldHVybiBhY2M7XG5cdFx0fSwgMCk7XG5cdFx0dmFyIGRlbiA9IDEyO1xuXHRcdHJldHVybiB7XG5cdFx0XHRudW06IG51bSxcblx0XHRcdGRlbjogZGVuLFxuXHRcdFx0bWVzc2FnZTogZGVuIC0gbnVtICsgXCIgbW9yZSB2b3RlcyByZXF1aXJlZFwiXG5cdFx0fTtcblx0fSxcblx0c2VsZWN0aW9uUHJvZ3Jlc3M6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbnVtID0gdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBnYXRoZXJlcikge1xuXHRcdFx0aWYgKGdhdGhlcmVyLnRlYW0gIT09IFwibG9iYnlcIikgYWNjKys7XG5cdFx0XHRyZXR1cm4gYWNjO1xuXHRcdH0sIDApO1xuXHRcdHZhciBkZW4gPSAxMjtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRudW06IG51bSxcblx0XHRcdGRlbjogZGVuLFxuXHRcdFx0bWVzc2FnZTogbnVtICsgXCIgb3V0IG9mIFwiICsgZGVuICsgXCIgcGxheWVycyBhc3NpZ25lZFwiXG5cdFx0fTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHByb2dyZXNzO1xuXHRcdHZhciBnYXRoZXJTdGF0ZSA9IHRoaXMucHJvcHMuZ2F0aGVyLnN0YXRlO1xuXHRcdGlmIChnYXRoZXJTdGF0ZSA9PT0gJ2dhdGhlcmluZycgJiYgdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmxlbmd0aCkge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLmdhdGhlcmluZ1Byb2dyZXNzKCk7XG5cdFx0fSBlbHNlIGlmIChnYXRoZXJTdGF0ZSA9PT0gJ2VsZWN0aW9uJykge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLmVsZWN0aW9uUHJvZ3Jlc3MoKTtcblx0XHR9IGVsc2UgaWYgKGdhdGhlclN0YXRlID09PSAnc2VsZWN0aW9uJykge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLnNlbGVjdGlvblByb2dyZXNzKCk7XG5cdFx0fVxuXHRcdGlmIChwcm9ncmVzcykge1xuXHRcdFx0dmFyIHN0eWxlID0ge1xuXHRcdFx0XHR3aWR0aDogTWF0aC5yb3VuZCgocHJvZ3Jlc3MubnVtIC8gcHJvZ3Jlc3MuZGVuICogMTAwKSkgKyBcIiVcIlxuXHRcdFx0fTtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keVwiPlxuXHRcdFx0XHRcdDxwPkdhdGhlciBQcm9ncmVzczwvcD5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInByb2dyZXNzXCI+XG5cdFx0XHRcdFx0ICA8ZGl2IGNsYXNzTmFtZT1cInByb2dyZXNzLWJhciBwcm9ncmVzcy1iYXItc3RyaXBlZCBhY3RpdmVcIiBcblx0XHRcdFx0XHQgIFx0ZGF0YS1yb2xlPVwicHJvZ3Jlc3NiYXJcIiBcblx0XHRcdFx0XHQgIFx0ZGF0YS1hcmlhLXZhbHVlbm93PXtwcm9ncmVzcy5udW19IFxuXHRcdFx0XHRcdCAgXHRkYXRhLWFyaWEtdmFsdWVtaW49XCIwXCIgXG5cdFx0XHRcdFx0ICBcdGRhdGEtYXJpYS12YWx1ZW1heD17cHJvZ3Jlc3MuZGVufSBcblx0XHRcdFx0XHQgIFx0c3R5bGU9e3N0eWxlfT5cblx0XHRcdFx0XHQgICAge3Byb2dyZXNzLm1lc3NhZ2V9XG5cdFx0XHRcdFx0ICA8L2Rpdj5cblx0XHRcdFx0ICA8L2Rpdj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59KTtcblxudmFyIEdhdGhlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0Z2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGdhdGhlcjoge1xuXHRcdFx0XHRnYXRoZXJlcnM6IFtdXG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRqb2luZWRHYXRoZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0cmV0dXJuIHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5zb21lKGZ1bmN0aW9uIChnYXRoZXJlcikge1xuXHRcdFx0cmV0dXJuIGdhdGhlcmVyLnVzZXIuaWQgPT09IHNlbGYucHJvcHMudXNlci5pZDtcblx0XHR9KTtcblx0fSxcblx0Y29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0c29ja2V0Lm9uKFwiZ2F0aGVyOnJlZnJlc2hcIiwgZnVuY3Rpb24gKGRhdGEpIHtcblx0XHRcdHNlbGYuc2V0UHJvcHMoe1xuXHRcdFx0XHRnYXRoZXI6IGRhdGEuZ2F0aGVyLFxuXHRcdFx0XHR1c2VyOiBkYXRhLnVzZXJcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9LFxuXHRzdGF0ZURlc2NyaXB0aW9uOiBmdW5jdGlvbiAoKSB7XG5cdFx0c3dpdGNoKHRoaXMucHJvcHMuZ2F0aGVyLnN0YXRlKSB7XG5cdFx0XHRjYXNlIFwiZ2F0aGVyaW5nXCI6XG5cdFx0XHRcdHJldHVybiBcIldhaXRpbmcgZm9yIG1vcmUgZ2F0aGVyZXJzXCI7XG5cdFx0XHRjYXNlIFwiZWxlY3Rpb25cIjpcblx0XHRcdFx0cmV0dXJuIFwiQ3VycmVudGx5IHZvdGluZyBmb3IgdGVhbSBsZWFkZXJzXCI7XG5cdFx0XHRjYXNlIFwic2VsZWN0aW9uXCI6XG5cdFx0XHRcdHJldHVybiBcIldhaXRpbmcgZm9yIGxlYWRlcnMgdG8gcGlja2luZyB0ZWFtc1wiO1xuXHRcdFx0Y2FzZSBcImRvbmVcIjpcblx0XHRcdFx0cmV0dXJuIFwiR2F0aGVyIGNvbXBsZXRlZFwiO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiSW5pdGlhbGlzaW5nIGdhdGhlclwiO1xuXHRcdH1cblx0fSxcblx0bGVhdmVHYXRoZXI6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHNvY2tldC5lbWl0KFwiZ2F0aGVyOmxlYXZlXCIsIHt9KTtcblx0fSxcblx0aW52aXRlVG9HYXRoZXI6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgam9pbkJ1dHRvbjtcblx0XHRpZiAodGhpcy5qb2luZWRHYXRoZXIoKSkge1xuXHRcdFx0am9pbkJ1dHRvbiA9ICg8bGk+PGJ1dHRvbiBcblx0XHRcdFx0XHRcdFx0b25DbGljaz17dGhpcy5sZWF2ZUdhdGhlcn0gXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4tZGFuZ2VyXCI+TGVhdmUgR2F0aGVyPC9idXR0b24+PC9saT4pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqb2luQnV0dG9uID0gKDxsaT48Sm9pbkdhdGhlckJ1dHRvbiAvPjwvbGk+KTtcblx0XHR9XG5cdFx0dmFyIGludml0ZUJ1dHRvbjtcblx0XHRpZiAodGhpcy5wcm9wcy5nYXRoZXIuc3RhdGUgPT09ICdnYXRoZXJpbmcnKSB7XG5cdFx0XHRpbnZpdGVCdXR0b24gPSAoPGxpPjxidXR0b25cblx0XHRcdFx0XHRcdFx0b25DbGljaz17dGhpcy5pbnZpdGVUb0dhdGhlcn1cblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCI+SW52aXRlIHRvIEdhdGhlcjwvYnV0dG9uPjwvbGk+KTtcblx0XHR9XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwgcGFuZWwtZGVmYXVsdFwiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWhlYWRpbmdcIj5cblx0XHRcdFx0XHQ8c3Ryb25nPk5TMiBHYXRoZXIgPC9zdHJvbmc+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiYmFkZ2UgYWRkLWxlZnRcIj57dGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmxlbmd0aH08L3NwYW4+XG5cdFx0XHRcdFx0PGJyIC8+XG5cdFx0XHRcdFx0e3RoaXMuc3RhdGVEZXNjcmlwdGlvbigpfVxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PEdhdGhlcmVycyBnYXRoZXJlcnM9e3RoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVyc30gLz5cblx0XHRcdFx0PEdhdGhlclByb2dyZXNzIGdhdGhlcj17dGhpcy5wcm9wcy5nYXRoZXJ9IC8+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtZm9vdGVyIHRleHQtcmlnaHRcIj5cblx0XHRcdFx0XHQ8dWwgY2xhc3NOYW1lPVwibGlzdC1pbmxpbmVcIj5cblx0XHRcdFx0XHRcdHtpbnZpdGVCdXR0b259XG5cdFx0XHRcdFx0XHR7am9pbkJ1dHRvbn1cblx0XHRcdFx0XHQ8L3VsPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgTGVhZGVyUG9sbCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keVwiPlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBHYXRoZXJlcnMgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBnYXRoZXJlcnMgPSB0aGlzLnByb3BzLmdhdGhlcmVycy5tYXAoZnVuY3Rpb24gKGdhdGhlcmVyKSB7XG5cdFx0XHR2YXIgbGlmZWZvcm1zID0gKFxuXHRcdFx0XHRnYXRoZXJlci51c2VyLmFiaWxpdHkubGlmZWZvcm1zLm1hcChmdW5jdGlvbiAobGlmZWZvcm0pIHtcblx0XHRcdFx0XHRyZXR1cm4gKDxzcGFuIGNsYXNzTmFtZT1cImxhYmVsIGxhYmVsLWRlZmF1bHRcIj57bGlmZWZvcm19PC9zcGFuPik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHRcdFx0dmFyIGRpdmlzaW9uID0gKDxzcGFuIGNsYXNzTmFtZT1cImxhYmVsIGxhYmVsLXByaW1hcnlcIj57Z2F0aGVyZXIudXNlci5hYmlsaXR5LmRpdmlzaW9ufTwvc3Bhbj4pO1xuXHRcdFx0dmFyIGNvbW1CYWRnZTtcblx0XHRcdGlmIChnYXRoZXJlci51c2VyLmFiaWxpdHkuY29tbWFuZGVyKSB7XG5cdFx0XHRcdGNvbW1CYWRnZSA9ICg8aW1nIHNyYz1cIi9pbWFnZXMvY29tbWFuZGVyLnBuZ1wiIFxuXHRcdFx0XHRcdFx0XHRhbHQ9XCJDb21tYW5kZXJcIiBcblx0XHRcdFx0XHRcdFx0aGVpZ2h0PVwiMjBcIlxuXHRcdFx0XHRcdFx0XHR3aWR0aD1cIjIwXCIgLz4pXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDx0ciBrZXk9e2dhdGhlcmVyLnVzZXIuaWR9PlxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJjb2wtbWQtMVwiPntjb21tQmFkZ2V9PC90ZD5cblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwiY29sLW1kLTVcIj57Z2F0aGVyZXIudXNlci51c2VybmFtZX08L3RkPlxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJjb2wtbWQtM1wiPntkaXZpc2lvbn0mbmJzcDs8L3RkPlxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJjb2wtbWQtM1wiPntsaWZlZm9ybXN9Jm5ic3A7PC90ZD5cblx0XHRcdFx0PC90cj5cblx0XHRcdCk7XG5cdFx0fSlcblx0XHRpZiAodGhpcy5wcm9wcy5nYXRoZXJlcnMubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWJvZHlcIj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtaGVhZGluZ1wiPlxuXHRcdFx0XHRcdFx0XHQ8aDUgY2xhc3NOYW1lPVwicGFuZWwtdGl0bGVcIj5Sb3N0ZXI8L2g1PlxuXHRcdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdFx0XHQ8dGFibGUgY2xhc3NOYW1lPVwidGFibGUgcm9zdGVyLXRhYmxlXCI+XG5cdFx0XHRcdFx0XHRcdDx0Ym9keT5cblx0XHRcdFx0XHRcdFx0XHR7Z2F0aGVyZXJzfVxuXHRcdFx0XHRcdFx0XHQ8L3Rib2R5PlxuXHRcdFx0XHRcdFx0PC90YWJsZT5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gKDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keSB0ZXh0LWNlbnRlclwiPjxKb2luR2F0aGVyQnV0dG9uIGJ1dHRvbkNsYXNzPVwiYnRuLWxnXCIgYnV0dG9uTmFtZT1cIlN0YXJ0IGEgR2F0aGVyXCIgLz48L2Rpdj4pO1xuXHRcdH1cblx0fVxufSk7XG5cbnZhciBzb2NrZXQ7XG5cbmZ1bmN0aW9uIGluaXRpYWxpc2VDb21wb25lbnRzICgpIHtcblx0dmFyIHNvY2tldFVybCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuXHRzb2NrZXQgPSBpbyhzb2NrZXRVcmwpXG5cdFx0Lm9uKFwiY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkNvbm5lY3RlZFwiKTtcblx0XHR9KVxuXHRcdC5vbihcInJlY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlJlY29ubmVjdGVkXCIpO1xuXHRcdH0pXG5cdFx0Lm9uKFwiZGlzY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkRpc2Nvbm5lY3RlZFwiKVxuXHRcdH0pO1xuXG5cdFJlYWN0LnJlbmRlcig8VXNlck1lbnUgLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaWRlLW1lbnUnKSk7XG5cdFJlYWN0LnJlbmRlcig8Q2hhdHJvb20gLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGF0cm9vbScpKTtcblx0UmVhY3QucmVuZGVyKDxHYXRoZXIgLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdnYXRoZXJzJykpO1xufTtcblxuaW5pdGlhbGlzZUNvbXBvbmVudHMoKTtcblxuXG5cbn0pO1xuXG4iXX0= \ No newline at end of file diff --git a/public/js/react-0.13.3.js b/public/js/react-0.13.3.js new file mode 100644 index 0000000..ee718d0 --- /dev/null +++ b/public/js/react-0.13.3.js @@ -0,0 +1,19602 @@ +/** + * React v0.13.3 + */ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.React = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { + console.debug( + 'Download the React DevTools for a better development experience: ' + + 'https://fb.me/react-devtools' + ); + } + } + + var expectedFeatures = [ + // shims + Array.isArray, + Array.prototype.every, + Array.prototype.forEach, + Array.prototype.indexOf, + Array.prototype.map, + Date.now, + Function.prototype.bind, + Object.keys, + String.prototype.split, + String.prototype.trim, + + // shams + Object.create, + Object.freeze + ]; + + for (var i = 0; i < expectedFeatures.length; i++) { + if (!expectedFeatures[i]) { + console.error( + 'One or more ES5 shim/shams expected by React are not available: ' + + 'https://fb.me/react-warning-polyfills' + ); + break; + } + } + } +} + +React.version = '0.13.3'; + +module.exports = React; + +},{"117":117,"144":144,"19":19,"21":21,"27":27,"32":32,"33":33,"34":34,"38":38,"39":39,"40":40,"51":51,"54":54,"57":57,"58":58,"66":66,"70":70,"75":75,"78":78,"81":81,"84":84}],2:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule AutoFocusMixin + * @typechecks static-only + */ + +'use strict'; + +var focusNode = _dereq_(119); + +var AutoFocusMixin = { + componentDidMount: function() { + if (this.props.autoFocus) { + focusNode(this.getDOMNode()); + } + } +}; + +module.exports = AutoFocusMixin; + +},{"119":119}],3:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015 Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule BeforeInputEventPlugin + * @typechecks static-only + */ + +'use strict'; + +var EventConstants = _dereq_(15); +var EventPropagators = _dereq_(20); +var ExecutionEnvironment = _dereq_(21); +var FallbackCompositionState = _dereq_(22); +var SyntheticCompositionEvent = _dereq_(93); +var SyntheticInputEvent = _dereq_(97); + +var keyOf = _dereq_(141); + +var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space +var START_KEYCODE = 229; + +var canUseCompositionEvent = ( + ExecutionEnvironment.canUseDOM && + 'CompositionEvent' in window +); + +var documentMode = null; +if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { + documentMode = document.documentMode; +} + +// Webkit offers a very useful `textInput` event that can be used to +// directly represent `beforeInput`. The IE `textinput` event is not as +// useful, so we don't use it. +var canUseTextInputEvent = ( + ExecutionEnvironment.canUseDOM && + 'TextEvent' in window && + !documentMode && + !isPresto() +); + +// In IE9+, we have access to composition events, but the data supplied +// by the native compositionend event may be incorrect. Japanese ideographic +// spaces, for instance (\u3000) are not recorded correctly. +var useFallbackCompositionData = ( + ExecutionEnvironment.canUseDOM && + ( + (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) + ) +); + +/** + * Opera <= 12 includes TextEvent in window, but does not fire + * text input events. Rely on keypress instead. + */ +function isPresto() { + var opera = window.opera; + return ( + typeof opera === 'object' && + typeof opera.version === 'function' && + parseInt(opera.version(), 10) <= 12 + ); +} + +var SPACEBAR_CODE = 32; +var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); + +var topLevelTypes = EventConstants.topLevelTypes; + +// Events and their corresponding property names. +var eventTypes = { + beforeInput: { + phasedRegistrationNames: { + bubbled: keyOf({onBeforeInput: null}), + captured: keyOf({onBeforeInputCapture: null}) + }, + dependencies: [ + topLevelTypes.topCompositionEnd, + topLevelTypes.topKeyPress, + topLevelTypes.topTextInput, + topLevelTypes.topPaste + ] + }, + compositionEnd: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionEnd: null}), + captured: keyOf({onCompositionEndCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionEnd, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + }, + compositionStart: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionStart: null}), + captured: keyOf({onCompositionStartCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionStart, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + }, + compositionUpdate: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionUpdate: null}), + captured: keyOf({onCompositionUpdateCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionUpdate, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + } +}; + +// Track whether we've ever handled a keypress on the space key. +var hasSpaceKeypress = false; + +/** + * Return whether a native keypress event is assumed to be a command. + * This is required because Firefox fires `keypress` events for key commands + * (cut, copy, select-all, etc.) even though no character is inserted. + */ +function isKeypressCommand(nativeEvent) { + return ( + (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && + // ctrlKey && altKey is equivalent to AltGr, and is not a command. + !(nativeEvent.ctrlKey && nativeEvent.altKey) + ); +} + + +/** + * Translate native top level events into event types. + * + * @param {string} topLevelType + * @return {object} + */ +function getCompositionEventType(topLevelType) { + switch (topLevelType) { + case topLevelTypes.topCompositionStart: + return eventTypes.compositionStart; + case topLevelTypes.topCompositionEnd: + return eventTypes.compositionEnd; + case topLevelTypes.topCompositionUpdate: + return eventTypes.compositionUpdate; + } +} + +/** + * Does our fallback best-guess model think this event signifies that + * composition has begun? + * + * @param {string} topLevelType + * @param {object} nativeEvent + * @return {boolean} + */ +function isFallbackCompositionStart(topLevelType, nativeEvent) { + return ( + topLevelType === topLevelTypes.topKeyDown && + nativeEvent.keyCode === START_KEYCODE + ); +} + +/** + * Does our fallback mode think that this event is the end of composition? + * + * @param {string} topLevelType + * @param {object} nativeEvent + * @return {boolean} + */ +function isFallbackCompositionEnd(topLevelType, nativeEvent) { + switch (topLevelType) { + case topLevelTypes.topKeyUp: + // Command keys insert or clear IME input. + return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); + case topLevelTypes.topKeyDown: + // Expect IME keyCode on each keydown. If we get any other + // code we must have exited earlier. + return (nativeEvent.keyCode !== START_KEYCODE); + case topLevelTypes.topKeyPress: + case topLevelTypes.topMouseDown: + case topLevelTypes.topBlur: + // Events are not possible without cancelling IME. + return true; + default: + return false; + } +} + +/** + * Google Input Tools provides composition data via a CustomEvent, + * with the `data` property populated in the `detail` object. If this + * is available on the event object, use it. If not, this is a plain + * composition event and we have nothing special to extract. + * + * @param {object} nativeEvent + * @return {?string} + */ +function getDataFromCustomEvent(nativeEvent) { + var detail = nativeEvent.detail; + if (typeof detail === 'object' && 'data' in detail) { + return detail.data; + } + return null; +} + +// Track the current IME composition fallback object, if any. +var currentComposition = null; + +/** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {?object} A SyntheticCompositionEvent. + */ +function extractCompositionEvent( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent +) { + var eventType; + var fallbackData; + + if (canUseCompositionEvent) { + eventType = getCompositionEventType(topLevelType); + } else if (!currentComposition) { + if (isFallbackCompositionStart(topLevelType, nativeEvent)) { + eventType = eventTypes.compositionStart; + } + } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { + eventType = eventTypes.compositionEnd; + } + + if (!eventType) { + return null; + } + + if (useFallbackCompositionData) { + // The current composition is stored statically and must not be + // overwritten while composition continues. + if (!currentComposition && eventType === eventTypes.compositionStart) { + currentComposition = FallbackCompositionState.getPooled(topLevelTarget); + } else if (eventType === eventTypes.compositionEnd) { + if (currentComposition) { + fallbackData = currentComposition.getData(); + } + } + } + + var event = SyntheticCompositionEvent.getPooled( + eventType, + topLevelTargetID, + nativeEvent + ); + + if (fallbackData) { + // Inject data generated from fallback path into the synthetic event. + // This matches the property of native CompositionEventInterface. + event.data = fallbackData; + } else { + var customData = getDataFromCustomEvent(nativeEvent); + if (customData !== null) { + event.data = customData; + } + } + + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; +} + +/** + * @param {string} topLevelType Record from `EventConstants`. + * @param {object} nativeEvent Native browser event. + * @return {?string} The string corresponding to this `beforeInput` event. + */ +function getNativeBeforeInputChars(topLevelType, nativeEvent) { + switch (topLevelType) { + case topLevelTypes.topCompositionEnd: + return getDataFromCustomEvent(nativeEvent); + case topLevelTypes.topKeyPress: + /** + * If native `textInput` events are available, our goal is to make + * use of them. However, there is a special case: the spacebar key. + * In Webkit, preventing default on a spacebar `textInput` event + * cancels character insertion, but it *also* causes the browser + * to fall back to its default spacebar behavior of scrolling the + * page. + * + * Tracking at: + * https://code.google.com/p/chromium/issues/detail?id=355103 + * + * To avoid this issue, use the keypress event as if no `textInput` + * event is available. + */ + var which = nativeEvent.which; + if (which !== SPACEBAR_CODE) { + return null; + } + + hasSpaceKeypress = true; + return SPACEBAR_CHAR; + + case topLevelTypes.topTextInput: + // Record the characters to be added to the DOM. + var chars = nativeEvent.data; + + // If it's a spacebar character, assume that we have already handled + // it at the keypress level and bail immediately. Android Chrome + // doesn't give us keycodes, so we need to blacklist it. + if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { + return null; + } + + return chars; + + default: + // For other native event types, do nothing. + return null; + } +} + +/** + * For browsers that do not provide the `textInput` event, extract the + * appropriate string to use for SyntheticInputEvent. + * + * @param {string} topLevelType Record from `EventConstants`. + * @param {object} nativeEvent Native browser event. + * @return {?string} The fallback string for this `beforeInput` event. + */ +function getFallbackBeforeInputChars(topLevelType, nativeEvent) { + // If we are currently composing (IME) and using a fallback to do so, + // try to extract the composed characters from the fallback object. + if (currentComposition) { + if ( + topLevelType === topLevelTypes.topCompositionEnd || + isFallbackCompositionEnd(topLevelType, nativeEvent) + ) { + var chars = currentComposition.getData(); + FallbackCompositionState.release(currentComposition); + currentComposition = null; + return chars; + } + return null; + } + + switch (topLevelType) { + case topLevelTypes.topPaste: + // If a paste event occurs after a keypress, throw out the input + // chars. Paste events should not lead to BeforeInput events. + return null; + case topLevelTypes.topKeyPress: + /** + * As of v27, Firefox may fire keypress events even when no character + * will be inserted. A few possibilities: + * + * - `which` is `0`. Arrow keys, Esc key, etc. + * + * - `which` is the pressed key code, but no char is available. + * Ex: 'AltGr + d` in Polish. There is no modified character for + * this key combination and no character is inserted into the + * document, but FF fires the keypress for char code `100` anyway. + * No `input` event will occur. + * + * - `which` is the pressed key code, but a command combination is + * being used. Ex: `Cmd+C`. No character is inserted, and no + * `input` event will occur. + */ + if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { + return String.fromCharCode(nativeEvent.which); + } + return null; + case topLevelTypes.topCompositionEnd: + return useFallbackCompositionData ? null : nativeEvent.data; + default: + return null; + } +} + +/** + * Extract a SyntheticInputEvent for `beforeInput`, based on either native + * `textInput` or fallback behavior. + * + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {?object} A SyntheticInputEvent. + */ +function extractBeforeInputEvent( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent +) { + var chars; + + if (canUseTextInputEvent) { + chars = getNativeBeforeInputChars(topLevelType, nativeEvent); + } else { + chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); + } + + // If no characters are being inserted, no BeforeInput event should + // be fired. + if (!chars) { + return null; + } + + var event = SyntheticInputEvent.getPooled( + eventTypes.beforeInput, + topLevelTargetID, + nativeEvent + ); + + event.data = chars; + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; +} + +/** + * Create an `onBeforeInput` event to match + * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. + * + * This event plugin is based on the native `textInput` event + * available in Chrome, Safari, Opera, and IE. This event fires after + * `onKeyPress` and `onCompositionEnd`, but before `onInput`. + * + * `beforeInput` is spec'd but not implemented in any browsers, and + * the `input` event does not provide any useful information about what has + * actually been added, contrary to the spec. Thus, `textInput` is the best + * available event to identify the characters that have actually been inserted + * into the target node. + * + * This plugin is also responsible for emitting `composition` events, thus + * allowing us to share composition fallback code for both `beforeInput` and + * `composition` event types. + */ +var BeforeInputEventPlugin = { + + eventTypes: eventTypes, + + /** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent + ) { + return [ + extractCompositionEvent( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent + ), + extractBeforeInputEvent( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent + ) + ]; + } +}; + +module.exports = BeforeInputEventPlugin; + +},{"141":141,"15":15,"20":20,"21":21,"22":22,"93":93,"97":97}],4:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSProperty + */ + +'use strict'; + +/** + * CSS properties which accept numbers but are not in units of "px". + */ +var isUnitlessNumber = { + boxFlex: true, + boxFlexGroup: true, + columnCount: true, + flex: true, + flexGrow: true, + flexPositive: true, + flexShrink: true, + flexNegative: true, + fontWeight: true, + lineClamp: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + widows: true, + zIndex: true, + zoom: true, + + // SVG-related properties + fillOpacity: true, + strokeDashoffset: true, + strokeOpacity: true, + strokeWidth: true +}; + +/** + * @param {string} prefix vendor-specific prefix, eg: Webkit + * @param {string} key style name, eg: transitionDuration + * @return {string} style name prefixed with `prefix`, properly camelCased, eg: + * WebkitTransitionDuration + */ +function prefixKey(prefix, key) { + return prefix + key.charAt(0).toUpperCase() + key.substring(1); +} + +/** + * Support style names that may come passed in prefixed by adding permutations + * of vendor prefixes. + */ +var prefixes = ['Webkit', 'ms', 'Moz', 'O']; + +// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an +// infinite loop, because it iterates over the newly added props too. +Object.keys(isUnitlessNumber).forEach(function(prop) { + prefixes.forEach(function(prefix) { + isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; + }); +}); + +/** + * Most style properties can be unset by doing .style[prop] = '' but IE8 + * doesn't like doing that with shorthand properties so for the properties that + * IE8 breaks on, which are listed here, we instead unset each of the + * individual properties. See http://bugs.jquery.com/ticket/12385. + * The 4-value 'clock' properties like margin, padding, border-width seem to + * behave without any problems. Curiously, list-style works too without any + * special prodding. + */ +var shorthandPropertyExpansions = { + background: { + backgroundImage: true, + backgroundPosition: true, + backgroundRepeat: true, + backgroundColor: true + }, + border: { + borderWidth: true, + borderStyle: true, + borderColor: true + }, + borderBottom: { + borderBottomWidth: true, + borderBottomStyle: true, + borderBottomColor: true + }, + borderLeft: { + borderLeftWidth: true, + borderLeftStyle: true, + borderLeftColor: true + }, + borderRight: { + borderRightWidth: true, + borderRightStyle: true, + borderRightColor: true + }, + borderTop: { + borderTopWidth: true, + borderTopStyle: true, + borderTopColor: true + }, + font: { + fontStyle: true, + fontVariant: true, + fontWeight: true, + fontSize: true, + lineHeight: true, + fontFamily: true + } +}; + +var CSSProperty = { + isUnitlessNumber: isUnitlessNumber, + shorthandPropertyExpansions: shorthandPropertyExpansions +}; + +module.exports = CSSProperty; + +},{}],5:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSPropertyOperations + * @typechecks static-only + */ + +'use strict'; + +var CSSProperty = _dereq_(4); +var ExecutionEnvironment = _dereq_(21); + +var camelizeStyleName = _dereq_(108); +var dangerousStyleValue = _dereq_(113); +var hyphenateStyleName = _dereq_(133); +var memoizeStringOnly = _dereq_(143); +var warning = _dereq_(154); + +var processStyleName = memoizeStringOnly(function(styleName) { + return hyphenateStyleName(styleName); +}); + +var styleFloatAccessor = 'cssFloat'; +if (ExecutionEnvironment.canUseDOM) { + // IE8 only supports accessing cssFloat (standard) as styleFloat + if (document.documentElement.style.cssFloat === undefined) { + styleFloatAccessor = 'styleFloat'; + } +} + +if ("production" !== "development") { + // 'msTransform' is correct, but the other prefixes should be capitalized + var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; + + // style values shouldn't contain a semicolon + var badStyleValueWithSemicolonPattern = /;\s*$/; + + var warnedStyleNames = {}; + var warnedStyleValues = {}; + + var warnHyphenatedStyleName = function(name) { + if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { + return; + } + + warnedStyleNames[name] = true; + ("production" !== "development" ? warning( + false, + 'Unsupported style property %s. Did you mean %s?', + name, + camelizeStyleName(name) + ) : null); + }; + + var warnBadVendoredStyleName = function(name) { + if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { + return; + } + + warnedStyleNames[name] = true; + ("production" !== "development" ? warning( + false, + 'Unsupported vendor-prefixed style property %s. Did you mean %s?', + name, + name.charAt(0).toUpperCase() + name.slice(1) + ) : null); + }; + + var warnStyleValueWithSemicolon = function(name, value) { + if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { + return; + } + + warnedStyleValues[value] = true; + ("production" !== "development" ? warning( + false, + 'Style property values shouldn\'t contain a semicolon. ' + + 'Try "%s: %s" instead.', + name, + value.replace(badStyleValueWithSemicolonPattern, '') + ) : null); + }; + + /** + * @param {string} name + * @param {*} value + */ + var warnValidStyle = function(name, value) { + if (name.indexOf('-') > -1) { + warnHyphenatedStyleName(name); + } else if (badVendoredStyleNamePattern.test(name)) { + warnBadVendoredStyleName(name); + } else if (badStyleValueWithSemicolonPattern.test(value)) { + warnStyleValueWithSemicolon(name, value); + } + }; +} + +/** + * Operations for dealing with CSS properties. + */ +var CSSPropertyOperations = { + + /** + * Serializes a mapping of style properties for use as inline styles: + * + * > createMarkupForStyles({width: '200px', height: 0}) + * "width:200px;height:0;" + * + * Undefined values are ignored so that declarative programming is easier. + * The result should be HTML-escaped before insertion into the DOM. + * + * @param {object} styles + * @return {?string} + */ + createMarkupForStyles: function(styles) { + var serialized = ''; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + var styleValue = styles[styleName]; + if ("production" !== "development") { + warnValidStyle(styleName, styleValue); + } + if (styleValue != null) { + serialized += processStyleName(styleName) + ':'; + serialized += dangerousStyleValue(styleName, styleValue) + ';'; + } + } + return serialized || null; + }, + + /** + * Sets the value for multiple styles on a node. If a value is specified as + * '' (empty string), the corresponding style property will be unset. + * + * @param {DOMElement} node + * @param {object} styles + */ + setValueForStyles: function(node, styles) { + var style = node.style; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + if ("production" !== "development") { + warnValidStyle(styleName, styles[styleName]); + } + var styleValue = dangerousStyleValue(styleName, styles[styleName]); + if (styleName === 'float') { + styleName = styleFloatAccessor; + } + if (styleValue) { + style[styleName] = styleValue; + } else { + var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; + if (expansion) { + // Shorthand property that IE8 won't like unsetting, so unset each + // component to placate it + for (var individualStyleName in expansion) { + style[individualStyleName] = ''; + } + } else { + style[styleName] = ''; + } + } + } + } + +}; + +module.exports = CSSPropertyOperations; + +},{"108":108,"113":113,"133":133,"143":143,"154":154,"21":21,"4":4}],6:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CallbackQueue + */ + +'use strict'; + +var PooledClass = _dereq_(28); + +var assign = _dereq_(27); +var invariant = _dereq_(135); + +/** + * A specialized pseudo-event module to help keep track of components waiting to + * be notified when their DOM representations are available for use. + * + * This implements `PooledClass`, so you should never need to instantiate this. + * Instead, use `CallbackQueue.getPooled()`. + * + * @class ReactMountReady + * @implements PooledClass + * @internal + */ +function CallbackQueue() { + this._callbacks = null; + this._contexts = null; +} + +assign(CallbackQueue.prototype, { + + /** + * Enqueues a callback to be invoked when `notifyAll` is invoked. + * + * @param {function} callback Invoked when `notifyAll` is invoked. + * @param {?object} context Context to call `callback` with. + * @internal + */ + enqueue: function(callback, context) { + this._callbacks = this._callbacks || []; + this._contexts = this._contexts || []; + this._callbacks.push(callback); + this._contexts.push(context); + }, + + /** + * Invokes all enqueued callbacks and clears the queue. This is invoked after + * the DOM representation of a component has been created or updated. + * + * @internal + */ + notifyAll: function() { + var callbacks = this._callbacks; + var contexts = this._contexts; + if (callbacks) { + ("production" !== "development" ? invariant( + callbacks.length === contexts.length, + 'Mismatched list of contexts in callback queue' + ) : invariant(callbacks.length === contexts.length)); + this._callbacks = null; + this._contexts = null; + for (var i = 0, l = callbacks.length; i < l; i++) { + callbacks[i].call(contexts[i]); + } + callbacks.length = 0; + contexts.length = 0; + } + }, + + /** + * Resets the internal queue. + * + * @internal + */ + reset: function() { + this._callbacks = null; + this._contexts = null; + }, + + /** + * `PooledClass` looks for this. + */ + destructor: function() { + this.reset(); + } + +}); + +PooledClass.addPoolingTo(CallbackQueue); + +module.exports = CallbackQueue; + +},{"135":135,"27":27,"28":28}],7:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ChangeEventPlugin + */ + +'use strict'; + +var EventConstants = _dereq_(15); +var EventPluginHub = _dereq_(17); +var EventPropagators = _dereq_(20); +var ExecutionEnvironment = _dereq_(21); +var ReactUpdates = _dereq_(87); +var SyntheticEvent = _dereq_(95); + +var isEventSupported = _dereq_(136); +var isTextInputElement = _dereq_(138); +var keyOf = _dereq_(141); + +var topLevelTypes = EventConstants.topLevelTypes; + +var eventTypes = { + change: { + phasedRegistrationNames: { + bubbled: keyOf({onChange: null}), + captured: keyOf({onChangeCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topChange, + topLevelTypes.topClick, + topLevelTypes.topFocus, + topLevelTypes.topInput, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyUp, + topLevelTypes.topSelectionChange + ] + } +}; + +/** + * For IE shims + */ +var activeElement = null; +var activeElementID = null; +var activeElementValue = null; +var activeElementValueProp = null; + +/** + * SECTION: handle `change` event + */ +function shouldUseChangeEvent(elem) { + return ( + elem.nodeName === 'SELECT' || + (elem.nodeName === 'INPUT' && elem.type === 'file') + ); +} + +var doesChangeEventBubble = false; +if (ExecutionEnvironment.canUseDOM) { + // See `handleChange` comment below + doesChangeEventBubble = isEventSupported('change') && ( + (!('documentMode' in document) || document.documentMode > 8) + ); +} + +function manualDispatchChangeEvent(nativeEvent) { + var event = SyntheticEvent.getPooled( + eventTypes.change, + activeElementID, + nativeEvent + ); + EventPropagators.accumulateTwoPhaseDispatches(event); + + // If change and propertychange bubbled, we'd just bind to it like all the + // other events and have it go through ReactBrowserEventEmitter. Since it + // doesn't, we manually listen for the events and so we have to enqueue and + // process the abstract event manually. + // + // Batching is necessary here in order to ensure that all event handlers run + // before the next rerender (including event handlers attached to ancestor + // elements instead of directly on the input). Without this, controlled + // components don't work properly in conjunction with event bubbling because + // the component is rerendered and the value reverted before all the event + // handlers can run. See https://github.com/facebook/react/issues/708. + ReactUpdates.batchedUpdates(runEventInBatch, event); +} + +function runEventInBatch(event) { + EventPluginHub.enqueueEvents(event); + EventPluginHub.processEventQueue(); +} + +function startWatchingForChangeEventIE8(target, targetID) { + activeElement = target; + activeElementID = targetID; + activeElement.attachEvent('onchange', manualDispatchChangeEvent); +} + +function stopWatchingForChangeEventIE8() { + if (!activeElement) { + return; + } + activeElement.detachEvent('onchange', manualDispatchChangeEvent); + activeElement = null; + activeElementID = null; +} + +function getTargetIDForChangeEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topChange) { + return topLevelTargetID; + } +} +function handleEventsForChangeEventIE8( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topFocus) { + // stopWatching() should be a noop here but we call it just in case we + // missed a blur event somehow. + stopWatchingForChangeEventIE8(); + startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); + } else if (topLevelType === topLevelTypes.topBlur) { + stopWatchingForChangeEventIE8(); + } +} + + +/** + * SECTION: handle `input` event + */ +var isInputEventSupported = false; +if (ExecutionEnvironment.canUseDOM) { + // IE9 claims to support the input event but fails to trigger it when + // deleting text, so we ignore its input events + isInputEventSupported = isEventSupported('input') && ( + (!('documentMode' in document) || document.documentMode > 9) + ); +} + +/** + * (For old IE.) Replacement getter/setter for the `value` property that gets + * set on the active element. + */ +var newValueProp = { + get: function() { + return activeElementValueProp.get.call(this); + }, + set: function(val) { + // Cast to a string so we can do equality checks. + activeElementValue = '' + val; + activeElementValueProp.set.call(this, val); + } +}; + +/** + * (For old IE.) Starts tracking propertychange events on the passed-in element + * and override the value property so that we can distinguish user events from + * value changes in JS. + */ +function startWatchingForValueChange(target, targetID) { + activeElement = target; + activeElementID = targetID; + activeElementValue = target.value; + activeElementValueProp = Object.getOwnPropertyDescriptor( + target.constructor.prototype, + 'value' + ); + + Object.defineProperty(activeElement, 'value', newValueProp); + activeElement.attachEvent('onpropertychange', handlePropertyChange); +} + +/** + * (For old IE.) Removes the event listeners from the currently-tracked element, + * if any exists. + */ +function stopWatchingForValueChange() { + if (!activeElement) { + return; + } + + // delete restores the original property definition + delete activeElement.value; + activeElement.detachEvent('onpropertychange', handlePropertyChange); + + activeElement = null; + activeElementID = null; + activeElementValue = null; + activeElementValueProp = null; +} + +/** + * (For old IE.) Handles a propertychange event, sending a `change` event if + * the value of the active element has changed. + */ +function handlePropertyChange(nativeEvent) { + if (nativeEvent.propertyName !== 'value') { + return; + } + var value = nativeEvent.srcElement.value; + if (value === activeElementValue) { + return; + } + activeElementValue = value; + + manualDispatchChangeEvent(nativeEvent); +} + +/** + * If a `change` event should be fired, returns the target's ID. + */ +function getTargetIDForInputEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topInput) { + // In modern browsers (i.e., not IE8 or IE9), the input event is exactly + // what we want so fall through here and trigger an abstract event + return topLevelTargetID; + } +} + +// For IE8 and IE9. +function handleEventsForInputEventIE( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topFocus) { + // In IE8, we can capture almost all .value changes by adding a + // propertychange handler and looking for events with propertyName + // equal to 'value' + // In IE9, propertychange fires for most input events but is buggy and + // doesn't fire when text is deleted, but conveniently, selectionchange + // appears to fire in all of the remaining cases so we catch those and + // forward the event if the value has changed + // In either case, we don't want to call the event handler if the value + // is changed from JS so we redefine a setter for `.value` that updates + // our activeElementValue variable, allowing us to ignore those changes + // + // stopWatching() should be a noop here but we call it just in case we + // missed a blur event somehow. + stopWatchingForValueChange(); + startWatchingForValueChange(topLevelTarget, topLevelTargetID); + } else if (topLevelType === topLevelTypes.topBlur) { + stopWatchingForValueChange(); + } +} + +// For IE8 and IE9. +function getTargetIDForInputEventIE( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topSelectionChange || + topLevelType === topLevelTypes.topKeyUp || + topLevelType === topLevelTypes.topKeyDown) { + // On the selectionchange event, the target is just document which isn't + // helpful for us so just check activeElement instead. + // + // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire + // propertychange on the first input event after setting `value` from a + // script and fires only keydown, keypress, keyup. Catching keyup usually + // gets it and catching keydown lets us fire an event for the first + // keystroke if user does a key repeat (it'll be a little delayed: right + // before the second keystroke). Other input methods (e.g., paste) seem to + // fire selectionchange normally. + if (activeElement && activeElement.value !== activeElementValue) { + activeElementValue = activeElement.value; + return activeElementID; + } + } +} + + +/** + * SECTION: handle `click` event + */ +function shouldUseClickEvent(elem) { + // Use the `click` event to detect changes to checkbox and radio inputs. + // This approach works across all browsers, whereas `change` does not fire + // until `blur` in IE8. + return ( + elem.nodeName === 'INPUT' && + (elem.type === 'checkbox' || elem.type === 'radio') + ); +} + +function getTargetIDForClickEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topClick) { + return topLevelTargetID; + } +} + +/** + * This plugin creates an `onChange` event that normalizes change events + * across form elements. This event fires at a time when it's possible to + * change the element's value without seeing a flicker. + * + * Supported elements are: + * - input (see `isTextInputElement`) + * - textarea + * - select + */ +var ChangeEventPlugin = { + + eventTypes: eventTypes, + + /** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + + var getTargetIDFunc, handleEventFunc; + if (shouldUseChangeEvent(topLevelTarget)) { + if (doesChangeEventBubble) { + getTargetIDFunc = getTargetIDForChangeEvent; + } else { + handleEventFunc = handleEventsForChangeEventIE8; + } + } else if (isTextInputElement(topLevelTarget)) { + if (isInputEventSupported) { + getTargetIDFunc = getTargetIDForInputEvent; + } else { + getTargetIDFunc = getTargetIDForInputEventIE; + handleEventFunc = handleEventsForInputEventIE; + } + } else if (shouldUseClickEvent(topLevelTarget)) { + getTargetIDFunc = getTargetIDForClickEvent; + } + + if (getTargetIDFunc) { + var targetID = getTargetIDFunc( + topLevelType, + topLevelTarget, + topLevelTargetID + ); + if (targetID) { + var event = SyntheticEvent.getPooled( + eventTypes.change, + targetID, + nativeEvent + ); + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; + } + } + + if (handleEventFunc) { + handleEventFunc( + topLevelType, + topLevelTarget, + topLevelTargetID + ); + } + } + +}; + +module.exports = ChangeEventPlugin; + +},{"136":136,"138":138,"141":141,"15":15,"17":17,"20":20,"21":21,"87":87,"95":95}],8:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ClientReactRootIndex + * @typechecks + */ + +'use strict'; + +var nextReactRootIndex = 0; + +var ClientReactRootIndex = { + createReactRootIndex: function() { + return nextReactRootIndex++; + } +}; + +module.exports = ClientReactRootIndex; + +},{}],9:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMChildrenOperations + * @typechecks static-only + */ + +'use strict'; + +var Danger = _dereq_(12); +var ReactMultiChildUpdateTypes = _dereq_(72); + +var setTextContent = _dereq_(149); +var invariant = _dereq_(135); + +/** + * Inserts `childNode` as a child of `parentNode` at the `index`. + * + * @param {DOMElement} parentNode Parent node in which to insert. + * @param {DOMElement} childNode Child node to insert. + * @param {number} index Index at which to insert the child. + * @internal + */ +function insertChildAt(parentNode, childNode, index) { + // By exploiting arrays returning `undefined` for an undefined index, we can + // rely exclusively on `insertBefore(node, null)` instead of also using + // `appendChild(node)`. However, using `undefined` is not allowed by all + // browsers so we must replace it with `null`. + parentNode.insertBefore( + childNode, + parentNode.childNodes[index] || null + ); +} + +/** + * Operations for updating with DOM children. + */ +var DOMChildrenOperations = { + + dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, + + updateTextContent: setTextContent, + + /** + * Updates a component's children by processing a series of updates. The + * update configurations are each expected to have a `parentNode` property. + * + * @param {array} updates List of update configurations. + * @param {array} markupList List of markup strings. + * @internal + */ + processUpdates: function(updates, markupList) { + var update; + // Mapping from parent IDs to initial child orderings. + var initialChildren = null; + // List of children that will be moved or removed. + var updatedChildren = null; + + for (var i = 0; i < updates.length; i++) { + update = updates[i]; + if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || + update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { + var updatedIndex = update.fromIndex; + var updatedChild = update.parentNode.childNodes[updatedIndex]; + var parentID = update.parentID; + + ("production" !== "development" ? invariant( + updatedChild, + 'processUpdates(): Unable to find child %s of element. This ' + + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + + 'browser), usually due to forgetting a when using tables, ' + + 'nesting tags like
    ,

    , or , or using non-SVG elements ' + + 'in an parent. Try inspecting the child nodes of the element ' + + 'with React ID `%s`.', + updatedIndex, + parentID + ) : invariant(updatedChild)); + + initialChildren = initialChildren || {}; + initialChildren[parentID] = initialChildren[parentID] || []; + initialChildren[parentID][updatedIndex] = updatedChild; + + updatedChildren = updatedChildren || []; + updatedChildren.push(updatedChild); + } + } + + var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + + // Remove updated children first so that `toIndex` is consistent. + if (updatedChildren) { + for (var j = 0; j < updatedChildren.length; j++) { + updatedChildren[j].parentNode.removeChild(updatedChildren[j]); + } + } + + for (var k = 0; k < updates.length; k++) { + update = updates[k]; + switch (update.type) { + case ReactMultiChildUpdateTypes.INSERT_MARKUP: + insertChildAt( + update.parentNode, + renderedMarkup[update.markupIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.MOVE_EXISTING: + insertChildAt( + update.parentNode, + initialChildren[update.parentID][update.fromIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.TEXT_CONTENT: + setTextContent( + update.parentNode, + update.textContent + ); + break; + case ReactMultiChildUpdateTypes.REMOVE_NODE: + // Already removed by the for-loop above. + break; + } + } + } + +}; + +module.exports = DOMChildrenOperations; + +},{"12":12,"135":135,"149":149,"72":72}],10:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMProperty + * @typechecks static-only + */ + +/*jslint bitwise: true */ + +'use strict'; + +var invariant = _dereq_(135); + +function checkMask(value, bitmask) { + return (value & bitmask) === bitmask; +} + +var DOMPropertyInjection = { + /** + * Mapping from normalized, camelcased property names to a configuration that + * specifies how the associated DOM property should be accessed or rendered. + */ + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, + + /** + * Inject some specialized knowledge about the DOM. This takes a config object + * with the following properties: + * + * isCustomAttribute: function that given an attribute name will return true + * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* + * attributes where it's impossible to enumerate all of the possible + * attribute names, + * + * Properties: object mapping DOM property name to one of the + * DOMPropertyInjection constants or null. If your attribute isn't in here, + * it won't get written to the DOM. + * + * DOMAttributeNames: object mapping React attribute name to the DOM + * attribute name. Attribute names not specified use the **lowercase** + * normalized name. + * + * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. + * Property names not specified use the normalized name. + * + * DOMMutationMethods: Properties that require special mutation methods. If + * `value` is undefined, the mutation method should unset the property. + * + * @param {object} domPropertyConfig the config as described above. + */ + injectDOMPropertyConfig: function(domPropertyConfig) { + var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; + var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; + var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; + + if (domPropertyConfig.isCustomAttribute) { + DOMProperty._isCustomAttributeFunctions.push( + domPropertyConfig.isCustomAttribute + ); + } + + for (var propName in Properties) { + ("production" !== "development" ? invariant( + !DOMProperty.isStandardName.hasOwnProperty(propName), + 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + + '\'%s\' which has already been injected. You may be accidentally ' + + 'injecting the same DOM property config twice, or you may be ' + + 'injecting two configs that have conflicting property names.', + propName + ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); + + DOMProperty.isStandardName[propName] = true; + + var lowerCased = propName.toLowerCase(); + DOMProperty.getPossibleStandardName[lowerCased] = propName; + + if (DOMAttributeNames.hasOwnProperty(propName)) { + var attributeName = DOMAttributeNames[propName]; + DOMProperty.getPossibleStandardName[attributeName] = propName; + DOMProperty.getAttributeName[propName] = attributeName; + } else { + DOMProperty.getAttributeName[propName] = lowerCased; + } + + DOMProperty.getPropertyName[propName] = + DOMPropertyNames.hasOwnProperty(propName) ? + DOMPropertyNames[propName] : + propName; + + if (DOMMutationMethods.hasOwnProperty(propName)) { + DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; + } else { + DOMProperty.getMutationMethod[propName] = null; + } + + var propConfig = Properties[propName]; + DOMProperty.mustUseAttribute[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); + DOMProperty.mustUseProperty[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); + DOMProperty.hasSideEffects[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); + DOMProperty.hasBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); + DOMProperty.hasNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); + DOMProperty.hasPositiveNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); + DOMProperty.hasOverloadedBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); + + ("production" !== "development" ? invariant( + !DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName], + 'DOMProperty: Cannot require using both attribute and property: %s', + propName + ) : invariant(!DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName])); + ("production" !== "development" ? invariant( + DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName], + 'DOMProperty: Properties that have side effects must use property: %s', + propName + ) : invariant(DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName])); + ("production" !== "development" ? invariant( + !!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, + 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + + 'numeric value, but not a combination: %s', + propName + ) : invariant(!!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + } + } +}; +var defaultValueCache = {}; + +/** + * DOMProperty exports lookup objects that can be used like functions: + * + * > DOMProperty.isValid['id'] + * true + * > DOMProperty.isValid['foobar'] + * undefined + * + * Although this may be confusing, it performs better in general. + * + * @see http://jsperf.com/key-exists + * @see http://jsperf.com/key-missing + */ +var DOMProperty = { + + ID_ATTRIBUTE_NAME: 'data-reactid', + + /** + * Checks whether a property name is a standard property. + * @type {Object} + */ + isStandardName: {}, + + /** + * Mapping from lowercase property names to the properly cased version, used + * to warn in the case of missing properties. + * @type {Object} + */ + getPossibleStandardName: {}, + + /** + * Mapping from normalized names to attribute names that differ. Attribute + * names are used when rendering markup or with `*Attribute()`. + * @type {Object} + */ + getAttributeName: {}, + + /** + * Mapping from normalized names to properties on DOM node instances. + * (This includes properties that mutate due to external factors.) + * @type {Object} + */ + getPropertyName: {}, + + /** + * Mapping from normalized names to mutation methods. This will only exist if + * mutation cannot be set simply by the property or `setAttribute()`. + * @type {Object} + */ + getMutationMethod: {}, + + /** + * Whether the property must be accessed and mutated as an object property. + * @type {Object} + */ + mustUseAttribute: {}, + + /** + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * @type {Object} + */ + mustUseProperty: {}, + + /** + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. We must ensure that + * the value is only set if it has changed. + * @type {Object} + */ + hasSideEffects: {}, + + /** + * Whether the property should be removed when set to a falsey value. + * @type {Object} + */ + hasBooleanValue: {}, + + /** + * Whether the property must be numeric or parse as a + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasNumericValue: {}, + + /** + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasPositiveNumericValue: {}, + + /** + * Whether the property can be used as a flag as well as with a value. Removed + * when strictly equal to false; present without a value when strictly equal + * to true; present with a value otherwise. + * @type {Object} + */ + hasOverloadedBooleanValue: {}, + + /** + * All of the isCustomAttribute() functions that have been injected. + */ + _isCustomAttributeFunctions: [], + + /** + * Checks whether a property name is a custom attribute. + * @method + */ + isCustomAttribute: function(attributeName) { + for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { + var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; + if (isCustomAttributeFn(attributeName)) { + return true; + } + } + return false; + }, + + /** + * Returns the default property value for a DOM property (i.e., not an + * attribute). Most default values are '' or false, but not all. Worse yet, + * some (in particular, `type`) vary depending on the type of element. + * + * TODO: Is it better to grab all the possible properties when creating an + * element to avoid having to create the same element twice? + */ + getDefaultValueForProperty: function(nodeName, prop) { + var nodeDefaults = defaultValueCache[nodeName]; + var testElement; + if (!nodeDefaults) { + defaultValueCache[nodeName] = nodeDefaults = {}; + } + if (!(prop in nodeDefaults)) { + testElement = document.createElement(nodeName); + nodeDefaults[prop] = testElement[prop]; + } + return nodeDefaults[prop]; + }, + + injection: DOMPropertyInjection +}; + +module.exports = DOMProperty; + +},{"135":135}],11:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMPropertyOperations + * @typechecks static-only + */ + +'use strict'; + +var DOMProperty = _dereq_(10); + +var quoteAttributeValueForBrowser = _dereq_(147); +var warning = _dereq_(154); + +function shouldIgnoreValue(name, value) { + return value == null || + (DOMProperty.hasBooleanValue[name] && !value) || + (DOMProperty.hasNumericValue[name] && isNaN(value)) || + (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || + (DOMProperty.hasOverloadedBooleanValue[name] && value === false); +} + +if ("production" !== "development") { + var reactProps = { + children: true, + dangerouslySetInnerHTML: true, + key: true, + ref: true + }; + var warnedProperties = {}; + + var warnUnknownProperty = function(name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || + warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + return; + } + + warnedProperties[name] = true; + var lowerCasedName = name.toLowerCase(); + + // data-* attributes should be lowercase; suggest the lowercase version + var standardName = ( + DOMProperty.isCustomAttribute(lowerCasedName) ? + lowerCasedName : + DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? + DOMProperty.getPossibleStandardName[lowerCasedName] : + null + ); + + // For now, only warn when we have a suggested correction. This prevents + // logging too much when using transferPropsTo. + ("production" !== "development" ? warning( + standardName == null, + 'Unknown DOM property %s. Did you mean %s?', + name, + standardName + ) : null); + + }; +} + +/** + * Operations for dealing with DOM properties. + */ +var DOMPropertyOperations = { + + /** + * Creates markup for the ID property. + * + * @param {string} id Unescaped ID. + * @return {string} Markup string. + */ + createMarkupForID: function(id) { + return DOMProperty.ID_ATTRIBUTE_NAME + '=' + + quoteAttributeValueForBrowser(id); + }, + + /** + * Creates markup for a property. + * + * @param {string} name + * @param {*} value + * @return {?string} Markup string, or null if the property was invalid. + */ + createMarkupForProperty: function(name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + if (shouldIgnoreValue(name, value)) { + return ''; + } + var attributeName = DOMProperty.getAttributeName[name]; + if (DOMProperty.hasBooleanValue[name] || + (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { + return attributeName; + } + return attributeName + '=' + quoteAttributeValueForBrowser(value); + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + return ''; + } + return name + '=' + quoteAttributeValueForBrowser(value); + } else if ("production" !== "development") { + warnUnknownProperty(name); + } + return null; + }, + + /** + * Sets the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + * @param {*} value + */ + setValueForProperty: function(node, name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, value); + } else if (shouldIgnoreValue(name, value)) { + this.deleteValueForProperty(node, name); + } else if (DOMProperty.mustUseAttribute[name]) { + // `setAttribute` with objects becomes only `[object]` in IE8/9, + // ('' + value) makes it output the correct toString()-value. + node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + } else { + var propName = DOMProperty.getPropertyName[name]; + // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the + // property type before comparing; only `value` does and is string. + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== ('' + value)) { + // Contrary to `setAttribute`, object properties are properly + // `toString`ed by IE8/9. + node[propName] = value; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + } else if ("production" !== "development") { + warnUnknownProperty(name); + } + }, + + /** + * Deletes the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + */ + deleteValueForProperty: function(node, name) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, undefined); + } else if (DOMProperty.mustUseAttribute[name]) { + node.removeAttribute(DOMProperty.getAttributeName[name]); + } else { + var propName = DOMProperty.getPropertyName[name]; + var defaultValue = DOMProperty.getDefaultValueForProperty( + node.nodeName, + propName + ); + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== defaultValue) { + node[propName] = defaultValue; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + node.removeAttribute(name); + } else if ("production" !== "development") { + warnUnknownProperty(name); + } + } + +}; + +module.exports = DOMPropertyOperations; + +},{"10":10,"147":147,"154":154}],12:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule Danger + * @typechecks static-only + */ + +/*jslint evil: true, sub: true */ + +'use strict'; + +var ExecutionEnvironment = _dereq_(21); + +var createNodesFromMarkup = _dereq_(112); +var emptyFunction = _dereq_(114); +var getMarkupWrap = _dereq_(127); +var invariant = _dereq_(135); + +var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; +var RESULT_INDEX_ATTR = 'data-danger-index'; + +/** + * Extracts the `nodeName` from a string of markup. + * + * NOTE: Extracting the `nodeName` does not require a regular expression match + * because we make assumptions about React-generated markup (i.e. there are no + * spaces surrounding the opening tag and there is at least one attribute). + * + * @param {string} markup String of markup. + * @return {string} Node name of the supplied markup. + * @see http://jsperf.com/extract-nodename + */ +function getNodeName(markup) { + return markup.substring(1, markup.indexOf(' ')); +} + +var Danger = { + + /** + * Renders markup into an array of nodes. The markup is expected to render + * into a list of root nodes. Also, the length of `resultList` and + * `markupList` should be the same. + * + * @param {array} markupList List of markup strings to render. + * @return {array} List of rendered nodes. + * @internal + */ + dangerouslyRenderMarkup: function(markupList) { + ("production" !== "development" ? invariant( + ExecutionEnvironment.canUseDOM, + 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + + 'thread. Make sure `window` and `document` are available globally ' + + 'before requiring React when unit testing or use ' + + 'React.renderToString for server rendering.' + ) : invariant(ExecutionEnvironment.canUseDOM)); + var nodeName; + var markupByNodeName = {}; + // Group markup by `nodeName` if a wrap is necessary, else by '*'. + for (var i = 0; i < markupList.length; i++) { + ("production" !== "development" ? invariant( + markupList[i], + 'dangerouslyRenderMarkup(...): Missing markup.' + ) : invariant(markupList[i])); + nodeName = getNodeName(markupList[i]); + nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; + markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; + markupByNodeName[nodeName][i] = markupList[i]; + } + var resultList = []; + var resultListAssignmentCount = 0; + for (nodeName in markupByNodeName) { + if (!markupByNodeName.hasOwnProperty(nodeName)) { + continue; + } + var markupListByNodeName = markupByNodeName[nodeName]; + + // This for-in loop skips the holes of the sparse array. The order of + // iteration should follow the order of assignment, which happens to match + // numerical index order, but we don't rely on that. + var resultIndex; + for (resultIndex in markupListByNodeName) { + if (markupListByNodeName.hasOwnProperty(resultIndex)) { + var markup = markupListByNodeName[resultIndex]; + + // Push the requested markup with an additional RESULT_INDEX_ATTR + // attribute. If the markup does not start with a < character, it + // will be discarded below (with an appropriate console.error). + markupListByNodeName[resultIndex] = markup.replace( + OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' + ); + } + } + + // Render each group of markup with similar wrapping `nodeName`. + var renderNodes = createNodesFromMarkup( + markupListByNodeName.join(''), + emptyFunction // Do nothing special with

    ; + * } + * }); + * + * The class specification supports a specific protocol of methods that have + * special meaning (e.g. `render`). See `ReactClassInterface` for + * more the comprehensive protocol. Any other properties and methods in the + * class specification will available on the prototype. + * + * @interface ReactClassInterface + * @internal + */ +var ReactClassInterface = { + + /** + * An array of Mixin objects to include when defining your component. + * + * @type {array} + * @optional + */ + mixins: SpecPolicy.DEFINE_MANY, + + /** + * An object containing properties and methods that should be defined on + * the component's constructor instead of its prototype (static methods). + * + * @type {object} + * @optional + */ + statics: SpecPolicy.DEFINE_MANY, + + /** + * Definition of prop types for this component. + * + * @type {object} + * @optional + */ + propTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types for this component. + * + * @type {object} + * @optional + */ + contextTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types this component sets for its children. + * + * @type {object} + * @optional + */ + childContextTypes: SpecPolicy.DEFINE_MANY, + + // ==== Definition methods ==== + + /** + * Invoked when the component is mounted. Values in the mapping will be set on + * `this.props` if that prop is not specified (i.e. using an `in` check). + * + * This method is invoked before `getInitialState` and therefore cannot rely + * on `this.state` or use `this.setState`. + * + * @return {object} + * @optional + */ + getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Invoked once before the component is mounted. The return value will be used + * as the initial value of `this.state`. + * + * getInitialState: function() { + * return { + * isOn: false, + * fooBaz: new BazFoo() + * } + * } + * + * @return {object} + * @optional + */ + getInitialState: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * @return {object} + * @optional + */ + getChildContext: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Uses props from `this.props` and state from `this.state` to render the + * structure of the component. + * + * No guarantees are made about when or how often this method is invoked, so + * it must not have side effects. + * + * render: function() { + * var name = this.props.name; + * return
    Hello, {name}!
    ; + * } + * + * @return {ReactComponent} + * @nosideeffects + * @required + */ + render: SpecPolicy.DEFINE_ONCE, + + + + // ==== Delegate methods ==== + + /** + * Invoked when the component is initially created and about to be mounted. + * This may have side effects, but any external subscriptions or data created + * by this method must be cleaned up in `componentWillUnmount`. + * + * @optional + */ + componentWillMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component has been mounted and has a DOM representation. + * However, there is no guarantee that the DOM node is in the document. + * + * Use this as an opportunity to operate on the DOM when the component has + * been mounted (initialized and rendered) for the first time. + * + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked before the component receives new props. + * + * Use this as an opportunity to react to a prop transition by updating the + * state using `this.setState`. Current props are accessed via `this.props`. + * + * componentWillReceiveProps: function(nextProps, nextContext) { + * this.setState({ + * likesIncreasing: nextProps.likeCount > this.props.likeCount + * }); + * } + * + * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop + * transition may cause a state change, but the opposite is not true. If you + * need it, you are probably looking for `componentWillUpdate`. + * + * @param {object} nextProps + * @optional + */ + componentWillReceiveProps: SpecPolicy.DEFINE_MANY, + + /** + * Invoked while deciding if the component should be updated as a result of + * receiving new props, state and/or context. + * + * Use this as an opportunity to `return false` when you're certain that the + * transition to the new props/state/context will not require a component + * update. + * + * shouldComponentUpdate: function(nextProps, nextState, nextContext) { + * return !equal(nextProps, this.props) || + * !equal(nextState, this.state) || + * !equal(nextContext, this.context); + * } + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @return {boolean} True if the component should update. + * @optional + */ + shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, + + /** + * Invoked when the component is about to update due to a transition from + * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` + * and `nextContext`. + * + * Use this as an opportunity to perform preparation before an update occurs. + * + * NOTE: You **cannot** use `this.setState()` in this method. + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @param {ReactReconcileTransaction} transaction + * @optional + */ + componentWillUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component's DOM representation has been updated. + * + * Use this as an opportunity to operate on the DOM when the component has + * been updated. + * + * @param {object} prevProps + * @param {?object} prevState + * @param {?object} prevContext + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component is about to be removed from its parent and have + * its DOM representation destroyed. + * + * Use this as an opportunity to deallocate any external resources. + * + * NOTE: There is no `componentDidUnmount` since your component will have been + * destroyed by that point. + * + * @optional + */ + componentWillUnmount: SpecPolicy.DEFINE_MANY, + + + + // ==== Advanced methods ==== + + /** + * Updates the component's currently mounted DOM representation. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @internal + * @overridable + */ + updateComponent: SpecPolicy.OVERRIDE_BASE + +}; + +/** + * Mapping from class specification keys to special processing functions. + * + * Although these are declared like instance properties in the specification + * when defining classes using `React.createClass`, they are actually static + * and are accessible on the constructor instead of the prototype. Despite + * being static, they must be defined outside of the "statics" key under + * which all other static methods are defined. + */ +var RESERVED_SPEC_KEYS = { + displayName: function(Constructor, displayName) { + Constructor.displayName = displayName; + }, + mixins: function(Constructor, mixins) { + if (mixins) { + for (var i = 0; i < mixins.length; i++) { + mixSpecIntoComponent(Constructor, mixins[i]); + } + } + }, + childContextTypes: function(Constructor, childContextTypes) { + if ("production" !== "development") { + validateTypeDef( + Constructor, + childContextTypes, + ReactPropTypeLocations.childContext + ); + } + Constructor.childContextTypes = assign( + {}, + Constructor.childContextTypes, + childContextTypes + ); + }, + contextTypes: function(Constructor, contextTypes) { + if ("production" !== "development") { + validateTypeDef( + Constructor, + contextTypes, + ReactPropTypeLocations.context + ); + } + Constructor.contextTypes = assign( + {}, + Constructor.contextTypes, + contextTypes + ); + }, + /** + * Special case getDefaultProps which should move into statics but requires + * automatic merging. + */ + getDefaultProps: function(Constructor, getDefaultProps) { + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps = createMergedResultFunction( + Constructor.getDefaultProps, + getDefaultProps + ); + } else { + Constructor.getDefaultProps = getDefaultProps; + } + }, + propTypes: function(Constructor, propTypes) { + if ("production" !== "development") { + validateTypeDef( + Constructor, + propTypes, + ReactPropTypeLocations.prop + ); + } + Constructor.propTypes = assign( + {}, + Constructor.propTypes, + propTypes + ); + }, + statics: function(Constructor, statics) { + mixStaticSpecIntoComponent(Constructor, statics); + } +}; + +function validateTypeDef(Constructor, typeDef, location) { + for (var propName in typeDef) { + if (typeDef.hasOwnProperty(propName)) { + // use a warning instead of an invariant so components + // don't show up in prod but not in __DEV__ + ("production" !== "development" ? warning( + typeof typeDef[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + Constructor.displayName || 'ReactClass', + ReactPropTypeLocationNames[location], + propName + ) : null); + } + } +} + +function validateMethodOverride(proto, name) { + var specPolicy = ReactClassInterface.hasOwnProperty(name) ? + ReactClassInterface[name] : + null; + + // Disallow overriding of base class methods unless explicitly allowed. + if (ReactClassMixin.hasOwnProperty(name)) { + ("production" !== "development" ? invariant( + specPolicy === SpecPolicy.OVERRIDE_BASE, + 'ReactClassInterface: You are attempting to override ' + + '`%s` from your class specification. Ensure that your method names ' + + 'do not overlap with React methods.', + name + ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); + } + + // Disallow defining methods more than once unless explicitly allowed. + if (proto.hasOwnProperty(name)) { + ("production" !== "development" ? invariant( + specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED, + 'ReactClassInterface: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be due ' + + 'to a mixin.', + name + ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); + } +} + +/** + * Mixin helper which handles policy validation and reserved + * specification keys when building React classses. + */ +function mixSpecIntoComponent(Constructor, spec) { + if (!spec) { + return; + } + + ("production" !== "development" ? invariant( + typeof spec !== 'function', + 'ReactClass: You\'re attempting to ' + + 'use a component class as a mixin. Instead, just use a regular object.' + ) : invariant(typeof spec !== 'function')); + ("production" !== "development" ? invariant( + !ReactElement.isValidElement(spec), + 'ReactClass: You\'re attempting to ' + + 'use a component as a mixin. Instead, just use a regular object.' + ) : invariant(!ReactElement.isValidElement(spec))); + + var proto = Constructor.prototype; + + // By handling mixins before any other properties, we ensure the same + // chaining order is applied to methods with DEFINE_MANY policy, whether + // mixins are listed before or after these methods in the spec. + if (spec.hasOwnProperty(MIXINS_KEY)) { + RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); + } + + for (var name in spec) { + if (!spec.hasOwnProperty(name)) { + continue; + } + + if (name === MIXINS_KEY) { + // We have already handled mixins in a special case above + continue; + } + + var property = spec[name]; + validateMethodOverride(proto, name); + + if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { + RESERVED_SPEC_KEYS[name](Constructor, property); + } else { + // Setup methods on prototype: + // The following member methods should not be automatically bound: + // 1. Expected ReactClass methods (in the "interface"). + // 2. Overridden methods (that were mixed in). + var isReactClassMethod = + ReactClassInterface.hasOwnProperty(name); + var isAlreadyDefined = proto.hasOwnProperty(name); + var markedDontBind = property && property.__reactDontBind; + var isFunction = typeof property === 'function'; + var shouldAutoBind = + isFunction && + !isReactClassMethod && + !isAlreadyDefined && + !markedDontBind; + + if (shouldAutoBind) { + if (!proto.__reactAutoBindMap) { + proto.__reactAutoBindMap = {}; + } + proto.__reactAutoBindMap[name] = property; + proto[name] = property; + } else { + if (isAlreadyDefined) { + var specPolicy = ReactClassInterface[name]; + + // These cases should already be caught by validateMethodOverride + ("production" !== "development" ? invariant( + isReactClassMethod && ( + (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) + ), + 'ReactClass: Unexpected spec policy %s for key %s ' + + 'when mixing in component specs.', + specPolicy, + name + ) : invariant(isReactClassMethod && ( + (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) + ))); + + // For methods which are defined more than once, call the existing + // methods before calling the new property, merging if appropriate. + if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { + proto[name] = createMergedResultFunction(proto[name], property); + } else if (specPolicy === SpecPolicy.DEFINE_MANY) { + proto[name] = createChainedFunction(proto[name], property); + } + } else { + proto[name] = property; + if ("production" !== "development") { + // Add verbose displayName to the function, which helps when looking + // at profiling tools. + if (typeof property === 'function' && spec.displayName) { + proto[name].displayName = spec.displayName + '_' + name; + } + } + } + } + } + } +} + +function mixStaticSpecIntoComponent(Constructor, statics) { + if (!statics) { + return; + } + for (var name in statics) { + var property = statics[name]; + if (!statics.hasOwnProperty(name)) { + continue; + } + + var isReserved = name in RESERVED_SPEC_KEYS; + ("production" !== "development" ? invariant( + !isReserved, + 'ReactClass: You are attempting to define a reserved ' + + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + + 'as an instance property instead; it will still be accessible on the ' + + 'constructor.', + name + ) : invariant(!isReserved)); + + var isInherited = name in Constructor; + ("production" !== "development" ? invariant( + !isInherited, + 'ReactClass: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be ' + + 'due to a mixin.', + name + ) : invariant(!isInherited)); + Constructor[name] = property; + } +} + +/** + * Merge two objects, but throw if both contain the same key. + * + * @param {object} one The first object, which is mutated. + * @param {object} two The second object + * @return {object} one after it has been mutated to contain everything in two. + */ +function mergeIntoWithNoDuplicateKeys(one, two) { + ("production" !== "development" ? invariant( + one && two && typeof one === 'object' && typeof two === 'object', + 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' + ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); + + for (var key in two) { + if (two.hasOwnProperty(key)) { + ("production" !== "development" ? invariant( + one[key] === undefined, + 'mergeIntoWithNoDuplicateKeys(): ' + + 'Tried to merge two objects with the same key: `%s`. This conflict ' + + 'may be due to a mixin; in particular, this may be caused by two ' + + 'getInitialState() or getDefaultProps() methods returning objects ' + + 'with clashing keys.', + key + ) : invariant(one[key] === undefined)); + one[key] = two[key]; + } + } + return one; +} + +/** + * Creates a function that invokes two functions and merges their return values. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createMergedResultFunction(one, two) { + return function mergedResult() { + var a = one.apply(this, arguments); + var b = two.apply(this, arguments); + if (a == null) { + return b; + } else if (b == null) { + return a; + } + var c = {}; + mergeIntoWithNoDuplicateKeys(c, a); + mergeIntoWithNoDuplicateKeys(c, b); + return c; + }; +} + +/** + * Creates a function that invokes two functions and ignores their return vales. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createChainedFunction(one, two) { + return function chainedFunction() { + one.apply(this, arguments); + two.apply(this, arguments); + }; +} + +/** + * Binds a method to the component. + * + * @param {object} component Component whose method is going to be bound. + * @param {function} method Method to be bound. + * @return {function} The bound method. + */ +function bindAutoBindMethod(component, method) { + var boundMethod = method.bind(component); + if ("production" !== "development") { + boundMethod.__reactBoundContext = component; + boundMethod.__reactBoundMethod = method; + boundMethod.__reactBoundArguments = null; + var componentName = component.constructor.displayName; + var _bind = boundMethod.bind; + /* eslint-disable block-scoped-var, no-undef */ + boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + // User is trying to bind() an autobound method; we effectively will + // ignore the value of "this" that the user is trying to use, so + // let's warn. + if (newThis !== component && newThis !== null) { + ("production" !== "development" ? warning( + false, + 'bind(): React component methods may only be bound to the ' + + 'component instance. See %s', + componentName + ) : null); + } else if (!args.length) { + ("production" !== "development" ? warning( + false, + 'bind(): You are binding a component method to the component. ' + + 'React does this for you automatically in a high-performance ' + + 'way, so you can safely remove this call. See %s', + componentName + ) : null); + return boundMethod; + } + var reboundMethod = _bind.apply(boundMethod, arguments); + reboundMethod.__reactBoundContext = component; + reboundMethod.__reactBoundMethod = method; + reboundMethod.__reactBoundArguments = args; + return reboundMethod; + /* eslint-enable */ + }; + } + return boundMethod; +} + +/** + * Binds all auto-bound methods in a component. + * + * @param {object} component Component whose method is going to be bound. + */ +function bindAutoBindMethods(component) { + for (var autoBindKey in component.__reactAutoBindMap) { + if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { + var method = component.__reactAutoBindMap[autoBindKey]; + component[autoBindKey] = bindAutoBindMethod( + component, + ReactErrorUtils.guard( + method, + component.constructor.displayName + '.' + autoBindKey + ) + ); + } + } +} + +var typeDeprecationDescriptor = { + enumerable: false, + get: function() { + var displayName = this.displayName || this.name || 'Component'; + ("production" !== "development" ? warning( + false, + '%s.type is deprecated. Use %s directly to access the class.', + displayName, + displayName + ) : null); + Object.defineProperty(this, 'type', { + value: this + }); + return this; + } +}; + +/** + * Add more to the ReactClass base class. These are all legacy features and + * therefore not already part of the modern ReactComponent. + */ +var ReactClassMixin = { + + /** + * TODO: This will be deprecated because state should always keep a consistent + * type signature and the only use case for this, is to avoid that. + */ + replaceState: function(newState, callback) { + ReactUpdateQueue.enqueueReplaceState(this, newState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Checks whether or not this composite component is mounted. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function() { + if ("production" !== "development") { + var owner = ReactCurrentOwner.current; + if (owner !== null) { + ("production" !== "development" ? warning( + owner._warnedAboutRefsInRender, + '%s is accessing isMounted inside its render() function. ' + + 'render() should be a pure function of props and state. It should ' + + 'never access something that requires stale data from the previous ' + + 'render, such as refs. Move this logic to componentDidMount and ' + + 'componentDidUpdate instead.', + owner.getName() || 'A component' + ) : null); + owner._warnedAboutRefsInRender = true; + } + } + var internalInstance = ReactInstanceMap.get(this); + return ( + internalInstance && + internalInstance !== ReactLifeCycle.currentlyMountingInstance + ); + }, + + /** + * Sets a subset of the props. + * + * @param {object} partialProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + setProps: function(partialProps, callback) { + ReactUpdateQueue.enqueueSetProps(this, partialProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Replace all the props. + * + * @param {object} newProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + replaceProps: function(newProps, callback) { + ReactUpdateQueue.enqueueReplaceProps(this, newProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + } +}; + +var ReactClassComponent = function() {}; +assign( + ReactClassComponent.prototype, + ReactComponent.prototype, + ReactClassMixin +); + +/** + * Module for creating composite components. + * + * @class ReactClass + */ +var ReactClass = { + + /** + * Creates a composite component class given a class specification. + * + * @param {object} spec Class specification (which must define `render`). + * @return {function} Component constructor function. + * @public + */ + createClass: function(spec) { + var Constructor = function(props, context) { + // This constructor is overridden by mocks. The argument is used + // by mocks to assert on what gets mounted. + + if ("production" !== "development") { + ("production" !== "development" ? warning( + this instanceof Constructor, + 'Something is calling a React component directly. Use a factory or ' + + 'JSX instead. See: https://fb.me/react-legacyfactory' + ) : null); + } + + // Wire up auto-binding + if (this.__reactAutoBindMap) { + bindAutoBindMethods(this); + } + + this.props = props; + this.context = context; + this.state = null; + + // ReactClasses doesn't have constructors. Instead, they use the + // getInitialState and componentWillMount methods for initialization. + + var initialState = this.getInitialState ? this.getInitialState() : null; + if ("production" !== "development") { + // We allow auto-mocks to proceed as if they're returning null. + if (typeof initialState === 'undefined' && + this.getInitialState._isMockFunction) { + // This is probably bad practice. Consider warning here and + // deprecating this convenience. + initialState = null; + } + } + ("production" !== "development" ? invariant( + typeof initialState === 'object' && !Array.isArray(initialState), + '%s.getInitialState(): must return an object or null', + Constructor.displayName || 'ReactCompositeComponent' + ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + + this.state = initialState; + }; + Constructor.prototype = new ReactClassComponent(); + Constructor.prototype.constructor = Constructor; + + injectedMixins.forEach( + mixSpecIntoComponent.bind(null, Constructor) + ); + + mixSpecIntoComponent(Constructor, spec); + + // Initialize the defaultProps property after all mixins have been merged + if (Constructor.getDefaultProps) { + Constructor.defaultProps = Constructor.getDefaultProps(); + } + + if ("production" !== "development") { + // This is a tag to indicate that the use of these method names is ok, + // since it's used with createClass. If it's not, then it's likely a + // mistake so we'll warn you to use the static property, property + // initializer or constructor respectively. + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps.isReactClassApproved = {}; + } + if (Constructor.prototype.getInitialState) { + Constructor.prototype.getInitialState.isReactClassApproved = {}; + } + } + + ("production" !== "development" ? invariant( + Constructor.prototype.render, + 'createClass(...): Class specification must implement a `render` method.' + ) : invariant(Constructor.prototype.render)); + + if ("production" !== "development") { + ("production" !== "development" ? warning( + !Constructor.prototype.componentShouldUpdate, + '%s has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.', + spec.displayName || 'A component' + ) : null); + } + + // Reduce time spent doing lookups by setting these on the prototype. + for (var methodName in ReactClassInterface) { + if (!Constructor.prototype[methodName]) { + Constructor.prototype[methodName] = null; + } + } + + // Legacy hook + Constructor.type = Constructor; + if ("production" !== "development") { + try { + Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + } + + return Constructor; + }, + + injection: { + injectMixin: function(mixin) { + injectedMixins.push(mixin); + } + } + +}; + +module.exports = ReactClass; + +},{"135":135,"140":140,"141":141,"154":154,"27":27,"34":34,"39":39,"57":57,"60":60,"67":67,"68":68,"76":76,"77":77,"86":86}],34:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponent + */ + +'use strict'; + +var ReactUpdateQueue = _dereq_(86); + +var invariant = _dereq_(135); +var warning = _dereq_(154); + +/** + * Base class helpers for the updating state of a component. + */ +function ReactComponent(props, context) { + this.props = props; + this.context = context; +} + +/** + * Sets a subset of the state. Always use this to mutate + * state. You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * There is no guarantee that calls to `setState` will run synchronously, + * as they may eventually be batched together. You can provide an optional + * callback that will be executed when the call to setState is actually + * completed. + * + * When a function is provided to setState, it will be called at some point in + * the future (not synchronously). It will be called with the up to date + * component arguments (state, props, context). These values can be different + * from this.* because your function may be called after receiveProps but before + * shouldComponentUpdate, and this new state, props, and context will not yet be + * assigned to this. + * + * @param {object|function} partialState Next partial state or function to + * produce next partial state to be merged with current state. + * @param {?function} callback Called after state is updated. + * @final + * @protected + */ +ReactComponent.prototype.setState = function(partialState, callback) { + ("production" !== "development" ? invariant( + typeof partialState === 'object' || + typeof partialState === 'function' || + partialState == null, + 'setState(...): takes an object of state variables to update or a ' + + 'function which returns an object of state variables.' + ) : invariant(typeof partialState === 'object' || + typeof partialState === 'function' || + partialState == null)); + if ("production" !== "development") { + ("production" !== "development" ? warning( + partialState != null, + 'setState(...): You passed an undefined or null state object; ' + + 'instead, use forceUpdate().' + ) : null); + } + ReactUpdateQueue.enqueueSetState(this, partialState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } +}; + +/** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldComponentUpdate`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {?function} callback Called after update is complete. + * @final + * @protected + */ +ReactComponent.prototype.forceUpdate = function(callback) { + ReactUpdateQueue.enqueueForceUpdate(this); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } +}; + +/** + * Deprecated APIs. These APIs used to exist on classic React classes but since + * we would like to deprecate them, we're not going to move them over to this + * modern base class. Instead, we define a getter that warns if it's accessed. + */ +if ("production" !== "development") { + var deprecatedAPIs = { + getDOMNode: [ + 'getDOMNode', + 'Use React.findDOMNode(component) instead.' + ], + isMounted: [ + 'isMounted', + 'Instead, make sure to clean up subscriptions and pending requests in ' + + 'componentWillUnmount to prevent memory leaks.' + ], + replaceProps: [ + 'replaceProps', + 'Instead call React.render again at the top level.' + ], + replaceState: [ + 'replaceState', + 'Refactor your code to use setState instead (see ' + + 'https://github.com/facebook/react/issues/3236).' + ], + setProps: [ + 'setProps', + 'Instead call React.render again at the top level.' + ] + }; + var defineDeprecationWarning = function(methodName, info) { + try { + Object.defineProperty(ReactComponent.prototype, methodName, { + get: function() { + ("production" !== "development" ? warning( + false, + '%s(...) is deprecated in plain JavaScript React classes. %s', + info[0], + info[1] + ) : null); + return undefined; + } + }); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + }; + for (var fnName in deprecatedAPIs) { + if (deprecatedAPIs.hasOwnProperty(fnName)) { + defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); + } + } +} + +module.exports = ReactComponent; + +},{"135":135,"154":154,"86":86}],35:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponentBrowserEnvironment + */ + +/*jslint evil: true */ + +'use strict'; + +var ReactDOMIDOperations = _dereq_(44); +var ReactMount = _dereq_(70); + +/** + * Abstracts away all functionality of the reconciler that requires knowledge of + * the browser context. TODO: These callers should be refactored to avoid the + * need for this injection. + */ +var ReactComponentBrowserEnvironment = { + + processChildrenUpdates: + ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, + + replaceNodeWithMarkupByID: + ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, + + /** + * If a particular environment requires that some resources be cleaned up, + * specify this in the injected Mixin. In the DOM, we would likely want to + * purge any cached node ID lookups. + * + * @private + */ + unmountIDFromEnvironment: function(rootNodeID) { + ReactMount.purgeID(rootNodeID); + } + +}; + +module.exports = ReactComponentBrowserEnvironment; + +},{"44":44,"70":70}],36:[function(_dereq_,module,exports){ +/** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponentEnvironment + */ + +'use strict'; + +var invariant = _dereq_(135); + +var injected = false; + +var ReactComponentEnvironment = { + + /** + * Optionally injectable environment dependent cleanup hook. (server vs. + * browser etc). Example: A browser system caches DOM nodes based on component + * ID and must remove that cache entry when this instance is unmounted. + */ + unmountIDFromEnvironment: null, + + /** + * Optionally injectable hook for swapping out mount images in the middle of + * the tree. + */ + replaceNodeWithMarkupByID: null, + + /** + * Optionally injectable hook for processing a queue of child updates. Will + * later move into MultiChildComponents. + */ + processChildrenUpdates: null, + + injection: { + injectEnvironment: function(environment) { + ("production" !== "development" ? invariant( + !injected, + 'ReactCompositeComponent: injectEnvironment() can only be called once.' + ) : invariant(!injected)); + ReactComponentEnvironment.unmountIDFromEnvironment = + environment.unmountIDFromEnvironment; + ReactComponentEnvironment.replaceNodeWithMarkupByID = + environment.replaceNodeWithMarkupByID; + ReactComponentEnvironment.processChildrenUpdates = + environment.processChildrenUpdates; + injected = true; + } + } + +}; + +module.exports = ReactComponentEnvironment; + +},{"135":135}],37:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactCompositeComponent + */ + +'use strict'; + +var ReactComponentEnvironment = _dereq_(36); +var ReactContext = _dereq_(38); +var ReactCurrentOwner = _dereq_(39); +var ReactElement = _dereq_(57); +var ReactElementValidator = _dereq_(58); +var ReactInstanceMap = _dereq_(67); +var ReactLifeCycle = _dereq_(68); +var ReactNativeComponent = _dereq_(73); +var ReactPerf = _dereq_(75); +var ReactPropTypeLocations = _dereq_(77); +var ReactPropTypeLocationNames = _dereq_(76); +var ReactReconciler = _dereq_(81); +var ReactUpdates = _dereq_(87); + +var assign = _dereq_(27); +var emptyObject = _dereq_(115); +var invariant = _dereq_(135); +var shouldUpdateReactComponent = _dereq_(151); +var warning = _dereq_(154); + +function getDeclarationErrorAddendum(component) { + var owner = component._currentElement._owner || null; + if (owner) { + var name = owner.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } + } + return ''; +} + +/** + * ------------------ The Life-Cycle of a Composite Component ------------------ + * + * - constructor: Initialization of state. The instance is now retained. + * - componentWillMount + * - render + * - [children's constructors] + * - [children's componentWillMount and render] + * - [children's componentDidMount] + * - componentDidMount + * + * Update Phases: + * - componentWillReceiveProps (only called if parent updated) + * - shouldComponentUpdate + * - componentWillUpdate + * - render + * - [children's constructors or receive props phases] + * - componentDidUpdate + * + * - componentWillUnmount + * - [children's componentWillUnmount] + * - [children destroyed] + * - (destroyed): The instance is now blank, released by React and ready for GC. + * + * ----------------------------------------------------------------------------- + */ + +/** + * An incrementing ID assigned to each component when it is mounted. This is + * used to enforce the order in which `ReactUpdates` updates dirty components. + * + * @private + */ +var nextMountID = 1; + +/** + * @lends {ReactCompositeComponent.prototype} + */ +var ReactCompositeComponentMixin = { + + /** + * Base constructor for all composite component. + * + * @param {ReactElement} element + * @final + * @internal + */ + construct: function(element) { + this._currentElement = element; + this._rootNodeID = null; + this._instance = null; + + // See ReactUpdateQueue + this._pendingElement = null; + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + + this._renderedComponent = null; + + this._context = null; + this._mountOrder = 0; + this._isTopLevel = false; + + // See ReactUpdates and ReactUpdateQueue. + this._pendingCallbacks = null; + }, + + /** + * Initializes the component, renders markup, and registers event listeners. + * + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {?string} Rendered markup to be inserted into the DOM. + * @final + * @internal + */ + mountComponent: function(rootID, transaction, context) { + this._context = context; + this._mountOrder = nextMountID++; + this._rootNodeID = rootID; + + var publicProps = this._processProps(this._currentElement.props); + var publicContext = this._processContext(this._currentElement._context); + + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + + // Initialize the public class + var inst = new Component(publicProps, publicContext); + + if ("production" !== "development") { + // This will throw later in _renderValidatedComponent, but add an early + // warning now to help debugging + ("production" !== "development" ? warning( + inst.render != null, + '%s(...): No `render` method found on the returned component ' + + 'instance: you may have forgotten to define `render` in your ' + + 'component or you may have accidentally tried to render an element ' + + 'whose type is a function that isn\'t a React component.', + Component.displayName || Component.name || 'Component' + ) : null); + } + + // These should be set up in the constructor, but as a convenience for + // simpler class abstractions, we set them up after the fact. + inst.props = publicProps; + inst.context = publicContext; + inst.refs = emptyObject; + + this._instance = inst; + + // Store a reference from the instance back to the internal representation + ReactInstanceMap.set(inst, this); + + if ("production" !== "development") { + this._warnIfContextsDiffer(this._currentElement._context, context); + } + + if ("production" !== "development") { + // Since plain JS classes are defined without any special initialization + // logic, we can not catch common errors early. Therefore, we have to + // catch them here, at initialization time, instead. + ("production" !== "development" ? warning( + !inst.getInitialState || + inst.getInitialState.isReactClassApproved, + 'getInitialState was defined on %s, a plain JavaScript class. ' + + 'This is only supported for classes created using React.createClass. ' + + 'Did you mean to define a state property instead?', + this.getName() || 'a component' + ) : null); + ("production" !== "development" ? warning( + !inst.getDefaultProps || + inst.getDefaultProps.isReactClassApproved, + 'getDefaultProps was defined on %s, a plain JavaScript class. ' + + 'This is only supported for classes created using React.createClass. ' + + 'Use a static property to define defaultProps instead.', + this.getName() || 'a component' + ) : null); + ("production" !== "development" ? warning( + !inst.propTypes, + 'propTypes was defined as an instance property on %s. Use a static ' + + 'property to define propTypes instead.', + this.getName() || 'a component' + ) : null); + ("production" !== "development" ? warning( + !inst.contextTypes, + 'contextTypes was defined as an instance property on %s. Use a ' + + 'static property to define contextTypes instead.', + this.getName() || 'a component' + ) : null); + ("production" !== "development" ? warning( + typeof inst.componentShouldUpdate !== 'function', + '%s has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.', + (this.getName() || 'A component') + ) : null); + } + + var initialState = inst.state; + if (initialState === undefined) { + inst.state = initialState = null; + } + ("production" !== "development" ? invariant( + typeof initialState === 'object' && !Array.isArray(initialState), + '%s.state: must be set to an object or null', + this.getName() || 'ReactCompositeComponent' + ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + + var childContext; + var renderedElement; + + var previouslyMounting = ReactLifeCycle.currentlyMountingInstance; + ReactLifeCycle.currentlyMountingInstance = this; + try { + if (inst.componentWillMount) { + inst.componentWillMount(); + // When mounting, calls to `setState` by `componentWillMount` will set + // `this._pendingStateQueue` without triggering a re-render. + if (this._pendingStateQueue) { + inst.state = this._processPendingState(inst.props, inst.context); + } + } + + childContext = this._getValidatedChildContext(context); + renderedElement = this._renderValidatedComponent(childContext); + } finally { + ReactLifeCycle.currentlyMountingInstance = previouslyMounting; + } + + this._renderedComponent = this._instantiateReactComponent( + renderedElement, + this._currentElement.type // The wrapping type + ); + + var markup = ReactReconciler.mountComponent( + this._renderedComponent, + rootID, + transaction, + this._mergeChildContext(context, childContext) + ); + if (inst.componentDidMount) { + transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); + } + + return markup; + }, + + /** + * Releases any resources allocated by `mountComponent`. + * + * @final + * @internal + */ + unmountComponent: function() { + var inst = this._instance; + + if (inst.componentWillUnmount) { + var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; + ReactLifeCycle.currentlyUnmountingInstance = this; + try { + inst.componentWillUnmount(); + } finally { + ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; + } + } + + ReactReconciler.unmountComponent(this._renderedComponent); + this._renderedComponent = null; + + // Reset pending fields + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + this._pendingCallbacks = null; + this._pendingElement = null; + + // These fields do not really need to be reset since this object is no + // longer accessible. + this._context = null; + this._rootNodeID = null; + + // Delete the reference from the instance to this internal representation + // which allow the internals to be properly cleaned up even if the user + // leaks a reference to the public instance. + ReactInstanceMap.remove(inst); + + // Some existing components rely on inst.props even after they've been + // destroyed (in event handlers). + // TODO: inst.props = null; + // TODO: inst.state = null; + // TODO: inst.context = null; + }, + + /** + * Schedule a partial update to the props. Only used for internal testing. + * + * @param {object} partialProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @internal + */ + _setPropsInternal: function(partialProps, callback) { + // This is a deoptimized path. We optimize for always having an element. + // This creates an extra internal element. + var element = this._pendingElement || this._currentElement; + this._pendingElement = ReactElement.cloneAndReplaceProps( + element, + assign({}, element.props, partialProps) + ); + ReactUpdates.enqueueUpdate(this, callback); + }, + + /** + * Filters the context object to only contain keys specified in + * `contextTypes` + * + * @param {object} context + * @return {?object} + * @private + */ + _maskContext: function(context) { + var maskedContext = null; + // This really should be getting the component class for the element, + // but we know that we're not going to need it for built-ins. + if (typeof this._currentElement.type === 'string') { + return emptyObject; + } + var contextTypes = this._currentElement.type.contextTypes; + if (!contextTypes) { + return emptyObject; + } + maskedContext = {}; + for (var contextName in contextTypes) { + maskedContext[contextName] = context[contextName]; + } + return maskedContext; + }, + + /** + * Filters the context object to only contain keys specified in + * `contextTypes`, and asserts that they are valid. + * + * @param {object} context + * @return {?object} + * @private + */ + _processContext: function(context) { + var maskedContext = this._maskContext(context); + if ("production" !== "development") { + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + if (Component.contextTypes) { + this._checkPropTypes( + Component.contextTypes, + maskedContext, + ReactPropTypeLocations.context + ); + } + } + return maskedContext; + }, + + /** + * @param {object} currentContext + * @return {object} + * @private + */ + _getValidatedChildContext: function(currentContext) { + var inst = this._instance; + var childContext = inst.getChildContext && inst.getChildContext(); + if (childContext) { + ("production" !== "development" ? invariant( + typeof inst.constructor.childContextTypes === 'object', + '%s.getChildContext(): childContextTypes must be defined in order to ' + + 'use getChildContext().', + this.getName() || 'ReactCompositeComponent' + ) : invariant(typeof inst.constructor.childContextTypes === 'object')); + if ("production" !== "development") { + this._checkPropTypes( + inst.constructor.childContextTypes, + childContext, + ReactPropTypeLocations.childContext + ); + } + for (var name in childContext) { + ("production" !== "development" ? invariant( + name in inst.constructor.childContextTypes, + '%s.getChildContext(): key "%s" is not defined in childContextTypes.', + this.getName() || 'ReactCompositeComponent', + name + ) : invariant(name in inst.constructor.childContextTypes)); + } + return childContext; + } + return null; + }, + + _mergeChildContext: function(currentContext, childContext) { + if (childContext) { + return assign({}, currentContext, childContext); + } + return currentContext; + }, + + /** + * Processes props by setting default values for unspecified props and + * asserting that the props are valid. Does not mutate its argument; returns + * a new props object with defaults merged in. + * + * @param {object} newProps + * @return {object} + * @private + */ + _processProps: function(newProps) { + if ("production" !== "development") { + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + if (Component.propTypes) { + this._checkPropTypes( + Component.propTypes, + newProps, + ReactPropTypeLocations.prop + ); + } + } + return newProps; + }, + + /** + * Assert that the props are valid + * + * @param {object} propTypes Map of prop name to a ReactPropType + * @param {object} props + * @param {string} location e.g. "prop", "context", "child context" + * @private + */ + _checkPropTypes: function(propTypes, props, location) { + // TODO: Stop validating prop types here and only use the element + // validation. + var componentName = this.getName(); + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + ("production" !== "development" ? invariant( + typeof propTypes[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually ' + + 'from React.PropTypes.', + componentName || 'React class', + ReactPropTypeLocationNames[location], + propName + ) : invariant(typeof propTypes[propName] === 'function')); + error = propTypes[propName](props, propName, componentName, location); + } catch (ex) { + error = ex; + } + if (error instanceof Error) { + // We may want to extend this logic for similar errors in + // React.render calls, so I'm abstracting it away into + // a function to minimize refactoring in the future + var addendum = getDeclarationErrorAddendum(this); + + if (location === ReactPropTypeLocations.prop) { + // Preface gives us something to blacklist in warning module + ("production" !== "development" ? warning( + false, + 'Failed Composite propType: %s%s', + error.message, + addendum + ) : null); + } else { + ("production" !== "development" ? warning( + false, + 'Failed Context Types: %s%s', + error.message, + addendum + ) : null); + } + } + } + } + }, + + receiveComponent: function(nextElement, transaction, nextContext) { + var prevElement = this._currentElement; + var prevContext = this._context; + + this._pendingElement = null; + + this.updateComponent( + transaction, + prevElement, + nextElement, + prevContext, + nextContext + ); + }, + + /** + * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` + * is set, update the component. + * + * @param {ReactReconcileTransaction} transaction + * @internal + */ + performUpdateIfNecessary: function(transaction) { + if (this._pendingElement != null) { + ReactReconciler.receiveComponent( + this, + this._pendingElement || this._currentElement, + transaction, + this._context + ); + } + + if (this._pendingStateQueue !== null || this._pendingForceUpdate) { + if ("production" !== "development") { + ReactElementValidator.checkAndWarnForMutatedProps( + this._currentElement + ); + } + + this.updateComponent( + transaction, + this._currentElement, + this._currentElement, + this._context, + this._context + ); + } + }, + + /** + * Compare two contexts, warning if they are different + * TODO: Remove this check when owner-context is removed + */ + _warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) { + ownerBasedContext = this._maskContext(ownerBasedContext); + parentBasedContext = this._maskContext(parentBasedContext); + var parentKeys = Object.keys(parentBasedContext).sort(); + var displayName = this.getName() || 'ReactCompositeComponent'; + for (var i = 0; i < parentKeys.length; i++) { + var key = parentKeys[i]; + ("production" !== "development" ? warning( + ownerBasedContext[key] === parentBasedContext[key], + 'owner-based and parent-based contexts differ ' + + '(values: `%s` vs `%s`) for key (%s) while mounting %s ' + + '(see: http://fb.me/react-context-by-parent)', + ownerBasedContext[key], + parentBasedContext[key], + key, + displayName + ) : null); + } + }, + + /** + * Perform an update to a mounted component. The componentWillReceiveProps and + * shouldComponentUpdate methods are called, then (assuming the update isn't + * skipped) the remaining update lifecycle methods are called and the DOM + * representation is updated. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @param {ReactElement} prevParentElement + * @param {ReactElement} nextParentElement + * @internal + * @overridable + */ + updateComponent: function( + transaction, + prevParentElement, + nextParentElement, + prevUnmaskedContext, + nextUnmaskedContext + ) { + var inst = this._instance; + + var nextContext = inst.context; + var nextProps = inst.props; + + // Distinguish between a props update versus a simple state update + if (prevParentElement !== nextParentElement) { + nextContext = this._processContext(nextParentElement._context); + nextProps = this._processProps(nextParentElement.props); + + if ("production" !== "development") { + if (nextUnmaskedContext != null) { + this._warnIfContextsDiffer( + nextParentElement._context, + nextUnmaskedContext + ); + } + } + + // An update here will schedule an update but immediately set + // _pendingStateQueue which will ensure that any state updates gets + // immediately reconciled instead of waiting for the next batch. + + if (inst.componentWillReceiveProps) { + inst.componentWillReceiveProps(nextProps, nextContext); + } + } + + var nextState = this._processPendingState(nextProps, nextContext); + + var shouldUpdate = + this._pendingForceUpdate || + !inst.shouldComponentUpdate || + inst.shouldComponentUpdate(nextProps, nextState, nextContext); + + if ("production" !== "development") { + ("production" !== "development" ? warning( + typeof shouldUpdate !== 'undefined', + '%s.shouldComponentUpdate(): Returned undefined instead of a ' + + 'boolean value. Make sure to return true or false.', + this.getName() || 'ReactCompositeComponent' + ) : null); + } + + if (shouldUpdate) { + this._pendingForceUpdate = false; + // Will set `this.props`, `this.state` and `this.context`. + this._performComponentUpdate( + nextParentElement, + nextProps, + nextState, + nextContext, + transaction, + nextUnmaskedContext + ); + } else { + // If it's determined that a component should not update, we still want + // to set props and state but we shortcut the rest of the update. + this._currentElement = nextParentElement; + this._context = nextUnmaskedContext; + inst.props = nextProps; + inst.state = nextState; + inst.context = nextContext; + } + }, + + _processPendingState: function(props, context) { + var inst = this._instance; + var queue = this._pendingStateQueue; + var replace = this._pendingReplaceState; + this._pendingReplaceState = false; + this._pendingStateQueue = null; + + if (!queue) { + return inst.state; + } + + if (replace && queue.length === 1) { + return queue[0]; + } + + var nextState = assign({}, replace ? queue[0] : inst.state); + for (var i = replace ? 1 : 0; i < queue.length; i++) { + var partial = queue[i]; + assign( + nextState, + typeof partial === 'function' ? + partial.call(inst, nextState, props, context) : + partial + ); + } + + return nextState; + }, + + /** + * Merges new props and state, notifies delegate methods of update and + * performs update. + * + * @param {ReactElement} nextElement Next element + * @param {object} nextProps Next public object to set as properties. + * @param {?object} nextState Next object to set as state. + * @param {?object} nextContext Next public object to set as context. + * @param {ReactReconcileTransaction} transaction + * @param {?object} unmaskedContext + * @private + */ + _performComponentUpdate: function( + nextElement, + nextProps, + nextState, + nextContext, + transaction, + unmaskedContext + ) { + var inst = this._instance; + + var prevProps = inst.props; + var prevState = inst.state; + var prevContext = inst.context; + + if (inst.componentWillUpdate) { + inst.componentWillUpdate(nextProps, nextState, nextContext); + } + + this._currentElement = nextElement; + this._context = unmaskedContext; + inst.props = nextProps; + inst.state = nextState; + inst.context = nextContext; + + this._updateRenderedComponent(transaction, unmaskedContext); + + if (inst.componentDidUpdate) { + transaction.getReactMountReady().enqueue( + inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), + inst + ); + } + }, + + /** + * Call the component's `render` method and update the DOM accordingly. + * + * @param {ReactReconcileTransaction} transaction + * @internal + */ + _updateRenderedComponent: function(transaction, context) { + var prevComponentInstance = this._renderedComponent; + var prevRenderedElement = prevComponentInstance._currentElement; + var childContext = this._getValidatedChildContext(); + var nextRenderedElement = this._renderValidatedComponent(childContext); + if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { + ReactReconciler.receiveComponent( + prevComponentInstance, + nextRenderedElement, + transaction, + this._mergeChildContext(context, childContext) + ); + } else { + // These two IDs are actually the same! But nothing should rely on that. + var thisID = this._rootNodeID; + var prevComponentID = prevComponentInstance._rootNodeID; + ReactReconciler.unmountComponent(prevComponentInstance); + + this._renderedComponent = this._instantiateReactComponent( + nextRenderedElement, + this._currentElement.type + ); + var nextMarkup = ReactReconciler.mountComponent( + this._renderedComponent, + thisID, + transaction, + this._mergeChildContext(context, childContext) + ); + this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); + } + }, + + /** + * @protected + */ + _replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) { + ReactComponentEnvironment.replaceNodeWithMarkupByID( + prevComponentID, + nextMarkup + ); + }, + + /** + * @protected + */ + _renderValidatedComponentWithoutOwnerOrContext: function() { + var inst = this._instance; + var renderedComponent = inst.render(); + if ("production" !== "development") { + // We allow auto-mocks to proceed as if they're returning null. + if (typeof renderedComponent === 'undefined' && + inst.render._isMockFunction) { + // This is probably bad practice. Consider warning here and + // deprecating this convenience. + renderedComponent = null; + } + } + + return renderedComponent; + }, + + /** + * @private + */ + _renderValidatedComponent: function(childContext) { + var renderedComponent; + var previousContext = ReactContext.current; + ReactContext.current = this._mergeChildContext( + this._currentElement._context, + childContext + ); + ReactCurrentOwner.current = this; + try { + renderedComponent = + this._renderValidatedComponentWithoutOwnerOrContext(); + } finally { + ReactContext.current = previousContext; + ReactCurrentOwner.current = null; + } + ("production" !== "development" ? invariant( + // TODO: An `isValidNode` function would probably be more appropriate + renderedComponent === null || renderedComponent === false || + ReactElement.isValidElement(renderedComponent), + '%s.render(): A valid ReactComponent must be returned. You may have ' + + 'returned undefined, an array or some other invalid object.', + this.getName() || 'ReactCompositeComponent' + ) : invariant(// TODO: An `isValidNode` function would probably be more appropriate + renderedComponent === null || renderedComponent === false || + ReactElement.isValidElement(renderedComponent))); + return renderedComponent; + }, + + /** + * Lazily allocates the refs object and stores `component` as `ref`. + * + * @param {string} ref Reference name. + * @param {component} component Component to store as `ref`. + * @final + * @private + */ + attachRef: function(ref, component) { + var inst = this.getPublicInstance(); + var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs; + refs[ref] = component.getPublicInstance(); + }, + + /** + * Detaches a reference name. + * + * @param {string} ref Name to dereference. + * @final + * @private + */ + detachRef: function(ref) { + var refs = this.getPublicInstance().refs; + delete refs[ref]; + }, + + /** + * Get a text description of the component that can be used to identify it + * in error messages. + * @return {string} The name or null. + * @internal + */ + getName: function() { + var type = this._currentElement.type; + var constructor = this._instance && this._instance.constructor; + return ( + type.displayName || (constructor && constructor.displayName) || + type.name || (constructor && constructor.name) || + null + ); + }, + + /** + * Get the publicly accessible representation of this component - i.e. what + * is exposed by refs and returned by React.render. Can be null for stateless + * components. + * + * @return {ReactComponent} the public component instance. + * @internal + */ + getPublicInstance: function() { + return this._instance; + }, + + // Stub + _instantiateReactComponent: null + +}; + +ReactPerf.measureMethods( + ReactCompositeComponentMixin, + 'ReactCompositeComponent', + { + mountComponent: 'mountComponent', + updateComponent: 'updateComponent', + _renderValidatedComponent: '_renderValidatedComponent' + } +); + +var ReactCompositeComponent = { + + Mixin: ReactCompositeComponentMixin + +}; + +module.exports = ReactCompositeComponent; + +},{"115":115,"135":135,"151":151,"154":154,"27":27,"36":36,"38":38,"39":39,"57":57,"58":58,"67":67,"68":68,"73":73,"75":75,"76":76,"77":77,"81":81,"87":87}],38:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactContext + */ + +'use strict'; + +var assign = _dereq_(27); +var emptyObject = _dereq_(115); +var warning = _dereq_(154); + +var didWarn = false; + +/** + * Keeps track of the current context. + * + * The context is automatically passed down the component ownership hierarchy + * and is accessible via `this.context` on ReactCompositeComponents. + */ +var ReactContext = { + + /** + * @internal + * @type {object} + */ + current: emptyObject, + + /** + * Temporarily extends the current context while executing scopedCallback. + * + * A typical use case might look like + * + * render: function() { + * var children = ReactContext.withContext({foo: 'foo'}, () => ( + * + * )); + * return
    {children}
    ; + * } + * + * @param {object} newContext New context to merge into the existing context + * @param {function} scopedCallback Callback to run with the new context + * @return {ReactComponent|array} + */ + withContext: function(newContext, scopedCallback) { + if ("production" !== "development") { + ("production" !== "development" ? warning( + didWarn, + 'withContext is deprecated and will be removed in a future version. ' + + 'Use a wrapper component with getChildContext instead.' + ) : null); + + didWarn = true; + } + + var result; + var previousContext = ReactContext.current; + ReactContext.current = assign({}, previousContext, newContext); + try { + result = scopedCallback(); + } finally { + ReactContext.current = previousContext; + } + return result; + } + +}; + +module.exports = ReactContext; + +},{"115":115,"154":154,"27":27}],39:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactCurrentOwner + */ + +'use strict'; + +/** + * Keeps track of the current owner. + * + * The current owner is the component who should own any components that are + * currently being constructed. + * + * The depth indicate how many composite components are above this render level. + */ +var ReactCurrentOwner = { + + /** + * @internal + * @type {ReactComponent} + */ + current: null + +}; + +module.exports = ReactCurrentOwner; + +},{}],40:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOM + * @typechecks static-only + */ + +'use strict'; + +var ReactElement = _dereq_(57); +var ReactElementValidator = _dereq_(58); + +var mapObject = _dereq_(142); + +/** + * Create a factory that creates HTML tag elements. + * + * @param {string} tag Tag name (e.g. `div`). + * @private + */ +function createDOMFactory(tag) { + if ("production" !== "development") { + return ReactElementValidator.createFactory(tag); + } + return ReactElement.createFactory(tag); +} + +/** + * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. + * This is also accessible via `React.DOM`. + * + * @public + */ +var ReactDOM = mapObject({ + a: 'a', + abbr: 'abbr', + address: 'address', + area: 'area', + article: 'article', + aside: 'aside', + audio: 'audio', + b: 'b', + base: 'base', + bdi: 'bdi', + bdo: 'bdo', + big: 'big', + blockquote: 'blockquote', + body: 'body', + br: 'br', + button: 'button', + canvas: 'canvas', + caption: 'caption', + cite: 'cite', + code: 'code', + col: 'col', + colgroup: 'colgroup', + data: 'data', + datalist: 'datalist', + dd: 'dd', + del: 'del', + details: 'details', + dfn: 'dfn', + dialog: 'dialog', + div: 'div', + dl: 'dl', + dt: 'dt', + em: 'em', + embed: 'embed', + fieldset: 'fieldset', + figcaption: 'figcaption', + figure: 'figure', + footer: 'footer', + form: 'form', + h1: 'h1', + h2: 'h2', + h3: 'h3', + h4: 'h4', + h5: 'h5', + h6: 'h6', + head: 'head', + header: 'header', + hr: 'hr', + html: 'html', + i: 'i', + iframe: 'iframe', + img: 'img', + input: 'input', + ins: 'ins', + kbd: 'kbd', + keygen: 'keygen', + label: 'label', + legend: 'legend', + li: 'li', + link: 'link', + main: 'main', + map: 'map', + mark: 'mark', + menu: 'menu', + menuitem: 'menuitem', + meta: 'meta', + meter: 'meter', + nav: 'nav', + noscript: 'noscript', + object: 'object', + ol: 'ol', + optgroup: 'optgroup', + option: 'option', + output: 'output', + p: 'p', + param: 'param', + picture: 'picture', + pre: 'pre', + progress: 'progress', + q: 'q', + rp: 'rp', + rt: 'rt', + ruby: 'ruby', + s: 's', + samp: 'samp', + script: 'script', + section: 'section', + select: 'select', + small: 'small', + source: 'source', + span: 'span', + strong: 'strong', + style: 'style', + sub: 'sub', + summary: 'summary', + sup: 'sup', + table: 'table', + tbody: 'tbody', + td: 'td', + textarea: 'textarea', + tfoot: 'tfoot', + th: 'th', + thead: 'thead', + time: 'time', + title: 'title', + tr: 'tr', + track: 'track', + u: 'u', + ul: 'ul', + 'var': 'var', + video: 'video', + wbr: 'wbr', + + // SVG + circle: 'circle', + clipPath: 'clipPath', + defs: 'defs', + ellipse: 'ellipse', + g: 'g', + line: 'line', + linearGradient: 'linearGradient', + mask: 'mask', + path: 'path', + pattern: 'pattern', + polygon: 'polygon', + polyline: 'polyline', + radialGradient: 'radialGradient', + rect: 'rect', + stop: 'stop', + svg: 'svg', + text: 'text', + tspan: 'tspan' + +}, createDOMFactory); + +module.exports = ReactDOM; + +},{"142":142,"57":57,"58":58}],41:[function(_dereq_,module,exports){ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMButton + */ + +'use strict'; + +var AutoFocusMixin = _dereq_(2); +var ReactBrowserComponentMixin = _dereq_(29); +var ReactClass = _dereq_(33); +var ReactElement = _dereq_(57); + +var keyMirror = _dereq_(140); + +var button = ReactElement.createFactory('button'); + +var mouseListenerNames = keyMirror({ + onClick: true, + onDoubleClick: true, + onMouseDown: true, + onMouseMove: true, + onMouseUp: true, + onClickCapture: true, + onDoubleClickCapture: true, + onMouseDownCapture: true, + onMouseMoveCapture: true, + onMouseUpCapture: true +}); + +/** + * Implements a