kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
538 lines (463 loc) • 58 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _fuzzy = _interopRequireDefault(require("fuzzy"));
var _classnames = _interopRequireDefault(require("classnames"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _window = require("global/window");
var _accessor = _interopRequireDefault(require("./accessor"));
var _keyevent = _interopRequireDefault(require("./keyevent"));
var _dropdownList = _interopRequireWildcard(require("./dropdown-list"));
var _icons = require("../icons");
function _templateObject4() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n right: 15px;\n top: 14px;\n color: ", ";\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n ", "\n :hover {\n cursor: pointer;\n background-color: ", ";\n }\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n padding: 8px;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: column;\n background-color: ", ";\n box-shadow: ", ";\n\n :focus {\n outline: 0;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
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 = _styledComponents["default"].div(_templateObject(), function (props) {
return props.theme.dropdownListBgd;
}, function (props) {
return props.theme.dropdownListShadow;
});
var InputBox = _styledComponents["default"].div(_templateObject2());
var TypeaheadInput = _styledComponents["default"].input(_templateObject3(), function (props) {
return props.theme.secondaryInput;
}, function (props) {
return props.theme.secondaryInputBgd;
});
var InputIcon = _styledComponents["default"].div(_templateObject4(), function (props) {
return props.theme.inputPlaceholderColor;
});
var Typeahead =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(Typeahead, _Component);
function Typeahead(props) {
var _this;
(0, _classCallCheck2["default"])(this, Typeahead);
_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Typeahead).call(this, props));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_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);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onTextEntryUpdated", function () {
if (_this.props.searchable) {
var value = _this.entry.value;
_this.setState({
searchResults: _this.getOptionsForValue(value, _this.props.options),
selection: '',
entryValue: value
});
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onEnter", function (event) {
var selection = _this.getSelection();
if (!selection) {
return _this.props.onKeyDown(event);
}
return _this._onOptionSelected(selection, event);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "navDown", function () {
_this._nav(1);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "navUp", function () {
_this._nav(-1);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onChange", function (event) {
if (_this.props.onChange) {
_this.props.onChange(event);
}
_this._onTextEntryUpdated();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_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();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onFocus", function (event) {
_this.setState({
isFocused: true
});
if (_this.props.onFocus) {
return _this.props.onFocus(event);
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_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, _createClass2["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 _react["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];
}
}, {
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[_keyevent["default"].DOM_VK_UP] = this.navUp;
events[_keyevent["default"].DOM_VK_DOWN] = this.navDown;
events[_keyevent["default"].DOM_VK_RETURN] = events[_keyevent["default"].DOM_VK_ENTER] = this._onEnter;
events[_keyevent["default"].DOM_VK_ESCAPE] = this._onEscape;
events[_keyevent["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 _react["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' ? _accessor["default"].generateAccessor(filterOptionProp) : _accessor["default"].IDENTITY_FN;
return function (value, options) {
return _fuzzy["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, _classnames["default"])(inputClasses);
var classes = (0, _defineProperty2["default"])({}, DEFAULT_CLASS, this.props.defaultClassNames);
classes[this.props.className] = Boolean(this.props.className);
var classList = (0, _classnames["default"])(classes);
return _react["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 ? _react["default"].createElement(InputBox, null, _react["default"].createElement(TypeaheadInput, (0, _extends2["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
})), _react["default"].createElement(InputIcon, null, _react["default"].createElement(_icons.Search, {
height: "18px"
}))) : null, this._renderIncrementalSearchResults());
}
}]);
return Typeahead;
}(_react.Component);
exports["default"] = Typeahead;
(0, _defineProperty2["default"])(Typeahead, "propTypes", {
name: _propTypes["default"].string,
customClasses: _propTypes["default"].object,
maxVisible: _propTypes["default"].number,
resultsTruncatedMessage: _propTypes["default"].string,
options: _propTypes["default"].arrayOf(_propTypes["default"].any),
fixedOptions: _propTypes["default"].arrayOf(_propTypes["default"].any),
allowCustomValues: _propTypes["default"].number,
initialValue: _propTypes["default"].string,
value: _propTypes["default"].string,
placeholder: _propTypes["default"].string,
disabled: _propTypes["default"].bool,
textarea: _propTypes["default"].bool,
inputProps: _propTypes["default"].object,
onOptionSelected: _propTypes["default"].func,
onChange: _propTypes["default"].func,
onKeyDown: _propTypes["default"].func,
onKeyPress: _propTypes["default"].func,
onKeyUp: _propTypes["default"].func,
onFocus: _propTypes["default"].func,
onBlur: _propTypes["default"].func,
filterOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
searchOptions: _propTypes["default"].func,
displayOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
inputDisplayOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
formInputOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
defaultClassNames: _propTypes["default"].bool,
customListComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
customListItemComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
customListHeaderComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
showOptionsWhenEmpty: _propTypes["default"].bool,
searchable: _propTypes["default"].bool
});
(0, _defineProperty2["default"])(Typeahead, "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: _dropdownList["default"],
customListItemComponent: _dropdownList.ListItem,
customListHeaderComponent: null,
showOptionsWhenEmpty: true,
searchable: true,
resultsTruncatedMessage: null
});
;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2NvbW1vbi9pdGVtLXNlbGVjdG9yL3R5cGVhaGVhZC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0NMQVNTIiwiVHlwZWFoZWFkV3JhcHBlciIsInN0eWxlZCIsImRpdiIsInByb3BzIiwidGhlbWUiLCJkcm9wZG93bkxpc3RCZ2QiLCJkcm9wZG93bkxpc3RTaGFkb3ciLCJJbnB1dEJveCIsIlR5cGVhaGVhZElucHV0IiwiaW5wdXQiLCJzZWNvbmRhcnlJbnB1dCIsInNlY29uZGFyeUlucHV0QmdkIiwiSW5wdXRJY29uIiwiaW5wdXRQbGFjZWhvbGRlckNvbG9yIiwiVHlwZWFoZWFkIiwib3B0aW9uIiwiZXZlbnQiLCJzZWFyY2hhYmxlIiwic2V0U3RhdGUiLCJzZWFyY2hSZXN1bHRzIiwiZ2V0T3B0aW9uc0ZvclZhbHVlIiwib3B0aW9ucyIsInNlbGVjdGlvbiIsImVudHJ5VmFsdWUiLCJvbk9wdGlvblNlbGVjdGVkIiwidmFsdWUiLCJlbnRyeSIsImdldFNlbGVjdGlvbiIsIm9uS2V5RG93biIsIl9vbk9wdGlvblNlbGVjdGVkIiwiX25hdiIsIm9uQ2hhbmdlIiwiX29uVGV4dEVudHJ5VXBkYXRlZCIsIl9oYXNIaW50Iiwic2hpZnRLZXkiLCJoYW5kbGVyIiwiZXZlbnRNYXAiLCJrZXlDb2RlIiwicHJldmVudERlZmF1bHQiLCJpc0ZvY3VzZWQiLCJvbkZvY3VzIiwib25CbHVyIiwic3RhdGUiLCJpbml0aWFsVmFsdWUiLCJzZWxlY3Rpb25JbmRleCIsImZvY3VzIiwicm9vdCIsIm5leHRQcm9wcyIsImVtcHR5VmFsdWUiLCJ0cmltIiwibGVuZ3RoIiwic2hvd09wdGlvbnNXaGVuRW1wdHkiLCJfc2hvdWxkU2tpcFNlYXJjaCIsInNlYXJjaE9wdGlvbnMiLCJfZ2VuZXJhdGVTZWFyY2hGdW5jdGlvbiIsImFsbG93Q3VzdG9tVmFsdWVzIiwiaW5kZXhPZiIsIl9oYXNDdXN0b21WYWx1ZSIsImZpeGVkT3B0aW9ucyIsIm1heFZpc2libGUiLCJzbGljZSIsInJlc3VsdHNUcnVuY2F0ZWRNZXNzYWdlIiwiX2dldEN1c3RvbVZhbHVlIiwiY3VzdG9tQ2xhc3NlcyIsImN1c3RvbUxpc3RJdGVtQ29tcG9uZW50IiwiY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudCIsImRlZmF1bHRDbGFzc05hbWVzIiwiZGlzcGxheU9wdGlvbiIsInNlbGVjdGVkSXRlbXMiLCJpbmRleCIsIl9oYXNGaXhlZE9wdGlvbnMiLCJldmVudHMiLCJLZXlFdmVudCIsIkRPTV9WS19VUCIsIm5hdlVwIiwiRE9NX1ZLX0RPV04iLCJuYXZEb3duIiwiRE9NX1ZLX1JFVFVSTiIsIkRPTV9WS19FTlRFUiIsIl9vbkVudGVyIiwiRE9NX1ZLX0VTQ0FQRSIsIl9vbkVzY2FwZSIsIkRPTV9WS19UQUIiLCJfb25UYWIiLCJkZWx0YSIsIm5ld0luZGV4IiwibmFtZSIsInNlYXJjaE9wdGlvbnNQcm9wIiwiZmlsdGVyT3B0aW9uUHJvcCIsImZpbHRlck9wdGlvbiIsIkNvbnNvbGUiLCJ3YXJuIiwiZmlsdGVyIiwibyIsIm1hcHBlciIsIkFjY2Vzc29yIiwiZ2VuZXJhdGVBY2Nlc3NvciIsIklERU5USVRZX0ZOIiwiZnV6enkiLCJleHRyYWN0IiwibWFwIiwicmVzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5wdXRDbGFzc2VzIiwiQm9vbGVhbiIsImlucHV0Q2xhc3NMaXN0IiwiY2xhc3NlcyIsImNsYXNzTmFtZSIsImNsYXNzTGlzdCIsImNvbXAiLCJfb25LZXlEb3duIiwib25LZXlQcmVzcyIsIm9uS2V5VXAiLCJfb25Gb2N1cyIsIl9yZW5kZXJIaWRkZW5JbnB1dCIsImRpc2FibGVkIiwiaW5wdXRQcm9wcyIsInBsYWNlaG9sZGVyIiwiX29uQ2hhbmdlIiwiX29uQmx1ciIsIl9yZW5kZXJJbmNyZW1lbnRhbFNlYXJjaFJlc3VsdHMiLCJDb21wb25lbnQiLCJQcm9wVHlwZXMiLCJzdHJpbmciLCJvYmplY3QiLCJudW1iZXIiLCJhcnJheU9mIiwiYW55IiwiYm9vbCIsInRleHRhcmVhIiwiZnVuYyIsIm9uZU9mVHlwZSIsImlucHV0RGlzcGxheU9wdGlvbiIsImZvcm1JbnB1dE9wdGlvbiIsImN1c3RvbUxpc3RDb21wb25lbnQiLCJlbGVtZW50IiwiRHJvcGRvd25MaXN0IiwiTGlzdEl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQSxJQUFNQSxhQUFhLEdBQUcsV0FBdEI7QUFDQTs7Ozs7OztBQU9BLElBQU1DLGdCQUFnQixHQUFHQyw2QkFBT0MsR0FBVixvQkFHQSxVQUFBQyxLQUFLO0FBQUEsU0FBSUEsS0FBSyxDQUFDQyxLQUFOLENBQVlDLGVBQWhCO0FBQUEsQ0FITCxFQUlOLFVBQUFGLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWUUsa0JBQWhCO0FBQUEsQ0FKQyxDQUF0Qjs7QUFXQSxJQUFNQyxRQUFRLEdBQUdOLDZCQUFPQyxHQUFWLG9CQUFkOztBQUlBLElBQU1NLGNBQWMsR0FBR1AsNkJBQU9RLEtBQVYscUJBQ2hCLFVBQUFOLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWU0sY0FBaEI7QUFBQSxDQURXLEVBSUksVUFBQVAsS0FBSztBQUFBLFNBQUlBLEtBQUssQ0FBQ0MsS0FBTixDQUFZTyxpQkFBaEI7QUFBQSxDQUpULENBQXBCOztBQVFBLElBQU1DLFNBQVMsR0FBR1gsNkJBQU9DLEdBQVYscUJBSUosVUFBQUMsS0FBSztBQUFBLFNBQUlBLEtBQUssQ0FBQ0MsS0FBTixDQUFZUyxxQkFBaEI7QUFBQSxDQUpELENBQWY7O0lBT3FCQyxTOzs7OztBQXNFbkIscUJBQVlYLEtBQVosRUFBbUI7QUFBQTs7QUFBQTtBQUNqQixxSEFBTUEsS0FBTjtBQURpQiwwR0FtSUMsVUFBQ1ksTUFBRCxF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cEJGLEVBQUFBLFFBQVEsRUFBRSxLQVBVO0FBUXBCYyxFQUFBQSxRQUFRLEVBQUUsS0FSVTtBQVNwQmIsRUFBQUEsVUFBVSxFQUFFLEVBVFE7QUFVcEI3RixFQUFBQSxnQkFWb0IsNEJBVUhULE1BVkcsRUFVSyxDQUFFLENBVlA7QUFXcEJnQixFQUFBQSxRQVhvQixvQkFXWGYsS0FYVyxFQVdKLENBQUUsQ0FYRTtBQVlwQlksRUFBQUEsU0Fab0IscUJBWVZaLEtBWlUsRUFZSCxDQUFFLENBWkM7QUFhcEJnRyxFQUFBQSxVQWJvQixzQkFhVGhHLEtBYlMsRUFhRixDQUFFLENBYkE7QUFjcEJpRyxFQUFBQSxPQWRvQixtQkFjWmpHLEtBZFksRUFjTCxDQUFFLENBZEc7QUFlcEJ3QixFQUFBQSxPQWZvQixtQkFlWnhCLEtBZlksRUFlTCxDQUFFLENBZkc7QUFnQnBCeUIsRUFBQUEsTUFoQm9CLGtCQWdCYnpCLEtBaEJhLEVBZ0JOLENBQUUsQ0FoQkk7QUFpQnBCeUUsRUFBQUEsWUFBWSxFQUFFLElBakJNO0FBa0JwQnBDLEVBQUFBLGFBQWEsRUFBRSxJQWxCSztBQW1CcEJnRixFQUFBQSxrQkFBa0IsRUFBRSxJQW5CQTtBQW9CcEJuRSxFQUFBQSxpQkFBaUIsRUFBRSxJQXBCQztBQXFCcEJxRSxFQUFBQSxtQkFBbUIsRUFBRUUsd0JBckJEO0FBc0JwQnpFLEVBQUFBLHVCQUF1QixFQUFFMEUsc0JBdEJMO0FBdUJwQnpFLEVBQUFBLHlCQUF5QixFQUFFLElBdkJQO0FBd0JwQmQsRUFBQUEsb0JBQW9CLEVBQUUsSUF4QkY7QUF5QnBCbEMsRUFBQUEsVUFBVSxFQUFFLElBekJRO0FBMEJwQjRDLEVBQUFBLHVCQUF1QixFQUFFO0FBMUJMLEM7QUFxWnZCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDE5IFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IFJlYWN0LCB7Q29tcG9uZW50fSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IGZ1enp5IGZyb20gJ2Z1enp5JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IHN0eWxlZCBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5cbmltcG9ydCBBY2Nlc3NvciBmcm9tICcuL2FjY2Vzc29yJztcbmltcG9ydCBLZXlFdmVudCBmcm9tICcuL2tleWV2ZW50JztcbmltcG9ydCBEcm9wZG93bkxpc3QsIHtMaXN0SXRlbX0gZnJvbSAnLi9kcm9wZG93bi1saXN0JztcbmltcG9ydCB7U2VhcmNofSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9pY29ucyc7XG5cbmNvbnN0IERFRkFVTFRfQ0xBU1MgPSAndHlwZWFoZWFkJztcbi8qKlxuICogQ29waWVkIG1vc3RseSBmcm9tICdyZWFjdC10eXBlYWhlYWQnLCBhbiBhdXRvLWNvbXBsZXRpbmcgdGV4dCBpbnB1dFxuICpcbiAqIFJlbmRlcnMgYW4gdGV4dCBpbnB1dCB0aGF0IHNob3dzIG9wdGlvbnMgbmVhcmJ5IHRoYXQgeW91IGNhbiB1c2UgdGhlXG4gKiBrZXlib2FyZCBvciBtb3VzZSB0byBzZWxlY3QuXG4gKi9cblxuY29uc3QgVHlwZWFoZWFkV3JhcHBlciA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZHJvcGRvd25MaXN0QmdkfTtcbiAgYm94LXNoYWRvdzogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5kcm9wZG93bkxpc3RTaGFkb3d9O1xuXG4gIDpmb2N1cyB7XG4gICAgb3V0bGluZTogMDtcbiAgfVxuYDtcblxuY29uc3QgSW5wdXRCb3ggPSBzdHlsZWQuZGl2YFxuICBwYWRkaW5nOiA4cHg7XG5gO1xuXG5jb25zdCBUeXBlYWhlYWRJbnB1dCA9IHN0eWxlZC5pbnB1dGBcbiAgJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5zZWNvbmRhcnlJbnB1dH1cbiAgOmhvdmVyIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5zZWNvbmRhcnlJbnB1dEJnZH07XG4gIH1cbmA7XG5cbmNvbnN0IElucHV0SWNvbiA9IHN0eWxlZC5kaXZgXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgcmlnaHQ6IDE1cHg7XG4gIHRvcDogMTRweDtcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuaW5wdXRQbGFjZWhvbGRlckNvbG9yfTtcbmA7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFR5cGVhaGVhZCBleHRlbmRzIENvbXBvbmVudCB7XG4gIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgbmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBjdXN0b21DbGFzc2VzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIG1heFZpc2libGU6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgcmVzdWx0c1RydW5jYXRlZE1lc3NhZ2U6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgb3B0aW9uczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSksXG4gICAgZml4ZWRPcHRpb25zOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KSxcbiAgICBhbGxvd0N1c3RvbVZhbHVlczogUHJvcFR5cGVzLm51bWJlcixcbiAgICBpbml0aWFsVmFsdWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgdmFsdWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgcGxhY2Vob2xkZXI6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgZGlzYWJsZWQ6IFByb3BUeXBlcy5ib29sLFxuICAgIHRleHRhcmVhOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBpbnB1dFByb3BzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIG9uT3B0aW9uU2VsZWN0ZWQ6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uQ2hhbmdlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbktleURvd246IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uS2V5UHJlc3M6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uS2V5VXA6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uRm9jdXM6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uQmx1cjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgZmlsdGVyT3B0aW9uOiBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIHNlYXJjaE9wdGlvbnM6IFByb3BUeXBlcy5mdW5jLFxuICAgIGRpc3BsYXlPcHRpb246IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5mdW5jXSksXG4gICAgaW5wdXREaXNwbGF5T3B0aW9uOiBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIGZvcm1JbnB1dE9wdGlvbjogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLnN0cmluZywgUHJvcFR5cGVzLmZ1bmNdKSxcbiAgICBkZWZhdWx0Q2xhc3NOYW1lczogUHJvcFR5cGVzLmJvb2wsXG4gICAgY3VzdG9tTGlzdENvbXBvbmVudDogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLmVsZW1lbnQsIFByb3BUeXBlcy5mdW5jXSksXG4gICAgY3VzdG9tTGlzdEl0ZW1Db21wb25lbnQ6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1xuICAgICAgUHJvcFR5cGVzLmVsZW1lbnQsXG4gICAgICBQcm9wVHlwZXMuZnVuY1xuICAgIF0pLFxuICAgIGN1c3RvbUxpc3RIZWFkZXJDb21wb25lbnQ6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1xuICAgICAgUHJvcFR5cGVzLmVsZW1lbnQsXG4gICAgICBQcm9wVHlwZXMuZnVuY1xuICAgIF0pLFxuICAgIHNob3dPcHRpb25zV2hlbkVtcHR5OiBQcm9wVHlwZXMuYm9vbCxcbiAgICBzZWFyY2hhYmxlOiBQcm9wVHlwZXMuYm9vbFxuICB9O1xuXG4gIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgb3B0aW9uczogW10sXG4gICAgY3VzdG9tQ2xhc3Nlczoge30sXG4gICAgYWxsb3dDdXN0b21WYWx1ZXM6IDAsXG4gICAgaW5pdGlhbFZhbHVlOiAnJyxcbiAgICB2YWx1ZTogJycsXG4gICAgcGxhY2Vob2xkZXI6ICcnLFxuICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICB0ZXh0YXJlYTogZmFsc2UsXG4gICAgaW5wdXRQcm9wczoge30sXG4gICAgb25PcHRpb25TZWxlY3RlZChvcHRpb24pIHt9LFxuICAgIG9uQ2hhbmdlKGV2ZW50KSB7fSxcbiAgICBvbktleURvd24oZXZlbnQpIHt9LFxuICAgIG9uS2V5UHJlc3MoZXZlbnQpIHt9LFxuICAgIG9uS2V5VXAoZXZlbnQpIHt9LFxuICAgIG9uRm9jdXMoZXZlbnQpIHt9LFxuICAgIG9uQmx1cihldmVudCkge30sXG4gICAgZmlsdGVyT3B0aW9uOiBudWxsLFxuICAgIHNlYXJjaE9wdGlvbnM6IG51bGwsXG4gICAgaW5wdXREaXNwbGF5T3B0aW9uOiBudWxsLFxuICAgIGRlZmF1bHRDbGFzc05hbWVzOiB0cnVlLFxuICAgIGN1c3RvbUxpc3RDb21wb25lbnQ6IERyb3Bkb3duTGlzdCxcbiAgICBjdXN0b21MaXN0SXRlbUNvbXBvbmVudDogTGlzdEl0ZW0sXG4gICAgY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudDogbnVsbCxcbiAgICBzaG93T3B0aW9uc1doZW5FbXB0eTogdHJ1ZSxcbiAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgIHJlc3VsdHNUcnVuY2F0ZWRNZXNzYWdlOiBudWxsXG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgc2VhcmNoUmVzdWx0czogdGhpcy5nZXRPcHRpb25zRm9yVmFsdWUoXG4gICAgICAgIHRoaXMucHJvcHMuaW5pdGlhbFZhbHVlLFxuICAgICAgICB0aGlzLnByb3BzLm9wdGlvbnNcbiAgICAgICksXG5cbiAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBzb21ldGhpbmcgZWxzZSwgJ2VudHJ5VmFsdWUnXG4gICAgICBlbnRyeVZhbHVlOiB0aGlzLnByb3BzLnZhbHVlIHx8IHRoaXMucHJvcHMuaW5pdGlhbFZhbHVlLFxuXG4gICAgICAvLyBBIHZhbGlkIHR5cGVhaGVhZCB2YWx1ZVxuICAgICAgc2VsZWN0aW9uOiB0aGlzLnByb3BzLnZhbHVlLFxuXG4gICAgICAvLyBJbmRleCBvZiB0aGUgc2VsZWN0aW9uXG4gICAgICBzZWxlY3Rpb25JbmRleDogbnVsbCxcblxuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgZm9jdXMgc3RhdGUgb2YgdGhlIGlucHV0IGVsZW1lbnQsIHRvIGRldGVybWluZVxuICAgICAgLy8gd2hldGhlciB0byBzaG93IG9wdGlvbnMgd2hlbiBlbXB0eSAoaWYgc2hvd09wdGlvbnNXaGVuRW1wdHkgaXMgdHJ1ZSlcbiAgICAgIGlzRm9jdXNlZDogZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWFyY2hSZXN1bHRzOiB0aGlzLmdldE9wdGlvbnNGb3JWYWx1ZSgnJywgdGhpcy5wcm9wcy5vcHRpb25zKVxuICAgIH0pO1xuXG4gICAgLy8gY2FsbCBmb2N1cyBvbiBlbnRyeSBvciBkaXYgdG8gdHJpZ2dlciBrZXkgZXZlbnRzIGxpc3RlbmVyXG4gICAgaWYgKHRoaXMuZW50cnkpIHtcbiAgICAgIHRoaXMuZW50cnkuZm9jdXMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb290LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICBjb25zdCBzZWFyY2hSZXN1bHRzID0gdGhpcy5nZXRPcHRpb25zRm9yVmFsdWUoXG4gICAgICB0aGlzLnN0YXRlLmVudHJ5VmFsdWUsXG4gICAgICBuZXh0UHJvcHMub3B0aW9uc1xuICAgICk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHtzZWFyY2hSZXN1bHRzfSk7XG4gIH1cblxuICBfc2hvdWxkU2tpcFNlYXJjaChpbnB1dCkge1xuICAgIGNvbnN0IGVtcHR5VmFsdWUgPSAhaW5wdXQgfHwgaW5wdXQudHJpbSgpLmxlbmd0aCA9PT0gMDtcblxuICAgIC8vIHRoaXMuc3RhdGUgbXVzdCBiZSBjaGVja2VkIGJlY2F1c2UgaXQgbWF5IG5vdCBiZSBkZWZpbmVkIHlldCBpZiB0aGlzIGZ1bmN0aW9uXG4gICAgLy8gaXMgY2FsbGVkIGZyb20gd2l0aGluIGdldEluaXRpYWxTdGF0ZVxuICAgIGNvbnN0IGlzRm9jdXNlZCA9IHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5pc0ZvY3VzZWQ7XG4gICAgcmV0dXJuICEodGhpcy5wcm9wcy5zaG93T3B0aW9uc1doZW5FbXB0eSAmJiBpc0ZvY3VzZWQpICYmIGVtcHR5VmFsdWU7XG4gIH1cblxuICBnZXRPcHRpb25zRm9yVmFsdWUodmFsdWUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIXRoaXMucHJvcHMuc2VhcmNoYWJsZSkge1xuICAgICAgLy8gZGlyZWN0bHkgcGFzcyB0aHJvdWdoIG9wdGlvbnMgaWYgY2FuIG5vdCBiZSBzZWFyY2hlZFxuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIGlmICh0aGlzLl9zaG91bGRTa2lwU2VhcmNoKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VhcmNoT3B0aW9ucyA9IHRoaXMuX2dlbmVyYXRlU2VhcmNoRnVuY3Rpb24oKTtcbiAgICByZXR1cm4gc2VhcmNoT3B0aW9ucyh2YWx1ZSwgb3B0aW9ucyk7XG4gIH1cblxuICBmb2N1cygpIHtcbiAgICBpZiAodGhpcy5lbnRyeSkge1xuICAgICAgdGhpcy5lbnRyeS5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIF9oYXNDdXN0b21WYWx1ZSgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5wcm9wcy5hbGxvd0N1c3RvbVZhbHVlcyA+IDAgJiZcbiAgICAgIHRoaXMuc3RhdGUuZW50cnlWYWx1ZS5sZW5ndGggPj0gdGhpcy5wcm9wcy5hbGxvd0N1c3RvbVZhbHVlcyAmJlxuICAgICAgdGhpcy5zdGF0ZS5zZWFyY2hSZXN1bHRzLmluZGV4T2YodGhpcy5zdGF0ZS5lbnRyeVZhbHVlKSA8IDBcbiAgICApO1xuICB9XG5cbiAgX2dldEN1c3RvbVZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLl9oYXNDdXN0b21WYWx1ZSgpID8gdGhpcy5zdGF0ZS5lbnRyeVZhbHVlIDogbnVsbDtcbiAgfVxuXG4gIF9yZW5kZXJJbmNyZW1lbnRhbFNlYXJjaFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDx0aGlzLnByb3BzLmN1c3RvbUxpc3RDb21wb25lbnRcbiAgICAgICAgZml4ZWRPcHRpb25zPXt0aGlzLnByb3BzLmZpeGVkT3B0aW9uc31cbiAgICAgICAgb3B0aW9ucz17XG4gICAgICAgICAgdGhpcy5wcm9wcy5tYXhWaXNpYmxlXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5zbGljZSgwLCB0aGlzLnByb3BzLm1heFZpc2libGUpXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0c1xuICAgICAgICB9XG4gICAgICAgIGFyZVJlc3VsdHNUcnVuY2F0ZWQ9e1xuICAgICAgICAgIHRoaXMucHJvcHMubWF4VmlzaWJsZSAmJlxuICAgICAgICAgIHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5sZW5ndGggPiB0aGlzLnByb3BzLm1heFZpc2libGVcbiAgICAgICAgfVxuICAgICAgICByZXN1bHRzVHJ1bmNhdGVkTWVzc2FnZT17dGhpcy5wcm9wcy5yZXN1bHRzVHJ1bmNhdGVkTWVzc2FnZX1cbiAgICAgICAgb25PcHRpb25TZWxlY3RlZD17dGhpcy5fb25PcHRpb25TZWxlY3RlZH1cbiAgICAgICAgYWxsb3dDdXN0b21WYWx1ZXM9e3RoaXMucHJvcHMuYWxsb3dDdXN0b21WYWx1ZXN9XG4gICAgICAgIGN1c3RvbVZhbHVlPXt0aGlzLl9nZXRDdXN0b21WYWx1ZSgpfVxuICAgICAgICBjdXN0b21DbGFzc2VzPXt0aGlzLnByb3BzLmN1c3RvbUNsYXNzZXN9XG4gICAgICAgIGN1c3RvbUxpc3RJdGVtQ29tcG9uZW50PXt0aGlzLnByb3BzLmN1c3RvbUxpc3RJdGVtQ29tcG9uZW50fVxuICAgICAgICBjdXN0b21MaXN0SGVhZGVyQ29tcG9uZW50PXt0aGlzLnByb3BzLmN1c3RvbUxpc3RIZWFkZXJDb21wb25lbnR9XG4gICAgICAgIHNlbGVjdGlvbkluZGV4PXt0aGlzLnN0YXRlLnNlbGVjdGlvbkluZGV4fVxuICAgICAgICBkZWZhdWx0Q2xhc3NOYW1lcz17dGhpcy5wcm9wcy5kZWZhdWx0Q2xhc3NOYW1lc31cbiAgICAgICAgZGlzcGxheU9wdGlvbj17dGhpcy5wcm9wcy5kaXNwbGF5T3B0aW9ufVxuICAgICAgICBzZWxlY3RlZEl0ZW1zPXt0aGlzLnByb3BzLnNlbGVjdGVkSXRlbXN9XG4gICAgICAvPlxuICAgICk7XG4gIH1cblxuICBnZXRTZWxlY3Rpb24oKSB7XG4gICAgbGV0IGluZGV4ID0gdGhpcy5zdGF0ZS5zZWxlY3Rpb25JbmRleDtcblxuICAgIGlmICh0aGlzLl9oYXNDdXN0b21WYWx1ZSgpKSB7XG4gICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuZW50cnlWYWx1ZTtcbiAgICAgIH1cbiAgICAgIGluZGV4LS07XG4gICAgfVxuICAgIGlmICh0aGlzLl9oYXNGaXhlZE9wdGlvbnMoKSkge1xuICAgICAgcmV0dXJuIGluZGV4IDwgdGhpcy5wcm9wcy5maXhlZE9wdGlvbnMubGVuZ3RoXG4gICAgICAgID8gdGhpcy5wcm9wcy5maXhlZE9wdGlvbnNbaW5kZXhdXG4gICAgICAgIDogdGhpcy5zdGF0ZS5zZWFyY2hSZXN1bHRzW2luZGV4IC0gdGhpcy5wcm9wcy5maXhlZE9wdGlvbnMubGVuZ3RoXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0c1tpbmRleF07XG4gIH1cblxuICBfb25PcHRpb25TZWxlY3RlZCA9IChvcHRpb24sIGV2ZW50KSA9PiB7XG4gICAgaWYgKHRoaXMucHJvcHMuc2VhcmNoYWJsZSkge1xuICAgICAgLy8gcmVzZXQgZW50cnkgaW5wdXRcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBzZWFyY2hSZXN1bHRzOiB0aGlzLmdldE9wdGlvbnNGb3JWYWx1ZSgnJywgdGhpcy5wcm9wcy5vcHRpb25zKSxcbiAgICAgICAgc2VsZWN0aW9uOiAnJyxcbiAgICAgICAgZW50cnlWYWx1ZTogJydcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb3BzLm9uT3B0aW9uU2VsZWN0ZWQob3B0aW9uLCBldmVudCk7XG4gIH07XG5cbiAgLy8gdXNlICgpID0+IHt9IHRvIGF2b2lkIGJpbmRpbmcgJ3RoaXM