UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

556 lines (472 loc) 56.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _taggedTemplateLiteral2 = require('babel-runtime/helpers/taggedTemplateLiteral'); var _taggedTemplateLiteral3 = _interopRequireDefault(_taggedTemplateLiteral2); var _class, _temp; var _templateObject = (0, _taggedTemplateLiteral3.default)(['\n display: flex;\n flex-direction: column;\n background-color: ', ';\n box-shadow: ', ';\n\n :focus {\n outline: 0;\n }\n'], ['\n display: flex;\n flex-direction: column;\n background-color: ', ';\n box-shadow: ', ';\n\n :focus {\n outline: 0;\n }\n']), _templateObject2 = (0, _taggedTemplateLiteral3.default)(['\n padding: 8px;\n'], ['\n padding: 8px;\n']), _templateObject3 = (0, _taggedTemplateLiteral3.default)(['\n ', '\n :hover {\n cursor: pointer;\n background-color: ', ';\n }\n'], ['\n ', '\n :hover {\n cursor: pointer;\n background-color: ', ';\n }\n']), _templateObject4 = (0, _taggedTemplateLiteral3.default)(['\n position: absolute;\n right: 15px;\n top: 14px;\n color: ', ';\n'], ['\n position: absolute;\n right: 15px;\n top: 14px;\n color: ', ';\n']); // Copyright (c) 2018 Uber Technologies, Inc. // // 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. var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _fuzzy = require('fuzzy'); var _fuzzy2 = _interopRequireDefault(_fuzzy); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _styledComponents = require('styled-components'); var _styledComponents2 = _interopRequireDefault(_styledComponents); var _window = require('global/window'); var _accessor = require('./accessor'); var _accessor2 = _interopRequireDefault(_accessor); var _keyevent = require('./keyevent'); var _keyevent2 = _interopRequireDefault(_keyevent); var _dropdownList = require('./dropdown-list'); var _dropdownList2 = _interopRequireDefault(_dropdownList); var _icons = require('../icons'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_CLASS = 'typeahead'; /** * Copied mostly from 'react-typeahead', an auto-completing text input * * Renders an text input that shows options nearby that you can use the * keyboard or mouse to select. */ var TypeaheadWrapper = _styledComponents2.default.div(_templateObject, function (props) { return props.theme.dropdownListBgd; }, function (props) { return props.theme.dropdownListShadow; }); var InputBox = _styledComponents2.default.div(_templateObject2); var TypeaheadInput = _styledComponents2.default.input(_templateObject3, function (props) { return props.theme.secondaryInput; }, function (props) { return props.theme.secondaryInputBgd; }); var InputIcon = _styledComponents2.default.div(_templateObject4, function (props) { return props.theme.inputPlaceholderColor; }); var Typeahead = (_temp = _class = function (_Component) { (0, _inherits3.default)(Typeahead, _Component); function Typeahead(props) { (0, _classCallCheck3.default)(this, Typeahead); var _this = (0, _possibleConstructorReturn3.default)(this, (Typeahead.__proto__ || Object.getPrototypeOf(Typeahead)).call(this, props)); _this._onOptionSelected = function (option, event) { if (_this.props.searchable) { // reset entry input _this.setState({ searchResults: _this.getOptionsForValue('', _this.props.options), selection: '', entryValue: '' }); } return _this.props.onOptionSelected(option, event); }; _this._onTextEntryUpdated = function () { if (_this.props.searchable) { var value = _this.entry.value; _this.setState({ searchResults: _this.getOptionsForValue(value, _this.props.options), selection: '', entryValue: value }); } }; _this._onEnter = function (event) { var selection = _this.getSelection(); if (!selection) { return _this.props.onKeyDown(event); } return _this._onOptionSelected(selection, event); }; _this.navDown = function () { _this._nav(1); }; _this.navUp = function () { _this._nav(-1); }; _this._onChange = function (event) { if (_this.props.onChange) { _this.props.onChange(event); } _this._onTextEntryUpdated(); }; _this._onKeyDown = function (event) { // If there are no visible elements, don't perform selector navigation. // Just pass this up to the upstream onKeydown handler. // Also skip if the user is pressing the shift key, since none of our handlers are looking for shift if (!_this._hasHint() || event.shiftKey) { return _this.props.onKeyDown(event); } var handler = _this.eventMap()[event.keyCode]; if (handler) { handler(event); } else { return _this.props.onKeyDown(event); } // Don't propagate the keystroke back to the DOM/browser event.preventDefault(); }; _this._onFocus = function (event) { _this.setState({ isFocused: true }); if (_this.props.onFocus) { return _this.props.onFocus(event); } }; _this._onBlur = function (event) { _this.setState({ isFocused: false }); if (_this.props.onBlur) { return _this.props.onBlur(event); } }; _this.state = { searchResults: _this.getOptionsForValue(_this.props.initialValue, _this.props.options), // This should be called something else, 'entryValue' entryValue: _this.props.value || _this.props.initialValue, // A valid typeahead value selection: _this.props.value, // Index of the selection selectionIndex: null, // Keep track of the focus state of the input element, to determine // whether to show options when empty (if showOptionsWhenEmpty is true) isFocused: false }; return _this; } (0, _createClass3.default)(Typeahead, [{ key: 'componentDidMount', value: function componentDidMount() { this.setState({ searchResults: this.getOptionsForValue('', this.props.options) }); // call focus on entry or div to trigger key events listener if (this.entry) { this.entry.focus(); } else { this.root.focus(); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var searchResults = this.getOptionsForValue(this.state.entryValue, nextProps.options); this.setState({ searchResults: searchResults }); } }, { key: '_shouldSkipSearch', value: function _shouldSkipSearch(input) { var emptyValue = !input || input.trim().length === 0; // this.state must be checked because it may not be defined yet if this function // is called from within getInitialState var isFocused = this.state && this.state.isFocused; return !(this.props.showOptionsWhenEmpty && isFocused) && emptyValue; } }, { key: 'getOptionsForValue', value: function getOptionsForValue(value, options) { if (!this.props.searchable) { // directly pass through options if can not be searched return options; } if (this._shouldSkipSearch(value)) { return options; } var searchOptions = this._generateSearchFunction(); return searchOptions(value, options); } }, { key: 'focus', value: function focus() { if (this.entry) { this.entry.focus(); } } }, { key: '_hasCustomValue', value: function _hasCustomValue() { return this.props.allowCustomValues > 0 && this.state.entryValue.length >= this.props.allowCustomValues && this.state.searchResults.indexOf(this.state.entryValue) < 0; } }, { key: '_getCustomValue', value: function _getCustomValue() { return this._hasCustomValue() ? this.state.entryValue : null; } }, { key: '_renderIncrementalSearchResults', value: function _renderIncrementalSearchResults() { return _react2.default.createElement(this.props.customListComponent, { fixedOptions: this.props.fixedOptions, options: this.props.maxVisible ? this.state.searchResults.slice(0, this.props.maxVisible) : this.state.searchResults, areResultsTruncated: this.props.maxVisible && this.state.searchResults.length > this.props.maxVisible, resultsTruncatedMessage: this.props.resultsTruncatedMessage, onOptionSelected: this._onOptionSelected, allowCustomValues: this.props.allowCustomValues, customValue: this._getCustomValue(), customClasses: this.props.customClasses, customListItemComponent: this.props.customListItemComponent, customListHeaderComponent: this.props.customListHeaderComponent, selectionIndex: this.state.selectionIndex, defaultClassNames: this.props.defaultClassNames, displayOption: this.props.displayOption, selectedItems: this.props.selectedItems }); } }, { key: 'getSelection', value: function getSelection() { var index = this.state.selectionIndex; if (this._hasCustomValue()) { if (index === 0) { return this.state.entryValue; } index--; } if (this._hasFixedOptions()) { return index < this.props.fixedOptions.length ? this.props.fixedOptions[index] : this.state.searchResults[index - this.props.fixedOptions.length]; } return this.state.searchResults[index]; } // use () => {} to avoid binding 'this' }, { key: '_onEscape', value: function _onEscape() { this.setState({ selectionIndex: null }); } }, { key: '_onTab', value: function _onTab(event) { var selection = this.getSelection(); var option = selection ? selection : this.state.searchResults.length > 0 ? this.state.searchResults[0] : null; if (option === null && this._hasCustomValue()) { option = this._getCustomValue(); } if (option !== null) { return this._onOptionSelected(option, event); } } }, { key: 'eventMap', value: function eventMap(event) { var events = {}; events[_keyevent2.default.DOM_VK_UP] = this.navUp; events[_keyevent2.default.DOM_VK_DOWN] = this.navDown; events[_keyevent2.default.DOM_VK_RETURN] = events[_keyevent2.default.DOM_VK_ENTER] = this._onEnter; events[_keyevent2.default.DOM_VK_ESCAPE] = this._onEscape; events[_keyevent2.default.DOM_VK_TAB] = this._onTab; return events; } }, { key: '_nav', value: function _nav(delta) { if (!this._hasHint()) { return; } var newIndex = this.state.selectionIndex === null ? delta === 1 ? 0 : delta : this.state.selectionIndex + delta; var length = this.props.maxVisible ? this.state.searchResults.slice(0, this.props.maxVisible).length : this.state.searchResults.length; if (this._hasCustomValue()) { length += 1; } if (newIndex < 0) { newIndex += length; } else if (newIndex >= length) { newIndex -= length; } this.setState({ selectionIndex: newIndex }); } }, { key: '_renderHiddenInput', value: function _renderHiddenInput() { if (!this.props.name) { return null; } return _react2.default.createElement('input', { type: 'hidden', name: this.props.name, value: this.state.selection }); } }, { key: '_generateSearchFunction', value: function _generateSearchFunction() { var searchOptionsProp = this.props.searchOptions; var filterOptionProp = this.props.filterOption; if (typeof searchOptionsProp === 'function') { if (filterOptionProp !== null) { _window.console.warn('searchOptions prop is being used, filterOption prop will be ignored'); } return searchOptionsProp; } else if (typeof filterOptionProp === 'function') { // use custom filter option return function (value, options) { return options.filter(function (o) { return filterOptionProp(value, o); }); }; } var mapper = typeof filterOptionProp === 'string' ? _accessor2.default.generateAccessor(filterOptionProp) : _accessor2.default.IDENTITY_FN; return function (value, options) { return _fuzzy2.default.filter(value, options, { extract: mapper }).map(function (res) { return options[res.index]; }); }; } }, { key: '_hasHint', value: function _hasHint() { return this.state.searchResults.length > 0 || this._hasCustomValue(); } }, { key: '_hasFixedOptions', value: function _hasFixedOptions() { return Array.isArray(this.props.fixedOptions) && this.props.fixedOptions.length; } }, { key: 'render', value: function render() { var _this2 = this; var inputClasses = {}; inputClasses[this.props.customClasses.input] = Boolean(this.props.customClasses.input); var inputClassList = (0, _classnames2.default)(inputClasses); var classes = (0, _defineProperty3.default)({}, DEFAULT_CLASS, this.props.defaultClassNames); classes[this.props.className] = Boolean(this.props.className); var classList = (0, _classnames2.default)(classes); return _react2.default.createElement( TypeaheadWrapper, { className: classList, innerRef: function innerRef(comp) { _this2.root = comp; }, tabIndex: '0', onKeyDown: this._onKeyDown, onKeyPress: this.props.onKeyPress, onKeyUp: this.props.onKeyUp, onFocus: this._onFocus }, this._renderHiddenInput(), this.props.searchable ? _react2.default.createElement( InputBox, null, _react2.default.createElement(TypeaheadInput, (0, _extends3.default)({ innerRef: function innerRef(comp) { _this2.entry = comp; }, type: 'text', disabled: this.props.disabled }, this.props.inputProps, { placeholder: this.props.placeholder, className: inputClassList, value: this.state.entryValue, onChange: this._onChange, onBlur: this._onBlur })), _react2.default.createElement( InputIcon, null, _react2.default.createElement(_icons.Search, { height: '18px' }) ) ) : null, this._renderIncrementalSearchResults() ); } }]); return Typeahead; }(_react.Component), _class.propTypes = { name: _propTypes2.default.string, customClasses: _propTypes2.default.object, maxVisible: _propTypes2.default.number, resultsTruncatedMessage: _propTypes2.default.string, options: _propTypes2.default.arrayOf(_propTypes2.default.any), fixedOptions: _propTypes2.default.arrayOf(_propTypes2.default.any), allowCustomValues: _propTypes2.default.number, initialValue: _propTypes2.default.string, value: _propTypes2.default.string, placeholder: _propTypes2.default.string, disabled: _propTypes2.default.bool, textarea: _propTypes2.default.bool, inputProps: _propTypes2.default.object, onOptionSelected: _propTypes2.default.func, onChange: _propTypes2.default.func, onKeyDown: _propTypes2.default.func, onKeyPress: _propTypes2.default.func, onKeyUp: _propTypes2.default.func, onFocus: _propTypes2.default.func, onBlur: _propTypes2.default.func, filterOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), searchOptions: _propTypes2.default.func, displayOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), inputDisplayOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), formInputOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), defaultClassNames: _propTypes2.default.bool, customListComponent: _propTypes2.default.oneOfType([_propTypes2.default.element, _propTypes2.default.func]), customListItemComponent: _propTypes2.default.oneOfType([_propTypes2.default.element, _propTypes2.default.func]), customListHeaderComponent: _propTypes2.default.oneOfType([_propTypes2.default.element, _propTypes2.default.func]), showOptionsWhenEmpty: _propTypes2.default.bool, searchable: _propTypes2.default.bool }, _class.defaultProps = { options: [], customClasses: {}, allowCustomValues: 0, initialValue: '', value: '', placeholder: '', disabled: false, textarea: false, inputProps: {}, onOptionSelected: function onOptionSelected(option) {}, onChange: function onChange(event) {}, onKeyDown: function onKeyDown(event) {}, onKeyPress: function onKeyPress(event) {}, onKeyUp: function onKeyUp(event) {}, onFocus: function onFocus(event) {}, onBlur: function onBlur(event) {}, filterOption: null, searchOptions: null, inputDisplayOption: null, defaultClassNames: true, customListComponent: _dropdownList2.default, customListItemComponent: _dropdownList.ListItem, customListHeaderComponent: null, showOptionsWhenEmpty: true, searchable: true, resultsTruncatedMessage: null }, _temp); exports.default = Typeahead; ; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2NvbW1vbi9pdGVtLXNlbGVjdG9yL3R5cGVhaGVhZC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0NMQVNTIiwiVHlwZWFoZWFkV3JhcHBlciIsInN0eWxlZCIsImRpdiIsInByb3BzIiwidGhlbWUiLCJkcm9wZG93bkxpc3RCZ2QiLCJkcm9wZG93bkxpc3RTaGFkb3ciLCJJbnB1dEJveCIsIlR5cGVhaGVhZElucHV0IiwiaW5wdXQiLCJzZWNvbmRhcnlJbnB1dCIsInNlY29uZGFyeUlucHV0QmdkIiwiSW5wdXRJY29uIiwiaW5wdXRQbGFjZWhvbGRlckNvbG9yIiwiVHlwZWFoZWFkIiwiX29uT3B0aW9uU2VsZWN0ZWQiLCJvcHRpb24iLCJldmVudCIsInNlYXJjaGFibGUiLCJzZXRTdGF0ZSIsInNlYXJjaFJlc3VsdHMiLCJnZXRPcHRpb25zRm9yVmFsdWUiLCJvcHRpb25zIiwic2VsZWN0aW9uIiwiZW50cnlWYWx1ZSIsIm9uT3B0aW9uU2VsZWN0ZWQiLCJfb25UZXh0RW50cnlVcGRhdGVkIiwidmFsdWUiLCJlbnRyeSIsIl9vbkVudGVyIiwiZ2V0U2VsZWN0aW9uIiwib25LZXlEb3duIiwibmF2RG93biIsIl9uYXYiLCJuYXZVcCIsIl9vbkNoYW5nZSIsIm9uQ2hhbmdlIiwiX29uS2V5RG93biIsIl9oYXNIaW50Iiwic2hpZnRLZXkiLCJoYW5kbGVyIiwiZXZlbnRNYXAiLCJrZXlDb2RlIiwicHJldmVudERlZmF1bHQiLCJfb25Gb2N1cyIsImlzRm9jdXNlZCIsIm9uRm9jdXMiLCJfb25CbHVyIiwib25CbHVyIiwic3RhdGUiLCJpbml0aWFsVmFsdWUiLCJzZWxlY3Rpb25JbmRleCIsImZvY3VzIiwicm9vdCIsIm5leHRQcm9wcyIsImVtcHR5VmFsdWUiLCJ0cmltIiwibGVuZ3RoIiwic2hvd09wdGlvbnNXaGVuRW1wdHkiLCJfc2hvdWxkU2tpcFNlYXJjaCIsInNlYXJjaE9wdGlvbnMiLCJfZ2VuZXJhdGVTZWFyY2hGdW5jdGlvbiIsImFsbG93Q3VzdG9tVmFsdWVzIiwiaW5kZXhPZiIsIl9oYXNDdXN0b21WYWx1ZSIsImZpeGVkT3B0aW9ucyIsIm1heFZpc2libGUiLCJzbGljZSIsInJlc3VsdHNUcnVuY2F0ZWRNZXNzYWdlIiwiX2dldEN1c3RvbVZhbHVlIiwiY3VzdG9tQ2xhc3NlcyIsImN1c3RvbUxpc3RJdGVtQ29tcG9uZW50IiwiY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudCIsImRlZmF1bHRDbGFzc05hbWVzIiwiZGlzcGxheU9wdGlvbiIsInNlbGVjdGVkSXRlbXMiLCJpbmRleCIsIl9oYXNGaXhlZE9wdGlvbnMiLCJldmVudHMiLCJLZXlFdmVudCIsIkRPTV9WS19VUCIsIkRPTV9WS19ET1dOIiwiRE9NX1ZLX1JFVFVSTiIsIkRPTV9WS19FTlRFUiIsIkRPTV9WS19FU0NBUEUiLCJfb25Fc2NhcGUiLCJET01fVktfVEFCIiwiX29uVGFiIiwiZGVsdGEiLCJuZXdJbmRleCIsIm5hbWUiLCJzZWFyY2hPcHRpb25zUHJvcCIsImZpbHRlck9wdGlvblByb3AiLCJmaWx0ZXJPcHRpb24iLCJDb25zb2xlIiwid2FybiIsImZpbHRlciIsIm8iLCJtYXBwZXIiLCJBY2Nlc3NvciIsImdlbmVyYXRlQWNjZXNzb3IiLCJJREVOVElUWV9GTiIsImZ1enp5IiwiZXh0cmFjdCIsIm1hcCIsInJlcyIsIkFycmF5IiwiaXNBcnJheSIsImlucHV0Q2xhc3NlcyIsIkJvb2xlYW4iLCJpbnB1dENsYXNzTGlzdCIsImNsYXNzZXMiLCJjbGFzc05hbWUiLCJjbGFzc0xpc3QiLCJjb21wIiwib25LZXlQcmVzcyIsIm9uS2V5VXAiLCJfcmVuZGVySGlkZGVuSW5wdXQiLCJkaXNhYmxlZCIsImlucHV0UHJvcHMiLCJwbGFjZWhvbGRlciIsIl9yZW5kZXJJbmNyZW1lbnRhbFNlYXJjaFJlc3VsdHMiLCJDb21wb25lbnQiLCJwcm9wVHlwZXMiLCJQcm9wVHlwZXMiLCJzdHJpbmciLCJvYmplY3QiLCJudW1iZXIiLCJhcnJheU9mIiwiYW55IiwiYm9vbCIsInRleHRhcmVhIiwiZnVuYyIsIm9uZU9mVHlwZSIsImlucHV0RGlzcGxheU9wdGlvbiIsImZvcm1JbnB1dE9wdGlvbiIsImN1c3RvbUxpc3RDb21wb25lbnQiLCJlbGVtZW50IiwiZGVmYXVsdFByb3BzIiwiRHJvcGRvd25MaXN0IiwiTGlzdEl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7dU5BQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOztBQUVBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUEsSUFBTUEsZ0JBQWdCLFdBQXRCO0FBQ0E7Ozs7Ozs7QUFPQSxJQUFNQyxtQkFBbUJDLDJCQUFPQyxHQUExQixrQkFHZ0I7QUFBQSxTQUFTQyxNQUFNQyxLQUFOLENBQVlDLGVBQXJCO0FBQUEsQ0FIaEIsRUFJVTtBQUFBLFNBQVNGLE1BQU1DLEtBQU4sQ0FBWUUsa0JBQXJCO0FBQUEsQ0FKVixDQUFOOztBQVdBLElBQU1DLFdBQVdOLDJCQUFPQyxHQUFsQixrQkFBTjs7QUFJQSxJQUFNTSxpQkFBaUJQLDJCQUFPUSxLQUF4QixtQkFDRjtBQUFBLFNBQVNOLE1BQU1DLEtBQU4sQ0FBWU0sY0FBckI7QUFBQSxDQURFLEVBSWtCO0FBQUEsU0FBU1AsTUFBTUMsS0FBTixDQUFZTyxpQkFBckI7QUFBQSxDQUpsQixDQUFOOztBQVFBLElBQU1DLFlBQVlYLDJCQUFPQyxHQUFuQixtQkFJSztBQUFBLFNBQVNDLE1BQU1DLEtBQU4sQ0FBWVMscUJBQXJCO0FBQUEsQ0FKTCxDQUFOOztJQU9xQkMsUzs7O0FBc0VuQixxQkFBWVgsS0FBWixFQUFtQjtBQUFBOztBQUFBLG9JQUNYQSxLQURXOztBQUFBLFVBbUluQlksaUJB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QUFjLElBakJNO0FBa0JwQmpDLGlCQUFlLElBbEJLO0FBbUJwQjBFLHNCQUFvQixJQW5CQTtBQW9CcEI3RCxxQkFBbUIsSUFwQkM7QUFxQnBCK0QsdUJBQXFCRyxzQkFyQkQ7QUFzQnBCcEUsMkJBQXlCcUUsc0JBdEJMO0FBdUJwQnBFLDZCQUEyQixJQXZCUDtBQXdCcEJkLHdCQUFzQixJQXhCRjtBQXlCcEJ4QyxjQUFZLElBekJRO0FBMEJwQmtELDJCQUF5QjtBQTFCTCxDO2tCQXpDSHRELFM7QUE4YnBCIiwiZmlsZSI6InR5cGVhaGVhZC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAxOCBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBmdXp6eSBmcm9tICdmdXp6eSc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtjb25zb2xlIGFzIENvbnNvbGV9IGZyb20gJ2dsb2JhbC93aW5kb3cnO1xuXG5pbXBvcnQgQWNjZXNzb3IgZnJvbSAnLi9hY2Nlc3Nvcic7XG5pbXBvcnQgS2V5RXZlbnQgZnJvbSAnLi9rZXlldmVudCc7XG5pbXBvcnQgRHJvcGRvd25MaXN0LCB7TGlzdEl0ZW19IGZyb20gJy4vZHJvcGRvd24tbGlzdCc7XG5pbXBvcnQge1NlYXJjaH0gZnJvbSAnY29tcG9uZW50cy9jb21tb24vaWNvbnMnO1xuXG5jb25zdCBERUZBVUxUX0NMQVNTID0gJ3R5cGVhaGVhZCc7XG4vKipcbiAqIENvcGllZCBtb3N0bHkgZnJvbSAncmVhY3QtdHlwZWFoZWFkJywgYW4gYXV0by1jb21wbGV0aW5nIHRleHQgaW5wdXRcbiAqXG4gKiBSZW5kZXJzIGFuIHRleHQgaW5wdXQgdGhhdCBzaG93cyBvcHRpb25zIG5lYXJieSB0aGF0IHlvdSBjYW4gdXNlIHRoZVxuICoga2V5Ym9hcmQgb3IgbW91c2UgdG8gc2VsZWN0LlxuICovXG5cbmNvbnN0IFR5cGVhaGVhZFdyYXBwZXIgPSBzdHlsZWQuZGl2YFxuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmRyb3Bkb3duTGlzdEJnZH07XG4gIGJveC1zaGFkb3c6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZHJvcGRvd25MaXN0U2hhZG93fTtcblxuICA6Zm9jdXMge1xuICAgIG91dGxpbmU6IDA7XG4gIH1cbmA7XG5cbmNvbnN0IElucHV0Qm94ID0gc3R5bGVkLmRpdmBcbiAgcGFkZGluZzogOHB4O1xuYDtcblxuY29uc3QgVHlwZWFoZWFkSW5wdXQgPSBzdHlsZWQuaW5wdXRgXG4gICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuc2Vjb25kYXJ5SW5wdXR9XG4gIDpob3ZlciB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuc2Vjb25kYXJ5SW5wdXRCZ2R9O1xuICB9XG5gO1xuXG5jb25zdCBJbnB1dEljb24gPSBzdHlsZWQuZGl2YFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHJpZ2h0OiAxNXB4O1xuICB0b3A6IDE0cHg7XG4gIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmlucHV0UGxhY2Vob2xkZXJDb2xvcn07XG5gO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUeXBlYWhlYWQgZXh0ZW5kcyBDb21wb25lbnQge1xuICBzdGF0aWMgcHJvcFR5cGVzID0ge1xuICAgIG5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgY3VzdG9tQ2xhc3NlczogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBtYXhWaXNpYmxlOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIHJlc3VsdHNUcnVuY2F0ZWRNZXNzYWdlOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIG9wdGlvbnM6IFByb3BUeXBlcy5hcnJheU9mKFByb3BUeXBlcy5hbnkpLFxuICAgIGZpeGVkT3B0aW9uczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSksXG4gICAgYWxsb3dDdXN0b21WYWx1ZXM6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgaW5pdGlhbFZhbHVlOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIHZhbHVlOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIHBsYWNlaG9sZGVyOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGRpc2FibGVkOiBQcm9wVHlwZXMuYm9vbCxcbiAgICB0ZXh0YXJlYTogUHJvcFR5cGVzLmJvb2wsXG4gICAgaW5wdXRQcm9wczogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBvbk9wdGlvblNlbGVjdGVkOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMsXG4gICAgb25LZXlEb3duOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbktleVByZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbktleVVwOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbkZvY3VzOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbkJsdXI6IFByb3BUeXBlcy5mdW5jLFxuICAgIGZpbHRlck9wdGlvbjogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLnN0cmluZywgUHJvcFR5cGVzLmZ1bmNdKSxcbiAgICBzZWFyY2hPcHRpb25zOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBkaXNwbGF5T3B0aW9uOiBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIGlucHV0RGlzcGxheU9wdGlvbjogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLnN0cmluZywgUHJvcFR5cGVzLmZ1bmNdKSxcbiAgICBmb3JtSW5wdXRPcHRpb246IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5mdW5jXSksXG4gICAgZGVmYXVsdENsYXNzTmFtZXM6IFByb3BUeXBlcy5ib29sLFxuICAgIGN1c3RvbUxpc3RDb21wb25lbnQ6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5lbGVtZW50LCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIGN1c3RvbUxpc3RJdGVtQ29tcG9uZW50OiBQcm9wVHlwZXMub25lT2ZUeXBlKFtcbiAgICAgIFByb3BUeXBlcy5lbGVtZW50LFxuICAgICAgUHJvcFR5cGVzLmZ1bmNcbiAgICBdKSxcbiAgICBjdXN0b21MaXN0SGVhZGVyQ29tcG9uZW50OiBQcm9wVHlwZXMub25lT2ZUeXBlKFtcbiAgICAgIFByb3BUeXBlcy5lbGVtZW50LFxuICAgICAgUHJvcFR5cGVzLmZ1bmNcbiAgICBdKSxcbiAgICBzaG93T3B0aW9uc1doZW5FbXB0eTogUHJvcFR5cGVzLmJvb2wsXG4gICAgc2VhcmNoYWJsZTogUHJvcFR5cGVzLmJvb2xcbiAgfTtcblxuICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgIG9wdGlvbnM6IFtdLFxuICAgIGN1c3RvbUNsYXNzZXM6IHt9LFxuICAgIGFsbG93Q3VzdG9tVmFsdWVzOiAwLFxuICAgIGluaXRpYWxWYWx1ZTogJycsXG4gICAgdmFsdWU6ICcnLFxuICAgIHBsYWNlaG9sZGVyOiAnJyxcbiAgICBkaXNhYmxlZDogZmFsc2UsXG4gICAgdGV4dGFyZWE6IGZhbHNlLFxuICAgIGlucHV0UHJvcHM6IHt9LFxuICAgIG9uT3B0aW9uU2VsZWN0ZWQob3B0aW9uKSB7fSxcbiAgICBvbkNoYW5nZShldmVudCkge30sXG4gICAgb25LZXlEb3duKGV2ZW50KSB7fSxcbiAgICBvbktleVByZXNzKGV2ZW50KSB7fSxcbiAgICBvbktleVVwKGV2ZW50KSB7fSxcbiAgICBvbkZvY3VzKGV2ZW50KSB7fSxcbiAgICBvbkJsdXIoZXZlbnQpIHt9LFxuICAgIGZpbHRlck9wdGlvbjogbnVsbCxcbiAgICBzZWFyY2hPcHRpb25zOiBudWxsLFxuICAgIGlucHV0RGlzcGxheU9wdGlvbjogbnVsbCxcbiAgICBkZWZhdWx0Q2xhc3NOYW1lczogdHJ1ZSxcbiAgICBjdXN0b21MaXN0Q29tcG9uZW50OiBEcm9wZG93bkxpc3QsXG4gICAgY3VzdG9tTGlzdEl0ZW1Db21wb25lbnQ6IExpc3RJdGVtLFxuICAgIGN1c3RvbUxpc3RIZWFkZXJDb21wb25lbnQ6IG51bGwsXG4gICAgc2hvd09wdGlvbnNXaGVuRW1wdHk6IHRydWUsXG4gICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICByZXN1bHRzVHJ1bmNhdGVkTWVzc2FnZTogbnVsbFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHNlYXJjaFJlc3VsdHM6IHRoaXMuZ2V0T3B0aW9uc0ZvclZhbHVlKFxuICAgICAgICB0aGlzLnByb3BzLmluaXRpYWxWYWx1ZSxcbiAgICAgICAgdGhpcy5wcm9wcy5vcHRpb25zXG4gICAgICApLFxuXG4gICAgICAvLyBUaGlzIHNob3VsZCBiZSBjYWxsZWQgc29tZXRoaW5nIGVsc2UsICdlbnRyeVZhbHVlJ1xuICAgICAgZW50cnlWYWx1ZTogdGhpcy5wcm9wcy52YWx1ZSB8fCB0aGlzLnByb3BzLmluaXRpYWxWYWx1ZSxcblxuICAgICAgLy8gQSB2YWxpZCB0eXBlYWhlYWQgdmFsdWVcbiAgICAgIHNlbGVjdGlvbjogdGhpcy5wcm9wcy52YWx1ZSxcblxuICAgICAgLy8gSW5kZXggb2YgdGhlIHNlbGVjdGlvblxuICAgICAgc2VsZWN0aW9uSW5kZXg6IG51bGwsXG5cbiAgICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIGZvY3VzIHN0YXRlIG9mIHRoZSBpbnB1dCBlbGVtZW50LCB0byBkZXRlcm1pbmVcbiAgICAgIC8vIHdoZXRoZXIgdG8gc2hvdyBvcHRpb25zIHdoZW4gZW1wdHkgKGlmIHNob3dPcHRpb25zV2hlbkVtcHR5IGlzIHRydWUpXG4gICAgICBpc0ZvY3VzZWQ6IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgc2VhcmNoUmVzdWx0czogdGhpcy5nZXRPcHRpb25zRm9yVmFsdWUoJycsIHRoaXMucHJvcHMub3B0aW9ucylcbiAgICB9KTtcblxuICAgIC8vIGNhbGwgZm9jdXMgb24gZW50cnkgb3IgZGl2IHRvIHRyaWdnZXIga2V5IGV2ZW50cyBsaXN0ZW5lclxuICAgIGlmICh0aGlzLmVudHJ5KSB7XG4gICAgICB0aGlzLmVudHJ5LmZvY3VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm9vdC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgY29uc3Qgc2VhcmNoUmVzdWx0cyA9IHRoaXMuZ2V0T3B0aW9uc0ZvclZhbHVlKFxuICAgICAgdGhpcy5zdGF0ZS5lbnRyeVZhbHVlLFxuICAgICAgbmV4dFByb3BzLm9wdGlvbnNcbiAgICApO1xuXG4gICAgdGhpcy5zZXRTdGF0ZSh7c2VhcmNoUmVzdWx0c30pO1xuICB9XG5cbiAgX3Nob3VsZFNraXBTZWFyY2goaW5wdXQpIHtcbiAgICBjb25zdCBlbXB0eVZhbHVlID0gIWlucHV0IHx8IGlucHV0LnRyaW0oKS5sZW5ndGggPT09IDA7XG5cbiAgICAvLyB0aGlzLnN0YXRlIG11c3QgYmUgY2hlY2tlZCBiZWNhdXNlIGl0IG1heSBub3QgYmUgZGVmaW5lZCB5ZXQgaWYgdGhpcyBmdW5jdGlvblxuICAgIC8vIGlzIGNhbGxlZCBmcm9tIHdpdGhpbiBnZXRJbml0aWFsU3RhdGVcbiAgICBjb25zdCBpc0ZvY3VzZWQgPSB0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuaXNGb2N1c2VkO1xuICAgIHJldHVybiAhKHRoaXMucHJvcHMuc2hvd09wdGlvbnNXaGVuRW1wdHkgJiYgaXNGb2N1c2VkKSAmJiBlbXB0eVZhbHVlO1xuICB9XG5cbiAgZ2V0T3B0aW9uc0ZvclZhbHVlKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgaWYgKCF0aGlzLnByb3BzLnNlYXJjaGFibGUpIHtcbiAgICAgIC8vIGRpcmVjdGx5IHBhc3MgdGhyb3VnaCBvcHRpb25zIGlmIGNhbiBub3QgYmUgc2VhcmNoZWRcbiAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cbiAgICBpZiAodGhpcy5fc2hvdWxkU2tpcFNlYXJjaCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaE9wdGlvbnMgPSB0aGlzLl9nZW5lcmF0ZVNlYXJjaEZ1bmN0aW9uKCk7XG4gICAgcmV0dXJuIHNlYXJjaE9wdGlvbnModmFsdWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgZm9jdXMoKSB7XG4gICAgaWYgKHRoaXMuZW50cnkpIHtcbiAgICAgIHRoaXMuZW50cnkuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBfaGFzQ3VzdG9tVmFsdWUoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMucHJvcHMuYWxsb3dDdXN0b21WYWx1ZXMgPiAwICYmXG4gICAgICB0aGlzLnN0YXRlLmVudHJ5VmFsdWUubGVuZ3RoID49IHRoaXMucHJvcHMuYWxsb3dDdXN0b21WYWx1ZXMgJiZcbiAgICAgIHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5pbmRleE9mKHRoaXMuc3RhdGUuZW50cnlWYWx1ZSkgPCAwXG4gICAgKTtcbiAgfVxuXG4gIF9nZXRDdXN0b21WYWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGFzQ3VzdG9tVmFsdWUoKSA/IHRoaXMuc3RhdGUuZW50cnlWYWx1ZSA6IG51bGw7XG4gIH1cblxuICBfcmVuZGVySW5jcmVtZW50YWxTZWFyY2hSZXN1bHRzKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8dGhpcy5wcm9wcy5jdXN0b21MaXN0Q29tcG9uZW50XG4gICAgICAgIGZpeGVkT3B0aW9ucz17dGhpcy5wcm9wcy5maXhlZE9wdGlvbnN9XG4gICAgICAgIG9wdGlvbnM9e1xuICAgICAgICAgIHRoaXMucHJvcHMubWF4VmlzaWJsZVxuICAgICAgICAgICAgPyB0aGlzLnN0YXRlLnNlYXJjaFJlc3VsdHMuc2xpY2UoMCwgdGhpcy5wcm9wcy5tYXhWaXNpYmxlKVxuICAgICAgICAgICAgOiB0aGlzLnN0YXRlLnNlYXJjaFJlc3VsdHNcbiAgICAgICAgfVxuICAgICAgICBhcmVSZXN1bHRzVHJ1bmNhdGVkPXtcbiAgICAgICAgICB0aGlzLnByb3BzLm1heFZpc2libGUgJiZcbiAgICAgICAgICB0aGlzLnN0YXRlLnNlYXJjaFJlc3VsdHMubGVuZ3RoID4gdGhpcy5wcm9wcy5tYXhWaXNpYmxlXG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0c1RydW5jYXRlZE1lc3NhZ2U9e3RoaXMucHJvcHMucmVzdWx0c1RydW5jYXRlZE1lc3NhZ2V9XG4gICAgICAgIG9uT3B0aW9uU2VsZWN0ZWQ9e3RoaXMuX29uT3B0aW9uU2VsZWN0ZWR9XG4gICAgICAgIGFsbG93Q3VzdG9tVmFsdWVzPXt0aGlzLnByb3BzLmFsbG93Q3VzdG9tVmFsdWVzfVxuICAgICAgICBjdXN0b21WYWx1ZT17dGhpcy5fZ2V0Q3VzdG9tVmFsdWUoKX1cbiAgICAgICAgY3VzdG9tQ2xhc3Nlcz17dGhpcy5wcm9wcy5jdXN0b21DbGFzc2VzfVxuICAgICAgICBjdXN0b21MaXN0SXRlbUNvbXBvbmVudD17dGhpcy5wcm9wcy5jdXN0b21MaXN0SXRlbUNvbXBvbmVudH1cbiAgICAgICAgY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudD17dGhpcy5wcm9wcy5jdXN0b21MaXN0SGVhZGVyQ29tcG9uZW50fVxuICAgICAgICBzZWxlY3Rpb25JbmRleD17dGhpcy5zdGF0ZS5zZWxlY3Rpb25JbmRleH1cbiAgICAgICAgZGVmYXVsdENsYXNzTmFtZXM9e3RoaXMucHJvcHMuZGVmYXVsdENsYXNzTmFtZXN9XG4gICAgICAgIGRpc3BsYXlPcHRpb249e3RoaXMucHJvcHMuZGlzcGxheU9wdGlvbn1cbiAgICAgICAgc2VsZWN0ZWRJdGVtcz17dGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1zfVxuICAgICAgLz5cbiAgICApO1xuICB9XG5cbiAgZ2V0U2VsZWN0aW9uKCkge1xuICAgIGxldCBpbmRleCA9IHRoaXMuc3RhdGUuc2VsZWN0aW9uSW5kZXg7XG5cbiAgICBpZiAodGhpcy5faGFzQ3VzdG9tVmFsdWUoKSkge1xuICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmVudHJ5VmFsdWU7XG4gICAgICB9XG4gICAgICBpbmRleC0tO1xuICAgIH1cbiAgICBpZiAodGhpcy5faGFzRml4ZWRPcHRpb25zKCkpIHtcbiAgICAgIHJldHVybiBpbmRleCA8IHRoaXMucHJvcHMuZml4ZWRPcHRpb25zLmxlbmd0aFxuICAgICAgICA/IHRoaXMucHJvcHMuZml4ZWRPcHRpb25zW2luZGV4XVxuICAgICAgICA6IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0c1tpbmRleCAtIHRoaXMucHJvcHMuZml4ZWRPcHRpb25zLmxlbmd0aF07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0YXRlLnNlYXJjaFJlc3VsdHNbaW5kZXhdO1xuICB9XG5cbiAgX29uT3B0aW9uU2VsZWN0ZWQgPSAob3B0aW9uLCBldmVudCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLnNlYXJjaGFibGUpIHtcbiAgICAgIC8vIHJlc2V0IGVudHJ5IGlucHV0XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgc2VhcmNoUmVzdWx0czogdGhpcy5nZXRPcHRpb25zRm9yVmFsdWUoJycsIHRoaXMucHJvcHMub3B0aW9ucyksXG4gICAgICAgIHNlbGVjdGlvbjogJycsXG4gICAgICAgIGVudHJ5VmFsdWU6ICcnXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wcm9wcy5vbk9wdGlvblNlbGVjdGVkKG9wdGlvbiwgZXZlbnQpO1xuICB9O1xuXG4gIC8vIHVzZSAoKSA9PiB7fSB0byBhdm9pZCBiaW5kaW5nICd0aGlzJ1xuICBfb25UZXh0RW50cnlVcGRhdGVkID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnByb3BzLnNlYXJjaGFibGUpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5lbnRyeS52YWx1ZTtcblxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHNlYXJjaFJlc3VsdHM6IHRoaXMuZ2V0T3B0aW9uc0ZvclZhbHVlKHZhbHVlLCB0aGlzLnByb3BzLm9wdGlvbnMpLFxuICAgICAgICBzZWxlY3Rpb246ICcnLFxuICAgICAgICBlbnRyeVZhbHVlOiB2YWx1ZVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIF9vbkVudGVyID0gZXZlbnQgPT4ge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHRoaXMuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLm9uS2V5RG93bihldmVudCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9vbk9wdGlvblNlbGVjdGVkKHNlbGVjdGlvbiwgZXZlbnQpO1xuICB9O1xuXG4gIF9vbkVzY2FwZSgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHNlbGVjdGlvbkluZGV4OiBudWxsXG4gICAgfSk7XG4gIH1cblxuICBfb25UYWIoZXZlbnQpIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbigpO1xuICAgIGxldCBvcHRpb24gPSBzZWxlY3Rpb25cbiAgICAgID8gc2VsZWN0aW9uXG4gICAgICA6IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5sZW5ndGggPiAwXG4gICAgICAgID8gdGhpcy5zdGF0ZS5zZWFyY2hSZXN1bHRzWzBdXG4gICAgICAgIDogbnVsbDtcblxuICAgIGlmIChvcHRpb24gPT09IG51bGwgJiYgdGhpcy5faGFzQ3VzdG9tVmFsdWUoKSkge1xuICAgICAgb3B0aW9uID0gdGhpcy5fZ2V0Q3VzdG9tVmFsdWUoKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9uICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5fb25PcHRpb25TZWxlY3RlZChvcHRpb24sIGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBldmVudE1hcChldmVudCkge1xuICAgIGNvbnN0