From 42a1e24ac86270bfaa753e01302c547423337272 Mon Sep 17 00:00:00 2001 From: Matt Garbis Date: Mon, 12 Oct 2015 18:18:50 -0400 Subject: [PATCH 01/10] removing focus after select --- lib/Select.js | 48 +++++++++++++++++++++++------------------------- src/Select.js | 13 ++----------- 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/lib/Select.js b/lib/Select.js index 3dc99df694..9a39a1df83 100644 --- a/lib/Select.js +++ b/lib/Select.js @@ -157,7 +157,6 @@ var Select = React.createClass({ componentWillUnmount: function componentWillUnmount() { clearTimeout(this._blurTimeout); - clearTimeout(this._focusTimeout); if (this.state.isOpen) { this._unbindCloseMenuIfClickedOutside(); } @@ -187,14 +186,8 @@ var Select = React.createClass({ }, componentDidUpdate: function componentDidUpdate() { - var _this3 = this; - - if (!this.props.disabled && this._focusAfterUpdate) { + if (!this.props.disabled) { clearTimeout(this._blurTimeout); - this._focusTimeout = setTimeout(function () { - _this3.getInputNode().focus(); - _this3._focusAfterUpdate = false; - }, 50); } if (this._focusedOptionReveal) { if (this.refs.focused && this.refs.menu) { @@ -287,10 +280,7 @@ var Select = React.createClass({ }); }, - setValue: function setValue(value, focusAfterUpdate) { - if (focusAfterUpdate || focusAfterUpdate === undefined) { - this._focusAfterUpdate = true; - } + setValue: function setValue(value) { var newState = this.getStateFromValue(value); newState.isOpen = false; this.fireChangeEvent(newState); @@ -354,6 +344,15 @@ var Select = React.createClass({ } event.stopPropagation(); event.preventDefault(); + + // for the non-searchable select, close the dropdown when button is clicked + if (this.state.isOpen && !this.props.searchable) { + this.setState({ + isOpen: false + }, this._unbindCloseMenuIfClickedOutside); + return; + } + if (this.state.isFocused) { this.setState({ isOpen: true @@ -400,11 +399,10 @@ var Select = React.createClass({ }, handleInputBlur: function handleInputBlur(event) { - var _this4 = this; + var _this3 = this; this._blurTimeout = setTimeout(function () { - if (_this4._focusAfterUpdate) return; - _this4.setState({ + _this3.setState({ isFocused: false, isOpen: false }); @@ -505,16 +503,16 @@ var Select = React.createClass({ }, autoloadAsyncOptions: function autoloadAsyncOptions() { - var _this5 = this; + var _this4 = this; this.loadAsyncOptions(this.props.value || '', {}, function () { // update with fetched but don't focus - _this5.setValue(_this5.props.value, false); + _this4.setValue(_this4.props.value, false); }); }, loadAsyncOptions: function loadAsyncOptions(input, state, callback) { - var _this6 = this; + var _this5 = this; var thisRequestId = this._currentRequestId = requestId++; if (this.props.cacheAsyncResults) { @@ -542,25 +540,25 @@ var Select = React.createClass({ this.props.asyncOptions(input, function (err, data) { if (err) throw err; - if (_this6.props.cacheAsyncResults) { - _this6._optionsCache[input] = data; + if (_this5.props.cacheAsyncResults) { + _this5._optionsCache[input] = data; } - if (thisRequestId !== _this6._currentRequestId) { + if (thisRequestId !== _this5._currentRequestId) { return; } - var filteredOptions = _this6.filterOptions(data.options); + var filteredOptions = _this5.filterOptions(data.options); var newState = { options: data.options, filteredOptions: filteredOptions, - focusedOption: _this6._getNewFocusedOption(filteredOptions) + focusedOption: _this5._getNewFocusedOption(filteredOptions) }; for (var key in state) { if (state.hasOwnProperty(key)) { newState[key] = state[key]; } } - _this6.setState(newState); - if (callback) callback.call(_this6, newState); + _this5.setState(newState); + if (callback) callback.call(_this5, newState); }); }, diff --git a/src/Select.js b/src/Select.js index 4d874a5cb3..13c51a92b7 100644 --- a/src/Select.js +++ b/src/Select.js @@ -151,7 +151,6 @@ var Select = React.createClass({ componentWillUnmount: function() { clearTimeout(this._blurTimeout); - clearTimeout(this._focusTimeout); if (this.state.isOpen) { this._unbindCloseMenuIfClickedOutside(); } @@ -182,12 +181,8 @@ var Select = React.createClass({ }, componentDidUpdate: function() { - if (!this.props.disabled && this._focusAfterUpdate) { + if (!this.props.disabled) { clearTimeout(this._blurTimeout); - this._focusTimeout = setTimeout(() => { - this.getInputNode().focus(); - this._focusAfterUpdate = false; - }, 50); } if (this._focusedOptionReveal) { if (this.refs.focused && this.refs.menu) { @@ -283,10 +278,7 @@ var Select = React.createClass({ }); }, - setValue: function(value, focusAfterUpdate) { - if (focusAfterUpdate || focusAfterUpdate === undefined) { - this._focusAfterUpdate = true; - } + setValue: function(value) { var newState = this.getStateFromValue(value); newState.isOpen = false; this.fireChangeEvent(newState); @@ -407,7 +399,6 @@ var Select = React.createClass({ handleInputBlur: function(event) { this._blurTimeout = setTimeout(() => { - if (this._focusAfterUpdate) return; this.setState({ isFocused: false, isOpen: false From 10e659952e123353350290a9e9ce674d51cd5cf1 Mon Sep 17 00:00:00 2001 From: Patrick McKelvy Date: Mon, 9 May 2016 14:50:30 -0400 Subject: [PATCH 02/10] IHM-274 updating react-select with onOpen and onClose functions. --- .idea/inspectionProfiles/Project_Default.xml | 11 + .../inspectionProfiles/profiles_settings.xml | 7 + .idea/jsLibraryMappings.xml | 6 + .idea/misc.xml | 38 ++++ .idea/modules.xml | 8 + .idea/react-select.iml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 209 ++++++++++++++++++ src/Select.js | 9 + 9 files changed, 302 insertions(+) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/react-select.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000..062dde0eaf --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000000..3b312839bf --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000000..b8387eb1ba --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000..8051e82cb3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + JavaScript + + + + + Spelling + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000..1e0754fbbc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/react-select.iml b/.idea/react-select.iml new file mode 100644 index 0000000000..c956989b29 --- /dev/null +++ b/.idea/react-select.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000..94a25f7f4c --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000000..e3a7355b8c --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + $PROJECT_DIR$/gulpfile.js + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1462819494563 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Select.js b/src/Select.js index 13c51a92b7..249e78e776 100644 --- a/src/Select.js +++ b/src/Select.js @@ -40,6 +40,8 @@ var Select = React.createClass({ noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results onBlur: React.PropTypes.func, // onBlur handler: function(event) {} onChange: React.PropTypes.func, // onChange handler: function(newValue) {} + onOpen: React.PropTypes.func, // fires when the menu is opened + onClose: React.PropTypes.func, // fires when the menu is closed onFocus: React.PropTypes.func, // onFocus handler: function(event) {} onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} optionComponent: React.PropTypes.func, // option component to render in dropdown @@ -180,6 +182,13 @@ var Select = React.createClass({ } }, + componentWillUpdate: function(nextProps, nextState) { + if (nextState.isOpen !== this.state.isOpen) { + const handler = nextState.isOpen ? nextProps.onOpen : nextProps.onClose; + handler && handler(); + } + }, + componentDidUpdate: function() { if (!this.props.disabled) { clearTimeout(this._blurTimeout); From 392f1f26b68a4b3aebaa33866788dcd8843a043e Mon Sep 17 00:00:00 2001 From: Patrick McKelvy Date: Mon, 9 May 2016 15:23:43 -0400 Subject: [PATCH 03/10] IHM-274 update formatting. --- .idea/workspace.xml | 18 +- src/Select.js | 1638 ++++++++++++++++++++++--------------------- 2 files changed, 848 insertions(+), 808 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index e3a7355b8c..84b86580cd 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,6 @@ - - @@ -28,8 +26,8 @@ - - + + @@ -156,19 +154,19 @@ - - + - + @@ -197,8 +195,8 @@ - - + + diff --git a/src/Select.js b/src/Select.js index 249e78e776..1b48137ac9 100644 --- a/src/Select.js +++ b/src/Select.js @@ -1,5 +1,5 @@ /* disable some rules until we refactor more completely; fixing them now would - cause conflicts with some open PRs unnecessarily. */ + cause conflicts with some open PRs unnecessarily. */ /* eslint react/jsx-sort-prop-types: 0, react/sort-comp: 0, react/prop-types: 0 */ var React = require('react'); @@ -13,811 +13,853 @@ var requestId = 0; var Select = React.createClass({ - displayName: 'Select', - - propTypes: { - addLabelText: React.PropTypes.string, // placeholder displayed when you want to add a label on a multi-value input - allowCreate: React.PropTypes.bool, // whether to allow creation of new entries - asyncOptions: React.PropTypes.func, // function to call to get options - autoload: React.PropTypes.bool, // whether to auto-load the default async options set - backspaceRemoves: React.PropTypes.bool, // whether backspace removes an item if there is no text input - cacheAsyncResults: React.PropTypes.bool, // whether to allow cache - className: React.PropTypes.string, // className for the outer element - clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true - clearValueText: React.PropTypes.string, // title for the "clear" control - clearable: React.PropTypes.bool, // should it be possible to reset value - delimiter: React.PropTypes.string, // delimiter to use to join multiple values - disabled: React.PropTypes.bool, // whether the Select is disabled or not - filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) - filterOptions: React.PropTypes.func, // method to filter the options array: function([options], filterString, [values]) - ignoreCase: React.PropTypes.bool, // whether to perform case-insensitive filtering - inputProps: React.PropTypes.object, // custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} - matchPos: React.PropTypes.string, // (any|start) match the start or entire string when filtering - matchProp: React.PropTypes.string, // (any|label|value) which option property to filter on - multi: React.PropTypes.bool, // multi-value input - name: React.PropTypes.string, // field name, for hidden tag - newOptionCreator: React.PropTypes.func, // factory to create new options when allowCreate set - noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results - onBlur: React.PropTypes.func, // onBlur handler: function(event) {} - onChange: React.PropTypes.func, // onChange handler: function(newValue) {} + displayName: 'Select', + + propTypes: { + addLabelText: React.PropTypes.string, // placeholder displayed when you want to add a label on a multi-value input + allowCreate: React.PropTypes.bool, // whether to allow creation of new entries + asyncOptions: React.PropTypes.func, // function to call to get options + autoload: React.PropTypes.bool, // whether to auto-load the default async options set + backspaceRemoves: React.PropTypes.bool, // whether backspace removes an item if there is no text input + cacheAsyncResults: React.PropTypes.bool, // whether to allow cache + className: React.PropTypes.string, // className for the outer element + clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true + clearValueText: React.PropTypes.string, // title for the "clear" control + clearable: React.PropTypes.bool, // should it be possible to reset value + delimiter: React.PropTypes.string, // delimiter to use to join multiple values + disabled: React.PropTypes.bool, // whether the Select is disabled or not + filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) + filterOptions: React.PropTypes.func, // method to filter the options array: function([options], filterString, [values]) + ignoreCase: React.PropTypes.bool, // whether to perform case-insensitive filtering + inputProps: React.PropTypes.object, // custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} + matchPos: React.PropTypes.string, // (any|start) match the start or entire string when filtering + matchProp: React.PropTypes.string, // (any|label|value) which option property to filter on + multi: React.PropTypes.bool, // multi-value input + name: React.PropTypes.string, // field name, for hidden tag + newOptionCreator: React.PropTypes.func, // factory to create new options when allowCreate set + noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results + onBlur: React.PropTypes.func, // onBlur handler: function(event) {} + onChange: React.PropTypes.func, // onChange handler: function(newValue) {} onOpen: React.PropTypes.func, // fires when the menu is opened onClose: React.PropTypes.func, // fires when the menu is closed - onFocus: React.PropTypes.func, // onFocus handler: function(event) {} - onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} - optionComponent: React.PropTypes.func, // option component to render in dropdown - optionRenderer: React.PropTypes.func, // optionRenderer: function(option) {} - options: React.PropTypes.array, // array of options - placeholder: React.PropTypes.string, // field placeholder, displayed when there's no value - searchable: React.PropTypes.bool, // whether to enable searching feature or not - searchPromptText: React.PropTypes.string, // label to prompt for search input - singleValueComponent: React.PropTypes.func,// single value component when multiple is set to false - value: React.PropTypes.any, // initial field value - valueComponent: React.PropTypes.func, // value component to render in multiple mode - valueRenderer: React.PropTypes.func // valueRenderer: function(option) {} - }, - - getDefaultProps: function() { - return { - addLabelText: 'Add {label} ?', - allowCreate: false, - asyncOptions: undefined, - autoload: true, - backspaceRemoves: true, - cacheAsyncResults: true, - className: undefined, - clearAllText: 'Clear all', - clearValueText: 'Clear value', - clearable: true, - delimiter: ',', - disabled: false, - ignoreCase: true, - inputProps: {}, - matchPos: 'any', - matchProp: 'any', - name: undefined, - newOptionCreator: undefined, - noResultsText: 'No results found', - onChange: undefined, - onOptionLabelClick: undefined, - optionComponent: Option, - options: undefined, - placeholder: 'Select...', - searchable: true, - searchPromptText: 'Type to search', - singleValueComponent: SingleValue, - value: undefined, - valueComponent: Value - }; - }, - - getInitialState: function() { - return { - /* - * set by getStateFromValue on componentWillMount: - * - value - * - values - * - filteredOptions - * - inputValue - * - placeholder - * - focusedOption - */ - isFocused: false, - isLoading: false, - isOpen: false, - options: this.props.options - }; - }, - - componentWillMount: function() { - this._optionsCache = {}; - this._optionsFilterString = ''; - this._closeMenuIfClickedOutside = (event) => { - if (!this.state.isOpen) { - return; - } - var menuElem = React.findDOMNode(this.refs.selectMenuContainer); - var controlElem = React.findDOMNode(this.refs.control); - - var eventOccuredOutsideMenu = this.clickedOutsideElement(menuElem, event); - var eventOccuredOutsideControl = this.clickedOutsideElement(controlElem, event); - - // Hide dropdown menu if click occurred outside of menu - if (eventOccuredOutsideMenu && eventOccuredOutsideControl) { - this.setState({ - isOpen: false - }, this._unbindCloseMenuIfClickedOutside); - } - }; - this._bindCloseMenuIfClickedOutside = function() { - if (!document.addEventListener && document.attachEvent) { - document.attachEvent('onclick', this._closeMenuIfClickedOutside); - } else { - document.addEventListener('click', this._closeMenuIfClickedOutside); - } - }; - this._unbindCloseMenuIfClickedOutside = function() { - if (!document.removeEventListener && document.detachEvent) { - document.detachEvent('onclick', this._closeMenuIfClickedOutside); - } else { - document.removeEventListener('click', this._closeMenuIfClickedOutside); - } - }; - this.setState(this.getStateFromValue(this.props.value)); - }, - - componentDidMount: function() { - if (this.props.asyncOptions && this.props.autoload) { - this.autoloadAsyncOptions(); - } - }, - - componentWillUnmount: function() { - clearTimeout(this._blurTimeout); - if (this.state.isOpen) { - this._unbindCloseMenuIfClickedOutside(); - } - }, - - componentWillReceiveProps: function(newProps) { - var optionsChanged = false; - if (JSON.stringify(newProps.options) !== JSON.stringify(this.props.options)) { - optionsChanged = true; - this.setState({ - options: newProps.options, - filteredOptions: this.filterOptions(newProps.options) - }); - } - if (newProps.value !== this.state.value || newProps.placeholder !== this.props.placeholder || optionsChanged) { - var setState = (newState) => { - this.setState(this.getStateFromValue(newProps.value, - (newState && newState.options) || newProps.options, - newProps.placeholder) - ); - }; - if (this.props.asyncOptions) { - this.loadAsyncOptions(newProps.value, {}, setState); - } else { - setState(); - } - } - }, - - componentWillUpdate: function(nextProps, nextState) { + onFocus: React.PropTypes.func, // onFocus handler: function(event) {} + onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} + optionComponent: React.PropTypes.func, // option component to render in dropdown + optionRenderer: React.PropTypes.func, // optionRenderer: function(option) {} + options: React.PropTypes.array, // array of options + placeholder: React.PropTypes.string, // field placeholder, displayed when there's no value + searchable: React.PropTypes.bool, // whether to enable searching feature or not + searchPromptText: React.PropTypes.string, // label to prompt for search input + singleValueComponent: React.PropTypes.func,// single value component when multiple is set to false + value: React.PropTypes.any, // initial field value + valueComponent: React.PropTypes.func, // value component to render in multiple mode + valueRenderer: React.PropTypes.func // valueRenderer: function(option) {} + }, + + getDefaultProps: function () { + return { + addLabelText: 'Add {label} ?', + allowCreate: false, + asyncOptions: undefined, + autoload: true, + backspaceRemoves: true, + cacheAsyncResults: true, + className: undefined, + clearAllText: 'Clear all', + clearValueText: 'Clear value', + clearable: true, + delimiter: ',', + disabled: false, + ignoreCase: true, + inputProps: {}, + matchPos: 'any', + matchProp: 'any', + name: undefined, + newOptionCreator: undefined, + noResultsText: 'No results found', + onChange: undefined, + onOptionLabelClick: undefined, + optionComponent: Option, + options: undefined, + placeholder: 'Select...', + searchable: true, + searchPromptText: 'Type to search', + singleValueComponent: SingleValue, + value: undefined, + valueComponent: Value + }; + }, + + getInitialState: function () { + return { + /* + * set by getStateFromValue on componentWillMount: + * - value + * - values + * - filteredOptions + * - inputValue + * - placeholder + * - focusedOption + */ + isFocused: false, + isLoading: false, + isOpen: false, + options: this.props.options + }; + }, + + componentWillMount: function () { + this._optionsCache = {}; + this._optionsFilterString = ''; + this._closeMenuIfClickedOutside = (event) => { + if (!this.state.isOpen) { + return; + } + var menuElem = React.findDOMNode(this.refs.selectMenuContainer); + var controlElem = React.findDOMNode(this.refs.control); + + var eventOccuredOutsideMenu = this.clickedOutsideElement(menuElem, event); + var eventOccuredOutsideControl = this.clickedOutsideElement(controlElem, event); + + // Hide dropdown menu if click occurred outside of menu + if (eventOccuredOutsideMenu && eventOccuredOutsideControl) { + this.setState({ + isOpen: false + }, this._unbindCloseMenuIfClickedOutside); + } + }; + this._bindCloseMenuIfClickedOutside = function () { + if (!document.addEventListener && document.attachEvent) { + document.attachEvent('onclick', this._closeMenuIfClickedOutside); + } + else { + document.addEventListener('click', this._closeMenuIfClickedOutside); + } + }; + this._unbindCloseMenuIfClickedOutside = function () { + if (!document.removeEventListener && document.detachEvent) { + document.detachEvent('onclick', this._closeMenuIfClickedOutside); + } + else { + document.removeEventListener('click', this._closeMenuIfClickedOutside); + } + }; + this.setState(this.getStateFromValue(this.props.value)); + }, + + componentDidMount: function () { + if (this.props.asyncOptions && this.props.autoload) { + this.autoloadAsyncOptions(); + } + }, + + componentWillUnmount: function () { + clearTimeout(this._blurTimeout); + if (this.state.isOpen) { + this._unbindCloseMenuIfClickedOutside(); + } + }, + + componentWillReceiveProps: function (newProps) { + var optionsChanged = false; + if (JSON.stringify(newProps.options) !== JSON.stringify(this.props.options)) { + optionsChanged = true; + this.setState({ + options: newProps.options, + filteredOptions: this.filterOptions(newProps.options) + }); + } + if (newProps.value !== this.state.value || newProps.placeholder !== this.props.placeholder || optionsChanged) { + var setState = (newState) => { + this.setState(this.getStateFromValue(newProps.value, + (newState && newState.options) || newProps.options, + newProps.placeholder) + ); + }; + if (this.props.asyncOptions) { + this.loadAsyncOptions(newProps.value, {}, setState); + } + else { + setState(); + } + } + }, + + componentWillUpdate: function (nextProps, nextState) { if (nextState.isOpen !== this.state.isOpen) { const handler = nextState.isOpen ? nextProps.onOpen : nextProps.onClose; handler && handler(); } }, - componentDidUpdate: function() { - if (!this.props.disabled) { - clearTimeout(this._blurTimeout); - } - if (this._focusedOptionReveal) { - if (this.refs.focused && this.refs.menu) { - var focusedDOM = React.findDOMNode(this.refs.focused); - var menuDOM = React.findDOMNode(this.refs.menu); - var focusedRect = focusedDOM.getBoundingClientRect(); - var menuRect = menuDOM.getBoundingClientRect(); - - if (focusedRect.bottom > menuRect.bottom || focusedRect.top < menuRect.top) { - menuDOM.scrollTop = (focusedDOM.offsetTop + focusedDOM.clientHeight - menuDOM.offsetHeight); - } - } - this._focusedOptionReveal = false; - } - }, - - focus: function() { - this.getInputNode().focus(); - }, - - clickedOutsideElement: function(element, event) { - var eventTarget = (event.target) ? event.target : event.srcElement; - while (eventTarget != null) { - if (eventTarget === element) return false; - eventTarget = eventTarget.offsetParent; - } - return true; - }, - - getStateFromValue: function(value, options, placeholder) { - if (!options) { - options = this.state.options; - } - if (!placeholder) { - placeholder = this.props.placeholder; - } - - // reset internal filter string - this._optionsFilterString = ''; - - var values = this.initValuesArray(value, options); - var filteredOptions = this.filterOptions(options, values); - - var focusedOption; - var valueForState = null; - if (!this.props.multi && values.length) { - focusedOption = values[0]; - valueForState = values[0].value; - } else { - for (var optionIndex = 0; optionIndex < filteredOptions.length; ++optionIndex) { - if (!filteredOptions[optionIndex].disabled) { - focusedOption = filteredOptions[optionIndex]; - break; - } - } - valueForState = values.map(function(v) { return v.value; }).join(this.props.delimiter); - } - - return { - value: valueForState, - values: values, - inputValue: '', - filteredOptions: filteredOptions, - placeholder: !this.props.multi && values.length ? values[0].label : placeholder, - focusedOption: focusedOption - }; - }, - - initValuesArray: function(values, options) { - if (!Array.isArray(values)) { - if (typeof values === 'string') { - values = values === '' ? [] : values.split(this.props.delimiter); - } else { - values = values !== undefined && values !== null ? [values] : []; - } - } - return values.map(function(val) { - if (typeof val === 'string' || typeof val === 'number') { - for (var key in options) { - if (options.hasOwnProperty(key) && - options[key] && - (options[key].value === val || - typeof options[key].value === 'number' && - options[key].value.toString() === val - )) { - return options[key]; - } - } - return { value: val, label: val }; - } else { - return val; - } - }); - }, - - setValue: function(value) { - var newState = this.getStateFromValue(value); - newState.isOpen = false; - this.fireChangeEvent(newState); - this.setState(newState); - }, - - selectValue: function(value) { - if (!this.props.multi) { - this.setValue(value); - } else if (value) { - this.addValue(value); - } - this._unbindCloseMenuIfClickedOutside(); - }, - - addValue: function(value) { - this.setValue(this.state.values.concat(value)); - }, - - popValue: function() { - this.setValue(this.state.values.slice(0, this.state.values.length - 1)); - }, - - removeValue: function(valueToRemove) { - this.setValue(this.state.values.filter(function(value) { - return value !== valueToRemove; - })); - }, - - clearValue: function(event) { - // if the event was triggered by a mousedown and not the primary - // button, ignore it. - if (event && event.type === 'mousedown' && event.button !== 0) { - return; - } - event.stopPropagation(); - event.preventDefault(); - this.setValue(null); - }, - - resetValue: function() { - this.setValue(this.state.value === '' ? null : this.state.value); - }, - - getInputNode: function () { - var input = this.refs.input; - return this.props.searchable ? input : React.findDOMNode(input); - }, - - fireChangeEvent: function(newState) { - if (newState.value !== this.state.value && this.props.onChange) { - this.props.onChange(newState.value, newState.values); - } - }, - - handleMouseDown: function(event) { - // if the event was triggered by a mousedown and not the primary - // button, or if the component is disabled, ignore it. - if (this.props.disabled || (event.type === 'mousedown' && event.button !== 0)) { - return; - } - event.stopPropagation(); - event.preventDefault(); - - // for the non-searchable select, close the dropdown when button is clicked - if (this.state.isOpen && !this.props.searchable) { - this.setState({ - isOpen: false - }, this._unbindCloseMenuIfClickedOutside); - return; - } - - if (this.state.isFocused) { - this.setState({ - isOpen: true - }, this._bindCloseMenuIfClickedOutside); - } else { - this._openAfterFocus = true; - this.getInputNode().focus(); - } - }, - - handleMouseDownOnArrow: function(event) { - // if the event was triggered by a mousedown and not the primary - // button, or if the component is disabled, ignore it. - if (this.props.disabled || (event.type === 'mousedown' && event.button !== 0)) { - return; - } - // If not focused, handleMouseDown will handle it - if (!this.state.isOpen) { - return; - } - event.stopPropagation(); - event.preventDefault(); - this.setState({ - isOpen: false - }, this._unbindCloseMenuIfClickedOutside); - }, - - handleInputFocus: function(event) { - var newIsOpen = this.state.isOpen || this._openAfterFocus; - this.setState({ - isFocused: true, - isOpen: newIsOpen - }, function() { - if(newIsOpen) { - this._bindCloseMenuIfClickedOutside(); - } - else { - this._unbindCloseMenuIfClickedOutside(); - } - }); - this._openAfterFocus = false; - if (this.props.onFocus) { - this.props.onFocus(event); - } - }, - - handleInputBlur: function(event) { - this._blurTimeout = setTimeout(() => { - this.setState({ - isFocused: false, - isOpen: false - }); - }, 50); - if (this.props.onBlur) { - this.props.onBlur(event); - } - }, - - handleKeyDown: function(event) { - if (this.props.disabled) return; - switch (event.keyCode) { - case 8: // backspace - if (!this.state.inputValue && this.props.backspaceRemoves) { - this.popValue(); - } - return; - case 9: // tab - if (event.shiftKey || !this.state.isOpen || !this.state.focusedOption) { - return; - } - this.selectFocusedOption(); - break; - case 13: // enter - if (!this.state.isOpen) return; - - this.selectFocusedOption(); - break; - case 27: // escape - if (this.state.isOpen) { - this.resetValue(); - } else if (this.props.clearable) { - this.clearValue(event); - } - break; - case 38: // up - this.focusPreviousOption(); - break; - case 40: // down - this.focusNextOption(); - break; - case 188: // , - if (this.props.allowCreate && this.props.multi) { - event.preventDefault(); - event.stopPropagation(); - this.selectFocusedOption(); - } else { - return; - } - break; - default: return; - } - event.preventDefault(); - }, - - // Ensures that the currently focused option is available in filteredOptions. - // If not, returns the first available option. - _getNewFocusedOption: function(filteredOptions) { - for (var key in filteredOptions) { - if (filteredOptions.hasOwnProperty(key) && filteredOptions[key] === this.state.focusedOption) { - return filteredOptions[key]; - } - } - return filteredOptions[0]; - }, - - handleInputChange: function(event) { - // assign an internal variable because we need to use - // the latest value before setState() has completed. - this._optionsFilterString = event.target.value; - - if (this.props.asyncOptions) { - this.setState({ - isLoading: true, - inputValue: event.target.value - }); - this.loadAsyncOptions(event.target.value, { - isLoading: false, - isOpen: true - }, this._bindCloseMenuIfClickedOutside); - } else { - var filteredOptions = this.filterOptions(this.state.options); - this.setState({ - isOpen: true, - inputValue: event.target.value, - filteredOptions: filteredOptions, - focusedOption: this._getNewFocusedOption(filteredOptions) - }, this._bindCloseMenuIfClickedOutside); - } - }, - - autoloadAsyncOptions: function() { - this.loadAsyncOptions((this.props.value || ''), {}, () => { - // update with fetched but don't focus - this.setValue(this.props.value, false); - }); - }, - - loadAsyncOptions: function(input, state, callback) { - var thisRequestId = this._currentRequestId = requestId++; - if (this.props.cacheAsyncResults) { - for (var i = 0; i <= input.length; i++) { - var cacheKey = input.slice(0, i); - if (this._optionsCache[cacheKey] && (input === cacheKey || this._optionsCache[cacheKey].complete)) { - var options = this._optionsCache[cacheKey].options; - var filteredOptions = this.filterOptions(options); - var newState = { - options: options, - filteredOptions: filteredOptions, - focusedOption: this._getNewFocusedOption(filteredOptions) - }; - for (var key in state) { - if (state.hasOwnProperty(key)) { - newState[key] = state[key]; - } - } - this.setState(newState); - if (callback) callback.call(this, newState); - return; - } - } - } - - this.props.asyncOptions(input, (err, data) => { - if (err) throw err; - if (this.props.cacheAsyncResults) { - this._optionsCache[input] = data; - } - if (thisRequestId !== this._currentRequestId) { - return; - } - var filteredOptions = this.filterOptions(data.options); - var newState = { - options: data.options, - filteredOptions: filteredOptions, - focusedOption: this._getNewFocusedOption(filteredOptions) - }; - for (var key in state) { - if (state.hasOwnProperty(key)) { - newState[key] = state[key]; - } - } - this.setState(newState); - if (callback) callback.call(this, newState); - }); - }, - - filterOptions: function(options, values) { - var filterValue = this._optionsFilterString; - var exclude = (values || this.state.values).map(function(i) { - return i.value; - }); - if (this.props.filterOptions) { - return this.props.filterOptions.call(this, options, filterValue, exclude); - } else { - var filterOption = function(op) { - if (this.props.multi && exclude.indexOf(op.value) > -1) return false; - if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue); - var valueTest = String(op.value), labelTest = String(op.label); - if (this.props.ignoreCase) { - valueTest = valueTest.toLowerCase(); - labelTest = labelTest.toLowerCase(); - filterValue = filterValue.toLowerCase(); - } - return !filterValue || (this.props.matchPos === 'start') ? ( - (this.props.matchProp !== 'label' && valueTest.substr(0, filterValue.length) === filterValue) || - (this.props.matchProp !== 'value' && labelTest.substr(0, filterValue.length) === filterValue) - ) : ( - (this.props.matchProp !== 'label' && valueTest.indexOf(filterValue) >= 0) || - (this.props.matchProp !== 'value' && labelTest.indexOf(filterValue) >= 0) - ); - }; - return (options || []).filter(filterOption, this); - } - }, - - selectFocusedOption: function() { - if (this.props.allowCreate && !this.state.focusedOption) { - return this.selectValue(this.state.inputValue); - } - return this.selectValue(this.state.focusedOption); - }, - - focusOption: function(op) { - this.setState({ - focusedOption: op - }); - }, - - focusNextOption: function() { - this.focusAdjacentOption('next'); - }, - - focusPreviousOption: function() { - this.focusAdjacentOption('previous'); - }, - - focusAdjacentOption: function(dir) { - this._focusedOptionReveal = true; - var ops = this.state.filteredOptions.filter(function(op) { - return !op.disabled; - }); - if (!this.state.isOpen) { - this.setState({ - isOpen: true, - inputValue: '', - focusedOption: this.state.focusedOption || ops[dir === 'next' ? 0 : ops.length - 1] - }, this._bindCloseMenuIfClickedOutside); - return; - } - if (!ops.length) { - return; - } - var focusedIndex = -1; - for (var i = 0; i < ops.length; i++) { - if (this.state.focusedOption === ops[i]) { - focusedIndex = i; - break; - } - } - var focusedOption = ops[0]; - if (dir === 'next' && focusedIndex > -1 && focusedIndex < ops.length - 1) { - focusedOption = ops[focusedIndex + 1]; - } else if (dir === 'previous') { - if (focusedIndex > 0) { - focusedOption = ops[focusedIndex - 1]; - } else { - focusedOption = ops[ops.length - 1]; - } - } - this.setState({ - focusedOption: focusedOption - }); - }, - - unfocusOption: function(op) { - if (this.state.focusedOption === op) { - this.setState({ - focusedOption: null - }); - } - }, - - buildMenu: function() { - var focusedValue = this.state.focusedOption ? this.state.focusedOption.value : null; - var renderLabel = this.props.optionRenderer || function(op) { - return op.label; - }; - if (this.state.filteredOptions.length > 0) { - focusedValue = focusedValue == null ? this.state.filteredOptions[0] : focusedValue; - } - // Add the current value to the filtered options in last resort - var options = this.state.filteredOptions; - if (this.props.allowCreate && this.state.inputValue.trim()) { - var inputValue = this.state.inputValue; - options = options.slice(); - var newOption = this.props.newOptionCreator ? this.props.newOptionCreator(inputValue) : { - value: inputValue, - label: inputValue, - create: true - }; - options.unshift(newOption); - } - var ops = Object.keys(options).map(function(key) { - var op = options[key]; - var isSelected = this.state.value === op.value; - var isFocused = focusedValue === op.value; - var optionClass = classes({ - 'Select-option': true, - 'is-selected': isSelected, - 'is-focused': isFocused, - 'is-disabled': op.disabled - }); - var ref = isFocused ? 'focused' : null; - var mouseEnter = this.focusOption.bind(this, op); - var mouseLeave = this.unfocusOption.bind(this, op); - var mouseDown = this.selectValue.bind(this, op); - var optionResult = React.createElement(this.props.optionComponent, { - key: 'option-' + op.value, - className: optionClass, - renderFunc: renderLabel, - mouseEnter: mouseEnter, - mouseLeave: mouseLeave, - mouseDown: mouseDown, - click: mouseDown, - addLabelText: this.props.addLabelText, - option: op, - ref: ref - }); - return optionResult; - }, this); - return ops.length ? ops : ( -
- {this.props.asyncOptions && !this.state.inputValue ? this.props.searchPromptText : this.props.noResultsText} -
- ); - }, - - handleOptionLabelClick: function (value, event) { - if (this.props.onOptionLabelClick) { - this.props.onOptionLabelClick(value, event); - } - }, - - render: function() { - var selectClass = classes('Select', this.props.className, { - 'is-multi': this.props.multi, - 'is-searchable': this.props.searchable, - 'is-open': this.state.isOpen, - 'is-focused': this.state.isFocused, - 'is-loading': this.state.isLoading, - 'is-disabled': this.props.disabled, - 'has-value': this.state.value - }); - var value = []; - if (this.props.multi) { - this.state.values.forEach(function(val) { - var onOptionLabelClick = this.handleOptionLabelClick.bind(this, val); - var onRemove = this.removeValue.bind(this, val); - var valueComponent = React.createElement(this.props.valueComponent, { - key: val.value, - option: val, - renderer: this.props.valueRenderer, - optionLabelClick: !!this.props.onOptionLabelClick, - onOptionLabelClick: onOptionLabelClick, - onRemove: onRemove, - disabled: this.props.disabled - }); - value.push(valueComponent); - }, this); - } - - if (!this.state.inputValue && (!this.props.multi || !value.length)) { - var val = this.state.values[0] || null; - if (this.props.valueRenderer && !!this.state.values.length) { - value.push(); - } else { - var singleValueComponent = React.createElement(this.props.singleValueComponent, { - key: 'placeholder', - value: val, - placeholder: this.state.placeholder - }); - value.push(singleValueComponent); - } - } - - var loading = this.state.isLoading ?
- @@ -193,15 +244,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + +
\ No newline at end of file diff --git a/dist/react-select.js b/dist/react-select.js index 035ef866bb..78662889a2 100644 --- a/dist/react-select.js +++ b/dist/react-select.js @@ -88,6 +88,8 @@ var Select = React.createClass({ noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results onBlur: React.PropTypes.func, // onBlur handler: function(event) {} onChange: React.PropTypes.func, // onChange handler: function(newValue) {} + onOpen: React.PropTypes.func, // fires when the menu is opened + onClose: React.PropTypes.func, // fires when the menu is closed onFocus: React.PropTypes.func, // onFocus handler: function(event) {} onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} optionComponent: React.PropTypes.func, // option component to render in dropdown @@ -230,6 +232,13 @@ var Select = React.createClass({ } }, + componentWillUpdate: function (nextProps, nextState) { + if (nextState.isOpen !== this.state.isOpen) { + const handler = nextState.isOpen ? nextProps.onOpen : nextProps.onClose; + handler && handler(); + } + }, + componentDidUpdate: function componentDidUpdate() { var _this3 = this; diff --git a/examples/dist/app.js b/examples/dist/app.js index e0bf21f599..cec696fe6a 100644 --- a/examples/dist/app.js +++ b/examples/dist/app.js @@ -37,7 +37,7 @@ var Option = React.createClass({ module.exports = Option; -},{"react":undefined,"react-gravatar":9}],2:[function(require,module,exports){ +},{"react":undefined,"react-gravatar":14}],2:[function(require,module,exports){ 'use strict'; var React = require('react'); @@ -70,7 +70,7 @@ var SingleValue = React.createClass({ module.exports = SingleValue; -},{"react":undefined,"react-gravatar":9}],3:[function(require,module,exports){ +},{"react":undefined,"react-gravatar":14}],3:[function(require,module,exports){ /* eslint react/prop-types: 0 */ 'use strict'; @@ -607,235 +607,158 @@ exports.US = [{ value: 'AL', label: 'Alabama', disabled: true }, { value: 'AK', exports.users = [{ value: 'John Smith', label: 'John Smith', email: 'john@smith.com' }, { value: 'Merry Jane', label: 'Merry Jane', email: 'merry@jane.com' }, { value: 'Stan Hoper', label: 'Stan Hoper', email: 'stan@hoper.com' }]; },{}],6:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; +var charenc = { + // UTF-8 encoding + utf8: { + // Convert a string to a byte array + stringToBytes: function(str) { + return charenc.bin.stringToBytes(unescape(encodeURIComponent(str))); + }, - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; + // Convert a byte array to a string + bytesToString: function(bytes) { + return decodeURIComponent(escape(charenc.bin.bytesToString(bytes))); } + }, - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); + // Binary encoding + bin: { + // Convert a string to a byte array + stringToBytes: function(str) { + for (var bytes = [], i = 0; i < str.length; i++) + bytes.push(str.charCodeAt(i) & 0xFF); + return bytes; + }, - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; + // Convert a byte array to a string + bytesToString: function(bytes) { + for (var str = [], i = 0; i < bytes.length; i++) + str.push(String.fromCharCode(bytes[i])); + return str.join(''); } } - - return obj; }; -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +module.exports = charenc; },{}],7:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - - case 'boolean': - return v ? 'true' : 'false'; - - case 'number': - return isFinite(v) ? v : ''; +(function() { + var base64map + = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', - default: - return ''; - } -}; + crypt = { + // Bit-wise rotation left + rotl: function(n, b) { + return (n << b) | (n >>> (32 - b)); + }, -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } + // Bit-wise rotation right + rotr: function(n, b) { + return (n << (32 - b)) | (n >>> b); + }, - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return map(obj[k], function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + // Swap big-endian to little-endian and vice versa + endian: function(n) { + // If number given, swap endian + if (n.constructor == Number) { + return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00; } - }).join(sep); - - } - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; + // Else, assume array and swap all items + for (var i = 0; i < n.length; i++) + n[i] = crypt.endian(n[i]); + return n; + }, -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + // Generate an array of any length of random bytes + randomBytes: function(n) { + for (var bytes = []; n > 0; n--) + bytes.push(Math.floor(Math.random() * 256)); + return bytes; + }, -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} + // Convert a byte array to big-endian 32-bit words + bytesToWords: function(bytes) { + for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) + words[b >>> 5] |= bytes[i] << (24 - b % 32); + return words; + }, -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; + // Convert big-endian 32-bit words to a byte array + wordsToBytes: function(words) { + for (var bytes = [], b = 0; b < words.length * 32; b += 8) + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + return bytes; + }, -},{}],8:[function(require,module,exports){ -'use strict'; + // Convert a byte array to a hex string + bytesToHex: function(bytes) { + for (var hex = [], i = 0; i < bytes.length; i++) { + hex.push((bytes[i] >>> 4).toString(16)); + hex.push((bytes[i] & 0xF).toString(16)); + } + return hex.join(''); + }, -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); + // Convert a hex string to a byte array + hexToBytes: function(hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; + }, -},{"./decode":6,"./encode":7}],9:[function(require,module,exports){ -// Generated by CoffeeScript 1.9.3 -var React, isRetina, md5, querystring; + // Convert a byte array to a base-64 string + bytesToBase64: function(bytes) { + for (var base64 = [], i = 0; i < bytes.length; i += 3) { + var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; + for (var j = 0; j < 4; j++) + if (i * 8 + j * 6 <= bytes.length * 8) + base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); + else + base64.push('='); + } + return base64.join(''); + }, -React = require('react'); + // Convert a base-64 string to a byte array + base64ToBytes: function(base64) { + // Remove non-base-64 characters + base64 = base64.replace(/[^A-Z0-9+\/]/ig, ''); -md5 = require('md5'); + for (var bytes = [], i = 0, imod4 = 0; i < base64.length; + imod4 = ++i % 4) { + if (imod4 == 0) continue; + bytes.push(((base64map.indexOf(base64.charAt(i - 1)) + & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) + | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); + } + return bytes; + } + }; -querystring = require('querystring'); + module.exports = crypt; +})(); -isRetina = require('is-retina'); +},{}],8:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ -module.exports = React.createClass({ - displayName: 'Gravatar', - propTypes: { - email: React.PropTypes.string.isRequired, - size: React.PropTypes.number, - rating: React.PropTypes.string, - https: React.PropTypes.bool, - "default": React.PropTypes.string, - className: React.PropTypes.string - }, - getDefaultProps: function() { - return { - size: 50, - rating: 'g', - https: false, - "default": "retro", - email: '', - className: "" - }; - }, - render: function() { - var base, query, src; - base = this.props.https ? "https://secure.gravatar.com/avatar/" : 'http://www.gravatar.com/avatar/'; - query = querystring.stringify({ - s: isRetina() ? this.props.size * 2 : this.props.size, - r: this.props.rating, - d: this.props["default"] - }); - src = base + md5(this.props.email) + "?" + query; - return React.createElement("img", React.__spread({}, this.props, { - "className": "react-gravatar " + this.props.className, - "src": src, - "height": this.props.size, - "width": this.props.size - })); - } -}); +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} -},{"is-retina":10,"md5":11,"querystring":8,"react":undefined}],10:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ module.exports = function() { var mediaQuery; if (typeof window !== "undefined" && window !== null) { @@ -850,7 +773,7 @@ module.exports = function() { return false; }; -},{}],11:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ (function(){ var crypt = require('crypt'), utf8 = require('charenc').utf8, @@ -1012,156 +935,234 @@ module.exports = function() { })(); -},{"charenc":12,"crypt":13,"is-buffer":14}],12:[function(require,module,exports){ -var charenc = { - // UTF-8 encoding - utf8: { - // Convert a string to a byte array - stringToBytes: function(str) { - return charenc.bin.stringToBytes(unescape(encodeURIComponent(str))); - }, +},{"charenc":6,"crypt":7,"is-buffer":8}],11:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; - // Convert a byte array to a string - bytesToString: function(bytes) { - return decodeURIComponent(escape(charenc.bin.bytesToString(bytes))); + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; } - }, - // Binary encoding - bin: { - // Convert a string to a byte array - stringToBytes: function(str) { - for (var bytes = [], i = 0; i < str.length; i++) - bytes.push(str.charCodeAt(i) & 0xFF); - return bytes; - }, + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); - // Convert a byte array to a string - bytesToString: function(bytes) { - for (var str = [], i = 0; i < bytes.length; i++) - str.push(String.fromCharCode(bytes[i])); - return str.join(''); + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; } } + + return obj; }; -module.exports = charenc; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; -},{}],13:[function(require,module,exports){ -(function() { - var base64map - = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', +},{}],12:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - crypt = { - // Bit-wise rotation left - rotl: function(n, b) { - return (n << b) | (n >>> (32 - b)); - }, +'use strict'; - // Bit-wise rotation right - rotr: function(n, b) { - return (n << (32 - b)) | (n >>> b); - }, +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; - // Swap big-endian to little-endian and vice versa - endian: function(n) { - // If number given, swap endian - if (n.constructor == Number) { - return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00; + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; + } +}; + +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return map(obj[k], function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } + }).join(sep); - // Else, assume array and swap all items - for (var i = 0; i < n.length; i++) - n[i] = crypt.endian(n[i]); - return n; - }, + } - // Generate an array of any length of random bytes - randomBytes: function(n) { - for (var bytes = []; n > 0; n--) - bytes.push(Math.floor(Math.random() * 256)); - return bytes; - }, + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; - // Convert a byte array to big-endian 32-bit words - bytesToWords: function(bytes) { - for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) - words[b >>> 5] |= bytes[i] << (24 - b % 32); - return words; - }, +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; - // Convert big-endian 32-bit words to a byte array - wordsToBytes: function(words) { - for (var bytes = [], b = 0; b < words.length * 32; b += 8) - bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); - return bytes; - }, +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} - // Convert a byte array to a hex string - bytesToHex: function(bytes) { - for (var hex = [], i = 0; i < bytes.length; i++) { - hex.push((bytes[i] >>> 4).toString(16)); - hex.push((bytes[i] & 0xF).toString(16)); - } - return hex.join(''); - }, +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; - // Convert a hex string to a byte array - hexToBytes: function(hex) { - for (var bytes = [], c = 0; c < hex.length; c += 2) - bytes.push(parseInt(hex.substr(c, 2), 16)); - return bytes; - }, +},{}],13:[function(require,module,exports){ +'use strict'; - // Convert a byte array to a base-64 string - bytesToBase64: function(bytes) { - for (var base64 = [], i = 0; i < bytes.length; i += 3) { - var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; - for (var j = 0; j < 4; j++) - if (i * 8 + j * 6 <= bytes.length * 8) - base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); - else - base64.push('='); - } - return base64.join(''); - }, +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); - // Convert a base-64 string to a byte array - base64ToBytes: function(base64) { - // Remove non-base-64 characters - base64 = base64.replace(/[^A-Z0-9+\/]/ig, ''); +},{"./decode":11,"./encode":12}],14:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.3 +var React, isRetina, md5, querystring; - for (var bytes = [], i = 0, imod4 = 0; i < base64.length; - imod4 = ++i % 4) { - if (imod4 == 0) continue; - bytes.push(((base64map.indexOf(base64.charAt(i - 1)) - & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) - | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); - } - return bytes; - } - }; +React = require('react'); - module.exports = crypt; -})(); +md5 = require('md5'); -},{}],14:[function(require,module,exports){ -/** - * Determine if an object is Buffer - * - * Author: Feross Aboukhadijeh - * License: MIT - * - * `npm install is-buffer` - */ +querystring = require('querystring'); -module.exports = function (obj) { - return !!( - obj != null && - obj.constructor && - typeof obj.constructor.isBuffer === 'function' && - obj.constructor.isBuffer(obj) - ) -} +isRetina = require('is-retina'); + +module.exports = React.createClass({ + displayName: 'Gravatar', + propTypes: { + email: React.PropTypes.string.isRequired, + size: React.PropTypes.number, + rating: React.PropTypes.string, + https: React.PropTypes.bool, + "default": React.PropTypes.string, + className: React.PropTypes.string + }, + getDefaultProps: function() { + return { + size: 50, + rating: 'g', + https: false, + "default": "retro", + email: '', + className: "" + }; + }, + render: function() { + var base, query, src; + base = this.props.https ? "https://secure.gravatar.com/avatar/" : 'http://www.gravatar.com/avatar/'; + query = querystring.stringify({ + s: isRetina() ? this.props.size * 2 : this.props.size, + r: this.props.rating, + d: this.props["default"] + }); + src = base + md5(this.props.email) + "?" + query; + return React.createElement("img", React.__spread({}, this.props, { + "className": "react-gravatar " + this.props.className, + "src": src, + "height": this.props.size, + "width": this.props.size + })); + } +}); -},{}]},{},[3]); +},{"is-retina":9,"md5":10,"querystring":13,"react":undefined}]},{},[3]) +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvcGF0cmlja21ja2VsdnkvRG9jdW1lbnRzL3dvcmsvcmVhY3Qtc2VsZWN0L2V4YW1wbGVzL3NyYy9DdXN0b21PcHRpb24uanMiLCIvVXNlcnMvcGF0cmlja21ja2VsdnkvRG9jdW1lbnRzL3dvcmsvcmVhY3Qtc2VsZWN0L2V4YW1wbGVzL3NyYy9DdXN0b21TaW5nbGVWYWx1ZS5qcyIsIi9Vc2Vycy9wYXRyaWNrbWNrZWx2eS9Eb2N1bWVudHMvd29yay9yZWFjdC1zZWxlY3QvZXhhbXBsZXMvc3JjL2FwcC5qcyIsIi9Vc2Vycy9wYXRyaWNrbWNrZWx2eS9Eb2N1bWVudHMvd29yay9yZWFjdC1zZWxlY3QvZXhhbXBsZXMvc3JjL2RhdGEvc3RhdGVzLmpzIiwiL1VzZXJzL3BhdHJpY2ttY2tlbHZ5L0RvY3VtZW50cy93b3JrL3JlYWN0LXNlbGVjdC9leGFtcGxlcy9zcmMvZGF0YS91c2Vycy5qcyIsIm5vZGVfbW9kdWxlcy9jaGFyZW5jL2NoYXJlbmMuanMiLCJub2RlX21vZHVsZXMvY3J5cHQvY3J5cHQuanMiLCJub2RlX21vZHVsZXMvaXMtYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lzLXJldGluYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9tZDUvbWQ1LmpzIiwibm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9kZWNvZGUuanMiLCJub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzL2VuY29kZS5qcyIsIm5vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcmVhY3QtZ3JhdmF0YXIvZGlzdC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQUEsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztBQUU3QixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsZ0JBQWdC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QUFFLEVBQ2xDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLEVBQ3ZDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQ2xDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQ25DLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEVBQ3JDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQ2xDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQ2pDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQ2xDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQ2hDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLEVBQ3ZDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEVBQ3BDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEVBQ3BDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQ2xDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsRUFDeEMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsRUFDdEMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxFQUNsRCxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUM5QixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxFQUNsQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUNoQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUMvQixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxFQUN0QyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxFQUNyQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxFQUN0QyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLEVBQ3hDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLEVBQ3RDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQ25DLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQy9CLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQzlCLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQ2pDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsRUFDeEMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFDbEMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsRUFDcEMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsRUFDdkMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsRUFDbkMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FDcEMsQ0FBQzs7Ozs7QUN2RUYsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUNaLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxFQUNyRSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsRUFDckUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLENBQ3hFLENBQUM7OztBQ0pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBHcmF2YXRhciA9IHJlcXVpcmUoJ3JlYWN0LWdyYXZhdGFyJyk7XG5cbnZhciBPcHRpb24gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gIHByb3BUeXBlczoge1xuICAgIGFkZExhYmVsVGV4dDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgbW91c2VEb3duOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBtb3VzZUVudGVyOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBtb3VzZUxlYXZlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvcHRpb246IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICByZW5kZXJGdW5jOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IHRoaXMucHJvcHMub3B0aW9uO1xuICAgIHZhciBzaXplID0gMTU7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9e3RoaXMucHJvcHMuY2xhc3NOYW1lfVxuICAgICAgICBvbk1vdXNlRW50ZXI9e3RoaXMucHJvcHMubW91c2VFbnRlcn1cbiAgICAgICAgb25Nb3VzZUxlYXZlPXt0aGlzLnByb3BzLm1vdXNlTGVhdmV9XG4gICAgICAgIG9uTW91c2VEb3duPXt0aGlzLnByb3BzLm1vdXNlRG93bn1cbiAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5tb3VzZURvd259PlxuICAgICAgICA8R3JhdmF0YXIgZW1haWw9e29iai5lbWFpbH0gc2l6ZT17c2l6ZX0vPlxuICAgICAgICB7b2JqLnZhbHVlfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gT3B0aW9uO1xuIiwidmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBHcmF2YXRhciA9IHJlcXVpcmUoJ3JlYWN0LWdyYXZhdGFyJyk7XG5cbnZhciBTaW5nbGVWYWx1ZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgcHJvcFR5cGVzOiB7XG4gICAgcGxhY2Vob2xkZXI6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgdmFsdWU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3RcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSB0aGlzLnByb3BzLnZhbHVlO1xuICAgIHZhciBzaXplID0gMTU7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJTZWxlY3QtcGxhY2Vob2xkZXJcIj5cbiAgICAgICAge29iaiA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxHcmF2YXRhciBlbWFpbD17b2JqLmVtYWlsfSBzaXplPXtzaXplfS8+XG4gICAgICAgICAgICAgIHtvYmoudmFsdWV9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5wbGFjZWhvbGRlclxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU2luZ2xlVmFsdWU7XG4iLCIvKiBlc2xpbnQgcmVhY3QvcHJvcC10eXBlczogMCAqL1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFNlbGVjdCA9IHJlcXVpcmUoJ3JlYWN0LXNlbGVjdCcpO1xudmFyIEdyYXZhdGFyT3B0aW9uID0gcmVxdWlyZSgnLi9DdXN0b21PcHRpb24nKTtcbnZhciBHcmF2YXRhclZhbHVlID0gcmVxdWlyZSgnLi9DdXN0b21TaW5nbGVWYWx1ZScpO1xuXG52YXIgU1RBVEVTID0gcmVxdWlyZSgnLi9kYXRhL3N0YXRlcycpO1xudmFyIFVTRVJTID0gcmVxdWlyZSgnLi9kYXRhL3VzZXJzJyk7XG52YXIgaWQgPSAwO1xuXG5mdW5jdGlvbiBsb2dDaGFuZ2UoKSB7XG5cdGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIFtdLmNvbmNhdChbJ1NlbGVjdCB2YWx1ZSBjaGFuZ2VkOiAnXSwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpKTtcbn1cblxudmFyIENvdW50cnlTZWxlY3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdG9uQ2xpY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMucHJvcHMub25TZWxlY3QodGhpcy5wcm9wcy52YWx1ZSk7XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNsYXNzTmFtZSA9IHRoaXMucHJvcHMudmFsdWUgPT09IHRoaXMucHJvcHMuc2VsZWN0ZWQgPyAnYWN0aXZlJyA6ICdsaW5rJztcblx0XHRyZXR1cm4gPHNwYW4gb25DbGljaz17dGhpcy5vbkNsaWNrfSBjbGFzc05hbWU9e2NsYXNzTmFtZX0+e3RoaXMucHJvcHMuY2hpbGRyZW59PC9zcGFuPjtcblx0fVxufSk7XG5cbnZhciBVc2Vyc0ZpZWxkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VhcmNoYWJsZTogdHJ1ZSxcblx0XHRcdGxhYmVsOiAnVXNlcnM6ICh3aXRoIGN1c3RvbSBvcHRpb24gYW5kIHZhbHVlIGNvbXBvbmVudCknXG5cdFx0fTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblxuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8bGFiZWw+e3RoaXMucHJvcHMubGFiZWx9PC9sYWJlbD5cblx0XHRcdFx0PFNlbGVjdFxuXHRcdFx0XHRcdG9uT3B0aW9uTGFiZWxDbGljaz17dGhpcy5vbkxhYmVsQ2xpY2t9XG5cdFx0XHRcdFx0cGxhY2Vob2xkZXI9XCJTZWxlY3QgdXNlclwiXG5cdFx0XHRcdFx0b3B0aW9uQ29tcG9uZW50PXtHcmF2YXRhck9wdGlvbn1cblx0XHRcdFx0XHRzaW5nbGVWYWx1ZUNvbXBvbmVudD17R3JhdmF0YXJWYWx1ZX1cblx0XHRcdFx0XHRvcHRpb25zPXtVU0VSUy51c2Vyc30vPlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBWYWx1ZXNBc051bWJlcnNGaWVsZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRvcHRpb25zOiBbXG5cdFx0XHRcdHsgdmFsdWU6IDEwLCBsYWJlbDogJ1RlbicgfSxcblx0XHRcdFx0eyB2YWx1ZTogMTEsIGxhYmVsOiAnRWxldmVuJyB9LFxuXHRcdFx0XHR7IHZhbHVlOiAxMiwgbGFiZWw6ICdUd2VsdmUnIH0sXG5cdFx0XHRcdHsgdmFsdWU6IDIzLCBsYWJlbDogJ1R3ZW50eS10aHJlZScgfSxcblx0XHRcdFx0eyB2YWx1ZTogMjQsIGxhYmVsOiAnVHdlbnR5LXRocmVlJyB9XG5cdFx0XHRdLFxuXHRcdFx0bWF0Y2hQb3M6ICdhbnknLFxuXHRcdFx0bWF0Y2hWYWx1ZTogdHJ1ZSxcblx0XHRcdG1hdGNoTGFiZWw6IHRydWUsXG5cdFx0XHR2YWx1ZTogbnVsbCxcblx0XHRcdG11bHRpOiBmYWxzZVxuXHRcdH07XG5cdH0sXG5cdFxuXHRvbkNoYW5nZU1hdGNoU3RhcnQoZXZlbnQpIHtcblx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdG1hdGNoUG9zOiBldmVudC50YXJnZXQuY2hlY2tlZCA/ICdzdGFydCcgOiAnYW55J1xuXHRcdH0pO1xuXHR9LFxuXG5cdG9uQ2hhbmdlTWF0Y2hWYWx1ZShldmVudCkge1xuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0bWF0Y2hWYWx1ZTogZXZlbnQudGFyZ2V0LmNoZWNrZWRcblx0XHR9KTtcblx0fSxcblxuXHRvbkNoYW5nZU1hdGNoTGFiZWwoZXZlbnQpIHtcblx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdG1hdGNoTGFiZWw6IGV2ZW50LnRhcmdldC5jaGVja2VkXG5cdFx0fSk7XG5cdH0sXG5cdFxuXHRvbkNoYW5nZSh2YWx1ZSwgdmFsdWVzKSB7XG5cdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHR2YWx1ZTogdmFsdWVcblx0XHR9KTtcblx0XHRsb2dDaGFuZ2UodmFsdWUsIHZhbHVlcyk7XG5cdH0sXG5cdFxuXHRvbkNoYW5nZU11bHRpKGV2ZW50KSB7XG5cdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHRtdWx0aTogZXZlbnQudGFyZ2V0LmNoZWNrZWRcblx0XHR9KTtcblx0fSxcblx0XG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdFxuXHRcdHZhciBtYXRjaFByb3AgPSAnYW55Jztcblx0XHRcblx0XHRpZiAodGhpcy5zdGF0ZS5tYXRjaExhYmVsICYmICF0aGlzLnN0YXRlLm1hdGNoVmFsdWUpIHtcblx0XHRcdG1hdGNoUHJvcCA9ICdsYWJlbCc7XG5cdFx0fVxuXHRcdFxuXHRcdGlmICghdGhpcy5zdGF0ZS5tYXRjaExhYmVsICYmIHRoaXMuc3RhdGUubWF0Y2hWYWx1ZSkge1xuXHRcdFx0bWF0Y2hQcm9wID0gJ3ZhbHVlJztcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxsYWJlbD57dGhpcy5wcm9wcy5sYWJlbH08L2xhYmVsPlxuXHRcdFx0XHQ8U2VsZWN0XG5cdFx0XHRcdFx0c2VhcmNoYWJsZT17dHJ1ZX1cblx0XHRcdFx0XHRtYXRjaFByb3A9e21hdGNoUHJvcH1cblx0XHRcdFx0XHRtYXRjaFBvcz17dGhpcy5zdGF0ZS5tYXRjaFBvc31cblx0XHRcdFx0XHRvcHRpb25zPXt0aGlzLnN0YXRlLm9wdGlvbnN9XG5cdFx0XHRcdFx0b25DaGFuZ2U9e3RoaXMub25DaGFuZ2V9XG5cdFx0XHRcdFx0dmFsdWU9e3RoaXMuc3RhdGUudmFsdWV9XG5cdFx0XHRcdFx0bXVsdGk9e3RoaXMuc3RhdGUubXVsdGl9XG5cdFx0XHRcdFx0Lz5cblx0XHRcdFx0PGRpdj5cblx0XHRcdFx0XHQ8bGFiZWwgaHRtbEZvcj1cInZhbHVlcy1hcy1udW1iZXJzLW11bHRpXCI+TXVsdGktU2VsZWN0PzwvbGFiZWw+XG5cdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwidmFsdWVzLWFzLW51bWJlcnMtbXVsdGlcIiBjaGVja2VkPXt0aGlzLnN0YXRlLm11bHRpfSBvbkNoYW5nZT17dGhpcy5vbkNoYW5nZU11bHRpfSAvPlxuXHRcdFx0XHRcdDxsYWJlbCBodG1sRm9yPVwidmFsdWVzLWFzLW51bWJlcnMtbWF0Y2hzdGFydFwiPk1hdGNoIG9ubHkgYXQgc3RhcnQ/PC9sYWJlbD5cblx0XHRcdFx0XHQ8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJ2YWx1ZXMtYXMtbnVtYmVycy1tYXRjaHN0YXJ0XCIgY2hlY2tlZD17dGhpcy5zdGF0ZS5tYXRjaFBvcyA9PT0gJ3N0YXJ0J30gb25DaGFuZ2U9e3RoaXMub25DaGFuZ2VNYXRjaFN0YXJ0fSAvPlxuXHRcdFx0XHRcdDxsYWJlbCBodG1sRm9yPVwidmFsdWVzLWFzLW51bWJlcnMtbWF0Y2h2YWx1ZVwiPk1hdGNoIHZhbHVlPzwvbGFiZWw+XG5cdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwidmFsdWVzLWFzLW51bWJlcnMtbWF0Y2h2YWx1ZVwiIGNoZWNrZWQ9e3RoaXMuc3RhdGUubWF0Y2hWYWx1ZX0gb25DaGFuZ2U9e3RoaXMub25DaGFuZ2VNYXRjaFZhbHVlfSAvPlxuXHRcdFx0XHRcdDxsYWJlbCBodG1sRm9yPVwidmFsdWVzLWFzLW51bWJlcnMtbWF0Y2hsYWJlbFwiPk1hdGNoIGxhYmVsPzwvbGFiZWw+XG5cdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGlkPVwidmFsdWVzLWFzLW51bWJlcnMtbWF0Y2hsYWJlbFwiIGNoZWNrZWQ9e3RoaXMuc3RhdGUubWF0Y2hMYWJlbH0gb25DaGFuZ2U9e3RoaXMub25DaGFuZ2VNYXRjaExhYmVsfSAvPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgU3RhdGVzRmllbGQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZWFyY2hhYmxlOiB0cnVlLFxuXHRcdFx0bGFiZWw6ICdTdGF0ZXM6J1xuXHRcdH07XG5cdH0sXG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGNvdW50cnk6ICdBVScsXG5cdFx0XHRkaXNhYmxlZDogZmFsc2UsXG5cdFx0XHRpZDogKytpZCxcblx0XHRcdHNlbGVjdFZhbHVlOiAnbmV3LXNvdXRoLXdhbGVzJ1xuXHRcdH07XG5cdH0sXG5cdHN3aXRjaENvdW50cnk6IGZ1bmN0aW9uKG5ld0NvdW50cnkpIHtcblx0XHRjb25zb2xlLmxvZygnQ291bnRyeSBjaGFuZ2VkIHRvICcgKyBuZXdDb3VudHJ5KTtcblx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdGNvdW50cnk6IG5ld0NvdW50cnksXG5cdFx0XHRzZWxlY3RWYWx1ZTogbnVsbFxuXHRcdH0pO1xuXHR9LFxuXHR1cGRhdGVWYWx1ZTogZnVuY3Rpb24obmV3VmFsdWUpIHtcblx0XHRsb2dDaGFuZ2UoJ1N0YXRlIGNoYW5nZWQgdG8gJyArIG5ld1ZhbHVlKTtcblx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdHNlbGVjdFZhbHVlOiBuZXdWYWx1ZSB8fCBudWxsXG5cdFx0fSk7XG5cdH0sXG5cdGZvY3VzU3RhdGVTZWxlY3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMucmVmcy5zdGF0ZVNlbGVjdC5mb2N1cygpO1xuXHR9LFxuXHR0b2dnbGVEaXNhYmxlZDogZnVuY3Rpb24oZSkge1xuXHRcdHRoaXMuc2V0U3RhdGUoeyBkaXNhYmxlZDogZS50YXJnZXQuY2hlY2tlZCB9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgb3BzID0gU1RBVEVTW3RoaXMuc3RhdGUuY291bnRyeV07XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxsYWJlbD57dGhpcy5wcm9wcy5sYWJlbH08L2xhYmVsPlxuXHRcdFx0XHQ8U2VsZWN0IHJlZj1cInN0YXRlU2VsZWN0XCIgb3B0aW9ucz17b3BzfSBkaXNhYmxlZD17dGhpcy5zdGF0ZS5kaXNhYmxlZH0gdmFsdWU9e3RoaXMuc3RhdGUuc2VsZWN0VmFsdWV9IG9uQ2hhbmdlPXt0aGlzLnVwZGF0ZVZhbHVlfSBzZWFyY2hhYmxlPXt0aGlzLnByb3BzLnNlYXJjaGFibGV9IC8+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwic3dpdGNoZXJcIj5cblx0XHRcdFx0XHRDb3VudHJ5OlxuXHRcdFx0XHRcdDxDb3VudHJ5U2VsZWN0IHZhbHVlPVwiQVVcIiBzZWxlY3RlZD17dGhpcy5zdGF0ZS5jb3VudHJ5fSBvblNlbGVjdD17dGhpcy5zd2l0Y2hDb3VudHJ5fT5BdXN0cmFsaWE8L0NvdW50cnlTZWxlY3Q+XG5cdFx0XHRcdFx0PENvdW50cnlTZWxlY3QgdmFsdWU9XCJVU1wiIHNlbGVjdGVkPXt0aGlzLnN0YXRlLmNvdW50cnl9IG9uU2VsZWN0PXt0aGlzLnN3aXRjaENvdW50cnl9PlVTPC9Db3VudHJ5U2VsZWN0PlxuXHRcdFx0XHRcdCZuYnNwOyA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBvbkNsaWNrPXt0aGlzLmZvY3VzU3RhdGVTZWxlY3R9PkZvY3VzIFNlbGVjdDwvYnV0dG9uPlxuXHRcdFx0XHRcdCZuYnNwOyA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2hlY2tlZD17dGhpcy5zdGF0ZS5kaXNhYmxlZH0gaWQ9eydkaXNhYmxlLXN0YXRlcy0nICsgdGhpcy5zdGF0ZS5pZH0gb25DaGFuZ2U9e3RoaXMudG9nZ2xlRGlzYWJsZWR9Lz5cblx0XHRcdFx0XHQ8bGFiZWwgaHRtbEZvcj17J2Rpc2FibGUtc3RhdGVzLScgKyB0aGlzLnN0YXRlLmlkfT5EaXNhYmxlPC9sYWJlbD5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIFJlbW90ZVNlbGVjdEZpZWxkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRsb2FkT3B0aW9uczogZnVuY3Rpb24oaW5wdXQsIGNhbGxiYWNrKSB7XG5cdFx0aW5wdXQgPSBpbnB1dC50b0xvd2VyQ2FzZSgpO1xuXHRcdHZhciBydG4gPSB7XG5cdFx0XHRvcHRpb25zOiBbXG5cdFx0XHRcdHsgbGFiZWw6ICdPbmUnLCB2YWx1ZTogJ29uZScgfSxcblx0XHRcdFx0eyBsYWJlbDogJ1R3bycsIHZhbHVlOiAndHdvJyB9LFxuXHRcdFx0XHR7IGxhYmVsOiAnVGhyZWUnLCB2YWx1ZTogJ3RocmVlJyB9XG5cdFx0XHRdLFxuXHRcdFx0Y29tcGxldGU6IHRydWVcblx0XHR9O1xuXHRcdGlmIChpbnB1dC5zbGljZSgwLCAxKSA9PT0gJ2EnKSB7XG5cdFx0XHRpZiAoaW5wdXQuc2xpY2UoMCwgMikgPT09ICdhYicpIHtcblx0XHRcdFx0cnRuID0ge1xuXHRcdFx0XHRcdG9wdGlvbnM6IFtcblx0XHRcdFx0XHRcdHsgbGFiZWw6ICdBQicsIHZhbHVlOiAnYWInIH0sXG5cdFx0XHRcdFx0XHR7IGxhYmVsOiAnQUJDJywgdmFsdWU6ICdhYmMnIH0sXG5cdFx0XHRcdFx0XHR7IGxhYmVsOiAnQUJDRCcsIHZhbHVlOiAnYWJjZCcgfVxuXHRcdFx0XHRcdF0sXG5cdFx0XHRcdFx0Y29tcGxldGU6IHRydWVcblx0XHRcdFx0fTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJ0biA9IHtcblx0XHRcdFx0XHRvcHRpb25zOiBbXG5cdFx0XHRcdFx0XHR7IGxhYmVsOiAnQScsIHZhbHVlOiAnYScgfSxcblx0XHRcdFx0XHRcdHsgbGFiZWw6ICdBQScsIHZhbHVlOiAnYWEnIH0sXG5cdFx0XHRcdFx0XHR7IGxhYmVsOiAnQUInLCB2YWx1ZTogJ2FiJyB9XG5cdFx0XHRcdFx0XSxcblx0XHRcdFx0XHRjb21wbGV0ZTogZmFsc2Vcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKCFpbnB1dC5sZW5ndGgpIHtcblx0XHRcdHJ0bi5jb21wbGV0ZSA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRjYWxsYmFjayhudWxsLCBydG4pO1xuXHRcdH0sIDUwMCk7XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxsYWJlbD57dGhpcy5wcm9wcy5sYWJlbH08L2xhYmVsPlxuXHRcdFx0XHQ8U2VsZWN0IGFzeW5jT3B0aW9ucz17dGhpcy5sb2FkT3B0aW9uc30gY2xhc3NOYW1lPVwicmVtb3RlLWV4YW1wbGVcIiAvPlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cblxudmFyIE11bHRpU2VsZWN0RmllbGQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGRpc2FibGVkOiBmYWxzZSxcblx0XHRcdHZhbHVlOiBbXVxuXHRcdH07XG5cdH0sXG5cdGhhbmRsZVNlbGVjdENoYW5nZTogZnVuY3Rpb24odmFsdWUsIHZhbHVlcykge1xuXHRcdGxvZ0NoYW5nZSgnTmV3IHZhbHVlOicsIHZhbHVlLCAnVmFsdWVzOicsIHZhbHVlcyk7XG5cdFx0dGhpcy5zZXRTdGF0ZSh7IHZhbHVlOiB2YWx1ZSB9KTtcblx0fSxcblx0dG9nZ2xlRGlzYWJsZWQ6IGZ1bmN0aW9uKGUpIHtcblx0XHR0aGlzLnNldFN0YXRlKHsgJ2Rpc2FibGVkJzogZS50YXJnZXQuY2hlY2tlZCB9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgb3BzID0gW1xuXHRcdFx0eyBsYWJlbDogJ0Nob2NvbGF0ZScsIHZhbHVlOiAnY2hvY29sYXRlJyB9LFxuXHRcdFx0eyBsYWJlbDogJ1ZhbmlsbGEnLCB2YWx1ZTogJ3ZhbmlsbGEnIH0sXG5cdFx0XHR7IGxhYmVsOiAnU3RyYXdiZXJyeScsIHZhbHVlOiAnc3RyYXdiZXJyeScgfSxcblx0XHRcdHsgbGFiZWw6ICdDYXJhbWVsJywgdmFsdWU6ICdjYXJhbWVsJyB9LFxuXHRcdFx0eyBsYWJlbDogJ0Nvb2tpZXMgYW5kIENyZWFtJywgdmFsdWU6ICdjb29raWVzY3JlYW0nIH0sXG5cdFx0XHR7IGxhYmVsOiAnUGVwcGVybWludCcsIHZhbHVlOiAncGVwcGVybWludCcgfVxuXHRcdF07XG5cdFx0cmV0dXJuIChcblx0XHRcdDxzcGFuPlxuXHRcdFx0XHQ8ZGl2PlxuXHRcdFx0XHRcdDxsYWJlbD57dGhpcy5wcm9wcy5sYWJlbH08L2xhYmVsPlxuXHRcdFx0XHRcdDxTZWxlY3QgbXVsdGk9e3RydWV9IGRpc2FibGVkPXt0aGlzLnN0YXRlLmRpc2FibGVkfSB2YWx1ZT17dGhpcy5zdGF0ZS52YWx1ZX0gcGxhY2Vob2xkZXI9XCJTZWxlY3QgeW91ciBmYXZvdXJpdGUocylcIiBvcHRpb25zPXtvcHN9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZVNlbGVjdENoYW5nZX0gLz5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXY+XG5cdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNoZWNrZWQ9e3RoaXMuc3RhdGUuZGlzYWJsZWR9IGlkPVwiZGlzYWJsZS1tdWx0aXNlbGVjdFwiIG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZURpc2FibGVkfS8+XG5cdFx0XHRcdFx0PGxhYmVsIGh0bWxGb3I9XCJkaXNhYmxlLW11bHRpc2VsZWN0XCI+RGlzYWJsZTwvbGFiZWw+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9zcGFuPlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgU2VsZWN0ZWRWYWx1ZXNGaWVsZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0b25MYWJlbENsaWNrOiBmdW5jdGlvbiAoZGF0YSwgZXZlbnQpIHtcblx0XHRjb25zb2xlLmxvZyhkYXRhLCBldmVudCk7XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG9wcyA9IFtcblx0XHRcdHsgbGFiZWw6ICdDaG9jb2xhdGUnLCB2YWx1ZTogJ2Nob2NvbGF0ZScgfSxcblx0XHRcdHsgbGFiZWw6ICdWYW5pbGxhJywgdmFsdWU6ICd2YW5pbGxhJyB9LFxuXHRcdFx0eyBsYWJlbDogJ1N0cmF3YmVycnknLCB2YWx1ZTogJ3N0cmF3YmVycnknIH0sXG5cdFx0XHR7IGxhYmVsOiAnQ2FyYW1lbCcsIHZhbHVlOiAnY2FyYW1lbCcgfSxcblx0XHRcdHsgbGFiZWw6ICdDb29raWVzIGFuZCBDcmVhbScsIHZhbHVlOiAnY29va2llc2NyZWFtJyB9LFxuXHRcdFx0eyBsYWJlbDogJ1BlcHBlcm1pbnQnLCB2YWx1ZTogJ3BlcHBlcm1pbnQnIH1cblx0XHRdO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8bGFiZWw+e3RoaXMucHJvcHMubGFiZWx9PC9sYWJlbD5cblx0XHRcdFx0PFNlbGVjdFxuXHRcdFx0XHRcdG9uT3B0aW9uTGFiZWxDbGljaz17dGhpcy5vbkxhYmVsQ2xpY2t9XG5cdFx0XHRcdFx0dmFsdWU9XCJjaG9jb2xhdGUsdmFuaWxsYSxzdHJhd2JlcnJ5XCJcblx0XHRcdFx0XHRtdWx0aT17dHJ1ZX1cblx0XHRcdFx0XHRwbGFjZWhvbGRlcj1cIlNlbGVjdCB5b3VyIGZhdm91cml0ZShzKVwiXG5cdFx0XHRcdFx0b3B0aW9ucz17b3BzfVxuXHRcdFx0XHRcdG9uQ2hhbmdlPXtsb2dDaGFuZ2V9IC8+XG5cdFx0XHQ8L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxuXG52YXIgU2VsZWN0ZWRWYWx1ZXNGaWVsZERpc2FibGVkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRvbkxhYmVsQ2xpY2s6IGZ1bmN0aW9uIChkYXRhLCBldmVudCkge1xuXHRcdGNvbnNvbGUubG9nKGRhdGEsIGV2ZW50KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgb3BzID0gW1xuXHRcdFx0eyBsYWJlbDogJ0Nob2NvbGF0ZScsIHZhbHVlOiAnY2hvY29sYXRlJyB9LFxuXHRcdFx0eyBsYWJlbDogJ1ZhbmlsbGEnLCB2YWx1ZTogJ3ZhbmlsbGEnIH0sXG5cdFx0XHR7IGxhYmVsOiAnU3RyYXdiZXJyeScsIHZhbHVlOiAnc3RyYXdiZXJyeScgfSxcblx0XHRcdHsgbGFiZWw6ICdDYXJhbWVsIChZb3UgZG9uXFwndCBsaWtlIGl0LCBhcHBhcmVudGx5KScsIHZhbHVlOiAnY2FyYW1lbCcsIGRpc2FibGVkOiB0cnVlIH0sXG5cdFx0XHR7IGxhYmVsOiAnQ29va2llcyBhbmQgQ3JlYW0nLCB2YWx1ZTogJ2Nvb2tpZXNjcmVhbScgfSxcblx0XHRcdHsgbGFiZWw6ICdQZXBwZXJtaW50JywgdmFsdWU6ICdwZXBwZXJtaW50JyB9XG5cdFx0XTtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGRpdj5cblx0XHRcdFx0PGxhYmVsPnt0aGlzLnByb3BzLmxhYmVsfTwvbGFiZWw+XG5cdFx0XHRcdDxTZWxlY3Rcblx0XHRcdFx0XHRvbk9wdGlvbkxhYmVsQ2xpY2s9e3RoaXMub25MYWJlbENsaWNrfVxuXHRcdFx0XHRcdHZhbHVlPVwiY2hvY29sYXRlLHZhbmlsbGEsc3RyYXdiZXJyeVwiXG5cdFx0XHRcdFx0bXVsdGk9e3RydWV9XG5cdFx0XHRcdFx0cGxhY2Vob2xkZXI9XCJTZWxlY3QgeW91ciBmYXZvdXJpdGUocylcIlxuXHRcdFx0XHRcdG9wdGlvbnM9e29wc31cblx0XHRcdFx0XHRvbkNoYW5nZT17bG9nQ2hhbmdlfSAvPlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBTZWxlY3RlZFZhbHVlc0ZpZWxkQ3JlYXRlID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRvbkxhYmVsQ2xpY2s6IGZ1bmN0aW9uIChkYXRhLCBldmVudCkge1xuXHRcdGNvbnNvbGUubG9nKGRhdGEsIGV2ZW50KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgb3BzID0gW1xuXHRcdFx0eyBsYWJlbDogJ0ZpcnN0IE9wdGlvbicsIHZhbHVlOiAnZmlyc3QnIH0sXG5cdFx0XHR7IGxhYmVsOiAnU2Vjb25kIE9wdGlvbicsIHZhbHVlOiAnc2Vjb25kJyB9LFxuXHRcdFx0eyBsYWJlbDogJ1RoaXJkIE9wdGlvbicsIHZhbHVlOiAndGhpcmQnIH1cblx0XHRdO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8bGFiZWw+e3RoaXMucHJvcHMubGFiZWx9PC9sYWJlbD5cblx0XHRcdFx0PFNlbGVjdFxuXHRcdFx0XHRcdHZhbHVlPVwiZmlyc3RcIlxuXHRcdFx0XHRcdGRlbGltaXRlcj1cIixcIlxuXHRcdFx0XHRcdG11bHRpPXt0cnVlfVxuXHRcdFx0XHRcdGFsbG93Q3JlYXRlPXt0cnVlfVxuXHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiU2VsZWN0IHlvdXIgZmF2b3VyaXRlKHMpXCJcblx0XHRcdFx0XHRvcHRpb25zPXtvcHN9XG5cdFx0XHRcdFx0b25DaGFuZ2U9e2xvZ0NoYW5nZX0gLz5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ3VzdG9tUmVuZGVyRmllbGQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdG9uTGFiZWxDbGljazogZnVuY3Rpb24gKGRhdGEsIGV2ZW50KSB7XG5cdFx0Y29uc29sZS5sb2coZGF0YSwgZXZlbnQpO1xuXHR9LFxuXHRyZW5kZXJPcHRpb246IGZ1bmN0aW9uKG9wdGlvbikge1xuXHRcdHJldHVybiA8c3BhbiBzdHlsZT17eyBjb2xvcjogb3B0aW9uLmhleCB9fT57b3B0aW9uLmxhYmVsfSAoe29wdGlvbi5oZXh9KTwvc3Bhbj47XG5cblx0fSxcblx0cmVuZGVyVmFsdWU6IGZ1bmN0aW9uKG9wdGlvbikge1xuXHRcdHJldHVybiA8c3Ryb25nIHN0eWxlPXt7IGNvbG9yOiBvcHRpb24uaGV4IH19PntvcHRpb24ubGFiZWx9PC9zdHJvbmc+O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBvcHMgPSBbXG5cdFx0XHR7IGxhYmVsOiAnUmVkJywgdmFsdWU6ICdyZWQnLCBoZXg6ICcjRUM2MjMwJyB9LFxuXHRcdFx0eyBsYWJlbDogJ0dyZWVuJywgdmFsdWU6ICdncmVlbicsIGhleDogJyM0RUQ4NEUnIH0sXG5cdFx0XHR7IGxhYmVsOiAnQmx1ZScsIHZhbHVlOiAnYmx1ZScsIGhleDogJyM2RDk3RTInIH1cblx0XHRdO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8bGFiZWw+e3RoaXMucHJvcHMubGFiZWx9PC9sYWJlbD5cblx0XHRcdFx0PFNlbGVjdFxuXHRcdFx0XHRcdGFsbG93Q3JlYXRlPXt0cnVlfVxuXHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiU2VsZWN0IHlvdXIgZmF2b3VyaXRlXCJcblx0XHRcdFx0XHRvcHRpb25zPXtvcHN9XG5cdFx0XHRcdFx0b3B0aW9uUmVuZGVyZXI9e3RoaXMucmVuZGVyT3B0aW9ufVxuXHRcdFx0XHRcdHZhbHVlUmVuZGVyZXI9e3RoaXMucmVuZGVyVmFsdWV9XG5cdFx0XHRcdFx0b25DaGFuZ2U9e2xvZ0NoYW5nZX0gLz5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ3VzdG9tUmVuZGVyTXVsdGlGaWVsZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0b25MYWJlbENsaWNrOiBmdW5jdGlvbiAoZGF0YSwgZXZlbnQpIHtcblx0XHRjb25zb2xlLmxvZyhkYXRhLCBldmVudCk7XG5cdH0sXG5cdHJlbmRlck9wdGlvbjogZnVuY3Rpb24ob3B0aW9uKSB7XG5cdFx0cmV0dXJuIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBvcHRpb24uaGV4IH19PntvcHRpb24ubGFiZWx9ICh7b3B0aW9uLmhleH0pPC9zcGFuPjtcblxuXHR9LFxuXHRyZW5kZXJWYWx1ZTogZnVuY3Rpb24ob3B0aW9uKSB7XG5cdFx0cmV0dXJuIDxzdHJvbmcgc3R5bGU9e3sgY29sb3I6IG9wdGlvbi5oZXggfX0+e29wdGlvbi5sYWJlbH08L3N0cm9uZz47XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG9wcyA9IFtcblx0XHRcdHsgbGFiZWw6ICdSZWQnLCB2YWx1ZTogJ3JlZCcsIGhleDogJyNFQzYyMzAnIH0sXG5cdFx0XHR7IGxhYmVsOiAnR3JlZW4nLCB2YWx1ZTogJ2dyZWVuJywgaGV4OiAnIzRFRDg0RScgfSxcblx0XHRcdHsgbGFiZWw6ICdCbHVlJywgdmFsdWU6ICdibHVlJywgaGV4OiAnIzZEOTdFMicgfVxuXHRcdF07XG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxsYWJlbD57dGhpcy5wcm9wcy5sYWJlbH08L2xhYmVsPlxuXHRcdFx0XHQ8U2VsZWN0XG5cdFx0XHRcdFx0ZGVsaW1pdGVyPVwiLFwiXG5cdFx0XHRcdFx0bXVsdGk9e3RydWV9XG5cdFx0XHRcdFx0YWxsb3dDcmVhdGU9e3RydWV9XG5cdFx0XHRcdFx0cGxhY2Vob2xkZXI9XCJTZWxlY3QgeW91ciBmYXZvdXJpdGUocylcIlxuXHRcdFx0XHRcdG9wdGlvbnM9e29wc31cblx0XHRcdFx0XHRvcHRpb25SZW5kZXJlcj17dGhpcy5yZW5kZXJPcHRpb259XG5cdFx0XHRcdFx0dmFsdWVSZW5kZXJlcj17dGhpcy5yZW5kZXJWYWx1ZX1cblx0XHRcdFx0XHRvbkNoYW5nZT17bG9nQ2hhbmdlfSAvPlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cblJlYWN0LnJlbmRlcihcblx0PGRpdj5cblx0XHQ8U3RhdGVzRmllbGQgLz5cblx0XHQ8U3RhdGVzRmllbGQgbGFiZWw9XCJTdGF0ZXMgKG5vbi1zZWFyY2hhYmxlKTpcIiBzZWFyY2hhYmxlPXtmYWxzZX0gLz5cblx0XHQ8VXNlcnNGaWVsZCAvPlxuXHRcdDxWYWx1ZXNBc051bWJlcnNGaWVsZCBsYWJlbD1cIlZhbHVlcyBhcyBudW1iZXJzXCIgLz5cblx0XHQ8TXVsdGlTZWxlY3RGaWVsZCBsYWJlbD1cIk11bHRpc2VsZWN0OlwiLz5cblx0XHQ8U2VsZWN0ZWRWYWx1ZXNGaWVsZCBsYWJlbD1cIkNsaWNrYWJsZSBsYWJlbHMgKGxhYmVscyBhcyBsaW5rcyk6XCIgLz5cblx0XHQ8U2VsZWN0ZWRWYWx1ZXNGaWVsZERpc2FibGVkIGxhYmVsPVwiRGlzYWJsZWQgb3B0aW9uOlwiIC8+XG5cdFx0PFNlbGVjdGVkVmFsdWVzRmllbGRDcmVhdGUgbGFiZWw9XCJPcHRpb24gQ3JlYXRpb24gKHRhZ3MgbW9kZSk6XCIgLz5cblx0XHQ8Q3VzdG9tUmVuZGVyRmllbGQgbGFiZWw9XCJDdXN0b20gcmVuZGVyaW5nIGZvciBvcHRpb25zIGFuZCB2YWx1ZXM6XCIgLz5cblx0XHQ8Q3VzdG9tUmVuZGVyTXVsdGlGaWVsZCBsYWJlbD1cIkN1c3RvbSByZW5kZXJpbmcgZm9yIG11bHRpcGxlIG9wdGlvbnMgYW5kIHZhbHVlczpcIiAvPlxuXHRcdDxSZW1vdGVTZWxlY3RGaWVsZCBsYWJlbD1cIlJlbW90ZSBPcHRpb25zOlwiLz5cblx0PC9kaXY+LFxuXHRkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXhhbXBsZScpXG4pO1xuIiwiZXhwb3J0cy5BVSA9IFtcblx0eyB2YWx1ZTogJ2F1c3RyYWxpYW4tY2FwaXRhbC10ZXJyaXRvcnknLCBsYWJlbDogJ0F1c3RyYWxpYW4gQ2FwaXRhbCBUZXJyaXRvcnknIH0sXG5cdHsgdmFsdWU6ICduZXctc291dGgtd2FsZXMnLCBsYWJlbDogJ05ldyBTb3V0aCBXYWxlcycgfSxcblx0eyB2YWx1ZTogJ3ZpY3RvcmlhJywgbGFiZWw6ICdWaWN0b3JpYScgfSxcblx0eyB2YWx1ZTogJ3F1ZWVuc2xhbmQnLCBsYWJlbDogJ1F1ZWVuc2xhbmQnIH0sXG5cdHsgdmFsdWU6ICd3ZXN0ZXJuLWF1c3RyYWxpYScsIGxhYmVsOiAnV2VzdGVybiBBdXN0cmFsaWEnIH0sXG5cdHsgdmFsdWU6ICdzb3V0aC1hdXN0cmFsaWEnLCBsYWJlbDogJ1NvdXRoIEF1c3RyYWxpYScgfSxcblx0eyB2YWx1ZTogJ3Rhc21hbmlhJywgbGFiZWw6ICdUYXNtYW5pYScgfSxcblx0eyB2YWx1ZTogJ25vcnRoZXJuLXRlcnJpdG9yeScsIGxhYmVsOiAnTm9ydGhlcm4gVGVycml0b3J5JyB9XG5dO1xuXG5leHBvcnRzLlVTID0gW1xuICAgIHsgdmFsdWU6ICdBTCcsIGxhYmVsOiAnQWxhYmFtYScsIGRpc2FibGVkOiB0cnVlIH0sXG4gICAgeyB2YWx1ZTogJ0FLJywgbGFiZWw6ICdBbGFza2EnIH0sXG4gICAgeyB2YWx1ZTogJ0FTJywgbGFiZWw6ICdBbWVyaWNhbiBTYW1vYScgfSxcbiAgICB7IHZhbHVlOiAnQVonLCBsYWJlbDogJ0FyaXpvbmEnIH0sXG4gICAgeyB2YWx1ZTogJ0FSJywgbGFiZWw6ICdBcmthbnNhcycgfSxcbiAgICB7IHZhbHVlOiAnQ0EnLCBsYWJlbDogJ0NhbGlmb3JuaWEnIH0sXG4gICAgeyB2YWx1ZTogJ0NPJywgbGFiZWw6ICdDb2xvcmFkbycgfSxcbiAgICB7IHZhbHVlOiAnQ1QnLCBsYWJlbDogJ0Nvbm5lY3RpY3V0JyB9LFxuICAgIHsgdmFsdWU6ICdERScsIGxhYmVsOiAnRGVsYXdhcmUnIH0sXG4gICAgeyB2YWx1ZTogJ0RDJywgbGFiZWw6ICdEaXN0cmljdCBPZiBDb2x1bWJpYScgfSxcbiAgICB7IHZhbHVlOiAnRk0nLCBsYWJlbDogJ0ZlZGVyYXRlZCBTdGF0ZXMgT2YgTWljcm9uZXNpYScgfSxcbiAgICB7IHZhbHVlOiAnRkwnLCBsYWJlbDogJ0Zsb3JpZGEnIH0sXG4gICAgeyB2YWx1ZTogJ0dBJywgbGFiZWw6ICdHZW9yZ2lhJyB9LFxuICAgIHsgdmFsdWU6ICdHVScsIGxhYmVsOiAnR3VhbScgfSxcbiAgICB7IHZhbHVlOiAnSEknLCBsYWJlbDogJ0hhd2FpaScgfSxcbiAgICB7IHZhbHVlOiAnSUQnLCBsYWJlbDogJ0lkYWhvJyB9LFxuICAgIHsgdmFsdWU6ICdJTCcsIGxhYmVsOiAnSWxsaW5vaXMnIH0sXG4gICAgeyB2YWx1ZTogJ0lOJywgbGFiZWw6ICdJbmRpYW5hJyB9LFxuICAgIHsgdmFsdWU6ICdJQScsIGxhYmVsOiAnSW93YScgfSxcbiAgICB7IHZhbHVlOiAnS1MnLCBsYWJlbDogJ0thbnNhcycgfSxcbiAgICB7IHZhbHVlOiAnS1knLCBsYWJlbDogJ0tlbnR1Y2t5JyB9LFxuICAgIHsgdmFsdWU6ICdMQScsIGxhYmVsOiAnTG91aXNpYW5hJyB9LFxuICAgIHsgdmFsdWU6ICdNRScsIGxhYmVsOiAnTWFpbmUnIH0sXG4gICAgeyB2YWx1ZTogJ01IJywgbGFiZWw6ICdNYXJzaGFsbCBJc2xhbmRzJyB9LFxuICAgIHsgdmFsdWU6ICdNRCcsIGxhYmVsOiAnTWFyeWxhbmQnIH0sXG4gICAgeyB2YWx1ZTogJ01BJywgbGFiZWw6ICdNYXNzYWNodXNldHRzJyB9LFxuICAgIHsgdmFsdWU6ICdNSScsIGxhYmVsOiAnTWljaGlnYW4nIH0sXG4gICAgeyB2YWx1ZTogJ01OJywgbGFiZWw6ICdNaW5uZXNvdGEnIH0sXG4gICAgeyB2YWx1ZTogJ01TJywgbGFiZWw6ICdNaXNzaXNzaXBwaScgfSxcbiAgICB7IHZhbHVlOiAnTU8nLCBsYWJlbDogJ01pc3NvdXJpJyB9LFxuICAgIHsgdmFsdWU6ICdNVCcsIGxhYmVsOiAnTW9udGFuYScgfSxcbiAgICB7IHZhbHVlOiAnTkUnLCBsYWJlbDogJ05lYnJhc2thJyB9LFxuICAgIHsgdmFsdWU6ICdOVicsIGxhYmVsOiAnTmV2YWRhJyB9LFxuICAgIHsgdmFsdWU6ICdOSCcsIGxhYmVsOiAnTmV3IEhhbXBzaGlyZScgfSxcbiAgICB7IHZhbHVlOiAnTkonLCBsYWJlbDogJ05ldyBKZXJzZXknIH0sXG4gICAgeyB2YWx1ZTogJ05NJywgbGFiZWw6ICdOZXcgTWV4aWNvJyB9LFxuICAgIHsgdmFsdWU6ICdOWScsIGxhYmVsOiAnTmV3IFlvcmsnIH0sXG4gICAgeyB2YWx1ZTogJ05DJywgbGFiZWw6ICdOb3J0aCBDYXJvbGluYScgfSxcbiAgICB7IHZhbHVlOiAnTkQnLCBsYWJlbDogJ05vcnRoIERha290YScgfSxcbiAgICB7IHZhbHVlOiAnTVAnLCBsYWJlbDogJ05vcnRoZXJuIE1hcmlhbmEgSXNsYW5kcycgfSxcbiAgICB7IHZhbHVlOiAnT0gnLCBsYWJlbDogJ09oaW8nIH0sXG4gICAgeyB2YWx1ZTogJ09LJywgbGFiZWw6ICdPa2xhaG9tYScgfSxcbiAgICB7IHZhbHVlOiAnT1InLCBsYWJlbDogJ09yZWdvbicgfSxcbiAgICB7IHZhbHVlOiAnUFcnLCBsYWJlbDogJ1BhbGF1JyB9LFxuICAgIHsgdmFsdWU6ICdQQScsIGxhYmVsOiAnUGVubnN5bHZhbmlhJyB9LFxuICAgIHsgdmFsdWU6ICdQUicsIGxhYmVsOiAnUHVlcnRvIFJpY28nIH0sXG4gICAgeyB2YWx1ZTogJ1JJJywgbGFiZWw6ICdSaG9kZSBJc2xhbmQnIH0sXG4gICAgeyB2YWx1ZTogJ1NDJywgbGFiZWw6ICdTb3V0aCBDYXJvbGluYScgfSxcbiAgICB7IHZhbHVlOiAnU0QnLCBsYWJlbDogJ1NvdXRoIERha290YScgfSxcbiAgICB7IHZhbHVlOiAnVE4nLCBsYWJlbDogJ1Rlbm5lc3NlZScgfSxcbiAgICB7IHZhbHVlOiAnVFgnLCBsYWJlbDogJ1RleGFzJyB9LFxuICAgIHsgdmFsdWU6ICdVVCcsIGxhYmVsOiAnVXRhaCcgfSxcbiAgICB7IHZhbHVlOiAnVlQnLCBsYWJlbDogJ1Zlcm1vbnQnIH0sXG4gICAgeyB2YWx1ZTogJ1ZJJywgbGFiZWw6ICdWaXJnaW4gSXNsYW5kcycgfSxcbiAgICB7IHZhbHVlOiAnVkEnLCBsYWJlbDogJ1ZpcmdpbmlhJyB9LFxuICAgIHsgdmFsdWU6ICdXQScsIGxhYmVsOiAnV2FzaGluZ3RvbicgfSxcbiAgICB7IHZhbHVlOiAnV1YnLCBsYWJlbDogJ1dlc3QgVmlyZ2luaWEnIH0sXG4gICAgeyB2YWx1ZTogJ1dJJywgbGFiZWw6ICdXaXNjb25zaW4nIH0sXG4gICAgeyB2YWx1ZTogJ1dZJywgbGFiZWw6ICdXeW9taW5nJyB9XG5dO1xuIiwiZXhwb3J0cy51c2VycyA9IFtcbiAgICB7IHZhbHVlOiAnSm9obiBTbWl0aCcsIGxhYmVsOiAnSm9obiBTbWl0aCcsIGVtYWlsOiAnam9obkBzbWl0aC5jb20nIH0sXG4gICAgeyB2YWx1ZTogJ01lcnJ5IEphbmUnLCBsYWJlbDogJ01lcnJ5IEphbmUnLCBlbWFpbDogJ21lcnJ5QGphbmUuY29tJyB9LFxuICAgIHsgdmFsdWU6ICdTdGFuIEhvcGVyJywgbGFiZWw6ICdTdGFuIEhvcGVyJywgZW1haWw6ICdzdGFuQGhvcGVyLmNvbScgfVxuXTtcbiIsInZhciBjaGFyZW5jID0ge1xuICAvLyBVVEYtOCBlbmNvZGluZ1xuICB1dGY4OiB7XG4gICAgLy8gQ29udmVydCBhIHN0cmluZyB0byBhIGJ5dGUgYXJyYXlcbiAgICBzdHJpbmdUb0J5dGVzOiBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHJldHVybiBjaGFyZW5jLmJpbi5zdHJpbmdUb0J5dGVzKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKSk7XG4gICAgfSxcblxuICAgIC8vIENvbnZlcnQgYSBieXRlIGFycmF5IHRvIGEgc3RyaW5nXG4gICAgYnl0ZXNUb1N0cmluZzogZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGNoYXJlbmMuYmluLmJ5dGVzVG9TdHJpbmcoYnl0ZXMpKSk7XG4gICAgfVxuICB9LFxuXG4gIC8vIEJpbmFyeSBlbmNvZGluZ1xuICBiaW46IHtcbiAgICAvLyBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgYnl0ZSBhcnJheVxuICAgIHN0cmluZ1RvQnl0ZXM6IGZ1bmN0aW9uKHN0cikge1xuICAgICAgZm9yICh2YXIgYnl0ZXMgPSBbXSwgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspXG4gICAgICAgIGJ5dGVzLnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKTtcbiAgICAgIHJldHVybiBieXRlcztcbiAgICB9LFxuXG4gICAgLy8gQ29udmVydCBhIGJ5dGUgYXJyYXkgdG8gYSBzdHJpbmdcbiAgICBieXRlc1RvU3RyaW5nOiBmdW5jdGlvbihieXRlcykge1xuICAgICAgZm9yICh2YXIgc3RyID0gW10sIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIHN0ci5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pKTtcbiAgICAgIHJldHVybiBzdHIuam9pbignJyk7XG4gICAgfVxuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNoYXJlbmM7XG4iLCIoZnVuY3Rpb24oKSB7XG4gIHZhciBiYXNlNjRtYXBcbiAgICAgID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nLFxuXG4gIGNyeXB0ID0ge1xuICAgIC8vIEJpdC13aXNlIHJvdGF0aW9uIGxlZnRcbiAgICByb3RsOiBmdW5jdGlvbihuLCBiKSB7XG4gICAgICByZXR1cm4gKG4gPDwgYikgfCAobiA+Pj4gKDMyIC0gYikpO1xuICAgIH0sXG5cbiAgICAvLyBCaXQtd2lzZSByb3RhdGlvbiByaWdodFxuICAgIHJvdHI6IGZ1bmN0aW9uKG4sIGIpIHtcbiAgICAgIHJldHVybiAobiA8PCAoMzIgLSBiKSkgfCAobiA+Pj4gYik7XG4gICAgfSxcblxuICAgIC8vIFN3YXAgYmlnLWVuZGlhbiB0byBsaXR0bGUtZW5kaWFuIGFuZCB2aWNlIHZlcnNhXG4gICAgZW5kaWFuOiBmdW5jdGlvbihuKSB7XG4gICAgICAvLyBJZiBudW1iZXIgZ2l2ZW4sIHN3YXAgZW5kaWFuXG4gICAgICBpZiAobi5jb25zdHJ1Y3RvciA9PSBOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGNyeXB0LnJvdGwobiwgOCkgJiAweDAwRkYwMEZGIHwgY3J5cHQucm90bChuLCAyNCkgJiAweEZGMDBGRjAwO1xuICAgICAgfVxuXG4gICAgICAvLyBFbHNlLCBhc3N1bWUgYXJyYXkgYW5kIHN3YXAgYWxsIGl0ZW1zXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4ubGVuZ3RoOyBpKyspXG4gICAgICAgIG5baV0gPSBjcnlwdC5lbmRpYW4obltpXSk7XG4gICAgICByZXR1cm4gbjtcbiAgICB9LFxuXG4gICAgLy8gR2VuZXJhdGUgYW4gYXJyYXkgb2YgYW55IGxlbmd0aCBvZiByYW5kb20gYnl0ZXNcbiAgICByYW5kb21CeXRlczogZnVuY3Rpb24obikge1xuICAgICAgZm9yICh2YXIgYnl0ZXMgPSBbXTsgbiA+IDA7IG4tLSlcbiAgICAgICAgYnl0ZXMucHVzaChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpKTtcbiAgICAgIHJldHVybiBieXRlcztcbiAgICB9LFxuXG4gICAgLy8gQ29udmVydCBhIGJ5dGUgYXJyYXkgdG8gYmlnLWVuZGlhbiAzMi1iaXQgd29yZHNcbiAgICBieXRlc1RvV29yZHM6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBmb3IgKHZhciB3b3JkcyA9IFtdLCBpID0gMCwgYiA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKywgYiArPSA4KVxuICAgICAgICB3b3Jkc1tiID4+PiA1XSB8PSBieXRlc1tpXSA8PCAoMjQgLSBiICUgMzIpO1xuICAgICAgcmV0dXJuIHdvcmRzO1xuICAgIH0sXG5cbiAgICAvLyBDb252ZXJ0IGJpZy1lbmRpYW4gMzItYml0IHdvcmRzIHRvIGEgYnl0ZSBhcnJheVxuICAgIHdvcmRzVG9CeXRlczogZnVuY3Rpb24od29yZHMpIHtcbiAgICAgIGZvciAodmFyIGJ5dGVzID0gW10sIGIgPSAwOyBiIDwgd29yZHMubGVuZ3RoICogMzI7IGIgKz0gOClcbiAgICAgICAgYnl0ZXMucHVzaCgod29yZHNbYiA+Pj4gNV0gPj4+ICgyNCAtIGIgJSAzMikpICYgMHhGRik7XG4gICAgICByZXR1cm4gYnl0ZXM7XG4gICAgfSxcblxuICAgIC8vIENvbnZlcnQgYSBieXRlIGFycmF5IHRvIGEgaGV4IHN0cmluZ1xuICAgIGJ5dGVzVG9IZXg6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBmb3IgKHZhciBoZXggPSBbXSwgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBoZXgucHVzaCgoYnl0ZXNbaV0gPj4+IDQpLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgIGhleC5wdXNoKChieXRlc1tpXSAmIDB4RikudG9TdHJpbmcoMTYpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoZXguam9pbignJyk7XG4gICAgfSxcblxuICAgIC8vIENvbnZlcnQgYSBoZXggc3RyaW5nIHRvIGEgYnl0ZSBhcnJheVxuICAgIGhleFRvQnl0ZXM6IGZ1bmN0aW9uKGhleCkge1xuICAgICAgZm9yICh2YXIgYnl0ZXMgPSBbXSwgYyA9IDA7IGMgPCBoZXgubGVuZ3RoOyBjICs9IDIpXG4gICAgICAgIGJ5dGVzLnB1c2gocGFyc2VJbnQoaGV4LnN1YnN0cihjLCAyKSwgMTYpKTtcbiAgICAgIHJldHVybiBieXRlcztcbiAgICB9LFxuXG4gICAgLy8gQ29udmVydCBhIGJ5dGUgYXJyYXkgdG8gYSBiYXNlLTY0IHN0cmluZ1xuICAgIGJ5dGVzVG9CYXNlNjQ6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBmb3IgKHZhciBiYXNlNjQgPSBbXSwgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB2YXIgdHJpcGxldCA9IChieXRlc1tpXSA8PCAxNikgfCAoYnl0ZXNbaSArIDFdIDw8IDgpIHwgYnl0ZXNbaSArIDJdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKylcbiAgICAgICAgICBpZiAoaSAqIDggKyBqICogNiA8PSBieXRlcy5sZW5ndGggKiA4KVxuICAgICAgICAgICAgYmFzZTY0LnB1c2goYmFzZTY0bWFwLmNoYXJBdCgodHJpcGxldCA+Pj4gNiAqICgzIC0gaikpICYgMHgzRikpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJhc2U2NC5wdXNoKCc9Jyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZTY0LmpvaW4oJycpO1xuICAgIH0sXG5cbiAgICAvLyBDb252ZXJ0IGEgYmFzZS02NCBzdHJpbmcgdG8gYSBieXRlIGFycmF5XG4gICAgYmFzZTY0VG9CeXRlczogZnVuY3Rpb24oYmFzZTY0KSB7XG4gICAgICAvLyBSZW1vdmUgbm9uLWJhc2UtNjQgY2hhcmFjdGVyc1xuICAgICAgYmFzZTY0ID0gYmFzZTY0LnJlcGxhY2UoL1teQS1aMC05K1xcL10vaWcsICcnKTtcblxuICAgICAgZm9yICh2YXIgYnl0ZXMgPSBbXSwgaSA9IDAsIGltb2Q0ID0gMDsgaSA8IGJhc2U2NC5sZW5ndGg7XG4gICAgICAgICAgaW1vZDQgPSArK2kgJSA0KSB7XG4gICAgICAgIGlmIChpbW9kNCA9PSAwKSBjb250aW51ZTtcbiAgICAgICAgYnl0ZXMucHVzaCgoKGJhc2U2NG1hcC5pbmRleE9mKGJhc2U2NC5jaGFyQXQoaSAtIDEpKVxuICAgICAgICAgICAgJiAoTWF0aC5wb3coMiwgLTIgKiBpbW9kNCArIDgpIC0gMSkpIDw8IChpbW9kNCAqIDIpKVxuICAgICAgICAgICAgfCAoYmFzZTY0bWFwLmluZGV4T2YoYmFzZTY0LmNoYXJBdChpKSkgPj4+ICg2IC0gaW1vZDQgKiAyKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ5dGVzO1xuICAgIH1cbiAgfTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IGNyeXB0O1xufSkoKTtcbiIsIi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBCdWZmZXJcbiAqXG4gKiBBdXRob3I6ICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIExpY2Vuc2U6ICBNSVRcbiAqXG4gKiBgbnBtIGluc3RhbGwgaXMtYnVmZmVyYFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gISEob2JqICE9IG51bGwgJiZcbiAgICAob2JqLl9pc0J1ZmZlciB8fCAvLyBGb3IgU2FmYXJpIDUtNyAobWlzc2luZyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKVxuICAgICAgKG9iai5jb25zdHJ1Y3RvciAmJlxuICAgICAgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaikpXG4gICAgKSlcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBtZWRpYVF1ZXJ5O1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cgIT09IG51bGwpIHtcbiAgICBtZWRpYVF1ZXJ5ID0gXCIoLXdlYmtpdC1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAxLjI1KSwgKG1pbi0tbW96LWRldmljZS1waXhlbC1yYXRpbzogMS4yNSksICgtby1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiA1LzQpLCAobWluLXJlc29sdXRpb246IDEuMjVkcHB4KVwiO1xuICAgIGlmICh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyA+IDEuMjUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAod2luZG93Lm1hdGNoTWVkaWEgJiYgd2luZG93Lm1hdGNoTWVkaWEobWVkaWFRdWVyeSkubWF0Y2hlcykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG4iLCIoZnVuY3Rpb24oKXtcclxuICB2YXIgY3J5cHQgPSByZXF1aXJlKCdjcnlwdCcpLFxyXG4gICAgICB1dGY4ID0gcmVxdWlyZSgnY2hhcmVuYycpLnV0ZjgsXHJcbiAgICAgIGlzQnVmZmVyID0gcmVxdWlyZSgnaXMtYnVmZmVyJyksXHJcbiAgICAgIGJpbiA9IHJlcXVpcmUoJ2NoYXJlbmMnKS5iaW4sXHJcblxyXG4gIC8vIFRoZSBjb3JlXHJcbiAgbWQ1ID0gZnVuY3Rpb24gKG1lc3NhZ2UsIG9wdGlvbnMpIHtcclxuICAgIC8vIENvbnZlcnQgdG8gYnl0ZSBhcnJheVxyXG4gICAgaWYgKG1lc3NhZ2UuY29uc3RydWN0b3IgPT0gU3RyaW5nKVxyXG4gICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmVuY29kaW5nID09PSAnYmluYXJ5JylcclxuICAgICAgICBtZXNzYWdlID0gYmluLnN0cmluZ1RvQnl0ZXMobWVzc2FnZSk7XHJcbiAgICAgIGVsc2VcclxuICAgICAgICBtZXNzYWdlID0gdXRmOC5zdHJpbmdUb0J5dGVzKG1lc3NhZ2UpO1xyXG4gICAgZWxzZSBpZiAoaXNCdWZmZXIobWVzc2FnZSkpXHJcbiAgICAgIG1lc3NhZ2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLCAwKTtcclxuICAgIGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UpKVxyXG4gICAgICBtZXNzYWdlID0gbWVzc2FnZS50b1N0cmluZygpO1xyXG4gICAgLy8gZWxzZSwgYXNzdW1lIGJ5dGUgYXJyYXkgYWxyZWFkeVxyXG5cclxuICAgIHZhciBtID0gY3J5cHQuYnl0ZXNUb1dvcmRzKG1lc3NhZ2UpLFxyXG4gICAgICAgIGwgPSBtZXNzYWdlLmxlbmd0aCAqIDgsXHJcbiAgICAgICAgYSA9ICAxNzMyNTg0MTkzLFxyXG4gICAgICAgIGIgPSAtMjcxNzMzODc5LFxyXG4gICAgICAgIGMgPSAtMTczMjU4NDE5NCxcclxuICAgICAgICBkID0gIDI3MTczMzg3ODtcclxuXHJcbiAgICAvLyBTd2FwIGVuZGlhblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIG1baV0gPSAoKG1baV0gPDwgIDgpIHwgKG1baV0gPj4+IDI0KSkgJiAweDAwRkYwMEZGIHxcclxuICAgICAgICAgICAgICgobVtpXSA8PCAyNCkgfCAobVtpXSA+Pj4gIDgpKSAmIDB4RkYwMEZGMDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUGFkZGluZ1xyXG4gICAgbVtsID4+PiA1XSB8PSAweDgwIDw8IChsICUgMzIpO1xyXG4gICAgbVsoKChsICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IGw7XHJcblxyXG4gICAgLy8gTWV0aG9kIHNob3J0Y3V0c1xyXG4gICAgdmFyIEZGID0gbWQ1Ll9mZixcclxuICAgICAgICBHRyA9IG1kNS5fZ2csXHJcbiAgICAgICAgSEggPSBtZDUuX2hoLFxyXG4gICAgICAgIElJID0gbWQ1Ll9paTtcclxuXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG0ubGVuZ3RoOyBpICs9IDE2KSB7XHJcblxyXG4gICAgICB2YXIgYWEgPSBhLFxyXG4gICAgICAgICAgYmIgPSBiLFxyXG4gICAgICAgICAgY2MgPSBjLFxyXG4gICAgICAgICAgZGQgPSBkO1xyXG5cclxuICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIG1baSsgMF0sICA3LCAtNjgwODc2OTM2KTtcclxuICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIG1baSsgMV0sIDEyLCAtMzg5NTY0NTg2KTtcclxuICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIG1baSsgMl0sIDE3LCAgNjA2MTA1ODE5KTtcclxuICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIG1baSsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XHJcbiAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBtW2krIDRdLCAgNywgLTE3NjQxODg5Nyk7XHJcbiAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBtW2krIDVdLCAxMiwgIDEyMDAwODA0MjYpO1xyXG4gICAgICBjID0gRkYoYywgZCwgYSwgYiwgbVtpKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcclxuICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIG1baSsgN10sIDIyLCAtNDU3MDU5ODMpO1xyXG4gICAgICBhID0gRkYoYSwgYiwgYywgZCwgbVtpKyA4XSwgIDcsICAxNzcwMDM1NDE2KTtcclxuICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIG1baSsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XHJcbiAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBtW2krMTBdLCAxNywgLTQyMDYzKTtcclxuICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIG1baSsxMV0sIDIyLCAtMTk5MDQwNDE2Mik7XHJcbiAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBtW2krMTJdLCAgNywgIDE4MDQ2MDM2ODIpO1xyXG4gICAgICBkID0gRkYoZCwgYSwgYiwgYywgbVtpKzEzXSwgMTIsIC00MDM0MTEwMSk7XHJcbiAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBtW2krMTRdLCAxNywgLTE1MDIwMDIyOTApO1xyXG4gICAgICBiID0gRkYoYiwgYywgZCwgYSwgbVtpKzE1XSwgMjIsICAxMjM2NTM1MzI5KTtcclxuXHJcbiAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBtW2krIDFdLCAgNSwgLTE2NTc5NjUxMCk7XHJcbiAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBtW2krIDZdLCAgOSwgLTEwNjk1MDE2MzIpO1xyXG4gICAgICBjID0gR0coYywgZCwgYSwgYiwgbVtpKzExXSwgMTQsICA2NDM3MTc3MTMpO1xyXG4gICAgICBiID0gR0coYiwgYywgZCwgYSwgbVtpKyAwXSwgMjAsIC0zNzM4OTczMDIpO1xyXG4gICAgICBhID0gR0coYSwgYiwgYywgZCwgbVtpKyA1XSwgIDUsIC03MDE1NTg2OTEpO1xyXG4gICAgICBkID0gR0coZCwgYSwgYiwgYywgbVtpKzEwXSwgIDksICAzODAxNjA4Myk7XHJcbiAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBtW2krMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XHJcbiAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBtW2krIDRdLCAyMCwgLTQwNTUzNzg0OCk7XHJcbiAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBtW2krIDldLCAgNSwgIDU2ODQ0NjQzOCk7XHJcbiAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBtW2krMTRdLCAgOSwgLTEwMTk4MDM2OTApO1xyXG4gICAgICBjID0gR0coYywgZCwgYSwgYiwgbVtpKyAzXSwgMTQsIC0xODczNjM5NjEpO1xyXG4gICAgICBiID0gR0coYiwgYywgZCwgYSwgbVtpKyA4XSwgMjAsICAxMTYzNTMxNTAxKTtcclxuICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIG1baSsxM10sICA1LCAtMTQ0NDY4MTQ2Nyk7XHJcbiAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBtW2krIDJdLCAgOSwgLTUxNDAzNzg0KTtcclxuICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIG1baSsgN10sIDE0LCAgMTczNTMyODQ3Myk7XHJcbiAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBtW2krMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xyXG5cclxuICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIG1baSsgNV0sICA0LCAtMzc4NTU4KTtcclxuICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIG1baSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XHJcbiAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBtW2krMTFdLCAxNiwgIDE4MzkwMzA1NjIpO1xyXG4gICAgICBiID0gSEgoYiwgYywgZCwgYSwgbVtpKzE0XSwgMjMsIC0zNTMwOTU1Nik7XHJcbiAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBtW2krIDFdLCAgNCwgLTE1MzA5OTIwNjApO1xyXG4gICAgICBkID0gSEgoZCwgYSwgYiwgYywgbVtpKyA0XSwgMTEsICAxMjcyODkzMzUzKTtcclxuICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIG1baSsgN10sIDE2LCAtMTU1NDk3NjMyKTtcclxuICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIG1baSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XHJcbiAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBtW2krMTNdLCAgNCwgIDY4MTI3OTE3NCk7XHJcbiAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBtW2krIDBdLCAxMSwgLTM1ODUzNzIyMik7XHJcbiAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBtW2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XHJcbiAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBtW2krIDZdLCAyMywgIDc2MDI5MTg5KTtcclxuICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIG1baSsgOV0sICA0LCAtNjQwMzY0NDg3KTtcclxuICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIG1baSsxMl0sIDExLCAtNDIxODE1ODM1KTtcclxuICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIG1baSsxNV0sIDE2LCAgNTMwNzQyNTIwKTtcclxuICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIG1baSsgMl0sIDIzLCAtOTk1MzM4NjUxKTtcclxuXHJcbiAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBtW2krIDBdLCAgNiwgLTE5ODYzMDg0NCk7XHJcbiAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBtW2krIDddLCAxMCwgIDExMjY4OTE0MTUpO1xyXG4gICAgICBjID0gSUkoYywgZCwgYSwgYiwgbVtpKzE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcclxuICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIG1baSsgNV0sIDIxLCAtNTc0MzQwNTUpO1xyXG4gICAgICBhID0gSUkoYSwgYiwgYywgZCwgbVtpKzEyXSwgIDYsICAxNzAwNDg1NTcxKTtcclxuICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIG1baSsgM10sIDEwLCAtMTg5NDk4NjYwNik7XHJcbiAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBtW2krMTBdLCAxNSwgLTEwNTE1MjMpO1xyXG4gICAgICBiID0gSUkoYiwgYywgZCwgYSwgbVtpKyAxXSwgMjEsIC0yMDU0OTIyNzk5KTtcclxuICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIG1baSsgOF0sICA2LCAgMTg3MzMxMzM1OSk7XHJcbiAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBtW2krMTVdLCAxMCwgLTMwNjExNzQ0KTtcclxuICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIG1baSsgNl0sIDE1LCAtMTU2MDE5ODM4MCk7XHJcbiAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBtW2krMTNdLCAyMSwgIDEzMDkxNTE2NDkpO1xyXG4gICAgICBhID0gSUkoYSwgYiwgYywgZCwgbVtpKyA0XSwgIDYsIC0xNDU1MjMwNzApO1xyXG4gICAgICBkID0gSUkoZCwgYSwgYiwgYywgbVtpKzExXSwgMTAsIC0xMTIwMjEwMzc5KTtcclxuICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIG1baSsgMl0sIDE1LCAgNzE4Nzg3MjU5KTtcclxuICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIG1baSsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcclxuXHJcbiAgICAgIGEgPSAoYSArIGFhKSA+Pj4gMDtcclxuICAgICAgYiA9IChiICsgYmIpID4+PiAwO1xyXG4gICAgICBjID0gKGMgKyBjYykgPj4+IDA7XHJcbiAgICAgIGQgPSAoZCArIGRkKSA+Pj4gMDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY3J5cHQuZW5kaWFuKFthLCBiLCBjLCBkXSk7XHJcbiAgfTtcclxuXHJcbiAgLy8gQXV4aWxpYXJ5IGZ1bmN0aW9uc1xyXG4gIG1kNS5fZmYgID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcclxuICAgIHZhciBuID0gYSArIChiICYgYyB8IH5iICYgZCkgKyAoeCA+Pj4gMCkgKyB0O1xyXG4gICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcclxuICB9O1xyXG4gIG1kNS5fZ2cgID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcclxuICAgIHZhciBuID0gYSArIChiICYgZCB8IGMgJiB+ZCkgKyAoeCA+Pj4gMCkgKyB0O1xyXG4gICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcclxuICB9O1xyXG4gIG1kNS5faGggID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcclxuICAgIHZhciBuID0gYSArIChiIF4gYyBeIGQpICsgKHggPj4+IDApICsgdDtcclxuICAgIHJldHVybiAoKG4gPDwgcykgfCAobiA+Pj4gKDMyIC0gcykpKSArIGI7XHJcbiAgfTtcclxuICBtZDUuX2lpICA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XHJcbiAgICB2YXIgbiA9IGEgKyAoYyBeIChiIHwgfmQpKSArICh4ID4+PiAwKSArIHQ7XHJcbiAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xyXG4gIH07XHJcblxyXG4gIC8vIFBhY2thZ2UgcHJpdmF0ZSBibG9ja3NpemVcclxuICBtZDUuX2Jsb2Nrc2l6ZSA9IDE2O1xyXG4gIG1kNS5fZGlnZXN0c2l6ZSA9IDE2O1xyXG5cclxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChtZXNzYWdlLCBvcHRpb25zKSB7XHJcbiAgICBpZih0eXBlb2YgbWVzc2FnZSA9PSAndW5kZWZpbmVkJylcclxuICAgICAgcmV0dXJuO1xyXG5cclxuICAgIHZhciBkaWdlc3RieXRlcyA9IGNyeXB0LndvcmRzVG9CeXRlcyhtZDUobWVzc2FnZSwgb3B0aW9ucykpO1xyXG4gICAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5hc0J5dGVzID8gZGlnZXN0Ynl0ZXMgOlxyXG4gICAgICAgIG9wdGlvbnMgJiYgb3B0aW9ucy5hc1N0cmluZyA/IGJpbi5ieXRlc1RvU3RyaW5nKGRpZ2VzdGJ5dGVzKSA6XHJcbiAgICAgICAgY3J5cHQuYnl0ZXNUb0hleChkaWdlc3RieXRlcyk7XHJcbiAgfTtcclxuXHJcbn0pKCk7XHJcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8vIElmIG9iai5oYXNPd25Qcm9wZXJ0eSBoYXMgYmVlbiBvdmVycmlkZGVuLCB0aGVuIGNhbGxpbmdcbi8vIG9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSB3aWxsIGJyZWFrLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vam95ZW50L25vZGUvaXNzdWVzLzE3MDdcbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ocXMsIHNlcCwgZXEsIG9wdGlvbnMpIHtcbiAgc2VwID0gc2VwIHx8ICcmJztcbiAgZXEgPSBlcSB8fCAnPSc7XG4gIHZhciBvYmogPSB7fTtcblxuICBpZiAodHlwZW9mIHFzICE9PSAnc3RyaW5nJyB8fCBxcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgdmFyIHJlZ2V4cCA9IC9cXCsvZztcbiAgcXMgPSBxcy5zcGxpdChzZXApO1xuXG4gIHZhciBtYXhLZXlzID0gMTAwMDtcbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMubWF4S2V5cyA9PT0gJ251bWJlcicpIHtcbiAgICBtYXhLZXlzID0gb3B0aW9ucy5tYXhLZXlzO1xuICB9XG5cbiAgdmFyIGxlbiA9IHFzLmxlbmd0aDtcbiAgLy8gbWF4S2V5cyA8PSAwIG1lYW5zIHRoYXQgd2Ugc2hvdWxkIG5vdCBsaW1pdCBrZXlzIGNvdW50XG4gIGlmIChtYXhLZXlzID4gMCAmJiBsZW4gPiBtYXhLZXlzKSB7XG4gICAgbGVuID0gbWF4S2V5cztcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgeCA9IHFzW2ldLnJlcGxhY2UocmVnZXhwLCAnJTIwJyksXG4gICAgICAgIGlkeCA9IHguaW5kZXhPZihlcSksXG4gICAgICAgIGtzdHIsIHZzdHIsIGssIHY7XG5cbiAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgIGtzdHIgPSB4LnN1YnN0cigwLCBpZHgpO1xuICAgICAgdnN0ciA9IHguc3Vic3RyKGlkeCArIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBrc3RyID0geDtcbiAgICAgIHZzdHIgPSAnJztcbiAgICB9XG5cbiAgICBrID0gZGVjb2RlVVJJQ29tcG9uZW50KGtzdHIpO1xuICAgIHYgPSBkZWNvZGVVUklDb21wb25lbnQodnN0cik7XG5cbiAgICBpZiAoIWhhc093blByb3BlcnR5KG9iaiwgaykpIHtcbiAgICAgIG9ialtrXSA9IHY7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KG9ialtrXSkpIHtcbiAgICAgIG9ialtrXS5wdXNoKHYpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmpba10gPSBbb2JqW2tdLCB2XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3RyaW5naWZ5UHJpbWl0aXZlID0gZnVuY3Rpb24odikge1xuICBzd2l0Y2ggKHR5cGVvZiB2KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiB2O1xuXG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gdiA/ICd0cnVlJyA6ICdmYWxzZSc7XG5cbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIGlzRmluaXRlKHYpID8gdiA6ICcnO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnJztcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmosIHNlcCwgZXEsIG5hbWUpIHtcbiAgc2VwID0gc2VwIHx8ICcmJztcbiAgZXEgPSBlcSB8fCAnPSc7XG4gIGlmIChvYmogPT09IG51bGwpIHtcbiAgICBvYmogPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbWFwKG9iamVjdEtleXMob2JqKSwgZnVuY3Rpb24oaykge1xuICAgICAgdmFyIGtzID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZShrKSkgKyBlcTtcbiAgICAgIGlmIChpc0FycmF5KG9ialtrXSkpIHtcbiAgICAgICAgcmV0dXJuIG1hcChvYmpba10sIGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgICByZXR1cm4ga3MgKyBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKHYpKTtcbiAgICAgICAgfSkuam9pbihzZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGtzICsgZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZShvYmpba10pKTtcbiAgICAgIH1cbiAgICB9KS5qb2luKHNlcCk7XG5cbiAgfVxuXG4gIGlmICghbmFtZSkgcmV0dXJuICcnO1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cmluZ2lmeVByaW1pdGl2ZShuYW1lKSkgKyBlcSArXG4gICAgICAgICBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKG9iaikpO1xufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG5cbmZ1bmN0aW9uIG1hcCAoeHMsIGYpIHtcbiAgaWYgKHhzLm1hcCkgcmV0dXJuIHhzLm1hcChmKTtcbiAgdmFyIHJlcyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzLnB1c2goZih4c1tpXSwgaSkpO1xuICB9XG4gIHJldHVybiByZXM7XG59XG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgcmVzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5kZWNvZGUgPSBleHBvcnRzLnBhcnNlID0gcmVxdWlyZSgnLi9kZWNvZGUnKTtcbmV4cG9ydHMuZW5jb2RlID0gZXhwb3J0cy5zdHJpbmdpZnkgPSByZXF1aXJlKCcuL2VuY29kZScpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjkuM1xudmFyIFJlYWN0LCBpc1JldGluYSwgbWQ1LCBxdWVyeXN0cmluZztcblxuUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG5tZDUgPSByZXF1aXJlKCdtZDUnKTtcblxucXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG5pc1JldGluYSA9IHJlcXVpcmUoJ2lzLXJldGluYScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgZGlzcGxheU5hbWU6ICdHcmF2YXRhcicsXG4gIHByb3BUeXBlczoge1xuICAgIGVtYWlsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgc2l6ZTogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcbiAgICByYXRpbmc6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgaHR0cHM6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIFwiZGVmYXVsdFwiOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICB9LFxuICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzaXplOiA1MCxcbiAgICAgIHJhdGluZzogJ2cnLFxuICAgICAgaHR0cHM6IGZhbHNlLFxuICAgICAgXCJkZWZhdWx0XCI6IFwicmV0cm9cIixcbiAgICAgIGVtYWlsOiAnJyxcbiAgICAgIGNsYXNzTmFtZTogXCJcIlxuICAgIH07XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJhc2UsIHF1ZXJ5LCBzcmM7XG4gICAgYmFzZSA9IHRoaXMucHJvcHMuaHR0cHMgPyBcImh0dHBzOi8vc2VjdXJlLmdyYXZhdGFyLmNvbS9hdmF0YXIvXCIgOiAnaHR0cDovL3d3dy5ncmF2YXRhci5jb20vYXZhdGFyLyc7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoe1xuICAgICAgczogaXNSZXRpbmEoKSA/IHRoaXMucHJvcHMuc2l6ZSAqIDIgOiB0aGlzLnByb3BzLnNpemUsXG4gICAgICByOiB0aGlzLnByb3BzLnJhdGluZyxcbiAgICAgIGQ6IHRoaXMucHJvcHNbXCJkZWZhdWx0XCJdXG4gICAgfSk7XG4gICAgc3JjID0gYmFzZSArIG1kNSh0aGlzLnByb3BzLmVtYWlsKSArIFwiP1wiICsgcXVlcnk7XG4gICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIiwgUmVhY3QuX19zcHJlYWQoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgIFwiY2xhc3NOYW1lXCI6IFwicmVhY3QtZ3JhdmF0YXIgXCIgKyB0aGlzLnByb3BzLmNsYXNzTmFtZSxcbiAgICAgIFwic3JjXCI6IHNyYyxcbiAgICAgIFwiaGVpZ2h0XCI6IHRoaXMucHJvcHMuc2l6ZSxcbiAgICAgIFwid2lkdGhcIjogdGhpcy5wcm9wcy5zaXplXG4gICAgfSkpO1xuICB9XG59KTtcbiJdfQ== diff --git a/examples/dist/bundle.js b/examples/dist/bundle.js index d4815b9a12..0121c85e5c 100644 --- a/examples/dist/bundle.js +++ b/examples/dist/bundle.js @@ -139,7 +139,7 @@ module.exports = Value; },{"react":undefined}],"react-select":[function(require,module,exports){ /* disable some rules until we refactor more completely; fixing them now would - cause conflicts with some open PRs unnecessarily. */ + cause conflicts with some open PRs unnecessarily. */ /* eslint react/jsx-sort-prop-types: 0, react/sort-comp: 0, react/prop-types: 0 */ 'use strict'; @@ -157,827 +157,859 @@ var requestId = 0; var Select = React.createClass({ - displayName: 'Select', - - propTypes: { - addLabelText: React.PropTypes.string, // placeholder displayed when you want to add a label on a multi-value input - allowCreate: React.PropTypes.bool, // whether to allow creation of new entries - asyncOptions: React.PropTypes.func, // function to call to get options - autoload: React.PropTypes.bool, // whether to auto-load the default async options set - backspaceRemoves: React.PropTypes.bool, // whether backspace removes an item if there is no text input - cacheAsyncResults: React.PropTypes.bool, // whether to allow cache - className: React.PropTypes.string, // className for the outer element - clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true - clearValueText: React.PropTypes.string, // title for the "clear" control - clearable: React.PropTypes.bool, // should it be possible to reset value - delimiter: React.PropTypes.string, // delimiter to use to join multiple values - disabled: React.PropTypes.bool, // whether the Select is disabled or not - filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) - filterOptions: React.PropTypes.func, // method to filter the options array: function([options], filterString, [values]) - ignoreCase: React.PropTypes.bool, // whether to perform case-insensitive filtering - inputProps: React.PropTypes.object, // custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} - matchPos: React.PropTypes.string, // (any|start) match the start or entire string when filtering - matchProp: React.PropTypes.string, // (any|label|value) which option property to filter on - multi: React.PropTypes.bool, // multi-value input - name: React.PropTypes.string, // field name, for hidden tag - newOptionCreator: React.PropTypes.func, // factory to create new options when allowCreate set - noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results - onBlur: React.PropTypes.func, // onBlur handler: function(event) {} - onChange: React.PropTypes.func, // onChange handler: function(newValue) {} - onFocus: React.PropTypes.func, // onFocus handler: function(event) {} - onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} - optionComponent: React.PropTypes.func, // option component to render in dropdown - optionRenderer: React.PropTypes.func, // optionRenderer: function(option) {} - options: React.PropTypes.array, // array of options - placeholder: React.PropTypes.string, // field placeholder, displayed when there's no value - searchable: React.PropTypes.bool, // whether to enable searching feature or not - searchPromptText: React.PropTypes.string, // label to prompt for search input - singleValueComponent: React.PropTypes.func, // single value component when multiple is set to false - value: React.PropTypes.any, // initial field value - valueComponent: React.PropTypes.func, // value component to render in multiple mode - valueRenderer: React.PropTypes.func // valueRenderer: function(option) {} - }, - - getDefaultProps: function getDefaultProps() { - return { - addLabelText: 'Add {label} ?', - allowCreate: false, - asyncOptions: undefined, - autoload: true, - backspaceRemoves: true, - cacheAsyncResults: true, - className: undefined, - clearAllText: 'Clear all', - clearValueText: 'Clear value', - clearable: true, - delimiter: ',', - disabled: false, - ignoreCase: true, - inputProps: {}, - matchPos: 'any', - matchProp: 'any', - name: undefined, - newOptionCreator: undefined, - noResultsText: 'No results found', - onChange: undefined, - onOptionLabelClick: undefined, - optionComponent: Option, - options: undefined, - placeholder: 'Select...', - searchable: true, - searchPromptText: 'Type to search', - singleValueComponent: SingleValue, - value: undefined, - valueComponent: Value - }; - }, - - getInitialState: function getInitialState() { - return { - /* - * set by getStateFromValue on componentWillMount: - * - value - * - values - * - filteredOptions - * - inputValue - * - placeholder - * - focusedOption - */ - isFocused: false, - isLoading: false, - isOpen: false, - options: this.props.options - }; - }, - - componentWillMount: function componentWillMount() { - var _this = this; - - this._optionsCache = {}; - this._optionsFilterString = ''; - this._closeMenuIfClickedOutside = function (event) { - if (!_this.state.isOpen) { - return; - } - var menuElem = React.findDOMNode(_this.refs.selectMenuContainer); - var controlElem = React.findDOMNode(_this.refs.control); - - var eventOccuredOutsideMenu = _this.clickedOutsideElement(menuElem, event); - var eventOccuredOutsideControl = _this.clickedOutsideElement(controlElem, event); - - // Hide dropdown menu if click occurred outside of menu - if (eventOccuredOutsideMenu && eventOccuredOutsideControl) { - _this.setState({ - isOpen: false - }, _this._unbindCloseMenuIfClickedOutside); - } - }; - this._bindCloseMenuIfClickedOutside = function () { - if (!document.addEventListener && document.attachEvent) { - document.attachEvent('onclick', this._closeMenuIfClickedOutside); - } else { - document.addEventListener('click', this._closeMenuIfClickedOutside); - } - }; - this._unbindCloseMenuIfClickedOutside = function () { - if (!document.removeEventListener && document.detachEvent) { - document.detachEvent('onclick', this._closeMenuIfClickedOutside); - } else { - document.removeEventListener('click', this._closeMenuIfClickedOutside); - } - }; - this.setState(this.getStateFromValue(this.props.value)); - }, - - componentDidMount: function componentDidMount() { - if (this.props.asyncOptions && this.props.autoload) { - this.autoloadAsyncOptions(); - } - }, - - componentWillUnmount: function componentWillUnmount() { - clearTimeout(this._blurTimeout); - clearTimeout(this._focusTimeout); - if (this.state.isOpen) { - this._unbindCloseMenuIfClickedOutside(); - } - }, - - componentWillReceiveProps: function componentWillReceiveProps(newProps) { - var _this2 = this; - - var optionsChanged = false; - if (JSON.stringify(newProps.options) !== JSON.stringify(this.props.options)) { - optionsChanged = true; - this.setState({ - options: newProps.options, - filteredOptions: this.filterOptions(newProps.options) - }); - } - if (newProps.value !== this.state.value || newProps.placeholder !== this.props.placeholder || optionsChanged) { - var setState = function setState(newState) { - _this2.setState(_this2.getStateFromValue(newProps.value, newState && newState.options || newProps.options, newProps.placeholder)); - }; - if (this.props.asyncOptions) { - this.loadAsyncOptions(newProps.value, {}, setState); - } else { - setState(); - } - } - }, - - componentDidUpdate: function componentDidUpdate() { - var _this3 = this; - - if (!this.props.disabled && this._focusAfterUpdate) { - clearTimeout(this._blurTimeout); - this._focusTimeout = setTimeout(function () { - _this3.getInputNode().focus(); - _this3._focusAfterUpdate = false; - }, 50); - } - if (this._focusedOptionReveal) { - if (this.refs.focused && this.refs.menu) { - var focusedDOM = React.findDOMNode(this.refs.focused); - var menuDOM = React.findDOMNode(this.refs.menu); - var focusedRect = focusedDOM.getBoundingClientRect(); - var menuRect = menuDOM.getBoundingClientRect(); - - if (focusedRect.bottom > menuRect.bottom || focusedRect.top < menuRect.top) { - menuDOM.scrollTop = focusedDOM.offsetTop + focusedDOM.clientHeight - menuDOM.offsetHeight; - } - } - this._focusedOptionReveal = false; - } - }, - - focus: function focus() { - this.getInputNode().focus(); - }, - - clickedOutsideElement: function clickedOutsideElement(element, event) { - var eventTarget = event.target ? event.target : event.srcElement; - while (eventTarget != null) { - if (eventTarget === element) return false; - eventTarget = eventTarget.offsetParent; - } - return true; - }, - - getStateFromValue: function getStateFromValue(value, options, placeholder) { - if (!options) { - options = this.state.options; - } - if (!placeholder) { - placeholder = this.props.placeholder; - } - - // reset internal filter string - this._optionsFilterString = ''; - - var values = this.initValuesArray(value, options); - var filteredOptions = this.filterOptions(options, values); - - var focusedOption; - var valueForState = null; - if (!this.props.multi && values.length) { - focusedOption = values[0]; - valueForState = values[0].value; - } else { - for (var optionIndex = 0; optionIndex < filteredOptions.length; ++optionIndex) { - if (!filteredOptions[optionIndex].disabled) { - focusedOption = filteredOptions[optionIndex]; - break; - } - } - valueForState = values.map(function (v) { - return v.value; - }).join(this.props.delimiter); - } - - return { - value: valueForState, - values: values, - inputValue: '', - filteredOptions: filteredOptions, - placeholder: !this.props.multi && values.length ? values[0].label : placeholder, - focusedOption: focusedOption - }; - }, - - initValuesArray: function initValuesArray(values, options) { - if (!Array.isArray(values)) { - if (typeof values === 'string') { - values = values === '' ? [] : values.split(this.props.delimiter); - } else { - values = values !== undefined && values !== null ? [values] : []; - } - } - return values.map(function (val) { - if (typeof val === 'string' || typeof val === 'number') { - for (var key in options) { - if (options.hasOwnProperty(key) && options[key] && (options[key].value === val || typeof options[key].value === 'number' && options[key].value.toString() === val)) { - return options[key]; - } - } - return { value: val, label: val }; - } else { - return val; - } - }); - }, - - setValue: function setValue(value, focusAfterUpdate) { - if (focusAfterUpdate || focusAfterUpdate === undefined) { - this._focusAfterUpdate = true; - } - var newState = this.getStateFromValue(value); - newState.isOpen = false; - this.fireChangeEvent(newState); - this.setState(newState); - }, - - selectValue: function selectValue(value) { - if (!this.props.multi) { - this.setValue(value); - } else if (value) { - this.addValue(value); - } - this._unbindCloseMenuIfClickedOutside(); - }, - - addValue: function addValue(value) { - this.setValue(this.state.values.concat(value)); - }, - - popValue: function popValue() { - this.setValue(this.state.values.slice(0, this.state.values.length - 1)); - }, - - removeValue: function removeValue(valueToRemove) { - this.setValue(this.state.values.filter(function (value) { - return value !== valueToRemove; - })); - }, - - clearValue: function clearValue(event) { - // if the event was triggered by a mousedown and not the primary - // button, ignore it. - if (event && event.type === 'mousedown' && event.button !== 0) { - return; - } - event.stopPropagation(); - event.preventDefault(); - this.setValue(null); - }, - - resetValue: function resetValue() { - this.setValue(this.state.value === '' ? null : this.state.value); - }, - - getInputNode: function getInputNode() { - var input = this.refs.input; - return this.props.searchable ? input : React.findDOMNode(input); - }, - - fireChangeEvent: function fireChangeEvent(newState) { - if (newState.value !== this.state.value && this.props.onChange) { - this.props.onChange(newState.value, newState.values); - } - }, - - handleMouseDown: function handleMouseDown(event) { - // if the event was triggered by a mousedown and not the primary - // button, or if the component is disabled, ignore it. - if (this.props.disabled || event.type === 'mousedown' && event.button !== 0) { - return; - } - event.stopPropagation(); - event.preventDefault(); - if (this.state.isFocused) { - this.setState({ - isOpen: true - }, this._bindCloseMenuIfClickedOutside); - } else { - this._openAfterFocus = true; - this.getInputNode().focus(); - } - }, - - handleMouseDownOnArrow: function handleMouseDownOnArrow(event) { - // if the event was triggered by a mousedown and not the primary - // button, or if the component is disabled, ignore it. - if (this.props.disabled || event.type === 'mousedown' && event.button !== 0) { - return; - } - // If not focused, handleMouseDown will handle it - if (!this.state.isOpen) { - return; - } - event.stopPropagation(); - event.preventDefault(); - this.setState({ - isOpen: false - }, this._unbindCloseMenuIfClickedOutside); - }, - - handleInputFocus: function handleInputFocus(event) { - var newIsOpen = this.state.isOpen || this._openAfterFocus; - this.setState({ - isFocused: true, - isOpen: newIsOpen - }, function () { - if (newIsOpen) { - this._bindCloseMenuIfClickedOutside(); - } else { - this._unbindCloseMenuIfClickedOutside(); - } - }); - this._openAfterFocus = false; - if (this.props.onFocus) { - this.props.onFocus(event); - } - }, - - handleInputBlur: function handleInputBlur(event) { - var _this4 = this; - - this._blurTimeout = setTimeout(function () { - if (_this4._focusAfterUpdate) return; - _this4.setState({ - isFocused: false, - isOpen: false - }); - }, 50); - if (this.props.onBlur) { - this.props.onBlur(event); - } - }, - - handleKeyDown: function handleKeyDown(event) { - if (this.props.disabled) return; - switch (event.keyCode) { - case 8: - // backspace - if (!this.state.inputValue && this.props.backspaceRemoves) { - this.popValue(); - } - return; - case 9: - // tab - if (event.shiftKey || !this.state.isOpen || !this.state.focusedOption) { - return; - } - this.selectFocusedOption(); - break; - case 13: - // enter - if (!this.state.isOpen) return; - - this.selectFocusedOption(); - break; - case 27: - // escape - if (this.state.isOpen) { - this.resetValue(); - } else if (this.props.clearable) { - this.clearValue(event); - } - break; - case 38: - // up - this.focusPreviousOption(); - break; - case 40: - // down - this.focusNextOption(); - break; - case 188: - // , - if (this.props.allowCreate && this.props.multi) { - event.preventDefault(); - event.stopPropagation(); - this.selectFocusedOption(); - } else { - return; - } - break; - default: - return; - } - event.preventDefault(); - }, - - // Ensures that the currently focused option is available in filteredOptions. - // If not, returns the first available option. - _getNewFocusedOption: function _getNewFocusedOption(filteredOptions) { - for (var key in filteredOptions) { - if (filteredOptions.hasOwnProperty(key) && filteredOptions[key] === this.state.focusedOption) { - return filteredOptions[key]; - } - } - return filteredOptions[0]; - }, - - handleInputChange: function handleInputChange(event) { - // assign an internal variable because we need to use - // the latest value before setState() has completed. - this._optionsFilterString = event.target.value; - - if (this.props.asyncOptions) { - this.setState({ - isLoading: true, - inputValue: event.target.value - }); - this.loadAsyncOptions(event.target.value, { - isLoading: false, - isOpen: true - }, this._bindCloseMenuIfClickedOutside); - } else { - var filteredOptions = this.filterOptions(this.state.options); - this.setState({ - isOpen: true, - inputValue: event.target.value, - filteredOptions: filteredOptions, - focusedOption: this._getNewFocusedOption(filteredOptions) - }, this._bindCloseMenuIfClickedOutside); - } - }, - - autoloadAsyncOptions: function autoloadAsyncOptions() { - var _this5 = this; - - this.loadAsyncOptions(this.props.value || '', {}, function () { - // update with fetched but don't focus - _this5.setValue(_this5.props.value, false); - }); - }, - - loadAsyncOptions: function loadAsyncOptions(input, state, callback) { - var _this6 = this; - - var thisRequestId = this._currentRequestId = requestId++; - if (this.props.cacheAsyncResults) { - for (var i = 0; i <= input.length; i++) { - var cacheKey = input.slice(0, i); - if (this._optionsCache[cacheKey] && (input === cacheKey || this._optionsCache[cacheKey].complete)) { - var options = this._optionsCache[cacheKey].options; - var filteredOptions = this.filterOptions(options); - var newState = { - options: options, - filteredOptions: filteredOptions, - focusedOption: this._getNewFocusedOption(filteredOptions) - }; - for (var key in state) { - if (state.hasOwnProperty(key)) { - newState[key] = state[key]; - } - } - this.setState(newState); - if (callback) callback.call(this, newState); - return; - } - } - } - - this.props.asyncOptions(input, function (err, data) { - if (err) throw err; - if (_this6.props.cacheAsyncResults) { - _this6._optionsCache[input] = data; - } - if (thisRequestId !== _this6._currentRequestId) { - return; - } - var filteredOptions = _this6.filterOptions(data.options); - var newState = { - options: data.options, - filteredOptions: filteredOptions, - focusedOption: _this6._getNewFocusedOption(filteredOptions) - }; - for (var key in state) { - if (state.hasOwnProperty(key)) { - newState[key] = state[key]; - } - } - _this6.setState(newState); - if (callback) callback.call(_this6, newState); - }); - }, - - filterOptions: function filterOptions(options, values) { - var filterValue = this._optionsFilterString; - var exclude = (values || this.state.values).map(function (i) { - return i.value; - }); - if (this.props.filterOptions) { - return this.props.filterOptions.call(this, options, filterValue, exclude); - } else { - var filterOption = function filterOption(op) { - if (this.props.multi && exclude.indexOf(op.value) > -1) return false; - if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue); - var valueTest = String(op.value), - labelTest = String(op.label); - if (this.props.ignoreCase) { - valueTest = valueTest.toLowerCase(); - labelTest = labelTest.toLowerCase(); - filterValue = filterValue.toLowerCase(); - } - return !filterValue || this.props.matchPos === 'start' ? this.props.matchProp !== 'label' && valueTest.substr(0, filterValue.length) === filterValue || this.props.matchProp !== 'value' && labelTest.substr(0, filterValue.length) === filterValue : this.props.matchProp !== 'label' && valueTest.indexOf(filterValue) >= 0 || this.props.matchProp !== 'value' && labelTest.indexOf(filterValue) >= 0; - }; - return (options || []).filter(filterOption, this); - } - }, - - selectFocusedOption: function selectFocusedOption() { - if (this.props.allowCreate && !this.state.focusedOption) { - return this.selectValue(this.state.inputValue); - } - return this.selectValue(this.state.focusedOption); - }, - - focusOption: function focusOption(op) { - this.setState({ - focusedOption: op - }); - }, - - focusNextOption: function focusNextOption() { - this.focusAdjacentOption('next'); - }, - - focusPreviousOption: function focusPreviousOption() { - this.focusAdjacentOption('previous'); - }, - - focusAdjacentOption: function focusAdjacentOption(dir) { - this._focusedOptionReveal = true; - var ops = this.state.filteredOptions.filter(function (op) { - return !op.disabled; - }); - if (!this.state.isOpen) { - this.setState({ - isOpen: true, - inputValue: '', - focusedOption: this.state.focusedOption || ops[dir === 'next' ? 0 : ops.length - 1] - }, this._bindCloseMenuIfClickedOutside); - return; - } - if (!ops.length) { - return; - } - var focusedIndex = -1; - for (var i = 0; i < ops.length; i++) { - if (this.state.focusedOption === ops[i]) { - focusedIndex = i; - break; - } - } - var focusedOption = ops[0]; - if (dir === 'next' && focusedIndex > -1 && focusedIndex < ops.length - 1) { - focusedOption = ops[focusedIndex + 1]; - } else if (dir === 'previous') { - if (focusedIndex > 0) { - focusedOption = ops[focusedIndex - 1]; - } else { - focusedOption = ops[ops.length - 1]; - } - } - this.setState({ - focusedOption: focusedOption - }); - }, - - unfocusOption: function unfocusOption(op) { - if (this.state.focusedOption === op) { - this.setState({ - focusedOption: null - }); - } - }, - - buildMenu: function buildMenu() { - var focusedValue = this.state.focusedOption ? this.state.focusedOption.value : null; - var renderLabel = this.props.optionRenderer || function (op) { - return op.label; - }; - if (this.state.filteredOptions.length > 0) { - focusedValue = focusedValue == null ? this.state.filteredOptions[0] : focusedValue; - } - // Add the current value to the filtered options in last resort - var options = this.state.filteredOptions; - if (this.props.allowCreate && this.state.inputValue.trim()) { - var inputValue = this.state.inputValue; - options = options.slice(); - var newOption = this.props.newOptionCreator ? this.props.newOptionCreator(inputValue) : { - value: inputValue, - label: inputValue, - create: true - }; - options.unshift(newOption); - } - var ops = Object.keys(options).map(function (key) { - var op = options[key]; - var isSelected = this.state.value === op.value; - var isFocused = focusedValue === op.value; - var optionClass = classes({ - 'Select-option': true, - 'is-selected': isSelected, - 'is-focused': isFocused, - 'is-disabled': op.disabled - }); - var ref = isFocused ? 'focused' : null; - var mouseEnter = this.focusOption.bind(this, op); - var mouseLeave = this.unfocusOption.bind(this, op); - var mouseDown = this.selectValue.bind(this, op); - var optionResult = React.createElement(this.props.optionComponent, { - key: 'option-' + op.value, - className: optionClass, - renderFunc: renderLabel, - mouseEnter: mouseEnter, - mouseLeave: mouseLeave, - mouseDown: mouseDown, - click: mouseDown, - addLabelText: this.props.addLabelText, - option: op, - ref: ref - }); - return optionResult; - }, this); - return ops.length ? ops : React.createElement( - 'div', - { className: 'Select-noresults' }, - this.props.asyncOptions && !this.state.inputValue ? this.props.searchPromptText : this.props.noResultsText - ); - }, - - handleOptionLabelClick: function handleOptionLabelClick(value, event) { - if (this.props.onOptionLabelClick) { - this.props.onOptionLabelClick(value, event); - } - }, - - render: function render() { - var selectClass = classes('Select', this.props.className, { - 'is-multi': this.props.multi, - 'is-searchable': this.props.searchable, - 'is-open': this.state.isOpen, - 'is-focused': this.state.isFocused, - 'is-loading': this.state.isLoading, - 'is-disabled': this.props.disabled, - 'has-value': this.state.value - }); - var value = []; - if (this.props.multi) { - this.state.values.forEach(function (val) { - var onOptionLabelClick = this.handleOptionLabelClick.bind(this, val); - var onRemove = this.removeValue.bind(this, val); - var valueComponent = React.createElement(this.props.valueComponent, { - key: val.value, - option: val, - renderer: this.props.valueRenderer, - optionLabelClick: !!this.props.onOptionLabelClick, - onOptionLabelClick: onOptionLabelClick, - onRemove: onRemove, - disabled: this.props.disabled - }); - value.push(valueComponent); - }, this); - } - - if (!this.state.inputValue && (!this.props.multi || !value.length)) { - var val = this.state.values[0] || null; - if (this.props.valueRenderer && !!this.state.values.length) { - value.push(React.createElement(Value, { - key: 0, - option: val, - renderer: this.props.valueRenderer, - disabled: this.props.disabled })); - } else { - var singleValueComponent = React.createElement(this.props.singleValueComponent, { - key: 'placeholder', - value: val, - placeholder: this.state.placeholder - }); - value.push(singleValueComponent); - } - } - - var loading = this.state.isLoading ? React.createElement('span', { className: 'Select-loading', 'aria-hidden': 'true' }) : null; - var clear = this.props.clearable && this.state.value && !this.props.disabled ? React.createElement('span', { className: 'Select-clear', title: this.props.multi ? this.props.clearAllText : this.props.clearValueText, 'aria-label': this.props.multi ? this.props.clearAllText : this.props.clearValueText, onMouseDown: this.clearValue, onClick: this.clearValue, dangerouslySetInnerHTML: { __html: '×' } }) : null; - - var menu; - var menuProps; - if (this.state.isOpen) { - menuProps = { - ref: 'menu', - className: 'Select-menu' - }; - if (this.props.multi) { - menuProps.onMouseDown = this.handleMouseDown; - } - menu = React.createElement( - 'div', - { ref: 'selectMenuContainer', className: 'Select-menu-outer' }, - React.createElement( - 'div', - menuProps, - this.buildMenu() - ) - ); - } - - var input; - var inputProps = { - ref: 'input', - className: 'Select-input ' + (this.props.inputProps.className || ''), - tabIndex: this.props.tabIndex || 0, - onFocus: this.handleInputFocus, - onBlur: this.handleInputBlur - }; - for (var key in this.props.inputProps) { - if (this.props.inputProps.hasOwnProperty(key) && key !== 'className') { - inputProps[key] = this.props.inputProps[key]; - } - } - - if (!this.props.disabled) { - if (this.props.searchable) { - input = React.createElement(Input, _extends({ value: this.state.inputValue, onChange: this.handleInputChange, minWidth: '5' }, inputProps)); - } else { - input = React.createElement( - 'div', - inputProps, - ' ' - ); - } - } else if (!this.props.multi || !this.state.values.length) { - input = React.createElement( - 'div', - { className: 'Select-input' }, - ' ' - ); - } - - return React.createElement( - 'div', - { ref: 'wrapper', className: selectClass }, - React.createElement('input', { type: 'hidden', ref: 'value', name: this.props.name, value: this.state.value, disabled: this.props.disabled }), - React.createElement( - 'div', - { className: 'Select-control', ref: 'control', onKeyDown: this.handleKeyDown, onMouseDown: this.handleMouseDown, onTouchEnd: this.handleMouseDown }, - value, - input, - React.createElement('span', { className: 'Select-arrow-zone', onMouseDown: this.handleMouseDownOnArrow }), - React.createElement('span', { className: 'Select-arrow', onMouseDown: this.handleMouseDownOnArrow }), - loading, - clear - ), - menu - ); - } + displayName: 'Select', + + propTypes: { + addLabelText: React.PropTypes.string, // placeholder displayed when you want to add a label on a multi-value input + allowCreate: React.PropTypes.bool, // whether to allow creation of new entries + asyncOptions: React.PropTypes.func, // function to call to get options + autoload: React.PropTypes.bool, // whether to auto-load the default async options set + backspaceRemoves: React.PropTypes.bool, // whether backspace removes an item if there is no text input + cacheAsyncResults: React.PropTypes.bool, // whether to allow cache + className: React.PropTypes.string, // className for the outer element + clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true + clearValueText: React.PropTypes.string, // title for the "clear" control + clearable: React.PropTypes.bool, // should it be possible to reset value + delimiter: React.PropTypes.string, // delimiter to use to join multiple values + disabled: React.PropTypes.bool, // whether the Select is disabled or not + filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) + filterOptions: React.PropTypes.func, // method to filter the options array: function([options], filterString, [values]) + ignoreCase: React.PropTypes.bool, // whether to perform case-insensitive filtering + inputProps: React.PropTypes.object, // custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} + matchPos: React.PropTypes.string, // (any|start) match the start or entire string when filtering + matchProp: React.PropTypes.string, // (any|label|value) which option property to filter on + multi: React.PropTypes.bool, // multi-value input + name: React.PropTypes.string, // field name, for hidden tag + newOptionCreator: React.PropTypes.func, // factory to create new options when allowCreate set + noResultsText: React.PropTypes.string, // placeholder displayed when there are no matching search results + onBlur: React.PropTypes.func, // onBlur handler: function(event) {} + onChange: React.PropTypes.func, // onChange handler: function(newValue) {} + onOpen: React.PropTypes.func, // fires when the menu is opened + onClose: React.PropTypes.func, // fires when the menu is closed + onFocus: React.PropTypes.func, // onFocus handler: function(event) {} + onOptionLabelClick: React.PropTypes.func, // onCLick handler for value labels: function (value, event) {} + optionComponent: React.PropTypes.func, // option component to render in dropdown + optionRenderer: React.PropTypes.func, // optionRenderer: function(option) {} + options: React.PropTypes.array, // array of options + placeholder: React.PropTypes.string, // field placeholder, displayed when there's no value + searchable: React.PropTypes.bool, // whether to enable searching feature or not + searchPromptText: React.PropTypes.string, // label to prompt for search input + singleValueComponent: React.PropTypes.func, // single value component when multiple is set to false + value: React.PropTypes.any, // initial field value + valueComponent: React.PropTypes.func, // value component to render in multiple mode + valueRenderer: React.PropTypes.func // valueRenderer: function(option) {} + }, + + getDefaultProps: function getDefaultProps() { + return { + addLabelText: 'Add {label} ?', + allowCreate: false, + asyncOptions: undefined, + autoload: true, + backspaceRemoves: true, + cacheAsyncResults: true, + className: undefined, + clearAllText: 'Clear all', + clearValueText: 'Clear value', + clearable: true, + delimiter: ',', + disabled: false, + ignoreCase: true, + inputProps: {}, + matchPos: 'any', + matchProp: 'any', + name: undefined, + newOptionCreator: undefined, + noResultsText: 'No results found', + onChange: undefined, + onOptionLabelClick: undefined, + optionComponent: Option, + options: undefined, + placeholder: 'Select...', + searchable: true, + searchPromptText: 'Type to search', + singleValueComponent: SingleValue, + value: undefined, + valueComponent: Value + }; + }, + + getInitialState: function getInitialState() { + return { + /* + * set by getStateFromValue on componentWillMount: + * - value + * - values + * - filteredOptions + * - inputValue + * - placeholder + * - focusedOption + */ + isFocused: false, + isLoading: false, + isOpen: false, + options: this.props.options + }; + }, + + componentWillMount: function componentWillMount() { + var _this = this; + + this._optionsCache = {}; + this._optionsFilterString = ''; + this._closeMenuIfClickedOutside = function (event) { + if (!_this.state.isOpen) { + return; + } + var menuElem = React.findDOMNode(_this.refs.selectMenuContainer); + var controlElem = React.findDOMNode(_this.refs.control); + + var eventOccuredOutsideMenu = _this.clickedOutsideElement(menuElem, event); + var eventOccuredOutsideControl = _this.clickedOutsideElement(controlElem, event); + + // Hide dropdown menu if click occurred outside of menu + if (eventOccuredOutsideMenu && eventOccuredOutsideControl) { + _this.setState({ + isOpen: false + }, _this._unbindCloseMenuIfClickedOutside); + } + }; + this._bindCloseMenuIfClickedOutside = function () { + if (!document.addEventListener && document.attachEvent) { + document.attachEvent('onclick', this._closeMenuIfClickedOutside); + } else { + document.addEventListener('click', this._closeMenuIfClickedOutside); + } + }; + this._unbindCloseMenuIfClickedOutside = function () { + if (!document.removeEventListener && document.detachEvent) { + document.detachEvent('onclick', this._closeMenuIfClickedOutside); + } else { + document.removeEventListener('click', this._closeMenuIfClickedOutside); + } + }; + this.setState(this.getStateFromValue(this.props.value)); + }, + + componentDidMount: function componentDidMount() { + if (this.props.asyncOptions && this.props.autoload) { + this.autoloadAsyncOptions(); + } + }, + + componentWillUnmount: function componentWillUnmount() { + clearTimeout(this._blurTimeout); + if (this.state.isOpen) { + this._unbindCloseMenuIfClickedOutside(); + } + }, + + componentWillReceiveProps: function componentWillReceiveProps(newProps) { + var _this2 = this; + + var optionsChanged = false; + if (JSON.stringify(newProps.options) !== JSON.stringify(this.props.options)) { + optionsChanged = true; + this.setState({ + options: newProps.options, + filteredOptions: this.filterOptions(newProps.options) + }); + } + if (newProps.value !== this.state.value || newProps.placeholder !== this.props.placeholder || optionsChanged) { + var setState = function setState(newState) { + _this2.setState(_this2.getStateFromValue(newProps.value, newState && newState.options || newProps.options, newProps.placeholder)); + }; + if (this.props.asyncOptions) { + this.loadAsyncOptions(newProps.value, {}, setState); + } else { + setState(); + } + } + }, + + componentWillUpdate: function componentWillUpdate(nextProps, nextState) { + if (nextState.isOpen !== this.state.isOpen) { + var handler = nextState.isOpen ? nextProps.onOpen : nextProps.onClose; + handler && handler(); + } + }, + + componentDidUpdate: function componentDidUpdate() { + if (!this.props.disabled) { + clearTimeout(this._blurTimeout); + } + if (this._focusedOptionReveal) { + if (this.refs.focused && this.refs.menu) { + var focusedDOM = React.findDOMNode(this.refs.focused); + var menuDOM = React.findDOMNode(this.refs.menu); + var focusedRect = focusedDOM.getBoundingClientRect(); + var menuRect = menuDOM.getBoundingClientRect(); + + if (focusedRect.bottom > menuRect.bottom || focusedRect.top < menuRect.top) { + menuDOM.scrollTop = focusedDOM.offsetTop + focusedDOM.clientHeight - menuDOM.offsetHeight; + } + } + this._focusedOptionReveal = false; + } + }, + + focus: function focus() { + this.getInputNode().focus(); + }, + + clickedOutsideElement: function clickedOutsideElement(element, event) { + var eventTarget = event.target ? event.target : event.srcElement; + while (eventTarget != null) { + if (eventTarget === element) { + return false; + } + eventTarget = eventTarget.offsetParent; + } + return true; + }, + + getStateFromValue: function getStateFromValue(value, options, placeholder) { + if (!options) { + options = this.state.options; + } + if (!placeholder) { + placeholder = this.props.placeholder; + } + + // reset internal filter string + this._optionsFilterString = ''; + + var values = this.initValuesArray(value, options); + var filteredOptions = this.filterOptions(options, values); + + var focusedOption; + var valueForState = null; + if (!this.props.multi && values.length) { + focusedOption = values[0]; + valueForState = values[0].value; + } else { + for (var optionIndex = 0; optionIndex < filteredOptions.length; ++optionIndex) { + if (!filteredOptions[optionIndex].disabled) { + focusedOption = filteredOptions[optionIndex]; + break; + } + } + valueForState = values.map(function (v) { + return v.value; + }).join(this.props.delimiter); + } + + return { + value: valueForState, + values: values, + inputValue: '', + filteredOptions: filteredOptions, + placeholder: !this.props.multi && values.length ? values[0].label : placeholder, + focusedOption: focusedOption + }; + }, + + initValuesArray: function initValuesArray(values, options) { + if (!Array.isArray(values)) { + if (typeof values === 'string') { + values = values === '' ? [] : values.split(this.props.delimiter); + } else { + values = values !== undefined && values !== null ? [values] : []; + } + } + return values.map(function (val) { + if (typeof val === 'string' || typeof val === 'number') { + for (var key in options) { + if (options.hasOwnProperty(key) && options[key] && (options[key].value === val || typeof options[key].value === 'number' && options[key].value.toString() === val)) { + return options[key]; + } + } + return { value: val, label: val }; + } else { + return val; + } + }); + }, + + setValue: function setValue(value) { + var newState = this.getStateFromValue(value); + newState.isOpen = false; + this.fireChangeEvent(newState); + this.setState(newState); + }, + + selectValue: function selectValue(value) { + if (!this.props.multi) { + this.setValue(value); + } else if (value) { + this.addValue(value); + } + this._unbindCloseMenuIfClickedOutside(); + }, + + addValue: function addValue(value) { + this.setValue(this.state.values.concat(value)); + }, + + popValue: function popValue() { + this.setValue(this.state.values.slice(0, this.state.values.length - 1)); + }, + + removeValue: function removeValue(valueToRemove) { + this.setValue(this.state.values.filter(function (value) { + return value !== valueToRemove; + })); + }, + + clearValue: function clearValue(event) { + // if the event was triggered by a mousedown and not the primary + // button, ignore it. + if (event && event.type === 'mousedown' && event.button !== 0) { + return; + } + event.stopPropagation(); + event.preventDefault(); + this.setValue(null); + }, + + resetValue: function resetValue() { + this.setValue(this.state.value === '' ? null : this.state.value); + }, + + getInputNode: function getInputNode() { + var input = this.refs.input; + return this.props.searchable ? input : React.findDOMNode(input); + }, + + fireChangeEvent: function fireChangeEvent(newState) { + if (newState.value !== this.state.value && this.props.onChange) { + this.props.onChange(newState.value, newState.values); + } + }, + + handleMouseDown: function handleMouseDown(event) { + // if the event was triggered by a mousedown and not the primary + // button, or if the component is disabled, ignore it. + if (this.props.disabled || event.type === 'mousedown' && event.button !== 0) { + return; + } + event.stopPropagation(); + event.preventDefault(); + + // for the non-searchable select, close the dropdown when button is clicked + if (this.state.isOpen && !this.props.searchable) { + this.setState({ + isOpen: false + }, this._unbindCloseMenuIfClickedOutside); + return; + } + + if (this.state.isFocused) { + this.setState({ + isOpen: true + }, this._bindCloseMenuIfClickedOutside); + } else { + this._openAfterFocus = true; + this.getInputNode().focus(); + } + }, + + handleMouseDownOnArrow: function handleMouseDownOnArrow(event) { + // if the event was triggered by a mousedown and not the primary + // button, or if the component is disabled, ignore it. + if (this.props.disabled || event.type === 'mousedown' && event.button !== 0) { + return; + } + // If not focused, handleMouseDown will handle it + if (!this.state.isOpen) { + return; + } + event.stopPropagation(); + event.preventDefault(); + this.setState({ + isOpen: false + }, this._unbindCloseMenuIfClickedOutside); + }, + + handleInputFocus: function handleInputFocus(event) { + var newIsOpen = this.state.isOpen || this._openAfterFocus; + this.setState({ + isFocused: true, + isOpen: newIsOpen + }, function () { + if (newIsOpen) { + this._bindCloseMenuIfClickedOutside(); + } else { + this._unbindCloseMenuIfClickedOutside(); + } + }); + this._openAfterFocus = false; + if (this.props.onFocus) { + this.props.onFocus(event); + } + }, + + handleInputBlur: function handleInputBlur(event) { + var _this3 = this; + + this._blurTimeout = setTimeout(function () { + _this3.setState({ + isFocused: false, + isOpen: false + }); + }, 50); + if (this.props.onBlur) { + this.props.onBlur(event); + } + }, + + handleKeyDown: function handleKeyDown(event) { + if (this.props.disabled) { + return; + } + switch (event.keyCode) { + case 8: + // backspace + if (!this.state.inputValue && this.props.backspaceRemoves) { + this.popValue(); + } + return; + case 9: + // tab + if (event.shiftKey || !this.state.isOpen || !this.state.focusedOption) { + return; + } + this.selectFocusedOption(); + break; + case 13: + // enter + if (!this.state.isOpen) { + return; + } + + this.selectFocusedOption(); + break; + case 27: + // escape + if (this.state.isOpen) { + this.resetValue(); + } else if (this.props.clearable) { + this.clearValue(event); + } + break; + case 38: + // up + this.focusPreviousOption(); + break; + case 40: + // down + this.focusNextOption(); + break; + case 188: + // , + if (this.props.allowCreate && this.props.multi) { + event.preventDefault(); + event.stopPropagation(); + this.selectFocusedOption(); + } else { + return; + } + break; + default: + return; + } + event.preventDefault(); + }, + + // Ensures that the currently focused option is available in filteredOptions. + // If not, returns the first available option. + _getNewFocusedOption: function _getNewFocusedOption(filteredOptions) { + for (var key in filteredOptions) { + if (filteredOptions.hasOwnProperty(key) && filteredOptions[key] === this.state.focusedOption) { + return filteredOptions[key]; + } + } + return filteredOptions[0]; + }, + + handleInputChange: function handleInputChange(event) { + // assign an internal variable because we need to use + // the latest value before setState() has completed. + this._optionsFilterString = event.target.value; + + if (this.props.asyncOptions) { + this.setState({ + isLoading: true, + inputValue: event.target.value + }); + this.loadAsyncOptions(event.target.value, { + isLoading: false, + isOpen: true + }, this._bindCloseMenuIfClickedOutside); + } else { + var filteredOptions = this.filterOptions(this.state.options); + this.setState({ + isOpen: true, + inputValue: event.target.value, + filteredOptions: filteredOptions, + focusedOption: this._getNewFocusedOption(filteredOptions) + }, this._bindCloseMenuIfClickedOutside); + } + }, + + autoloadAsyncOptions: function autoloadAsyncOptions() { + var _this4 = this; + + this.loadAsyncOptions(this.props.value || '', {}, function () { + // update with fetched but don't focus + _this4.setValue(_this4.props.value, false); + }); + }, + + loadAsyncOptions: function loadAsyncOptions(input, state, callback) { + var _this5 = this; + + var thisRequestId = this._currentRequestId = requestId++; + if (this.props.cacheAsyncResults) { + for (var i = 0; i <= input.length; i++) { + var cacheKey = input.slice(0, i); + if (this._optionsCache[cacheKey] && (input === cacheKey || this._optionsCache[cacheKey].complete)) { + var options = this._optionsCache[cacheKey].options; + var filteredOptions = this.filterOptions(options); + var newState = { + options: options, + filteredOptions: filteredOptions, + focusedOption: this._getNewFocusedOption(filteredOptions) + }; + for (var key in state) { + if (state.hasOwnProperty(key)) { + newState[key] = state[key]; + } + } + this.setState(newState); + if (callback) { + callback.call(this, newState); + } + return; + } + } + } + + this.props.asyncOptions(input, function (err, data) { + if (err) { + throw err; + } + if (_this5.props.cacheAsyncResults) { + _this5._optionsCache[input] = data; + } + if (thisRequestId !== _this5._currentRequestId) { + return; + } + var filteredOptions = _this5.filterOptions(data.options); + var newState = { + options: data.options, + filteredOptions: filteredOptions, + focusedOption: _this5._getNewFocusedOption(filteredOptions) + }; + for (var key in state) { + if (state.hasOwnProperty(key)) { + newState[key] = state[key]; + } + } + _this5.setState(newState); + if (callback) { + callback.call(_this5, newState); + } + }); + }, + + filterOptions: function filterOptions(options, values) { + var filterValue = this._optionsFilterString; + var exclude = (values || this.state.values).map(function (i) { + return i.value; + }); + if (this.props.filterOptions) { + return this.props.filterOptions.call(this, options, filterValue, exclude); + } else { + var filterOption = function filterOption(op) { + if (this.props.multi && exclude.indexOf(op.value) > -1) { + return false; + } + if (this.props.filterOption) { + return this.props.filterOption.call(this, op, filterValue); + } + var valueTest = String(op.value), + labelTest = String(op.label); + if (this.props.ignoreCase) { + valueTest = valueTest.toLowerCase(); + labelTest = labelTest.toLowerCase(); + filterValue = filterValue.toLowerCase(); + } + return !filterValue || this.props.matchPos === 'start' ? this.props.matchProp !== 'label' && valueTest.substr(0, filterValue.length) === filterValue || this.props.matchProp !== 'value' && labelTest.substr(0, filterValue.length) === filterValue : this.props.matchProp !== 'label' && valueTest.indexOf(filterValue) >= 0 || this.props.matchProp !== 'value' && labelTest.indexOf(filterValue) >= 0; + }; + return (options || []).filter(filterOption, this); + } + }, + + selectFocusedOption: function selectFocusedOption() { + if (this.props.allowCreate && !this.state.focusedOption) { + return this.selectValue(this.state.inputValue); + } + return this.selectValue(this.state.focusedOption); + }, + + focusOption: function focusOption(op) { + this.setState({ + focusedOption: op + }); + }, + + focusNextOption: function focusNextOption() { + this.focusAdjacentOption('next'); + }, + + focusPreviousOption: function focusPreviousOption() { + this.focusAdjacentOption('previous'); + }, + + focusAdjacentOption: function focusAdjacentOption(dir) { + this._focusedOptionReveal = true; + var ops = this.state.filteredOptions.filter(function (op) { + return !op.disabled; + }); + if (!this.state.isOpen) { + this.setState({ + isOpen: true, + inputValue: '', + focusedOption: this.state.focusedOption || ops[dir === 'next' ? 0 : ops.length - 1] + }, this._bindCloseMenuIfClickedOutside); + return; + } + if (!ops.length) { + return; + } + var focusedIndex = -1; + for (var i = 0; i < ops.length; i++) { + if (this.state.focusedOption === ops[i]) { + focusedIndex = i; + break; + } + } + var focusedOption = ops[0]; + if (dir === 'next' && focusedIndex > -1 && focusedIndex < ops.length - 1) { + focusedOption = ops[focusedIndex + 1]; + } else if (dir === 'previous') { + if (focusedIndex > 0) { + focusedOption = ops[focusedIndex - 1]; + } else { + focusedOption = ops[ops.length - 1]; + } + } + this.setState({ + focusedOption: focusedOption + }); + }, + + unfocusOption: function unfocusOption(op) { + if (this.state.focusedOption === op) { + this.setState({ + focusedOption: null + }); + } + }, + + buildMenu: function buildMenu() { + var focusedValue = this.state.focusedOption ? this.state.focusedOption.value : null; + var renderLabel = this.props.optionRenderer || function (op) { + return op.label; + }; + if (this.state.filteredOptions.length > 0) { + focusedValue = focusedValue == null ? this.state.filteredOptions[0] : focusedValue; + } + // Add the current value to the filtered options in last resort + var options = this.state.filteredOptions; + if (this.props.allowCreate && this.state.inputValue.trim()) { + var inputValue = this.state.inputValue; + options = options.slice(); + var newOption = this.props.newOptionCreator ? this.props.newOptionCreator(inputValue) : { + value: inputValue, + label: inputValue, + create: true + }; + options.unshift(newOption); + } + var ops = Object.keys(options).map(function (key) { + var op = options[key]; + var isSelected = this.state.value === op.value; + var isFocused = focusedValue === op.value; + var optionClass = classes({ + 'Select-option': true, + 'is-selected': isSelected, + 'is-focused': isFocused, + 'is-disabled': op.disabled + }); + var ref = isFocused ? 'focused' : null; + var mouseEnter = this.focusOption.bind(this, op); + var mouseLeave = this.unfocusOption.bind(this, op); + var mouseDown = this.selectValue.bind(this, op); + var optionResult = React.createElement(this.props.optionComponent, { + key: 'option-' + op.value, + className: optionClass, + renderFunc: renderLabel, + mouseEnter: mouseEnter, + mouseLeave: mouseLeave, + mouseDown: mouseDown, + click: mouseDown, + addLabelText: this.props.addLabelText, + option: op, + ref: ref + }); + return optionResult; + }, this); + return ops.length ? ops : React.createElement( + 'div', + { className: 'Select-noresults' }, + this.props.asyncOptions && !this.state.inputValue ? this.props.searchPromptText : this.props.noResultsText + ); + }, + + handleOptionLabelClick: function handleOptionLabelClick(value, event) { + if (this.props.onOptionLabelClick) { + this.props.onOptionLabelClick(value, event); + } + }, + + render: function render() { + var selectClass = classes('Select', this.props.className, { + 'is-multi': this.props.multi, + 'is-searchable': this.props.searchable, + 'is-open': this.state.isOpen, + 'is-focused': this.state.isFocused, + 'is-loading': this.state.isLoading, + 'is-disabled': this.props.disabled, + 'has-value': this.state.value + }); + var value = []; + if (this.props.multi) { + this.state.values.forEach(function (val) { + var onOptionLabelClick = this.handleOptionLabelClick.bind(this, val); + var onRemove = this.removeValue.bind(this, val); + var valueComponent = React.createElement(this.props.valueComponent, { + key: val.value, + option: val, + renderer: this.props.valueRenderer, + optionLabelClick: !!this.props.onOptionLabelClick, + onOptionLabelClick: onOptionLabelClick, + onRemove: onRemove, + disabled: this.props.disabled + }); + value.push(valueComponent); + }, this); + } + + if (!this.state.inputValue && (!this.props.multi || !value.length)) { + var val = this.state.values[0] || null; + if (this.props.valueRenderer && !!this.state.values.length) { + value.push(React.createElement(Value, { + key: 0, + option: val, + renderer: this.props.valueRenderer, + disabled: this.props.disabled })); + } else { + var singleValueComponent = React.createElement(this.props.singleValueComponent, { + key: 'placeholder', + value: val, + placeholder: this.state.placeholder + }); + value.push(singleValueComponent); + } + } + + var loading = this.state.isLoading ? React.createElement('span', { className: 'Select-loading', 'aria-hidden': 'true' }) : null; + var clear = this.props.clearable && this.state.value && !this.props.disabled ? React.createElement('span', { className: 'Select-clear', + title: this.props.multi ? this.props.clearAllText : this.props.clearValueText, + 'aria-label': this.props.multi ? this.props.clearAllText : this.props.clearValueText, + onMouseDown: this.clearValue, + onClick: this.clearValue, + dangerouslySetInnerHTML: { __html: '×' } }) : null; + + var menu; + var menuProps; + if (this.state.isOpen) { + menuProps = { + ref: 'menu', + className: 'Select-menu' + }; + if (this.props.multi) { + menuProps.onMouseDown = this.handleMouseDown; + } + menu = React.createElement( + 'div', + { ref: 'selectMenuContainer', className: 'Select-menu-outer' }, + React.createElement( + 'div', + menuProps, + this.buildMenu() + ) + ); + } + + var input; + var inputProps = { + ref: 'input', + className: 'Select-input ' + (this.props.inputProps.className || ''), + tabIndex: this.props.tabIndex || 0, + onFocus: this.handleInputFocus, + onBlur: this.handleInputBlur + }; + for (var key in this.props.inputProps) { + if (this.props.inputProps.hasOwnProperty(key) && key !== 'className') { + inputProps[key] = this.props.inputProps[key]; + } + } + + if (!this.props.disabled) { + if (this.props.searchable) { + input = React.createElement(Input, _extends({ value: this.state.inputValue, onChange: this.handleInputChange, + minWidth: '5' }, inputProps)); + } else { + input = React.createElement( + 'div', + inputProps, + ' ' + ); + } + } else if (!this.props.multi || !this.state.values.length) { + input = React.createElement( + 'div', + { className: 'Select-input' }, + ' ' + ); + } + + return React.createElement( + 'div', + { ref: 'wrapper', className: selectClass }, + React.createElement('input', { type: 'hidden', ref: 'value', name: this.props.name, value: this.state.value, + disabled: this.props.disabled }), + React.createElement( + 'div', + { className: 'Select-control', ref: 'control', onKeyDown: this.handleKeyDown, + onMouseDown: this.handleMouseDown, onTouchEnd: this.handleMouseDown }, + value, + input, + React.createElement('span', { className: 'Select-arrow-zone', onMouseDown: this.handleMouseDownOnArrow }), + React.createElement('span', { className: 'Select-arrow', onMouseDown: this.handleMouseDownOnArrow }), + loading, + clear + ), + menu + ); + } }); module.exports = Select; -},{"./Option":1,"./SingleValue":2,"./Value":3,"classnames":undefined,"react":undefined,"react-input-autosize":undefined}]},{},[]); +},{"./Option":1,"./SingleValue":2,"./Value":3,"classnames":undefined,"react":undefined,"react-input-autosize":undefined}]},{},[]) +//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvcGF0cmlja21ja2VsdnkvRG9jdW1lbnRzL3dvcmsvcmVhY3Qtc2VsZWN0L3NyYy9PcHRpb24uanMiLCIvVXNlcnMvcGF0cmlja21ja2VsdnkvRG9jdW1lbnRzL3dvcmsvcmVhY3Qtc2VsZWN0L3NyYy9TaW5nbGVWYWx1ZS5qcyIsIi9Vc2Vycy9wYXRyaWNrbWNrZWx2eS9Eb2N1bWVudHMvd29yay9yZWFjdC1zZWxlY3Qvc3JjL1ZhbHVlLmpzIiwiL1VzZXJzL3BhdHJpY2ttY2tlbHZ5L0RvY3VtZW50cy93b3JrL3JlYWN0LXNlbGVjdC9zcmMvU2VsZWN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7QUNBQSxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRTdCLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7OztBQUM5QixVQUFTLEVBQUU7QUFDVixjQUFZLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNO0FBQ3BDLFdBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU07QUFDakMsV0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSTtBQUMvQixZQUFVLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJO0FBQ2hDLFlBQVUsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUk7QUFDaEMsUUFBTSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVU7QUFDekMsWUFBVSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSTtFQUNoQzs7QUFFRCxPQUFNLEVBQUUsa0JBQVc7QUFDbEIsTUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7QUFDNUIsTUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxD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LFdBQVcsQUFBQztZQUMxQywrQkFBTyxJQUFJLEVBQUcsUUFBUSxFQUFDLEdBQUcsRUFBRyxPQUFPLEVBQUMsSUFBSSxFQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxBQUFDLEVBQUMsS0FBSyxFQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxBQUFDO0FBQ2pGLHdCQUFRLEVBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEFBQUMsR0FBRTtZQUN6Qzs7a0JBQUssU0FBUyxFQUFHLGdCQUFnQixFQUFDLEdBQUcsRUFBRyxTQUFTLEVBQUMsU0FBUyxFQUFJLElBQUksQ0FBQyxhQUFhLEFBQUM7QUFDN0UsK0JBQVcsRUFBSSxJQUFJLENBQUMsZUFBZSxBQUFDLEVBQUMsVUFBVSxFQUFJLElBQUksQ0FBQyxlQUFlLEFBQUM7Z0JBQ3hFLEtBQUs7Z0JBQ0wsS0FBSztnQkFDTiw4QkFBTSxTQUFTLEVBQUcsbUJBQW1CLEVBQUMsV0FBVyxFQUFJLElBQUksQ0FBQyxzQkFBc0IsQUFBQyxHQUFFO2dCQUNuRiw4QkFBTSxTQUFTLEVBQUcsY0FBYyxFQUFDLFdBQVcsRUFBSSxJQUFJLENBQUMsc0JBQXNCLEFBQUMsR0FBRTtnQkFDN0UsT0FBTztnQkFDUCxLQUFLO2FBQ0o7WUFDTCxJQUFJO1NBQ0gsQ0FDUjtLQUNMOztDQUVKLENBQUMsQ0FBQzs7QUFFSCxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJ2YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgT3B0aW9uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRwcm9wVHlwZXM6IHtcblx0XHRhZGRMYWJlbFRleHQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAgICAgICAgIC8vIHN0cmluZyByZW5kZXJlZCBpbiBjYXNlIG9mIGFsbG93Q3JlYXRlIG9wdGlvbiBwYXNzZWQgdG8gUmVhY3RTZWxlY3Rcblx0XHRjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAgICAgICAgICAgIC8vIGNsYXNzTmFtZSAoYmFzZWQgb24gbW91c2UgcG9zaXRpb24pXG5cdFx0bW91c2VEb3duOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAgICAgICAvLyBtZXRob2QgdG8gaGFuZGxlIGNsaWNrIG9uIG9wdGlvbiBlbGVtZW50XG5cdFx0bW91c2VFbnRlcjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsICAgICAgICAgICAgICAvLyBtZXRob2QgdG8gaGFuZGxlIG1vdXNlRW50ZXIgb24gb3B0aW9uIGVsZW1lbnRcblx0XHRtb3VzZUxlYXZlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAgICAgIC8vIG1ldGhvZCB0byBoYW5kbGUgbW91c2VMZWF2ZSBvbiBvcHRpb24gZWxlbWVudFxuXHRcdG9wdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLCAgICAgLy8gb2JqZWN0IHRoYXQgaXMgYmFzZSBmb3IgdGhhdCBvcHRpb25cblx0XHRyZW5kZXJGdW5jOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyAgICAgICAgICAgICAgIC8vIG1ldGhvZCBwYXNzZWQgdG8gUmVhY3RTZWxlY3QgY29tcG9uZW50IHRvIHJlbmRlciBsYWJlbCB0ZXh0XG5cdH0sXG5cblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgb2JqID0gdGhpcy5wcm9wcy5vcHRpb247XG5cdFx0dmFyIHJlbmRlcmVkTGFiZWwgPSB0aGlzLnByb3BzLnJlbmRlckZ1bmMob2JqKTtcblxuXHRcdHJldHVybiBvYmouZGlzYWJsZWQgPyAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT17dGhpcy5wcm9wcy5jbGFzc05hbWV9PntyZW5kZXJlZExhYmVsfTwvZGl2PlxuXHRcdCkgOiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT17dGhpcy5wcm9wcy5jbGFzc05hbWV9XG5cdFx0XHRcdG9uTW91c2VFbnRlcj17dGhpcy5wcm9wcy5tb3VzZUVudGVyfVxuXHRcdFx0XHRvbk1vdXNlTGVhdmU9e3RoaXMucHJvcHMubW91c2VMZWF2ZX1cblx0XHRcdFx0b25Nb3VzZURvd249e3RoaXMucHJvcHMubW91c2VEb3dufVxuXHRcdFx0XHRvbkNsaWNrPXt0aGlzLnByb3BzLm1vdXNlRG93bn0+XG5cdFx0XHRcdHsgb2JqLmNyZWF0ZSA/IHRoaXMucHJvcHMuYWRkTGFiZWxUZXh0LnJlcGxhY2UoJ3tsYWJlbH0nLCBvYmoubGFiZWwpIDogcmVuZGVyZWRMYWJlbCB9XG5cdFx0XHQ8L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBPcHRpb247XG4iLCJ2YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgU2luZ2xlVmFsdWUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHByb3BUeXBlczoge1xuXHRcdHBsYWNlaG9sZGVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgICAvLyB0aGlzIGlzIGRlZmF1bHQgdmFsdWUgcHJvdmlkZWQgYnkgUmVhY3QtU2VsZWN0IGJhc2VkIGNvbXBvbmVudFxuXHRcdHZhbHVlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0ICAgICAgICAgICAgICAvLyBzZWxlY3RlZCBvcHRpb25cblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJTZWxlY3QtcGxhY2Vob2xkZXJcIj57dGhpcy5wcm9wcy5wbGFjZWhvbGRlcn08L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBTaW5nbGVWYWx1ZTtcbiIsInZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBWYWx1ZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblxuXHRkaXNwbGF5TmFtZTogJ1ZhbHVlJyxcblxuXHRwcm9wVHlwZXM6IHtcblx0XHRkaXNhYmxlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsICAgICAgICAgICAgICAgICAgIC8vIGRpc2FibGVkIHByb3AgcGFzc2VkIHRvIFJlYWN0U2VsZWN0XG5cdFx0b25PcHRpb25MYWJlbENsaWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAvLyBtZXRob2QgdG8gaGFuZGxlIGNsaWNrIG9uIHZhbHVlIGxhYmVsXG5cdFx0b25SZW1vdmU6IFJlYWN0LlByb3BUeXBlcy5mdW5jLCAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QgdG8gaGFuZGxlIHJlbW92ZSBvZiB0aGF0IHZhbHVlXG5cdFx0b3B0aW9uOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsICAgICAgICAvLyBvcHRpb24gcGFzc2VkIHRvIGNvbXBvbmVudFxuXHRcdG9wdGlvbkxhYmVsQ2xpY2s6IFJlYWN0LlByb3BUeXBlcy5ib29sLCAgICAgICAgICAgLy8gaW5kaWNhdGVzIGlmIG9uT3B0aW9uTGFiZWxDbGljayBzaG91bGQgYmUgaGFuZGxlZFxuXHRcdHJlbmRlcmVyOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kIHRvIHJlbmRlciBvcHRpb24gbGFiZWwgcGFzc2VkIHRvIFJlYWN0U2VsZWN0XG5cdH0sXG5cblx0YmxvY2tFdmVudDogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0fSxcblxuXHRoYW5kbGVPblJlbW92ZTogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMucHJvcHMuZGlzYWJsZWQpIHtcblx0XHRcdHRoaXMucHJvcHMub25SZW1vdmUoZXZlbnQpO1xuXHRcdH1cblx0fSxcblxuXHRyZW5kZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBsYWJlbCA9IHRoaXMucHJvcHMub3B0aW9uLmxhYmVsO1xuXHRcdGlmICh0aGlzLnByb3BzLnJlbmRlcmVyKSB7XG5cdFx0XHRsYWJlbCA9IHRoaXMucHJvcHMucmVuZGVyZXIodGhpcy5wcm9wcy5vcHRpb24pO1xuXHRcdH1cblxuXHRcdGlmKCF0aGlzLnByb3BzLm9uUmVtb3ZlICYmICF0aGlzLnByb3BzLm9wdGlvbkxhYmVsQ2xpY2spIHtcblx0XHRcdHJldHVybiA8ZGl2IGNsYXNzTmFtZT1cIlNlbGVjdC12YWx1ZVwiPntsYWJlbH08L2Rpdj47XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMucHJvcHMub3B0aW9uTGFiZWxDbGljaykge1xuXHRcdFx0bGFiZWwgPSAoXG5cdFx0XHRcdDxhIGNsYXNzTmFtZT1cIlNlbGVjdC1pdGVtLWxhYmVsX19hXCJcblx0XHRcdFx0XHRvbk1vdXNlRG93bj17dGhpcy5ibG9ja0V2ZW50fVxuXHRcdFx0XHRcdG9uVG91Y2hFbmQ9e3RoaXMucHJvcHMub25PcHRpb25MYWJlbENsaWNrfVxuXHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMucHJvcHMub25PcHRpb25MYWJlbENsaWNrfT5cblx0XHRcdFx0XHR7bGFiZWx9XG5cdFx0XHRcdDwvYT5cblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIChcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiU2VsZWN0LWl0ZW1cIj5cblx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiU2VsZWN0LWl0ZW0taWNvblwiXG5cdFx0XHRcdFx0b25Nb3VzZURvd249e3RoaXMuYmxvY2tFdmVudH1cblx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLmhhbmRsZU9uUmVtb3ZlfVxuXHRcdFx0XHRcdG9uVG91Y2hFbmQ9e3RoaXMuaGFuZGxlT25SZW1vdmV9PiZ0aW1lczs8L3NwYW4+XG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cIlNlbGVjdC1pdGVtLWxhYmVsXCI+e2xhYmVsfTwvc3Bhbj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cblxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmFsdWU7XG4iLCIvKiBkaXNhYmxlIHNvbWUgcnVsZXMgdW50aWwgd2UgcmVmYWN0b3IgbW9yZSBjb21wbGV0ZWx5OyBmaXhpbmcgdGhlbSBub3cgd291bGRcbiBjYXVzZSBjb25mbGljdHMgd2l0aCBzb21lIG9wZW4gUFJzIHVubmVjZXNzYXJpbHkuICovXG4vKiBlc2xpbnQgcmVhY3QvanN4LXNvcnQtcHJvcC10eXBlczogMCwgcmVhY3Qvc29ydC1jb21wOiAwLCByZWFjdC9wcm9wLXR5cGVzOiAwICovXG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgSW5wdXQgPSByZXF1aXJlKCdyZWFjdC1pbnB1dC1hdXRvc2l6ZScpO1xudmFyIGNsYXNzZXMgPSByZXF1aXJlKCdjbGFzc25hbWVzJyk7XG52YXIgVmFsdWUgPSByZXF1aXJlKCcuL1ZhbHVlJyk7XG52YXIgU2luZ2xlVmFsdWUgPSByZXF1aXJlKCcuL1NpbmdsZVZhbHVlJyk7XG52YXIgT3B0aW9uID0gcmVxdWlyZSgnLi9PcHRpb24nKTtcblxudmFyIHJlcXVlc3RJZCA9IDA7XG5cbnZhciBTZWxlY3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cbiAgICBkaXNwbGF5TmFtZTogJ1NlbGVjdCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgYWRkTGFiZWxUZXh0OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgIC8vIHBsYWNlaG9sZGVyIGRpc3BsYXllZCB3aGVuIHlvdSB3YW50IHRvIGFkZCBhIGxhYmVsIG9uIGEgbXVsdGktdmFsdWUgaW5wdXRcbiAgICAgICAgYWxsb3dDcmVhdGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLCAgICAgICAgIC8vIHdoZXRoZXIgdG8gYWxsb3cgY3JlYXRpb24gb2YgbmV3IGVudHJpZXNcbiAgICAgICAgYXN5bmNPcHRpb25zOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgIC8vIGZ1bmN0aW9uIHRvIGNhbGwgdG8gZ2V0IG9wdGlvbnNcbiAgICAgICAgYXV0b2xvYWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLCAgICAgICAgICAgIC8vIHdoZXRoZXIgdG8gYXV0by1sb2FkIHRoZSBkZWZhdWx0IGFzeW5jIG9wdGlvbnMgc2V0XG4gICAgICAgIGJhY2tzcGFjZVJlbW92ZXM6IFJlYWN0LlByb3BUeXBlcy5ib29sLCAgICAvLyB3aGV0aGVyIGJhY2tzcGFjZSByZW1vdmVzIGFuIGl0ZW0gaWYgdGhlcmUgaXMgbm8gdGV4dCBpbnB1dFxuICAgICAgICBjYWNoZUFzeW5jUmVzdWx0czogUmVhY3QuUHJvcFR5cGVzLmJvb2wsICAgLy8gd2hldGhlciB0byBhbGxvdyBjYWNoZVxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAgICAgICAgLy8gY2xhc3NOYW1lIGZvciB0aGUgb3V0ZXIgZWxlbWVudFxuICAgICAgICBjbGVhckFsbFRleHQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAgICAgLy8gdGl0bGUgZm9yIHRoZSBcImNsZWFyXCIgY29udHJvbCB3aGVuIG11bHRpOiB0cnVlXG4gICAgICAgIGNsZWFyVmFsdWVUZXh0OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAvLyB0aXRsZSBmb3IgdGhlIFwiY2xlYXJcIiBjb250cm9sXG4gICAgICAgIGNsZWFyYWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsICAgICAgICAgICAvLyBzaG91bGQgaXQgYmUgcG9zc2libGUgdG8gcmVzZXQgdmFsdWVcbiAgICAgICAgZGVsaW1pdGVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgICAgIC8vIGRlbGltaXRlciB0byB1c2UgdG8gam9pbiBtdWx0aXBsZSB2YWx1ZXNcbiAgICAgICAgZGlzYWJsZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLCAgICAgICAgICAgIC8vIHdoZXRoZXIgdGhlIFNlbGVjdCBpcyBkaXNhYmxlZCBvciBub3RcbiAgICAgICAgZmlsdGVyT3B0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgIC8vIG1ldGhvZCB0byBmaWx0ZXIgYSBzaW5nbGUgb3B0aW9uOiBmdW5jdGlvbihvcHRpb24sIGZpbHRlclN0cmluZylcbiAgICAgICAgZmlsdGVyT3B0aW9uczogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsICAgICAgIC8vIG1ldGhvZCB0byBmaWx0ZXIgdGhlIG9wdGlvbnMgYXJyYXk6IGZ1bmN0aW9uKFtvcHRpb25zXSwgZmlsdGVyU3RyaW5nLCBbdmFsdWVzXSlcbiAgICAgICAgaWdub3JlQ2FzZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsICAgICAgICAgIC8vIHdoZXRoZXIgdG8gcGVyZm9ybSBjYXNlLWluc2Vuc2l0aXZlIGZpbHRlcmluZ1xuICAgICAgICBpbnB1dFByb3BzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LCAgICAgICAgLy8gY3VzdG9tIGF0dHJpYnV0ZXMgZm9yIHRoZSBJbnB1dCAoaW4gdGhlIFNlbGVjdC1jb250cm9sKSBlLmc6IHsnZGF0YS1mb28nOiAnYmFyJ31cbiAgICAgICAgbWF0Y2hQb3M6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAgICAgICAgIC8vIChhbnl8c3RhcnQpIG1hdGNoIHRoZSBzdGFydCBvciBlbnRpcmUgc3RyaW5nIHdoZW4gZmlsdGVyaW5nXG4gICAgICAgIG1hdGNoUHJvcDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZywgICAgICAgICAvLyAoYW55fGxhYmVsfHZhbHVlKSB3aGljaCBvcHRpb24gcHJvcGVydHkgdG8gZmlsdGVyIG9uXG4gICAgICAgIG11bHRpOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCwgICAgICAgICAgICAgICAvLyBtdWx0aS12YWx1ZSBpbnB1dFxuICAgICAgICBuYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgICAgICAgICAgLy8gZmllbGQgbmFtZSwgZm9yIGhpZGRlbiA8aW5wdXQgLz4gdGFnXG4gICAgICAgIG5ld09wdGlvbkNyZWF0b3I6IFJlYWN0LlByb3BUeXBlcy5mdW5jLCAgICAvLyBmYWN0b3J5IHRvIGNyZWF0ZSBuZXcgb3B0aW9ucyB3aGVuIGFsbG93Q3JlYXRlIHNldFxuICAgICAgICBub1Jlc3VsdHNUZXh0OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgLy8gcGxhY2Vob2xkZXIgZGlzcGxheWVkIHdoZW4gdGhlcmUgYXJlIG5vIG1hdGNoaW5nIHNlYXJjaCByZXN1bHRzXG4gICAgICAgIG9uQmx1cjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsICAgICAgICAgICAgICAvLyBvbkJsdXIgaGFuZGxlcjogZnVuY3Rpb24oZXZlbnQpIHt9XG4gICAgICAgIG9uQ2hhbmdlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAgICAvLyBvbkNoYW5nZSBoYW5kbGVyOiBmdW5jdGlvbihuZXdWYWx1ZSkge31cbiAgICAgICAgb25PcGVuOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAgICAgIC8vIGZpcmVzIHdoZW4gdGhlIG1lbnUgaXMgb3BlbmVkXG4gICAgICAgIG9uQ2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLCAgICAgICAgICAgICAvLyBmaXJlcyB3aGVuIHRoZSBtZW51IGlzIGNsb3NlZFxuICAgICAgICBvbkZvY3VzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgICAgICAgICAgICAgLy8gb25Gb2N1cyBoYW5kbGVyOiBmdW5jdGlvbihldmVudCkge31cbiAgICAgICAgb25PcHRpb25MYWJlbENsaWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYywgIC8vIG9uQ0xpY2sgaGFuZGxlciBmb3IgdmFsdWUgbGFiZWxzOiBmdW5jdGlvbiAodmFsdWUsIGV2ZW50KSB7fVxuICAgICAgICBvcHRpb25Db21wb25lbnQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLCAgICAgLy8gb3B0aW9uIGNvbXBvbmVudCB0byByZW5kZXIgaW4gZHJvcGRvd25cbiAgICAgICAgb3B0aW9uUmVuZGVyZXI6IFJlYWN0LlByb3BUeXBlcy5mdW5jLCAgICAgIC8vIG9wdGlvblJlbmRlcmVyOiBmdW5jdGlvbihvcHRpb24pIHt9XG4gICAgICAgIG9wdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSwgICAgICAgICAgICAvLyBhcnJheSBvZiBvcHRpb25zXG4gICAgICAgIHBsYWNlaG9sZGVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCAgICAgICAvLyBmaWVsZCBwbGFjZWhvbGRlciwgZGlzcGxheWVkIHdoZW4gdGhlcmUncyBubyB2YWx1ZVxuICAgICAgICBzZWFyY2hhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCwgICAgICAgICAgLy8gd2hldGhlciB0byBlbmFibGUgc2VhcmNoaW5nIGZlYXR1cmUgb3Igbm90XG4gICAgICAgIHNlYXJjaFByb21wdFRleHQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsICAvLyBsYWJlbCB0byBwcm9tcHQgZm9yIHNlYXJjaCBpbnB1dFxuICAgICAgICBzaW5nbGVWYWx1ZUNvbXBvbmVudDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsLy8gc2luZ2xlIHZhbHVlIGNvbXBvbmVudCB3aGVuIG11bHRpcGxlIGlzIHNldCB0byBmYWxzZVxuICAgICAgICB2YWx1ZTogUmVhY3QuUHJvcFR5cGVzLmFueSwgICAgICAgICAgICAgICAgLy8gaW5pdGlhbCBmaWVsZCB2YWx1ZVxuICAgICAgICB2YWx1ZUNvbXBvbmVudDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsICAgICAgLy8gdmFsdWUgY29tcG9uZW50IHRvIHJlbmRlciBpbiBtdWx0aXBsZSBtb2RlXG4gICAgICAgIHZhbHVlUmVuZGVyZXI6IFJlYWN0LlByb3BUeXBlcy5mdW5jICAgICAgICAvLyB2YWx1ZVJlbmRlcmVyOiBmdW5jdGlvbihvcHRpb24pIHt9XG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWRkTGFiZWxUZXh0OiAnQWRkIHtsYWJlbH0gPycsXG4gICAgICAgICAgICBhbGxvd0NyZWF0ZTogZmFsc2UsXG4gICAgICAgICAgICBhc3luY09wdGlvbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGF1dG9sb2FkOiB0cnVlLFxuICAgICAgICAgICAgYmFja3NwYWNlUmVtb3ZlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhY2hlQXN5bmNSZXN1bHRzOiB0cnVlLFxuICAgICAgICAgICAgY2xhc3NOYW1lOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBjbGVhckFsbFRleHQ6ICdDbGVhciBhbGwnLFxuICAgICAgICAgICAgY2xlYXJWYWx1ZVRleHQ6ICdDbGVhciB2YWx1ZScsXG4gICAgICAgICAgICBjbGVhcmFibGU6IHRydWUsXG4gICAgICAgICAgICBkZWxpbWl0ZXI6ICcsJyxcbiAgICAgICAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICAgICAgICAgIGlnbm9yZUNhc2U6IHRydWUsXG4gICAgICAgICAgICBpbnB1dFByb3BzOiB7fSxcbiAgICAgICAgICAgIG1hdGNoUG9zOiAnYW55JyxcbiAgICAgICAgICAgIG1hdGNoUHJvcDogJ2FueScsXG4gICAgICAgICAgICBuYW1lOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdPcHRpb25DcmVhdG9yOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBub1Jlc3VsdHNUZXh0OiAnTm8gcmVzdWx0cyBmb3VuZCcsXG4gICAgICAgICAgICBvbkNoYW5nZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25PcHRpb25MYWJlbENsaWNrOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBvcHRpb25Db21wb25lbnQ6IE9wdGlvbixcbiAgICAgICAgICAgIG9wdGlvbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0Li4uJyxcbiAgICAgICAgICAgIHNlYXJjaGFibGU6IHRydWUsXG4gICAgICAgICAgICBzZWFyY2hQcm9tcHRUZXh0OiAnVHlwZSB0byBzZWFyY2gnLFxuICAgICAgICAgICAgc2luZ2xlVmFsdWVDb21wb25lbnQ6IFNpbmdsZVZhbHVlLFxuICAgICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHZhbHVlQ29tcG9uZW50OiBWYWx1ZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBzZXQgYnkgZ2V0U3RhdGVGcm9tVmFsdWUgb24gY29tcG9uZW50V2lsbE1vdW50OlxuICAgICAgICAgICAgICogLSB2YWx1ZVxuICAgICAgICAgICAgICogLSB2YWx1ZXNcbiAgICAgICAgICAgICAqIC0gZmlsdGVyZWRPcHRpb25zXG4gICAgICAgICAgICAgKiAtIGlucHV0VmFsdWVcbiAgICAgICAgICAgICAqIC0gcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAqIC0gZm9jdXNlZE9wdGlvblxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpc0ZvY3VzZWQ6IGZhbHNlLFxuICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGlzT3BlbjogZmFsc2UsXG4gICAgICAgICAgICBvcHRpb25zOiB0aGlzLnByb3BzLm9wdGlvbnNcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX29wdGlvbnNDYWNoZSA9IHt9O1xuICAgICAgICB0aGlzLl9vcHRpb25zRmlsdGVyU3RyaW5nID0gJyc7XG4gICAgICAgIHRoaXMuX2Nsb3NlTWVudUlmQ2xpY2tlZE91dHNpZGUgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5pc09wZW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbWVudUVsZW0gPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuc2VsZWN0TWVudUNvbnRhaW5lcik7XG4gICAgICAgICAgICB2YXIgY29udHJvbEVsZW0gPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuY29udHJvbCk7XG5cbiAgICAgICAgICAgIHZhciBldmVudE9jY3VyZWRPdXRzaWRlTWVudSA9IHRoaXMuY2xpY2tlZE91dHNpZGVFbGVtZW50KG1lbnVFbGVtLCBldmVudCk7XG4gICAgICAgICAgICB2YXIgZXZlbnRPY2N1cmVkT3V0c2lkZUNvbnRyb2wgPSB0aGlzLmNsaWNrZWRPdXRzaWRlRWxlbWVudChjb250cm9sRWxlbSwgZXZlbnQpO1xuXG4gICAgICAgICAgICAvLyBIaWRlIGRyb3Bkb3duIG1lbnUgaWYgY2xpY2sgb2NjdXJyZWQgb3V0c2lkZSBvZiBtZW51XG4gICAgICAgICAgICBpZiAoZXZlbnRPY2N1cmVkT3V0c2lkZU1lbnUgJiYgZXZlbnRPY2N1cmVkT3V0c2lkZUNvbnRyb2wpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgaXNPcGVuOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sIHRoaXMuX3VuYmluZENsb3NlTWVudUlmQ2xpY2tlZE91dHNpZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9iaW5kQ2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciAmJiBkb2N1bWVudC5hdHRhY2hFdmVudCkge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCdvbmNsaWNrJywgdGhpcy5fY2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2Nsb3NlTWVudUlmQ2xpY2tlZE91dHNpZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl91bmJpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCFkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyICYmIGRvY3VtZW50LmRldGFjaEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZGV0YWNoRXZlbnQoJ29uY2xpY2snLCB0aGlzLl9jbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fY2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0U3RhdGUodGhpcy5nZXRTdGF0ZUZyb21WYWx1ZSh0aGlzLnByb3BzLnZhbHVlKSk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmFzeW5jT3B0aW9ucyAmJiB0aGlzLnByb3BzLmF1dG9sb2FkKSB7XG4gICAgICAgICAgICB0aGlzLmF1dG9sb2FkQXN5bmNPcHRpb25zKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2JsdXJUaW1lb3V0KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLl91bmJpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gKG5ld1Byb3BzKSB7XG4gICAgICAgIHZhciBvcHRpb25zQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkobmV3UHJvcHMub3B0aW9ucykgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMucHJvcHMub3B0aW9ucykpIHtcbiAgICAgICAgICAgIG9wdGlvbnNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIG9wdGlvbnM6IG5ld1Byb3BzLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgZmlsdGVyZWRPcHRpb25zOiB0aGlzLmZpbHRlck9wdGlvbnMobmV3UHJvcHMub3B0aW9ucylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZXdQcm9wcy52YWx1ZSAhPT0gdGhpcy5zdGF0ZS52YWx1ZSB8fCBuZXdQcm9wcy5wbGFjZWhvbGRlciAhPT0gdGhpcy5wcm9wcy5wbGFjZWhvbGRlciB8fCBvcHRpb25zQ2hhbmdlZCkge1xuICAgICAgICAgICAgdmFyIHNldFN0YXRlID0gKG5ld1N0YXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh0aGlzLmdldFN0YXRlRnJvbVZhbHVlKG5ld1Byb3BzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAobmV3U3RhdGUgJiYgbmV3U3RhdGUub3B0aW9ucykgfHwgbmV3UHJvcHMub3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgbmV3UHJvcHMucGxhY2Vob2xkZXIpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5hc3luY09wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRBc3luY09wdGlvbnMobmV3UHJvcHMudmFsdWUsIHt9LCBzZXRTdGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRTdGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVcGRhdGU6IGZ1bmN0aW9uIChuZXh0UHJvcHMsIG5leHRTdGF0ZSkge1xuICAgICAgICBpZiAobmV4dFN0YXRlLmlzT3BlbiAhPT0gdGhpcy5zdGF0ZS5pc09wZW4pIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSBuZXh0U3RhdGUuaXNPcGVuID8gbmV4dFByb3BzLm9uT3BlbiA6IG5leHRQcm9wcy5vbkNsb3NlO1xuICAgICAgICAgICAgaGFuZGxlciAmJiBoYW5kbGVyKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2JsdXJUaW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fZm9jdXNlZE9wdGlvblJldmVhbCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucmVmcy5mb2N1c2VkICYmIHRoaXMucmVmcy5tZW51KSB7XG4gICAgICAgICAgICAgICAgdmFyIGZvY3VzZWRET00gPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuZm9jdXNlZCk7XG4gICAgICAgICAgICAgICAgdmFyIG1lbnVET00gPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMubWVudSk7XG4gICAgICAgICAgICAgICAgdmFyIGZvY3VzZWRSZWN0ID0gZm9jdXNlZERPTS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgICAgICB2YXIgbWVudVJlY3QgPSBtZW51RE9NLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGZvY3VzZWRSZWN0LmJvdHRvbSA+IG1lbnVSZWN0LmJvdHRvbSB8fCBmb2N1c2VkUmVjdC50b3AgPCBtZW51UmVjdC50b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgbWVudURPTS5zY3JvbGxUb3AgPSAoZm9jdXNlZERPTS5vZmZzZXRUb3AgKyBmb2N1c2VkRE9NLmNsaWVudEhlaWdodCAtIG1lbnVET00ub2Zmc2V0SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9mb2N1c2VkT3B0aW9uUmV2ZWFsID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZm9jdXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXRJbnB1dE5vZGUoKS5mb2N1cygpO1xuICAgIH0sXG5cbiAgICBjbGlja2VkT3V0c2lkZUVsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50LCBldmVudCkge1xuICAgICAgICB2YXIgZXZlbnRUYXJnZXQgPSAoZXZlbnQudGFyZ2V0KSA/IGV2ZW50LnRhcmdldCA6IGV2ZW50LnNyY0VsZW1lbnQ7XG4gICAgICAgIHdoaWxlIChldmVudFRhcmdldCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnRUYXJnZXQgPT09IGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBldmVudFRhcmdldCA9IGV2ZW50VGFyZ2V0Lm9mZnNldFBhcmVudDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZ2V0U3RhdGVGcm9tVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgb3B0aW9ucywgcGxhY2Vob2xkZXIpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gdGhpcy5zdGF0ZS5vcHRpb25zO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyID0gdGhpcy5wcm9wcy5wbGFjZWhvbGRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlc2V0IGludGVybmFsIGZpbHRlciBzdHJpbmdcbiAgICAgICAgdGhpcy5fb3B0aW9uc0ZpbHRlclN0cmluZyA9ICcnO1xuXG4gICAgICAgIHZhciB2YWx1ZXMgPSB0aGlzLmluaXRWYWx1ZXNBcnJheSh2YWx1ZSwgb3B0aW9ucyk7XG4gICAgICAgIHZhciBmaWx0ZXJlZE9wdGlvbnMgPSB0aGlzLmZpbHRlck9wdGlvbnMob3B0aW9ucywgdmFsdWVzKTtcblxuICAgICAgICB2YXIgZm9jdXNlZE9wdGlvbjtcbiAgICAgICAgdmFyIHZhbHVlRm9yU3RhdGUgPSBudWxsO1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMubXVsdGkgJiYgdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgZm9jdXNlZE9wdGlvbiA9IHZhbHVlc1swXTtcbiAgICAgICAgICAgIHZhbHVlRm9yU3RhdGUgPSB2YWx1ZXNbMF0udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKHZhciBvcHRpb25JbmRleCA9IDA7IG9wdGlvbkluZGV4IDwgZmlsdGVyZWRPcHRpb25zLmxlbmd0aDsgKytvcHRpb25JbmRleCkge1xuICAgICAgICAgICAgICAgIGlmICghZmlsdGVyZWRPcHRpb25zW29wdGlvbkluZGV4XS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICBmb2N1c2VkT3B0aW9uID0gZmlsdGVyZWRPcHRpb25zW29wdGlvbkluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVGb3JTdGF0ZSA9IHZhbHVlcy5tYXAoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHYudmFsdWU7IH0pLmpvaW4odGhpcy5wcm9wcy5kZWxpbWl0ZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZUZvclN0YXRlLFxuICAgICAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICAgICAgICBpbnB1dFZhbHVlOiAnJyxcbiAgICAgICAgICAgIGZpbHRlcmVkT3B0aW9uczogZmlsdGVyZWRPcHRpb25zLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICF0aGlzLnByb3BzLm11bHRpICYmIHZhbHVlcy5sZW5ndGggPyB2YWx1ZXNbMF0ubGFiZWwgOiBwbGFjZWhvbGRlcixcbiAgICAgICAgICAgIGZvY3VzZWRPcHRpb246IGZvY3VzZWRPcHRpb25cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgaW5pdFZhbHVlc0FycmF5OiBmdW5jdGlvbiAodmFsdWVzLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMgPT09ICcnID8gW10gOiB2YWx1ZXMuc3BsaXQodGhpcy5wcm9wcy5kZWxpbWl0ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzICE9PSB1bmRlZmluZWQgJiYgdmFsdWVzICE9PSBudWxsID8gW3ZhbHVlc10gOiBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWVzLm1hcChmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zW2tleV0gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChvcHRpb25zW2tleV0udmFsdWUgPT09IHZhbCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBvcHRpb25zW2tleV0udmFsdWUgPT09ICdudW1iZXInICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc1trZXldLnZhbHVlLnRvU3RyaW5nKCkgPT09IHZhbFxuICAgICAgICAgICAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4ge3ZhbHVlOiB2YWwsIGxhYmVsOiB2YWx9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHNldFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIG5ld1N0YXRlID0gdGhpcy5nZXRTdGF0ZUZyb21WYWx1ZSh2YWx1ZSk7XG4gICAgICAgIG5ld1N0YXRlLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpcmVDaGFuZ2VFdmVudChuZXdTdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH0sXG5cbiAgICBzZWxlY3RWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5tdWx0aSkge1xuICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkVmFsdWUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3VuYmluZENsb3NlTWVudUlmQ2xpY2tlZE91dHNpZGUoKTtcbiAgICB9LFxuXG4gICAgYWRkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFZhbHVlKHRoaXMuc3RhdGUudmFsdWVzLmNvbmNhdCh2YWx1ZSkpO1xuICAgIH0sXG5cbiAgICBwb3BWYWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFZhbHVlKHRoaXMuc3RhdGUudmFsdWVzLnNsaWNlKDAsIHRoaXMuc3RhdGUudmFsdWVzLmxlbmd0aCAtIDEpKTtcbiAgICB9LFxuXG4gICAgcmVtb3ZlVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZVRvUmVtb3ZlKSB7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUodGhpcy5zdGF0ZS52YWx1ZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZVRvUmVtb3ZlO1xuICAgICAgICB9KSk7XG4gICAgfSxcblxuICAgIGNsZWFyVmFsdWU6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAvLyBpZiB0aGUgZXZlbnQgd2FzIHRyaWdnZXJlZCBieSBhIG1vdXNlZG93biBhbmQgbm90IHRoZSBwcmltYXJ5XG4gICAgICAgIC8vIGJ1dHRvbiwgaWdub3JlIGl0LlxuICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgJiYgZXZlbnQuYnV0dG9uICE9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUobnVsbCk7XG4gICAgfSxcblxuICAgIHJlc2V0VmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZSh0aGlzLnN0YXRlLnZhbHVlID09PSAnJyA/IG51bGwgOiB0aGlzLnN0YXRlLnZhbHVlKTtcbiAgICB9LFxuXG4gICAgZ2V0SW5wdXROb2RlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IHRoaXMucmVmcy5pbnB1dDtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuc2VhcmNoYWJsZSA/IGlucHV0IDogUmVhY3QuZmluZERPTU5vZGUoaW5wdXQpO1xuICAgIH0sXG5cbiAgICBmaXJlQ2hhbmdlRXZlbnQ6IGZ1bmN0aW9uIChuZXdTdGF0ZSkge1xuICAgICAgICBpZiAobmV3U3RhdGUudmFsdWUgIT09IHRoaXMuc3RhdGUudmFsdWUgJiYgdGhpcy5wcm9wcy5vbkNoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5nZShuZXdTdGF0ZS52YWx1ZSwgbmV3U3RhdGUudmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBoYW5kbGVNb3VzZURvd246IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAvLyBpZiB0aGUgZXZlbnQgd2FzIHRyaWdnZXJlZCBieSBhIG1vdXNlZG93biBhbmQgbm90IHRoZSBwcmltYXJ5XG4gICAgICAgIC8vIGJ1dHRvbiwgb3IgaWYgdGhlIGNvbXBvbmVudCBpcyBkaXNhYmxlZCwgaWdub3JlIGl0LlxuICAgICAgICBpZiAodGhpcy5wcm9wcy5kaXNhYmxlZCB8fCAoZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgJiYgZXZlbnQuYnV0dG9uICE9PSAwKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgbm9uLXNlYXJjaGFibGUgc2VsZWN0LCBjbG9zZSB0aGUgZHJvcGRvd24gd2hlbiBidXR0b24gaXMgY2xpY2tlZFxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc09wZW4gJiYgIXRoaXMucHJvcHMuc2VhcmNoYWJsZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgaXNPcGVuOiBmYWxzZVxuICAgICAgICAgICAgfSwgdGhpcy5fdW5iaW5kQ2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc0ZvY3VzZWQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGlzT3BlbjogdHJ1ZVxuICAgICAgICAgICAgfSwgdGhpcy5fYmluZENsb3NlTWVudUlmQ2xpY2tlZE91dHNpZGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fb3BlbkFmdGVyRm9jdXMgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5nZXRJbnB1dE5vZGUoKS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGhhbmRsZU1vdXNlRG93bk9uQXJyb3c6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAvLyBpZiB0aGUgZXZlbnQgd2FzIHRyaWdnZXJlZCBieSBhIG1vdXNlZG93biBhbmQgbm90IHRoZSBwcmltYXJ5XG4gICAgICAgIC8vIGJ1dHRvbiwgb3IgaWYgdGhlIGNvbXBvbmVudCBpcyBkaXNhYmxlZCwgaWdub3JlIGl0LlxuICAgICAgICBpZiAodGhpcy5wcm9wcy5kaXNhYmxlZCB8fCAoZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicgJiYgZXZlbnQuYnV0dG9uICE9PSAwKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIG5vdCBmb2N1c2VkLCBoYW5kbGVNb3VzZURvd24gd2lsbCBoYW5kbGUgaXRcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmlzT3Blbikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzT3BlbjogZmFsc2VcbiAgICAgICAgfSwgdGhpcy5fdW5iaW5kQ2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSk7XG4gICAgfSxcblxuICAgIGhhbmRsZUlucHV0Rm9jdXM6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB2YXIgbmV3SXNPcGVuID0gdGhpcy5zdGF0ZS5pc09wZW4gfHwgdGhpcy5fb3BlbkFmdGVyRm9jdXM7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgaXNGb2N1c2VkOiB0cnVlLFxuICAgICAgICAgICAgaXNPcGVuOiBuZXdJc09wZW5cbiAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKG5ld0lzT3Blbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2JpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl91bmJpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vcGVuQWZ0ZXJGb2N1cyA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkZvY3VzKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uRm9jdXMoZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGhhbmRsZUlucHV0Qmx1cjogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX2JsdXJUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBpc0ZvY3VzZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGlzT3BlbjogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCA1MCk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uQmx1cikge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkJsdXIoZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGhhbmRsZUtleURvd246IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xuICAgICAgICAgICAgY2FzZSA4OiAvLyBiYWNrc3BhY2VcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaW5wdXRWYWx1ZSAmJiB0aGlzLnByb3BzLmJhY2tzcGFjZVJlbW92ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3BWYWx1ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBjYXNlIDk6IC8vIHRhYlxuICAgICAgICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSB8fCAhdGhpcy5zdGF0ZS5pc09wZW4gfHwgIXRoaXMuc3RhdGUuZm9jdXNlZE9wdGlvbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rm9jdXNlZE9wdGlvbigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAxMzogLy8gZW50ZXJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaXNPcGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEZvY3VzZWRPcHRpb24oKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMjc6IC8vIGVzY2FwZVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmlzT3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0VmFsdWUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9wcy5jbGVhcmFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclZhbHVlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDM4OiAvLyB1cFxuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXNQcmV2aW91c09wdGlvbigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSA0MDogLy8gZG93blxuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXNOZXh0T3B0aW9uKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDE4ODogLy8gLFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmFsbG93Q3JlYXRlICYmIHRoaXMucHJvcHMubXVsdGkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rm9jdXNlZE9wdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcblxuICAgIC8vIEVuc3VyZXMgdGhhdCB0aGUgY3VycmVudGx5IGZvY3VzZWQgb3B0aW9uIGlzIGF2YWlsYWJsZSBpbiBmaWx0ZXJlZE9wdGlvbnMuXG4gICAgLy8gSWYgbm90LCByZXR1cm5zIHRoZSBmaXJzdCBhdmFpbGFibGUgb3B0aW9uLlxuICAgIF9nZXROZXdGb2N1c2VkT3B0aW9uOiBmdW5jdGlvbiAoZmlsdGVyZWRPcHRpb25zKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBmaWx0ZXJlZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChmaWx0ZXJlZE9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBmaWx0ZXJlZE9wdGlvbnNba2V5XSA9PT0gdGhpcy5zdGF0ZS5mb2N1c2VkT3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlcmVkT3B0aW9uc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJlZE9wdGlvbnNbMF07XG4gICAgfSxcblxuICAgIGhhbmRsZUlucHV0Q2hhbmdlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgLy8gYXNzaWduIGFuIGludGVybmFsIHZhcmlhYmxlIGJlY2F1c2Ugd2UgbmVlZCB0byB1c2VcbiAgICAgICAgLy8gdGhlIGxhdGVzdCB2YWx1ZSBiZWZvcmUgc2V0U3RhdGUoKSBoYXMgY29tcGxldGVkLlxuICAgICAgICB0aGlzLl9vcHRpb25zRmlsdGVyU3RyaW5nID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLmFzeW5jT3B0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiB0cnVlLFxuICAgICAgICAgICAgICAgIGlucHV0VmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmxvYWRBc3luY09wdGlvbnMoZXZlbnQudGFyZ2V0LnZhbHVlLCB7XG4gICAgICAgICAgICAgICAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBpc09wZW46IHRydWVcbiAgICAgICAgICAgIH0sIHRoaXMuX2JpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBmaWx0ZXJlZE9wdGlvbnMgPSB0aGlzLmZpbHRlck9wdGlvbnModGhpcy5zdGF0ZS5vcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGlzT3BlbjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBpbnB1dFZhbHVlOiBldmVudC50YXJnZXQudmFsdWUsXG4gICAgICAgICAgICAgICAgZmlsdGVyZWRPcHRpb25zOiBmaWx0ZXJlZE9wdGlvbnMsXG4gICAgICAgICAgICAgICAgZm9jdXNlZE9wdGlvbjogdGhpcy5fZ2V0TmV3Rm9jdXNlZE9wdGlvbihmaWx0ZXJlZE9wdGlvbnMpXG4gICAgICAgICAgICB9LCB0aGlzLl9iaW5kQ2xvc2VNZW51SWZDbGlja2VkT3V0c2lkZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYXV0b2xvYWRBc3luY09wdGlvbnM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5sb2FkQXN5bmNPcHRpb25zKCh0aGlzLnByb3BzLnZhbHVlIHx8ICcnKSwge30sICgpID0+IHtcbiAgICAgICAgICAgIC8vIHVwZGF0ZSB3aXRoIGZldGNoZWQgYnV0IGRvbid0IGZvY3VzXG4gICAgICAgICAgICB0aGlzLnNldFZhbHVlKHRoaXMucHJvcHMudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGxvYWRBc3luY09wdGlvbnM6IGZ1bmN0aW9uIChpbnB1dCwgc3RhdGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB0aGlzUmVxdWVzdElkID0gdGhpcy5fY3VycmVudFJlcXVlc3RJZCA9IHJlcXVlc3RJZCsrO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5jYWNoZUFzeW5jUmVzdWx0cykge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgY2FjaGVLZXkgPSBpbnB1dC5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9uc0NhY2hlW2NhY2hlS2V5XSAmJiAoaW5wdXQgPT09IGNhY2hlS2V5IHx8IHRoaXMuX29wdGlvbnNDYWNoZVtjYWNoZUtleV0uY29tcGxldGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5fb3B0aW9uc0NhY2hlW2NhY2hlS2V5XS5vcHRpb25zO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZmlsdGVyZWRPcHRpb25zID0gdGhpcy5maWx0ZXJPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRPcHRpb25zOiBmaWx0ZXJlZE9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb2N1c2VkT3B0aW9uOiB0aGlzLl9nZXROZXdGb2N1c2VkT3B0aW9uKGZpbHRlcmVkT3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YXRlW2tleV0gPSBzdGF0ZVtrZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcywgbmV3U3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByb3BzLmFzeW5jT3B0aW9ucyhpbnB1dCwgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNhY2hlQXN5bmNSZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9uc0NhY2hlW2lucHV0XSA9IGRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpc1JlcXVlc3RJZCAhPT0gdGhpcy5fY3VycmVudFJlcXVlc3RJZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBmaWx0ZXJlZE9wdGlvbnMgPSB0aGlzLmZpbHRlck9wdGlvbnMoZGF0YS5vcHRpb25zKTtcbiAgICAgICAgICAgIHZhciBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICBvcHRpb25zOiBkYXRhLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgZmlsdGVyZWRPcHRpb25zOiBmaWx0ZXJlZE9wdGlvbnMsXG4gICAgICAgICAgICAgICAgZm9jdXNlZE9wdGlvbjogdGhpcy5fZ2V0TmV3Rm9jdXNlZE9wdGlvbihmaWx0ZXJlZE9wdGlvbnMpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3U3RhdGVba2V5XSA9IHN0YXRlW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKHRoaXMsIG5ld1N0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGZpbHRlck9wdGlvbnM6IGZ1bmN0aW9uIChvcHRpb25zLCB2YWx1ZXMpIHtcbiAgICAgICAgdmFyIGZpbHRlclZhbHVlID0gdGhpcy5fb3B0aW9uc0ZpbHRlclN0cmluZztcbiAgICAgICAgdmFyIGV4Y2x1ZGUgPSAodmFsdWVzIHx8IHRoaXMuc3RhdGUudmFsdWVzKS5tYXAoZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICAgIHJldHVybiBpLnZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZmlsdGVyT3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuZmlsdGVyT3B0aW9ucy5jYWxsKHRoaXMsIG9wdGlvbnMsIGZpbHRlclZhbHVlLCBleGNsdWRlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBmaWx0ZXJPcHRpb24gPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5tdWx0aSAmJiBleGNsdWRlLmluZGV4T2Yob3AudmFsdWUpID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5maWx0ZXJPcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuZmlsdGVyT3B0aW9uLmNhbGwodGhpcywgb3AsIGZpbHRlclZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlVGVzdCA9IFN0cmluZyhvcC52YWx1ZSksIGxhYmVsVGVzdCA9IFN0cmluZyhvcC5sYWJlbCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuaWdub3JlQ2FzZSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZVRlc3QgPSB2YWx1ZVRlc3QudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxUZXN0ID0gbGFiZWxUZXN0LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlclZhbHVlID0gZmlsdGVyVmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuICFmaWx0ZXJWYWx1ZSB8fCAodGhpcy5wcm9wcy5tYXRjaFBvcyA9PT0gJ3N0YXJ0JykgPyAoXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLnByb3BzLm1hdGNoUHJvcCAhPT0gJ2xhYmVsJyAmJiB2YWx1ZVRlc3Quc3Vic3RyKDAsIGZpbHRlclZhbHVlLmxlbmd0aCkgPT09IGZpbHRlclZhbHVlKSB8fFxuICAgICAgICAgICAgICAgICAgICAodGhpcy5wcm9wcy5tYXRjaFByb3AgIT09ICd2YWx1ZScgJiYgbGFiZWxUZXN0LnN1YnN0cigwLCBmaWx0ZXJWYWx1ZS5sZW5ndGgpID09PSBmaWx0ZXJWYWx1ZSlcbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgICAodGhpcy5wcm9wcy5tYXRjaFByb3AgIT09ICdsYWJlbCcgJiYgdmFsdWVUZXN0LmluZGV4T2YoZmlsdGVyVmFsdWUpID49IDApIHx8XG4gICAgICAgICAgICAgICAgICAgICh0aGlzLnByb3BzLm1hdGNoUHJvcCAhPT0gJ3ZhbHVlJyAmJiBsYWJlbFRlc3QuaW5kZXhPZihmaWx0ZXJWYWx1ZSkgPj0gMClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiAob3B0aW9ucyB8fCBbXSkuZmlsdGVyKGZpbHRlck9wdGlvbiwgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2VsZWN0Rm9jdXNlZE9wdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5hbGxvd0NyZWF0ZSAmJiAhdGhpcy5zdGF0ZS5mb2N1c2VkT3B0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RWYWx1ZSh0aGlzLnN0YXRlLmlucHV0VmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdFZhbHVlKHRoaXMuc3RhdGUuZm9jdXNlZE9wdGlvbik7XG4gICAgfSxcblxuICAgIGZvY3VzT3B0aW9uOiBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBmb2N1c2VkT3B0aW9uOiBvcFxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgZm9jdXNOZXh0T3B0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZm9jdXNBZGphY2VudE9wdGlvbignbmV4dCcpO1xuICAgIH0sXG5cbiAgICBmb2N1c1ByZXZpb3VzT3B0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZm9jdXNBZGphY2VudE9wdGlvbigncHJldmlvdXMnKTtcbiAgICB9LFxuXG4gICAgZm9jdXNBZGphY2VudE9wdGlvbjogZnVuY3Rpb24gKGRpcikge1xuICAgICAgICB0aGlzLl9mb2N1c2VkT3B0aW9uUmV2ZWFsID0gdHJ1ZTtcbiAgICAgICAgdmFyIG9wcyA9IHRoaXMuc3RhdGUuZmlsdGVyZWRPcHRpb25zLmZpbHRlcihmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiAhb3AuZGlzYWJsZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBpc09wZW46IHRydWUsXG4gICAgICAgICAgICAgICAgaW5wdXRWYWx1ZTogJycsXG4gICAgICAgICAgICAgICAgZm9jdXNlZE9wdGlvbjogdGhpcy5zdGF0ZS5mb2N1c2VkT3B0aW9uIHx8IG9wc1tkaXIgPT09ICduZXh0JyA/IDAgOiBvcHMubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgIH0sIHRoaXMuX2JpbmRDbG9zZU1lbnVJZkNsaWNrZWRPdXRzaWRlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW9wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm9jdXNlZEluZGV4ID0gLTE7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5mb2N1c2VkT3B0aW9uID09PSBvcHNbaV0pIHtcbiAgICAgICAgICAgICAgICBmb2N1c2VkSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBmb2N1c2VkT3B0aW9uID0gb3BzWzBdO1xuICAgICAgICBpZiAoZGlyID09PSAnbmV4dCcgJiYgZm9jdXNlZEluZGV4ID4gLTEgJiYgZm9jdXNlZEluZGV4IDwgb3BzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGZvY3VzZWRPcHRpb24gPSBvcHNbZm9jdXNlZEluZGV4ICsgMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGlyID09PSAncHJldmlvdXMnKSB7XG4gICAgICAgICAgICBpZiAoZm9jdXNlZEluZGV4ID4gMCkge1xuICAgICAgICAgICAgICAgIGZvY3VzZWRPcHRpb24gPSBvcHNbZm9jdXNlZEluZGV4IC0gMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb2N1c2VkT3B0aW9uID0gb3BzW29wcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGZvY3VzZWRPcHRpb246IGZvY3VzZWRPcHRpb25cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHVuZm9jdXNPcHRpb246IGZ1bmN0aW9uIChvcCkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5mb2N1c2VkT3B0aW9uID09PSBvcCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgZm9jdXNlZE9wdGlvbjogbnVsbFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYnVpbGRNZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmb2N1c2VkVmFsdWUgPSB0aGlzLnN0YXRlLmZvY3VzZWRPcHRpb24gPyB0aGlzLnN0YXRlLmZvY3VzZWRPcHRpb24udmFsdWUgOiBudWxsO1xuICAgICAgICB2YXIgcmVuZGVyTGFiZWwgPSB0aGlzLnByb3BzLm9wdGlvblJlbmRlcmVyIHx8IGZ1bmN0aW9uIChvcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcC5sYWJlbDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmZpbHRlcmVkT3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb2N1c2VkVmFsdWUgPSBmb2N1c2VkVmFsdWUgPT0gbnVsbCA/IHRoaXMuc3RhdGUuZmlsdGVyZWRPcHRpb25zWzBdIDogZm9jdXNlZFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFkZCB0aGUgY3VycmVudCB2YWx1ZSB0byB0aGUgZmlsdGVyZWQgb3B0aW9ucyBpbiBsYXN0IHJlc29ydFxuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMuc3RhdGUuZmlsdGVyZWRPcHRpb25zO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5hbGxvd0NyZWF0ZSAmJiB0aGlzLnN0YXRlLmlucHV0VmFsdWUudHJpbSgpKSB7XG4gICAgICAgICAgICB2YXIgaW5wdXRWYWx1ZSA9IHRoaXMuc3RhdGUuaW5wdXRWYWx1ZTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zLnNsaWNlKCk7XG4gICAgICAgICAgICB2YXIgbmV3T3B0aW9uID0gdGhpcy5wcm9wcy5uZXdPcHRpb25DcmVhdG9yID8gdGhpcy5wcm9wcy5uZXdPcHRpb25DcmVhdG9yKGlucHV0VmFsdWUpIDoge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBpbnB1dFZhbHVlLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBpbnB1dFZhbHVlLFxuICAgICAgICAgICAgICAgIGNyZWF0ZTogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG9wdGlvbnMudW5zaGlmdChuZXdPcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvcHMgPSBPYmplY3Qua2V5cyhvcHRpb25zKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgdmFyIG9wID0gb3B0aW9uc1trZXldO1xuICAgICAgICAgICAgdmFyIGlzU2VsZWN0ZWQgPSB0aGlzLnN0YXRlLnZhbHVlID09PSBvcC52YWx1ZTtcbiAgICAgICAgICAgIHZhciBpc0ZvY3VzZWQgPSBmb2N1c2VkVmFsdWUgPT09IG9wLnZhbHVlO1xuICAgICAgICAgICAgdmFyIG9wdGlvbkNsYXNzID0gY2xhc3Nlcyh7XG4gICAgICAgICAgICAgICAgJ1NlbGVjdC1vcHRpb24nOiB0cnVlLFxuICAgICAgICAgICAgICAgICdpcy1zZWxlY3RlZCc6IGlzU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgJ2lzLWZvY3VzZWQnOiBpc0ZvY3VzZWQsXG4gICAgICAgICAgICAgICAgJ2lzLWRpc2FibGVkJzogb3AuZGlzYWJsZWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHJlZiA9IGlzRm9jdXNlZCA/ICdmb2N1c2VkJyA6IG51bGw7XG4gICAgICAgICAgICB2YXIgbW91c2VFbnRlciA9IHRoaXMuZm9jdXNPcHRpb24uYmluZCh0aGlzLCBvcCk7XG4gICAgICAgICAgICB2YXIgbW91c2VMZWF2ZSA9IHRoaXMudW5mb2N1c09wdGlvbi5iaW5kKHRoaXMsIG9wKTtcbiAgICAgICAgICAgIHZhciBtb3VzZURvd24gPSB0aGlzLnNlbGVjdFZhbHVlLmJpbmQodGhpcywgb3ApO1xuICAgICAgICAgICAgdmFyIG9wdGlvblJlc3VsdCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQodGhpcy5wcm9wcy5vcHRpb25Db21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICBrZXk6ICdvcHRpb24tJyArIG9wLnZhbHVlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogb3B0aW9uQ2xhc3MsXG4gICAgICAgICAgICAgICAgcmVuZGVyRnVuYzogcmVuZGVyTGFiZWwsXG4gICAgICAgICAgICAgICAgbW91c2VFbnRlcjogbW91c2VFbnRlcixcbiAgICAgICAgICAgICAgICBtb3VzZUxlYXZlOiBtb3VzZUxlYXZlLFxuICAgICAgICAgICAgICAgIG1vdXNlRG93bjogbW91c2VEb3duLFxuICAgICAgICAgICAgICAgIGNsaWNrOiBtb3VzZURvd24sXG4gICAgICAgICAgICAgICAgYWRkTGFiZWxUZXh0OiB0aGlzLnByb3BzLmFkZExhYmVsVGV4dCxcbiAgICAgICAgICAgICAgICBvcHRpb246IG9wLFxuICAgICAgICAgICAgICAgIHJlZjogcmVmXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25SZXN1bHQ7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgICAgICByZXR1cm4gb3BzLmxlbmd0aCA/IG9wcyA6IChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lID0gXCJTZWxlY3Qtbm9yZXN1bHRzXCI+XG4gICAgICAgICAgICAgICAge3RoaXMucHJvcHMuYXN5bmNPcHRpb25zICYmICF0aGlzLnN0YXRlLmlucHV0VmFsdWUgPyB0aGlzLnByb3BzLnNlYXJjaFByb21wdFRleHQgOiB0aGlzLnByb3BzLm5vUmVzdWx0c1RleHR9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlT3B0aW9uTGFiZWxDbGljazogZnVuY3Rpb24gKHZhbHVlLCBldmVudCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk9wdGlvbkxhYmVsQ2xpY2spIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25PcHRpb25MYWJlbENsaWNrKHZhbHVlLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzZWxlY3RDbGFzcyA9IGNsYXNzZXMoJ1NlbGVjdCcsIHRoaXMucHJvcHMuY2xhc3NOYW1lLCB7XG4gICAgICAgICAgICAnaXMtbXVsdGknOiB0aGlzLnByb3BzLm11bHRpLFxuICAgICAgICAgICAgJ2lzLXNlYXJjaGFibGUnOiB0aGlzLnByb3BzLnNlYXJjaGFibGUsXG4gICAgICAgICAgICAnaXMtb3Blbic6IHRoaXMuc3RhdGUuaXNPcGVuLFxuICAgICAgICAgICAgJ2lzLWZvY3VzZWQnOiB0aGlzLnN0YXRlLmlzRm9jdXNlZCxcbiAgICAgICAgICAgICdpcy1sb2FkaW5nJzogdGhpcy5zdGF0ZS5pc0xvYWRpbmcsXG4gICAgICAgICAgICAnaXMtZGlzYWJsZWQnOiB0aGlzLnByb3BzLmRpc2FibGVkLFxuICAgICAgICAgICAgJ2hhcy12YWx1ZSc6IHRoaXMuc3RhdGUudmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB2YWx1ZSA9IFtdO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5tdWx0aSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS52YWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9uT3B0aW9uTGFiZWxDbGljayA9IHRoaXMuaGFuZGxlT3B0aW9uTGFiZWxDbGljay5iaW5kKHRoaXMsIHZhbCk7XG4gICAgICAgICAgICAgICAgdmFyIG9uUmVtb3ZlID0gdGhpcy5yZW1vdmVWYWx1ZS5iaW5kKHRoaXMsIHZhbCk7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudCh0aGlzLnByb3BzLnZhbHVlQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgIGtleTogdmFsLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBvcHRpb246IHZhbCxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXI6IHRoaXMucHJvcHMudmFsdWVSZW5kZXJlcixcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uTGFiZWxDbGljazogISF0aGlzLnByb3BzLm9uT3B0aW9uTGFiZWxDbGljayxcbiAgICAgICAgICAgICAgICAgICAgb25PcHRpb25MYWJlbENsaWNrOiBvbk9wdGlvbkxhYmVsQ2xpY2ssXG4gICAgICAgICAgICAgICAgICAgIG9uUmVtb3ZlOiBvblJlbW92ZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucHJvcHMuZGlzYWJsZWRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2YWx1ZS5wdXNoKHZhbHVlQ29tcG9uZW50KTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmlucHV0VmFsdWUgJiYgKCF0aGlzLnByb3BzLm11bHRpIHx8ICF2YWx1ZS5sZW5ndGgpKSB7XG4gICAgICAgICAgICB2YXIgdmFsID0gdGhpcy5zdGF0ZS52YWx1ZXNbMF0gfHwgbnVsbDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnZhbHVlUmVuZGVyZXIgJiYgISF0aGlzLnN0YXRlLnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5wdXNoKDxWYWx1ZVxuICAgICAgICAgICAgICAgICAgICBrZXkgPSB7MH1cbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uID0ge3ZhbH1cbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXIgPSB7dGhpcy5wcm9wcy52YWx1ZVJlbmRlcmVyfVxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZCA9IHt0aGlzLnByb3BzLmRpc2FibGVkfS8+KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBzaW5nbGVWYWx1ZUNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQodGhpcy5wcm9wcy5zaW5nbGVWYWx1ZUNvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgICAgICBrZXk6ICdwbGFjZWhvbGRlcicsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWwsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLnN0YXRlLnBsYWNlaG9sZGVyXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdmFsdWUucHVzaChzaW5nbGVWYWx1ZUNvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9hZGluZyA9IHRoaXMuc3RhdGUuaXNMb2FkaW5nID8gPHNwYW4gY2xhc3NOYW1lID0gXCJTZWxlY3QtbG9hZGluZ1wiIGFyaWEtaGlkZGVuID0gXCJ0cnVlXCIvPiA6IG51bGw7XG4gICAgICAgIHZhciBjbGVhciA9IHRoaXMucHJvcHMuY2xlYXJhYmxlICYmIHRoaXMuc3RhdGUudmFsdWUgJiYgIXRoaXMucHJvcHMuZGlzYWJsZWQgPyA8c3BhbiBjbGFzc05hbWUgPSBcIlNlbGVjdC1jbGVhclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IHt0aGlzLnByb3BzLm11bHRpID8gdGhpcy5wcm9wcy5jbGVhckFsbFRleHQgOiB0aGlzLnByb3BzLmNsZWFyVmFsdWVUZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbCA9IHt0aGlzLnByb3BzLm11bHRpID8gdGhpcy5wcm9wcy5jbGVhckFsbFRleHQgOiB0aGlzLnByb3BzLmNsZWFyVmFsdWVUZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Nb3VzZURvd24gPSB7dGhpcy5jbGVhclZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljayA9IHt0aGlzLmNsZWFyVmFsdWV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYW5nZXJvdXNseVNldElubmVySFRNTCA9IHt7IF9faHRtbDogJyZ0aW1lczsnIH19Lz4gOiBudWxsO1xuXG4gICAgICAgIHZhciBtZW51O1xuICAgICAgICB2YXIgbWVudVByb3BzO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc09wZW4pIHtcbiAgICAgICAgICAgIG1lbnVQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICByZWY6ICdtZW51JyxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdTZWxlY3QtbWVudSdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5tdWx0aSkge1xuICAgICAgICAgICAgICAgIG1lbnVQcm9wcy5vbk1vdXNlRG93biA9IHRoaXMuaGFuZGxlTW91c2VEb3duO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVudSA9IChcbiAgICAgICAgICAgICAgICA8ZGl2IHJlZiA9IFwic2VsZWN0TWVudUNvbnRhaW5lclwiIGNsYXNzTmFtZSA9IFwiU2VsZWN0LW1lbnUtb3V0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiB7Li4ubWVudVByb3BzfT57dGhpcy5idWlsZE1lbnUoKX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaW5wdXQ7XG4gICAgICAgIHZhciBpbnB1dFByb3BzID0ge1xuICAgICAgICAgICAgcmVmOiAnaW5wdXQnLFxuICAgICAgICAgICAgY2xhc3NOYW1lOiAnU2VsZWN0LWlucHV0ICcgKyAodGhpcy5wcm9wcy5pbnB1dFByb3BzLmNsYXNzTmFtZSB8fCAnJyksXG4gICAgICAgICAgICB0YWJJbmRleDogdGhpcy5wcm9wcy50YWJJbmRleCB8fCAwLFxuICAgICAgICAgICAgb25Gb2N1czogdGhpcy5oYW5kbGVJbnB1dEZvY3VzLFxuICAgICAgICAgICAgb25CbHVyOiB0aGlzLmhhbmRsZUlucHV0Qmx1clxuICAgICAgICB9O1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5wcm9wcy5pbnB1dFByb3BzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5pbnB1dFByb3BzLmhhc093blByb3BlcnR5KGtleSkgJiYga2V5ICE9PSAnY2xhc3NOYW1lJykge1xuICAgICAgICAgICAgICAgIGlucHV0UHJvcHNba2V5XSA9IHRoaXMucHJvcHMuaW5wdXRQcm9wc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5zZWFyY2hhYmxlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSA8SW5wdXQgdmFsdWUgPSB7dGhpcy5zdGF0ZS5pbnB1dFZhbHVlfSBvbkNoYW5nZSA9IHt0aGlzLmhhbmRsZUlucHV0Q2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbldpZHRoID0gXCI1XCIgey4uLmlucHV0UHJvcHN9IC8+O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSA8ZGl2IHsuLi5pbnB1dFByb3BzfT4mbmJzcDs8L2Rpdj47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMucHJvcHMubXVsdGkgfHwgIXRoaXMuc3RhdGUudmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgaW5wdXQgPSA8ZGl2IGNsYXNzTmFtZSA9IFwiU2VsZWN0LWlucHV0XCI+Jm5ic3A7PC9kaXY+O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgcmVmID0gXCJ3cmFwcGVyXCIgY2xhc3NOYW1lID0ge3NlbGVjdENsYXNzfT5cbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZSA9IFwiaGlkZGVuXCIgcmVmID0gXCJ2YWx1ZVwiIG5hbWUgPSB7dGhpcy5wcm9wcy5uYW1lfSB2YWx1ZSA9IHt0aGlzLnN0YXRlLnZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZCA9IHt0aGlzLnByb3BzLmRpc2FibGVkfS8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWUgPSBcIlNlbGVjdC1jb250cm9sXCIgcmVmID0gXCJjb250cm9sXCIgb25LZXlEb3duID0ge3RoaXMuaGFuZGxlS2V5RG93bn1cbiAgICAgICAgICAgICAgICAgICAgIG9uTW91c2VEb3duID0ge3RoaXMuaGFuZGxlTW91c2VEb3dufSBvblRvdWNoRW5kID0ge3RoaXMuaGFuZGxlTW91c2VEb3dufT5cbiAgICAgICAgICAgICAgICAgICAge3ZhbHVlfVxuICAgICAgICAgICAgICAgICAgICB7aW5wdXR9XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZSA9IFwiU2VsZWN0LWFycm93LXpvbmVcIiBvbk1vdXNlRG93biA9IHt0aGlzLmhhbmRsZU1vdXNlRG93bk9uQXJyb3d9Lz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lID0gXCJTZWxlY3QtYXJyb3dcIiBvbk1vdXNlRG93biA9IHt0aGlzLmhhbmRsZU1vdXNlRG93bk9uQXJyb3d9Lz5cbiAgICAgICAgICAgICAgICAgICAge2xvYWRpbmd9XG4gICAgICAgICAgICAgICAgICAgIHtjbGVhcn1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB7bWVudX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0O1xuIl19 diff --git a/examples/dist/common.js b/examples/dist/common.js index 8890b730ef..b4543900bf 100644 --- a/examples/dist/common.js +++ b/examples/dist/common.js @@ -1,19291 +1,3381 @@ require=(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 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; +var emptyObject = {}; -/** - * 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) - ); +if (process.env.NODE_ENV !== 'production') { + Object.freeze(emptyObject); } +module.exports = emptyObject; +}).call(this,require('_process')) +},{"_process":9}],3:[function(require,module,exports){ +(function (process){ /** - * Translate native top level events into event types. + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. * - * @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? + * 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. * - * @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; - } -} +'use strict'; /** - * 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. + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. * - * @param {object} nativeEvent - * @return {?string} + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. */ -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; +function invariant(condition, format, a, b, c, d, e, f) { + if (process.env.NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); } - } 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(); - } + if (!condition) { + var error; + if (format === undefined) { + error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error(format.replace(/%s/g, function () { + return args[argIndex++]; + })); + error.name = 'Invariant Violation'; } - } - 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; - } + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; } - - 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; - } -} +module.exports = invariant; +}).call(this,require('_process')) +},{"_process":9}],4:[function(require,module,exports){ +(function (process){ /** - * For browsers that do not provide the `textInput` event, extract the - * appropriate string to use for SyntheticInputEvent. + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. * - * @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. + * 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. * - * @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. + * @typechecks static-only */ -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 - ); +'use strict'; - event.data = chars; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; -} +var invariant = require('./invariant'); /** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; * - * 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`. + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. * - * `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. + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} * - * This plugin is also responsible for emitting `composition` events, thus - * allowing us to share composition fallback code for both `beforeInput` and - * `composition` event types. + * @param {object} obj + * @return {object} */ -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 - ) - ]; +var keyMirror = function (obj) { + var ret = {}; + var key; + !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : void 0; + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; } + return ret; }; -module.exports = BeforeInputEventPlugin; +module.exports = keyMirror; +}).call(this,require('_process')) + +},{"./invariant":3,"_process":9}],5:[function(require,module,exports){ +"use strict"; -},{"./EventConstants":14,"./EventPropagators":19,"./ExecutionEnvironment":20,"./FallbackCompositionState":21,"./SyntheticCompositionEvent":93,"./SyntheticInputEvent":97,"./keyOf":141}],3:[function(require,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule CSSProperty */ -'use strict'; - /** - * CSS properties which accept numbers but are not in units of "px". + * Allows extraction of a minified key. Let's the build system minify keys + * without losing the ability to dynamically use key strings as values + * themselves. Pass in an object with a single key/val pair and it will return + * you the string key of that single record. Suppose you want to grab the + * value for a key 'className' inside of an object. Key/val minification may + * have aliased that key to be 'xa12'. keyOf({className: null}) will return + * 'xa12' in that case. Resolve keys you want to use once at startup time, then + * reuse those resolutions. */ -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 +var keyOf = function (oneKeyObj) { + var key; + for (key in oneKeyObj) { + if (!oneKeyObj.hasOwnProperty(key)) { + continue; + } + return key; + } + return null; }; +module.exports = keyOf; +},{}],6:[function(require,module,exports){ /** - * @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 + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * */ -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']; +'use strict'; -// 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]; - }); -}); +var hasOwnProperty = Object.prototype.hasOwnProperty; /** - * 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. + * Executes the provided `callback` once for each enumerable own property in the + * object and constructs a new object from the results. The `callback` is + * invoked with three arguments: + * + * - the property value + * - the property name + * - the object being traversed + * + * Properties that are added after the call to `mapObject` will not be visited + * by `callback`. If the values of existing properties are changed, the value + * passed to `callback` will be the value at the time `mapObject` visits them. + * Properties that are deleted before being visited are not visited. + * + * @grep function objectMap() + * @grep function objMap() + * + * @param {?object} object + * @param {function} callback + * @param {*} context + * @return {?object} */ -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 +function mapObject(object, callback, context) { + if (!object) { + return null; } -}; - -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions -}; - -module.exports = CSSProperty; + var result = {}; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result[name] = callback.call(context, object[name], name, object); + } + } + return result; +} -},{}],4:[function(require,module,exports){ +module.exports = mapObject; +},{}],7:[function(require,module,exports){ +(function (process){ /** - * Copyright 2013-2015, Facebook, Inc. + * 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 CSSPropertyOperations - * @typechecks static-only */ 'use strict'; -var CSSProperty = require("./CSSProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var emptyFunction = require('./emptyFunction'); -var camelizeStyleName = require("./camelizeStyleName"); -var dangerousStyleValue = require("./dangerousStyleValue"); -var hyphenateStyleName = require("./hyphenateStyleName"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ -var processStyleName = memoizeStringOnly(function(styleName) { - return hyphenateStyleName(styleName); -}); +var warning = emptyFunction; -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; - } -} +if (process.env.NODE_ENV !== 'production') { + warning = function (condition, format) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } -if ("production" !== "production") { - // 'msTransform' is correct, but the other prefixes should be capitalized - var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; + if (format === undefined) { + throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); + } - // 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; + if (format.indexOf('Failed Composite propType: ') === 0) { + return; // Ignore CompositeComponent proptype check. } - warnedStyleNames[name] = true; - ("production" !== "production" ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); + if (!condition) { + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, function () { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + } }; +} - var warnBadVendoredStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } +module.exports = warning; +}).call(this,require('_process')) - warnedStyleNames[name] = true; - ("production" !== "production" ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); - }; +},{"./emptyFunction":1,"_process":9}],8:[function(require,module,exports){ +'use strict'; +/* eslint-disable no-unused-vars */ +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; - var warnStyleValueWithSemicolon = function(name, value) { - if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { - return; - } +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } - warnedStyleValues[value] = true; - ("production" !== "production" ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); - }; + return Object(val); +} - /** - * @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); +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (e) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (Object.getOwnPropertySymbols) { + symbols = Object.getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; + +},{}],9:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); } - }; } -/** - * Operations for dealing with CSS properties. - */ -var CSSPropertyOperations = { +function drainQueue() { + if (draining) { + return; + } + var timeout = setTimeout(cleanUpNextTick); + draining = true; - /** - * 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" !== "production") { - warnValidStyle(styleName, styleValue); - } - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; } - return serialized || null; - }, + currentQueue = null; + draining = false; + clearTimeout(timeout); +} - /** - * 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" !== "production") { - 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] = ''; +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; } - } } - } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.binding = function (name) { + throw new Error('process.binding is not supported'); }; -module.exports = CSSPropertyOperations; +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; -},{"./CSSProperty":3,"./ExecutionEnvironment":20,"./camelizeStyleName":108,"./dangerousStyleValue":113,"./hyphenateStyleName":133,"./memoizeStringOnly":143,"./warning":154}],5:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule CallbackQueue + * @providesModule KeyEscapeUtils */ 'use strict'; -var PooledClass = require("./PooledClass"); - -var assign = require("./Object.assign"); -var invariant = require("./invariant"); - /** - * 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()`. + * Escape and wrap key so it is safe to use as a reactid * - * @class ReactMountReady - * @implements PooledClass - * @internal + * @param {*} key to be escaped. + * @return {string} the escaped key. */ -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" !== "production" ? 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; - }, +function escape(key) { + var escapeRegex = /[=:]/g; + var escaperLookup = { + '=': '=0', + ':': '=2' + }; + var escapedString = ('' + key).replace(escapeRegex, function (match) { + return escaperLookup[match]; + }); - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } + return '$' + escapedString; +} -}); +/** + * Unescape and unwrap key for human-readable display + * + * @param {string} key to unescape. + * @return {string} the unescaped key. + */ +function unescape(key) { + var unescapeRegex = /(=0|=2)/g; + var unescaperLookup = { + '=0': '=', + '=2': ':' + }; + var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); -PooledClass.addPoolingTo(CallbackQueue); + return ('' + keySubstring).replace(unescapeRegex, function (match) { + return unescaperLookup[match]; + }); +} -module.exports = CallbackQueue; +var KeyEscapeUtils = { + escape: escape, + unescape: unescape +}; -},{"./Object.assign":26,"./PooledClass":27,"./invariant":135}],6:[function(require,module,exports){ +module.exports = KeyEscapeUtils; +},{}],11:[function(require,module,exports){ +(function (process){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ChangeEventPlugin + * @providesModule PooledClass */ 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); - -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); - -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; +var invariant = require('fbjs/lib/invariant'); /** - * SECTION: handle `change` event + * Static poolers. Several custom versions for each potential number of + * arguments. A completely generic pooler is easy to implement, but would + * require accessing the `arguments` object. In each of these, `this` refers to + * the Class itself, not an instance. If any others are needed, simply add them + * here, or in their own files. */ -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(); -} +var oneArgumentPooler = function (copyFieldsFrom) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, copyFieldsFrom); + return instance; + } else { + return new Klass(copyFieldsFrom); + } +}; -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} +var twoArgumentPooler = function (a1, a2) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2); + return instance; + } else { + return new Klass(a1, a2); + } +}; -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; +var threeArgumentPooler = function (a1, a2, a3) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3); + return instance; + } else { + return new Klass(a1, a2, a3); } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} +}; -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; +var fourArgumentPooler = function (a1, a2, a3, a4) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3, a4); + return instance; + } else { + return new Klass(a1, a2, a3, a4); } -} -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(); +}; + +var fiveArgumentPooler = function (a1, a2, a3, a4, a5) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3, a4, a5); + return instance; + } else { + return new Klass(a1, a2, a3, a4, a5); } -} +}; +var standardReleaser = function (instance) { + var Klass = this; + !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : invariant(false) : void 0; + instance.destructor(); + if (Klass.instancePool.length < Klass.poolSize) { + Klass.instancePool.push(instance); + } +}; -/** - * 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) - ); -} +var DEFAULT_POOL_SIZE = 10; +var DEFAULT_POOLER = oneArgumentPooler; /** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. + * Augments `CopyConstructor` to be a poolable class, augmenting only the class + * itself (statically) not adding any prototypical fields. Any CopyConstructor + * you give this may have a `poolSize` property, and will look for a + * prototypical `destructor` on instances (optional). + * + * @param {Function} CopyConstructor Constructor that can be used to reset. + * @param {Function} pooler Customizable pooler. */ -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); +var addPoolingTo = function (CopyConstructor, pooler) { + var NewKlass = CopyConstructor; + NewKlass.instancePool = []; + NewKlass.getPooled = pooler || DEFAULT_POOLER; + if (!NewKlass.poolSize) { + NewKlass.poolSize = DEFAULT_POOL_SIZE; } + NewKlass.release = standardReleaser; + return NewKlass; }; -/** - * (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); -} +var PooledClass = { + addPoolingTo: addPoolingTo, + oneArgumentPooler: oneArgumentPooler, + twoArgumentPooler: twoArgumentPooler, + threeArgumentPooler: threeArgumentPooler, + fourArgumentPooler: fourArgumentPooler, + fiveArgumentPooler: fiveArgumentPooler +}; + +module.exports = PooledClass; +}).call(this,require('_process')) +},{"_process":9,"fbjs/lib/invariant":3}],12:[function(require,module,exports){ +(function (process){ /** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule React */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); +'use strict'; - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} +var _assign = require('object-assign'); -/** - * (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; +var ReactChildren = require('./ReactChildren'); +var ReactComponent = require('./ReactComponent'); +var ReactClass = require('./ReactClass'); +var ReactDOMFactories = require('./ReactDOMFactories'); +var ReactElement = require('./ReactElement'); +var ReactElementValidator = require('./ReactElementValidator'); +var ReactPropTypes = require('./ReactPropTypes'); +var ReactVersion = require('./ReactVersion'); - manualDispatchChangeEvent(nativeEvent); -} +var onlyChild = require('./onlyChild'); +var warning = require('fbjs/lib/warning'); -/** - * 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; - } -} +var createElement = ReactElement.createElement; +var createFactory = ReactElement.createFactory; +var cloneElement = ReactElement.cloneElement; -// 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(); - } +if (process.env.NODE_ENV !== 'production') { + createElement = ReactElementValidator.createElement; + createFactory = ReactElementValidator.createFactory; + cloneElement = ReactElementValidator.cloneElement; } -// 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; - } - } +var __spread = _assign; + +if (process.env.NODE_ENV !== 'production') { + var warned = false; + __spread = function () { + process.env.NODE_ENV !== 'production' ? warning(warned, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.') : void 0; + warned = true; + return _assign.apply(null, arguments); + }; } +var React = { -/** - * 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') - ); -} + // Modern -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} + Children: { + map: ReactChildren.map, + forEach: ReactChildren.forEach, + count: ReactChildren.count, + toArray: ReactChildren.toArray, + only: onlyChild + }, -/** - * 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 = { + Component: ReactComponent, + + createElement: createElement, + cloneElement: cloneElement, + isValidElement: ReactElement.isValidElement, - eventTypes: eventTypes, + // Classic - /** - * @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; - } + PropTypes: ReactPropTypes, + createClass: ReactClass.createClass, + createFactory: createFactory, + createMixin: function (mixin) { + // Currently a noop. Will be used to validate and trace mixins. + return mixin; + }, - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } + // This looks DOM specific but these are actually isomorphic helpers + // since they are just generating DOM strings. + DOM: ReactDOMFactories, - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } + version: ReactVersion, + // Deprecated hook for JSX spread, don't use this for anything. + __spread: __spread }; -module.exports = ChangeEventPlugin; +module.exports = React; +}).call(this,require('_process')) -},{"./EventConstants":14,"./EventPluginHub":16,"./EventPropagators":19,"./ExecutionEnvironment":20,"./ReactUpdates":87,"./SyntheticEvent":95,"./isEventSupported":136,"./isTextInputElement":138,"./keyOf":141}],7:[function(require,module,exports){ +},{"./ReactChildren":13,"./ReactClass":14,"./ReactComponent":15,"./ReactDOMFactories":17,"./ReactElement":19,"./ReactElementValidator":20,"./ReactPropTypes":26,"./ReactVersion":27,"./onlyChild":30,"_process":9,"fbjs/lib/warning":7,"object-assign":8}],13:[function(require,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ClientReactRootIndex - * @typechecks + * @providesModule ReactChildren */ 'use strict'; -var nextReactRootIndex = 0; +var PooledClass = require('./PooledClass'); +var ReactElement = require('./ReactElement'); -var ClientReactRootIndex = { - createReactRootIndex: function() { - return nextReactRootIndex++; - } -}; +var emptyFunction = require('fbjs/lib/emptyFunction'); +var traverseAllChildren = require('./traverseAllChildren'); + +var twoArgumentPooler = PooledClass.twoArgumentPooler; +var fourArgumentPooler = PooledClass.fourArgumentPooler; -module.exports = ClientReactRootIndex; +var userProvidedKeyEscapeRegex = /\/+/g; +function escapeUserProvidedKey(text) { + return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/'); +} -},{}],8:[function(require,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. + * PooledClass representing the bookkeeping associated with performing a child + * traversal. Allows avoiding binding callbacks. * - * @providesModule DOMChildrenOperations - * @typechecks static-only + * @constructor ForEachBookKeeping + * @param {!function} forEachFunction Function to perform traversal with. + * @param {?*} forEachContext Context to perform context with. */ +function ForEachBookKeeping(forEachFunction, forEachContext) { + this.func = forEachFunction; + this.context = forEachContext; + this.count = 0; +} +ForEachBookKeeping.prototype.destructor = function () { + this.func = null; + this.context = null; + this.count = 0; +}; +PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); -'use strict'; - -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); +function forEachSingleChild(bookKeeping, child, name) { + var func = bookKeeping.func; + var context = bookKeeping.context; -var setTextContent = require("./setTextContent"); -var invariant = require("./invariant"); + func.call(context, child, bookKeeping.count++); +} /** - * Inserts `childNode` as a child of `parentNode` at the `index`. + * Iterates through children that are typically specified as `props.children`. * - * @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 + * The provided forEachFunc(child, index) will be called for each + * leaf child. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} forEachFunc + * @param {*} forEachContext Context for forEachContext. */ -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 - ); +function forEachChildren(children, forEachFunc, forEachContext) { + if (children == null) { + return children; + } + var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); + traverseAllChildren(children, forEachSingleChild, traverseContext); + ForEachBookKeeping.release(traverseContext); } /** - * Operations for updating with DOM children. + * PooledClass representing the bookkeeping associated with performing a child + * mapping. Allows avoiding binding callbacks. + * + * @constructor MapBookKeeping + * @param {!*} mapResult Object containing the ordered map of results. + * @param {!function} mapFunction Function to perform mapping with. + * @param {?*} mapContext Context to perform mapping with. */ -var DOMChildrenOperations = { +function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) { + this.result = mapResult; + this.keyPrefix = keyPrefix; + this.func = mapFunction; + this.context = mapContext; + this.count = 0; +} +MapBookKeeping.prototype.destructor = function () { + this.result = null; + this.keyPrefix = null; + this.func = null; + this.context = null; + this.count = 0; +}; +PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, +function mapSingleChildIntoContext(bookKeeping, child, childKey) { + var result = bookKeeping.result; + var keyPrefix = bookKeeping.keyPrefix; + var func = bookKeeping.func; + var context = bookKeeping.context; - 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" !== "production" ? 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 mappedChild = func.call(context, child, bookKeeping.count++); + if (Array.isArray(mappedChild)) { + mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument); + } else if (mappedChild != null) { + if (ReactElement.isValidElement(mappedChild)) { + mappedChild = ReactElement.cloneAndReplaceKey(mappedChild, + // Keep both the (mapped) and old keys if they differ, just as + // traverseAllChildren used to do for objects as children + keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey); } + result.push(mappedChild); + } +} - 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]); - } - } +function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { + var escapedPrefix = ''; + if (prefix != null) { + escapedPrefix = escapeUserProvidedKey(prefix) + '/'; + } + var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context); + traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); + MapBookKeeping.release(traverseContext); +} - 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; - } - } +/** + * Maps children that are typically specified as `props.children`. + * + * The provided mapFunction(child, index) will be called for each + * leaf child. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} func The map function. + * @param {*} context Context for mapFunction. + * @return {object} Object containing the ordered map of results. + */ +function mapChildren(children, func, context) { + if (children == null) { + return children; } + var result = []; + mapIntoWithKeyPrefixInternal(children, result, null, func, context); + return result; +} -}; +function forEachSingleChildDummy(traverseContext, child, name) { + return null; +} + +/** + * Count the number of children that are typically specified as + * `props.children`. + * + * @param {?*} children Children tree container. + * @return {number} The number of children. + */ +function countChildren(children, context) { + return traverseAllChildren(children, forEachSingleChildDummy, null); +} + +/** + * Flatten a children object (typically specified as `props.children`) and + * return an array with appropriately re-keyed children. + */ +function toArray(children) { + var result = []; + mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument); + return result; +} -module.exports = DOMChildrenOperations; +var ReactChildren = { + forEach: forEachChildren, + map: mapChildren, + mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal, + count: countChildren, + toArray: toArray +}; -},{"./Danger":11,"./ReactMultiChildUpdateTypes":72,"./invariant":135,"./setTextContent":149}],9:[function(require,module,exports){ +module.exports = ReactChildren; +},{"./PooledClass":11,"./ReactElement":19,"./traverseAllChildren":31,"fbjs/lib/emptyFunction":1}],14:[function(require,module,exports){ +(function (process){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule DOMProperty - * @typechecks static-only + * @providesModule ReactClass */ -/*jslint bitwise: true */ - 'use strict'; -var invariant = require("./invariant"); - -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" !== "production" ? 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; - } +var _assign = require('object-assign'); - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; +var ReactComponent = require('./ReactComponent'); +var ReactElement = require('./ReactElement'); +var ReactPropTypeLocations = require('./ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); +var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue'); - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } +var emptyObject = require('fbjs/lib/emptyObject'); +var invariant = require('fbjs/lib/invariant'); +var keyMirror = require('fbjs/lib/keyMirror'); +var keyOf = require('fbjs/lib/keyOf'); +var warning = require('fbjs/lib/warning'); - 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" !== "production" ? 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" !== "production" ? 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" !== "production" ? 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 = {}; +var MIXINS_KEY = keyOf({ mixins: null }); /** - * 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 + * Policies that describe methods in `ReactClassInterface`. */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - +var SpecPolicy = keyMirror({ /** - * Checks whether a property name is a standard property. - * @type {Object} + * These methods may be defined only once by the class specification or mixin. */ - isStandardName: {}, - + DEFINE_ONCE: null, /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} + * These methods may be defined by both the class specification and mixins. + * Subsequent definitions will be chained. These methods must return void. */ - getPossibleStandardName: {}, - + DEFINE_MANY: null, /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} + * These methods are overriding the base class. */ - getAttributeName: {}, - + OVERRIDE_BASE: null, /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} + * These methods are similar to DEFINE_MANY, except we assume they return + * objects. We try to merge the keys of the return values of all the mixed in + * functions. If there is a key conflict we throw. */ - getPropertyName: {}, + DEFINE_MANY_MERGED: null +}); - /** - * 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: {}, +var injectedMixins = []; - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, +/** + * Composite components are higher-level components that compose other composite + * or native components. + * + * To create a new type of `ReactClass`, pass a specification of + * your new class to `React.createClass`. The only requirement of your class + * specification is that you implement a `render` method. + * + * var MyComponent = React.createClass({ + * render: function() { + * return

; + * } + * }); + * + * 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 be available on the prototype. + * + * @interface ReactClassInterface + * @internal + */ +var ReactClassInterface = { /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} + * An array of Mixin objects to include when defining your component. + * + * @type {array} + * @optional */ - mustUseProperty: {}, + mixins: SpecPolicy.DEFINE_MANY, /** - * 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} + * An object containing properties and methods that should be defined on + * the component's constructor instead of its prototype (static methods). + * + * @type {object} + * @optional */ - hasSideEffects: {}, + statics: SpecPolicy.DEFINE_MANY, /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} + * Definition of prop types for this component. + * + * @type {object} + * @optional */ - hasBooleanValue: {}, + propTypes: SpecPolicy.DEFINE_MANY, /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} + * Definition of context types for this component. + * + * @type {object} + * @optional */ - hasNumericValue: {}, + contextTypes: SpecPolicy.DEFINE_MANY, /** - * 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} + * Definition of context types this component sets for its children. + * + * @type {object} + * @optional */ - hasPositiveNumericValue: {}, + childContextTypes: SpecPolicy.DEFINE_MANY, - /** - * 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: {}, + // ==== Definition methods ==== /** - * 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. + * 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). * - * 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; - -},{"./invariant":135}],10:[function(require,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 = require("./DOMProperty"); - -var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser"); -var warning = require("./warning"); - -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" !== "production") { - 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" !== "production" ? 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. + * This method is invoked before `getInitialState` and therefore cannot rely + * on `this.state` or use `this.setState`. * - * @param {string} id Unescaped ID. - * @return {string} Markup string. + * @return {object} + * @optional */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); - }, + getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, /** - * Creates markup for a property. + * 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() + * } + * } * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. + * @return {object} + * @optional */ - 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" !== "production") { - warnUnknownProperty(name); - } - return null; - }, + getInitialState: SpecPolicy.DEFINE_MANY_MERGED, /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value + * @return {object} + * @optional */ - 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" !== "production") { - warnUnknownProperty(name); - } - }, + getChildContext: SpecPolicy.DEFINE_MANY_MERGED, /** - * Deletes the value for a property on a node. + * 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}!
; + * } * - * @param {DOMElement} node - * @param {string} name + * @return {ReactComponent} + * @nosideeffects + * @required */ - 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" !== "production") { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -},{"./DOMProperty":9,"./quoteAttributeValueForBrowser":147,"./warning":154}],11:[function(require,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 = require("./ExecutionEnvironment"); - -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); - -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(' ')); -} + render: SpecPolicy.DEFINE_ONCE, -var Danger = { + // ==== Delegate methods ==== /** - * 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. + * 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`. * - * @param {array} markupList List of markup strings to render. - * @return {array} List of rendered nodes. - * @internal + * @optional */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== "production" ? 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" !== "production" ? 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