matrix-react-sdk
Version:
SDK for matrix.org using React
326 lines (320 loc) • 48.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _AccessibleButton = _interopRequireDefault(require("./AccessibleButton"));
var _languageHandler = require("../../../languageHandler");
var _KeyBindingsManager = require("../../../KeyBindingsManager");
var _KeyboardShortcuts = require("../../../accessibility/KeyboardShortcuts");
var _objects = require("../../../utils/objects");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright 2024 New Vector Ltd.
Copyright 2017-2021 The Matrix.org Foundation C.I.C.
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
class MenuOption extends _react.default.Component {
constructor(...args) {
super(...args);
(0, _defineProperty2.default)(this, "onMouseEnter", () => {
this.props.onMouseEnter(this.props.dropdownKey);
});
(0, _defineProperty2.default)(this, "onClick", e => {
e.preventDefault();
e.stopPropagation();
this.props.onClick(this.props.dropdownKey);
});
}
render() {
const optClasses = (0, _classnames.default)({
mx_Dropdown_option: true,
mx_Dropdown_option_highlight: this.props.highlighted
});
return /*#__PURE__*/_react.default.createElement("li", {
id: this.props.id,
className: optClasses,
onClick: this.onClick,
onMouseEnter: this.onMouseEnter,
role: "option",
"aria-selected": this.props.highlighted,
ref: this.props.inputRef
}, this.props.children);
}
}
(0, _defineProperty2.default)(MenuOption, "defaultProps", {
disabled: false
});
/*
* Reusable dropdown select control, akin to react-select,
* but somewhat simpler as react-select is 79KB of minified
* javascript.
*/
class Dropdown extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "buttonRef", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "dropdownRootElement", null);
(0, _defineProperty2.default)(this, "ignoreEvent", null);
(0, _defineProperty2.default)(this, "childrenByKey", {});
(0, _defineProperty2.default)(this, "onDocumentClick", ev => {
// Close the dropdown if the user clicks anywhere that isn't
// within our root element
if (ev !== this.ignoreEvent) {
this.setState({
expanded: false
});
}
});
(0, _defineProperty2.default)(this, "onRootClick", ev => {
// This captures any clicks that happen within our elements,
// such that we can then ignore them when they're seen by the
// click listener on the document handler, ie. not close the
// dropdown immediately after opening it.
// NB. We can't just stopPropagation() because then the event
// doesn't reach the React onClick().
this.ignoreEvent = ev;
});
(0, _defineProperty2.default)(this, "onAccessibleButtonClick", ev => {
if (this.props.disabled) return;
const action = (0, _KeyBindingsManager.getKeyBindingsManager)().getAccessibilityAction(ev);
if (!this.state.expanded) {
this.setState({
expanded: true
});
ev.preventDefault();
} else if (action === _KeyboardShortcuts.KeyBindingAction.Enter) {
// the accessible button consumes enter onKeyDown for firing onClick, so handle it here
this.props.onOptionChange(this.state.highlightedOption);
this.close();
} else if (!ev.key) {
// collapse on other non-keyboard event activations
this.setState({
expanded: false
});
ev.preventDefault();
}
});
(0, _defineProperty2.default)(this, "onMenuOptionClick", dropdownKey => {
this.close();
this.props.onOptionChange(dropdownKey);
});
(0, _defineProperty2.default)(this, "onKeyDown", e => {
let handled = true;
// These keys don't generate keypress events and so needs to be on keyup
const action = (0, _KeyBindingsManager.getKeyBindingsManager)().getAccessibilityAction(e);
switch (action) {
case _KeyboardShortcuts.KeyBindingAction.Enter:
this.props.onOptionChange(this.state.highlightedOption);
// fallthrough
case _KeyboardShortcuts.KeyBindingAction.Escape:
this.close();
break;
case _KeyboardShortcuts.KeyBindingAction.ArrowDown:
if (this.state.expanded) {
this.setState({
highlightedOption: this.nextOption(this.state.highlightedOption)
});
} else {
this.setState({
expanded: true
});
}
break;
case _KeyboardShortcuts.KeyBindingAction.ArrowUp:
if (this.state.expanded) {
this.setState({
highlightedOption: this.prevOption(this.state.highlightedOption)
});
} else {
this.setState({
expanded: true
});
}
break;
default:
handled = false;
}
if (handled) {
e.preventDefault();
e.stopPropagation();
}
});
(0, _defineProperty2.default)(this, "onInputChange", e => {
this.setState({
searchQuery: e.currentTarget.value
});
if (this.props.onSearchChange) {
this.props.onSearchChange(e.currentTarget.value);
}
});
(0, _defineProperty2.default)(this, "collectRoot", e => {
if (this.dropdownRootElement) {
this.dropdownRootElement.removeEventListener("click", this.onRootClick, false);
}
if (e) {
e.addEventListener("click", this.onRootClick, false);
}
this.dropdownRootElement = e;
});
(0, _defineProperty2.default)(this, "setHighlightedOption", optionKey => {
this.setState({
highlightedOption: optionKey
});
});
this.reindexChildren(this.props.children);
const firstChild = props.children[0];
this.state = {
// True if the menu is dropped-down
expanded: false,
// The key of the highlighted option
// (the option that would become selected if you pressed enter)
highlightedOption: firstChild.key,
// the current search query
searchQuery: ""
};
// Listen for all clicks on the document so we can close the
// menu when the user clicks somewhere else
document.addEventListener("click", this.onDocumentClick, false);
}
componentDidUpdate(prevProps) {
if ((0, _objects.objectHasDiff)(this.props, prevProps) && this.props.children?.length) {
this.reindexChildren(this.props.children);
const firstChild = this.props.children[0];
this.setState({
highlightedOption: firstChild.key
});
}
}
componentWillUnmount() {
document.removeEventListener("click", this.onDocumentClick, false);
}
reindexChildren(children) {
this.childrenByKey = {};
_react.default.Children.forEach(children, child => {
this.childrenByKey[child.key] = child;
});
}
close() {
this.setState({
expanded: false
});
// their focus was on the input, its getting unmounted, move it to the button
if (this.buttonRef.current) {
this.buttonRef.current.focus();
}
}
nextOption(optionKey) {
const keys = Object.keys(this.childrenByKey);
const index = keys.indexOf(optionKey);
return keys[(index + 1) % keys.length];
}
prevOption(optionKey) {
const keys = Object.keys(this.childrenByKey);
const index = keys.indexOf(optionKey);
return keys[index <= 0 ? keys.length - 1 : (index - 1) % keys.length];
}
scrollIntoView(node) {
node?.scrollIntoView({
block: "nearest",
behavior: "auto"
});
}
getMenuOptions() {
const options = _react.default.Children.map(this.props.children, child => {
const highlighted = this.state.highlightedOption === child.key;
return /*#__PURE__*/_react.default.createElement(MenuOption, {
id: `${this.props.id}__${child.key}`,
key: child.key,
dropdownKey: child.key,
highlighted: highlighted,
onMouseEnter: this.setHighlightedOption,
onClick: this.onMenuOptionClick,
inputRef: highlighted ? this.scrollIntoView : undefined
}, child);
});
if (!options?.length) {
return [/*#__PURE__*/_react.default.createElement("li", {
key: "0",
className: "mx_Dropdown_option",
role: "option",
"aria-selected": false
}, (0, _languageHandler._t)("common|no_results"))];
}
return options;
}
render() {
let currentValue;
const menuStyle = {};
if (this.props.menuWidth) menuStyle.width = this.props.menuWidth;
let menu;
if (this.state.expanded) {
if (this.props.searchEnabled) {
currentValue = /*#__PURE__*/_react.default.createElement("input", {
id: `${this.props.id}_input`,
type: "text",
autoFocus: true,
autoComplete: this.props.autoComplete,
className: "mx_Dropdown_option",
onChange: this.onInputChange,
value: this.state.searchQuery,
role: "combobox",
"aria-autocomplete": "list",
"aria-activedescendant": `${this.props.id}__${this.state.highlightedOption}`,
"aria-expanded": this.state.expanded,
"aria-controls": `${this.props.id}_listbox`,
"aria-disabled": this.props.disabled,
"aria-label": this.props.label,
onKeyDown: this.onKeyDown
});
}
menu = /*#__PURE__*/_react.default.createElement("ul", {
className: "mx_Dropdown_menu",
style: menuStyle,
role: "listbox",
id: `${this.props.id}_listbox`
}, this.getMenuOptions());
}
if (!currentValue) {
let selectedChild;
if (this.props.value) {
selectedChild = this.props.getShortOption ? this.props.getShortOption(this.props.value) : this.childrenByKey[this.props.value];
}
currentValue = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Dropdown_option",
id: `${this.props.id}_value`
}, selectedChild || this.props.placeholder);
}
const dropdownClasses = (0, _classnames.default)("mx_Dropdown", this.props.className, {
mx_Dropdown_disabled: !!this.props.disabled
});
// Note the menu sits inside the AccessibleButton div so it's anchored
// to the input, but overflows below it. The root contains both.
return /*#__PURE__*/_react.default.createElement("div", {
className: dropdownClasses,
ref: this.collectRoot
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_Dropdown_input mx_no_textinput",
onClick: this.onAccessibleButtonClick,
"aria-haspopup": "listbox",
"aria-expanded": this.state.expanded,
disabled: this.props.disabled,
ref: this.buttonRef,
"aria-label": this.props.label,
"aria-describedby": `${this.props.id}_value`,
"aria-owns": `${this.props.id}_input`,
onKeyDown: this.onKeyDown
}, currentValue, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_Dropdown_arrow"
}), menu));
}
}
exports.default = Dropdown;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2xhc3NuYW1lcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfS2V5QmluZGluZ3NNYW5hZ2VyIiwiX0tleWJvYXJkU2hvcnRjdXRzIiwiX29iamVjdHMiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJNZW51T3B0aW9uIiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsImFyZ3MiLCJfZGVmaW5lUHJvcGVydHkyIiwicHJvcHMiLCJvbk1vdXNlRW50ZXIiLCJkcm9wZG93bktleSIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwib25DbGljayIsInJlbmRlciIsIm9wdENsYXNzZXMiLCJjbGFzc25hbWVzIiwibXhfRHJvcGRvd25fb3B0aW9uIiwibXhfRHJvcGRvd25fb3B0aW9uX2hpZ2hsaWdodCIsImhpZ2hsaWdodGVkIiwiY3JlYXRlRWxlbWVudCIsImlkIiwiY2xhc3NOYW1lIiwicm9sZSIsInJlZiIsImlucHV0UmVmIiwiY2hpbGRyZW4iLCJkaXNhYmxlZCIsIkRyb3Bkb3duIiwiY3JlYXRlUmVmIiwiZXYiLCJpZ25vcmVFdmVudCIsInNldFN0YXRlIiwiZXhwYW5kZWQiLCJhY3Rpb24iLCJnZXRLZXlCaW5kaW5nc01hbmFnZXIiLCJnZXRBY2Nlc3NpYmlsaXR5QWN0aW9uIiwic3RhdGUiLCJLZXlCaW5kaW5nQWN0aW9uIiwiRW50ZXIiLCJvbk9wdGlvbkNoYW5nZSIsImhpZ2hsaWdodGVkT3B0aW9uIiwiY2xvc2UiLCJrZXkiLCJoYW5kbGVkIiwiRXNjYXBlIiwiQXJyb3dEb3duIiwibmV4dE9wdGlvbiIsIkFycm93VXAiLCJwcmV2T3B0aW9uIiwic2VhcmNoUXVlcnkiLCJjdXJyZW50VGFyZ2V0IiwidmFsdWUiLCJvblNlYXJjaENoYW5nZSIsImRyb3Bkb3duUm9vdEVsZW1lbnQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwib25Sb290Q2xpY2siLCJhZGRFdmVudExpc3RlbmVyIiwib3B0aW9uS2V5IiwicmVpbmRleENoaWxkcmVuIiwiZmlyc3RDaGlsZCIsImRvY3VtZW50Iiwib25Eb2N1bWVudENsaWNrIiwiY29tcG9uZW50RGlkVXBkYXRlIiwicHJldlByb3BzIiwib2JqZWN0SGFzRGlmZiIsImxlbmd0aCIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwiY2hpbGRyZW5CeUtleSIsIkNoaWxkcmVuIiwiZm9yRWFjaCIsImNoaWxkIiwiYnV0dG9uUmVmIiwiY3VycmVudCIsImZvY3VzIiwia2V5cyIsImluZGV4IiwiaW5kZXhPZiIsInNjcm9sbEludG9WaWV3Iiwibm9kZSIsImJsb2NrIiwiYmVoYXZpb3IiLCJnZXRNZW51T3B0aW9ucyIsIm9wdGlvbnMiLCJtYXAiLCJzZXRIaWdobGlnaHRlZE9wdGlvbiIsIm9uTWVudU9wdGlvbkNsaWNrIiwidW5kZWZpbmVkIiwiX3QiLCJjdXJyZW50VmFsdWUiLCJtZW51U3R5bGUiLCJtZW51V2lkdGgiLCJ3aWR0aCIsIm1lbnUiLCJzZWFyY2hFbmFibGVkIiwidHlwZSIsImF1dG9Gb2N1cyIsImF1dG9Db21wbGV0ZSIsIm9uQ2hhbmdlIiwib25JbnB1dENoYW5nZSIsImxhYmVsIiwib25LZXlEb3duIiwic3R5bGUiLCJzZWxlY3RlZENoaWxkIiwiZ2V0U2hvcnRPcHRpb24iLCJwbGFjZWhvbGRlciIsImRyb3Bkb3duQ2xhc3NlcyIsIm14X0Ryb3Bkb3duX2Rpc2FibGVkIiwiY29sbGVjdFJvb3QiLCJvbkFjY2Vzc2libGVCdXR0b25DbGljayIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9lbGVtZW50cy9Ecm9wZG93bi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTctMjAyMSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuQ29weXJpZ2h0IDIwMTkgTWljaGFlbCBUZWxhdHluc2tpIDw3dDNjaGd1eUBnbWFpbC5jb20+XG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyBDaGFuZ2VFdmVudCwgY3JlYXRlUmVmLCBDU1NQcm9wZXJ0aWVzLCBSZWFjdEVsZW1lbnQsIFJlYWN0Tm9kZSwgUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgY2xhc3NuYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuXG5pbXBvcnQgQWNjZXNzaWJsZUJ1dHRvbiwgeyBCdXR0b25FdmVudCB9IGZyb20gXCIuL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCB7IF90IH0gZnJvbSBcIi4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlclwiO1xuaW1wb3J0IHsgZ2V0S2V5QmluZGluZ3NNYW5hZ2VyIH0gZnJvbSBcIi4uLy4uLy4uL0tleUJpbmRpbmdzTWFuYWdlclwiO1xuaW1wb3J0IHsgS2V5QmluZGluZ0FjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9hY2Nlc3NpYmlsaXR5L0tleWJvYXJkU2hvcnRjdXRzXCI7XG5pbXBvcnQgeyBvYmplY3RIYXNEaWZmIH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL29iamVjdHNcIjtcbmltcG9ydCB7IE5vbkVtcHR5QXJyYXkgfSBmcm9tIFwiLi4vLi4vLi4vQHR5cGVzL2NvbW1vblwiO1xuXG5pbnRlcmZhY2UgSU1lbnVPcHRpb25Qcm9wcyB7XG4gICAgY2hpbGRyZW46IFJlYWN0RWxlbWVudDtcbiAgICBoaWdobGlnaHRlZD86IGJvb2xlYW47XG4gICAgZHJvcGRvd25LZXk6IHN0cmluZztcbiAgICBpZD86IHN0cmluZztcbiAgICBpbnB1dFJlZj86IFJlZjxIVE1MTElFbGVtZW50PjtcbiAgICBvbkNsaWNrKGRyb3Bkb3duS2V5OiBzdHJpbmcpOiB2b2lkO1xuICAgIG9uTW91c2VFbnRlcihkcm9wZG93bktleTogc3RyaW5nKTogdm9pZDtcbn1cblxuY2xhc3MgTWVudU9wdGlvbiBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxJTWVudU9wdGlvblByb3BzPiB7XG4gICAgcHVibGljIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbk1vdXNlRW50ZXIgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMucHJvcHMub25Nb3VzZUVudGVyKHRoaXMucHJvcHMuZHJvcGRvd25LZXkpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQ2xpY2sgPSAoZTogUmVhY3QuTW91c2VFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMucHJvcHMub25DbGljayh0aGlzLnByb3BzLmRyb3Bkb3duS2V5KTtcbiAgICB9O1xuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBjb25zdCBvcHRDbGFzc2VzID0gY2xhc3NuYW1lcyh7XG4gICAgICAgICAgICBteF9Ecm9wZG93bl9vcHRpb246IHRydWUsXG4gICAgICAgICAgICBteF9Ecm9wZG93bl9vcHRpb25faGlnaGxpZ2h0OiB0aGlzLnByb3BzLmhpZ2hsaWdodGVkLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGxpXG4gICAgICAgICAgICAgICAgaWQ9e3RoaXMucHJvcHMuaWR9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtvcHRDbGFzc2VzfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25DbGlja31cbiAgICAgICAgICAgICAgICBvbk1vdXNlRW50ZXI9e3RoaXMub25Nb3VzZUVudGVyfVxuICAgICAgICAgICAgICAgIHJvbGU9XCJvcHRpb25cIlxuICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9e3RoaXMucHJvcHMuaGlnaGxpZ2h0ZWR9XG4gICAgICAgICAgICAgICAgcmVmPXt0aGlzLnByb3BzLmlucHV0UmVmfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLmNoaWxkcmVufVxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRHJvcGRvd25Qcm9wcyB7XG4gICAgaWQ6IHN0cmluZztcbiAgICAvLyBBUklBIGxhYmVsXG4gICAgbGFiZWw6IHN0cmluZztcbiAgICB2YWx1ZT86IHN0cmluZztcbiAgICBjbGFzc05hbWU/OiBzdHJpbmc7XG4gICAgYXV0b0NvbXBsZXRlPzogc3RyaW5nO1xuICAgIGNoaWxkcmVuOiBOb25FbXB0eUFycmF5PFJlYWN0RWxlbWVudCAmIHsga2V5OiBzdHJpbmcgfT47XG4gICAgLy8gbmVnYXRpdmUgZm9yIGNvbnNpc3RlbmN5IHdpdGggSFRNTFxuICAgIGRpc2FibGVkPzogYm9vbGVhbjtcbiAgICAvLyBUaGUgd2lkdGggdGhhdCB0aGUgZHJvcGRvd24gc2hvdWxkIGJlLiBJZiBzcGVjaWZpZWQsXG4gICAgLy8gdGhlIGRyb3BwZWQtZG93biBwYXJ0IG9mIHRoZSBtZW51IHdpbGwgYmUgc2V0IHRvIHRoaXNcbiAgICAvLyB3aWR0aC5cbiAgICBtZW51V2lkdGg/OiBudW1iZXI7XG4gICAgc2VhcmNoRW5hYmxlZD86IGJvb2xlYW47XG4gICAgLy8gUGxhY2Vob2xkZXIgdG8gc2hvdyB3aGVuIG5vIHZhbHVlIGlzIHNlbGVjdGVkXG4gICAgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gICAgLy8gQ2FsbGVkIHdoZW4gdGhlIHNlbGVjdGVkIG9wdGlvbiBjaGFuZ2VzXG4gICAgb25PcHRpb25DaGFuZ2UoZHJvcGRvd25LZXk6IHN0cmluZyk6IHZvaWQ7XG4gICAgLy8gQ2FsbGVkIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBzZWFyY2ggZmllbGQgY2hhbmdlc1xuICAgIG9uU2VhcmNoQ2hhbmdlPyhxdWVyeTogc3RyaW5nKTogdm9pZDtcbiAgICAvLyBGdW5jdGlvbiB0aGF0LCBnaXZlbiB0aGUga2V5IG9mIGFuIG9wdGlvbiwgcmV0dXJuc1xuICAgIC8vIGEgbm9kZSByZXByZXNlbnRpbmcgdGhhdCBvcHRpb24gdG8gYmUgZGlzcGxheWVkIGluIHRoZVxuICAgIC8vIGJveCBpdHNlbGYgYXMgdGhlIGN1cnJlbnRseS1zZWxlY3RlZCBvcHRpb24gKGllLiBhc1xuICAgIC8vIG9wcG9zZWQgdG8gaW4gdGhlIGFjdHVhbCBkcm9wcGVkLWRvd24gcGFydCkuIElmXG4gICAgLy8gdW5zcGVjaWZpZWQsIHRoZSBhcHByb3ByaWF0ZSBjaGlsZCBlbGVtZW50IGlzIHVzZWQgYXNcbiAgICAvLyBpbiB0aGUgZHJvcHBlZC1kb3duIG1lbnUuXG4gICAgZ2V0U2hvcnRPcHRpb24/KHZhbHVlOiBzdHJpbmcpOiBSZWFjdE5vZGU7XG59XG5cbmludGVyZmFjZSBJU3RhdGUge1xuICAgIGV4cGFuZGVkOiBib29sZWFuO1xuICAgIGhpZ2hsaWdodGVkT3B0aW9uOiBzdHJpbmc7XG4gICAgc2VhcmNoUXVlcnk6IHN0cmluZztcbn1cblxuLypcbiAqIFJldXNhYmxlIGRyb3Bkb3duIHNlbGVjdCBjb250cm9sLCBha2luIHRvIHJlYWN0LXNlbGVjdCxcbiAqIGJ1dCBzb21ld2hhdCBzaW1wbGVyIGFzIHJlYWN0LXNlbGVjdCBpcyA3OUtCIG9mIG1pbmlmaWVkXG4gKiBqYXZhc2NyaXB0LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEcm9wZG93biBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxEcm9wZG93blByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1dHRvblJlZiA9IGNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcbiAgICBwcml2YXRlIGRyb3Bkb3duUm9vdEVsZW1lbnQ6IEhUTUxEaXZFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBpZ25vcmVFdmVudDogTW91c2VFdmVudCB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgY2hpbGRyZW5CeUtleTogUmVjb3JkPHN0cmluZywgUmVhY3ROb2RlPiA9IHt9O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBEcm9wZG93blByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLnJlaW5kZXhDaGlsZHJlbih0aGlzLnByb3BzLmNoaWxkcmVuKTtcblxuICAgICAgICBjb25zdCBmaXJzdENoaWxkID0gcHJvcHMuY2hpbGRyZW5bMF07XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIC8vIFRydWUgaWYgdGhlIG1lbnUgaXMgZHJvcHBlZC1kb3duXG4gICAgICAgICAgICBleHBhbmRlZDogZmFsc2UsXG4gICAgICAgICAgICAvLyBUaGUga2V5IG9mIHRoZSBoaWdobGlnaHRlZCBvcHRpb25cbiAgICAgICAgICAgIC8vICh0aGUgb3B0aW9uIHRoYXQgd291bGQgYmVjb21lIHNlbGVjdGVkIGlmIHlvdSBwcmVzc2VkIGVudGVyKVxuICAgICAgICAgICAgaGlnaGxpZ2h0ZWRPcHRpb246IGZpcnN0Q2hpbGQua2V5LFxuICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgc2VhcmNoIHF1ZXJ5XG4gICAgICAgICAgICBzZWFyY2hRdWVyeTogXCJcIixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBMaXN0ZW4gZm9yIGFsbCBjbGlja3Mgb24gdGhlIGRvY3VtZW50IHNvIHdlIGNhbiBjbG9zZSB0aGVcbiAgICAgICAgLy8gbWVudSB3aGVuIHRoZSB1c2VyIGNsaWNrcyBzb21ld2hlcmUgZWxzZVxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5vbkRvY3VtZW50Q2xpY2ssIGZhbHNlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogUmVhZG9ubHk8RHJvcGRvd25Qcm9wcz4pOiB2b2lkIHtcbiAgICAgICAgaWYgKG9iamVjdEhhc0RpZmYodGhpcy5wcm9wcywgcHJldlByb3BzKSAmJiB0aGlzLnByb3BzLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMucmVpbmRleENoaWxkcmVuKHRoaXMucHJvcHMuY2hpbGRyZW4pO1xuICAgICAgICAgICAgY29uc3QgZmlyc3RDaGlsZCA9IHRoaXMucHJvcHMuY2hpbGRyZW5bMF07XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBoaWdobGlnaHRlZE9wdGlvbjogZmlyc3RDaGlsZC5rZXksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpOiB2b2lkIHtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25Eb2N1bWVudENsaWNrLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWluZGV4Q2hpbGRyZW4oY2hpbGRyZW46IFJlYWN0RWxlbWVudFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hpbGRyZW5CeUtleSA9IHt9O1xuICAgICAgICBSZWFjdC5DaGlsZHJlbi5mb3JFYWNoKGNoaWxkcmVuLCAoY2hpbGQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hpbGRyZW5CeUtleVsoY2hpbGQgYXMgRHJvcGRvd25Qcm9wc1tcImNoaWxkcmVuXCJdW251bWJlcl0pLmtleV0gPSBjaGlsZDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRvY3VtZW50Q2xpY2sgPSAoZXY6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgLy8gQ2xvc2UgdGhlIGRyb3Bkb3duIGlmIHRoZSB1c2VyIGNsaWNrcyBhbnl3aGVyZSB0aGF0IGlzbid0XG4gICAgICAgIC8vIHdpdGhpbiBvdXIgcm9vdCBlbGVtZW50XG4gICAgICAgIGlmIChldiAhPT0gdGhpcy5pZ25vcmVFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgZXhwYW5kZWQ6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblJvb3RDbGljayA9IChldjogTW91c2VFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICAvLyBUaGlzIGNhcHR1cmVzIGFueSBjbGlja3MgdGhhdCBoYXBwZW4gd2l0aGluIG91ciBlbGVtZW50cyxcbiAgICAgICAgLy8gc3VjaCB0aGF0IHdlIGNhbiB0aGVuIGlnbm9yZSB0aGVtIHdoZW4gdGhleSdyZSBzZWVuIGJ5IHRoZVxuICAgICAgICAvLyBjbGljayBsaXN0ZW5lciBvbiB0aGUgZG9jdW1lbnQgaGFuZGxlciwgaWUuIG5vdCBjbG9zZSB0aGVcbiAgICAgICAgLy8gZHJvcGRvd24gaW1tZWRpYXRlbHkgYWZ0ZXIgb3BlbmluZyBpdC5cbiAgICAgICAgLy8gTkIuIFdlIGNhbid0IGp1c3Qgc3RvcFByb3BhZ2F0aW9uKCkgYmVjYXVzZSB0aGVuIHRoZSBldmVudFxuICAgICAgICAvLyBkb2Vzbid0IHJlYWNoIHRoZSBSZWFjdCBvbkNsaWNrKCkuXG4gICAgICAgIHRoaXMuaWdub3JlRXZlbnQgPSBldjtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkFjY2Vzc2libGVCdXR0b25DbGljayA9IChldjogQnV0dG9uRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZGlzYWJsZWQpIHJldHVybjtcblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBnZXRLZXlCaW5kaW5nc01hbmFnZXIoKS5nZXRBY2Nlc3NpYmlsaXR5QWN0aW9uKGV2IGFzIFJlYWN0LktleWJvYXJkRXZlbnQpO1xuXG4gICAgICAgIGlmICghdGhpcy5zdGF0ZS5leHBhbmRlZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGV4cGFuZGVkOiB0cnVlIH0pO1xuICAgICAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT09IEtleUJpbmRpbmdBY3Rpb24uRW50ZXIpIHtcbiAgICAgICAgICAgIC8vIHRoZSBhY2Nlc3NpYmxlIGJ1dHRvbiBjb25zdW1lcyBlbnRlciBvbktleURvd24gZm9yIGZpcmluZyBvbkNsaWNrLCBzbyBoYW5kbGUgaXQgaGVyZVxuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk9wdGlvbkNoYW5nZSh0aGlzLnN0YXRlLmhpZ2hsaWdodGVkT3B0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfSBlbHNlIGlmICghKGV2IGFzIFJlYWN0LktleWJvYXJkRXZlbnQpLmtleSkge1xuICAgICAgICAgICAgLy8gY29sbGFwc2Ugb24gb3RoZXIgbm9uLWtleWJvYXJkIGV2ZW50IGFjdGl2YXRpb25zXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXhwYW5kZWQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIGNsb3NlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGV4cGFuZGVkOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHRoZWlyIGZvY3VzIHdhcyBvbiB0aGUgaW5wdXQsIGl0cyBnZXR0aW5nIHVubW91bnRlZCwgbW92ZSBpdCB0byB0aGUgYnV0dG9uXG4gICAgICAgIGlmICh0aGlzLmJ1dHRvblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmJ1dHRvblJlZi5jdXJyZW50LmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTWVudU9wdGlvbkNsaWNrID0gKGRyb3Bkb3duS2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLnByb3BzLm9uT3B0aW9uQ2hhbmdlKGRyb3Bkb3duS2V5KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbktleURvd24gPSAoZTogUmVhY3QuS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICBsZXQgaGFuZGxlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhlc2Uga2V5cyBkb24ndCBnZW5lcmF0ZSBrZXlwcmVzcyBldmVudHMgYW5kIHNvIG5lZWRzIHRvIGJlIG9uIGtleXVwXG4gICAgICAgIGNvbnN0IGFjdGlvbiA9IGdldEtleUJpbmRpbmdzTWFuYWdlcigpLmdldEFjY2Vzc2liaWxpdHlBY3Rpb24oZSk7XG4gICAgICAgIHN3aXRjaCAoYWN0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uRW50ZXI6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk9wdGlvbkNoYW5nZSh0aGlzLnN0YXRlLmhpZ2hsaWdodGVkT3B0aW9uKTtcbiAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoXG4gICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uRXNjYXBlOlxuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgS2V5QmluZGluZ0FjdGlvbi5BcnJvd0Rvd246XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZXhwYW5kZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaWdobGlnaHRlZE9wdGlvbjogdGhpcy5uZXh0T3B0aW9uKHRoaXMuc3RhdGUuaGlnaGxpZ2h0ZWRPcHRpb24pLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXhwYW5kZWQ6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBLZXlCaW5kaW5nQWN0aW9uLkFycm93VXA6XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZXhwYW5kZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaWdobGlnaHRlZE9wdGlvbjogdGhpcy5wcmV2T3B0aW9uKHRoaXMuc3RhdGUuaGlnaGxpZ2h0ZWRPcHRpb24pLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXhwYW5kZWQ6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBoYW5kbGVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFuZGxlZCkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uSW5wdXRDaGFuZ2UgPSAoZTogQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWFyY2hRdWVyeTogZS5jdXJyZW50VGFyZ2V0LnZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25TZWFyY2hDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25TZWFyY2hDaGFuZ2UoZS5jdXJyZW50VGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIGNvbGxlY3RSb290ID0gKGU6IEhUTUxEaXZFbGVtZW50KTogdm9pZCA9PiB7XG4gICAgICAgIGlmICh0aGlzLmRyb3Bkb3duUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuZHJvcGRvd25Sb290RWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5vblJvb3RDbGljaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICBlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLm9uUm9vdENsaWNrLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kcm9wZG93blJvb3RFbGVtZW50ID0gZTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBzZXRIaWdobGlnaHRlZE9wdGlvbiA9IChvcHRpb25LZXk6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGhpZ2hsaWdodGVkT3B0aW9uOiBvcHRpb25LZXksXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG5leHRPcHRpb24ob3B0aW9uS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXModGhpcy5jaGlsZHJlbkJ5S2V5KTtcbiAgICAgICAgY29uc3QgaW5kZXggPSBrZXlzLmluZGV4T2Yob3B0aW9uS2V5KTtcbiAgICAgICAgcmV0dXJuIGtleXNbKGluZGV4ICsgMSkgJSBrZXlzLmxlbmd0aF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwcmV2T3B0aW9uKG9wdGlvbktleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuY2hpbGRyZW5CeUtleSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0ga2V5cy5pbmRleE9mKG9wdGlvbktleSk7XG4gICAgICAgIHJldHVybiBrZXlzW2luZGV4IDw9IDAgPyBrZXlzLmxlbmd0aCAtIDEgOiAoaW5kZXggLSAxKSAlIGtleXMubGVuZ3RoXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNjcm9sbEludG9WaWV3KG5vZGU6IEVsZW1lbnQgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIG5vZGU/LnNjcm9sbEludG9WaWV3KHtcbiAgICAgICAgICAgIGJsb2NrOiBcIm5lYXJlc3RcIixcbiAgICAgICAgICAgIGJlaGF2aW9yOiBcImF1dG9cIixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRNZW51T3B0aW9ucygpOiBKU1guRWxlbWVudFtdIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IFJlYWN0LkNoaWxkcmVuLm1hcCh0aGlzLnByb3BzLmNoaWxkcmVuLCAoY2hpbGQ6IFJlYWN0RWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaGlnaGxpZ2h0ZWQgPSB0aGlzLnN0YXRlLmhpZ2hsaWdodGVkT3B0aW9uID09PSBjaGlsZC5rZXk7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlkPXtgJHt0aGlzLnByb3BzLmlkfV9fJHtjaGlsZC5rZXl9YH1cbiAgICAgICAgICAgICAgICAgICAga2V5PXtjaGlsZC5rZXl9XG4gICAgICAgICAgICAgICAgICAgIGRyb3Bkb3duS2V5PXtjaGlsZC5rZXkgYXMgc3RyaW5nfVxuICAgICAgICAgICAgICAgICAgICBoaWdobGlnaHRlZD17aGlnaGxpZ2h0ZWR9XG4gICAgICAgICAgICAgICAgICAgIG9uTW91c2VFbnRlcj17dGhpcy5zZXRIaWdobGlnaHRlZE9wdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5vbk1lbnVPcHRpb25DbGlja31cbiAgICAgICAgICAgICAgICAgICAgaW5wdXRSZWY9e2hpZ2hsaWdodGVkID8gdGhpcy5zY3JvbGxJbnRvVmlldyA6IHVuZGVmaW5lZH1cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHtjaGlsZH1cbiAgICAgICAgICAgICAgICA8L01lbnVPcHRpb24+XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFvcHRpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgPGxpIGtleT1cIjBcIiBjbGFzc05hbWU9XCJteF9Ecm9wZG93bl9vcHRpb25cIiByb2xlPVwib3B0aW9uXCIgYXJpYS1zZWxlY3RlZD17ZmFsc2V9PlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJjb21tb258bm9fcmVzdWx0c1wiKX1cbiAgICAgICAgICAgICAgICA8L2xpPixcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBsZXQgY3VycmVudFZhbHVlOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBtZW51U3R5bGU6IENTU1Byb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubWVudVdpZHRoKSBtZW51U3R5bGUud2lkdGggPSB0aGlzLnByb3BzLm1lbnVXaWR0aDtcblxuICAgICAgICBsZXQgbWVudTogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmV4cGFuZGVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5zZWFyY2hFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFZhbHVlID0gKFxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPXtgJHt0aGlzLnByb3BzLmlkfV9pbnB1dGB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvRm9jdXM9e3RydWV9XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvQ29tcGxldGU9e3RoaXMucHJvcHMuYXV0b0NvbXBsZXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfRHJvcGRvd25fb3B0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uSW5wdXRDaGFuZ2V9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5zZWFyY2hRdWVyeX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJvbGU9XCJjb21ib2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWF1dG9jb21wbGV0ZT1cImxpc3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1hY3RpdmVkZXNjZW5kYW50PXtgJHt0aGlzLnByb3BzLmlkfV9fJHt0aGlzLnN0YXRlLmhpZ2hsaWdodGVkT3B0aW9ufWB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWV4cGFuZGVkPXt0aGlzLnN0YXRlLmV4cGFuZGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1jb250cm9scz17YCR7dGhpcy5wcm9wcy5pZH1fbGlzdGJveGB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWRpc2FibGVkPXt0aGlzLnByb3BzLmRpc2FibGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17dGhpcy5wcm9wcy5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uS2V5RG93bj17dGhpcy5vbktleURvd259XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1lbnUgPSAoXG4gICAgICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT1cIm14X0Ryb3Bkb3duX21lbnVcIiBzdHlsZT17bWVudVN0eWxlfSByb2xlPVwibGlzdGJveFwiIGlkPXtgJHt0aGlzLnByb3BzLmlkfV9saXN0Ym94YH0+XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLmdldE1lbnVPcHRpb25zKCl9XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgICAgbGV0IHNlbGVjdGVkQ2hpbGQ6IFJlYWN0Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRDaGlsZCA9IHRoaXMucHJvcHMuZ2V0U2hvcnRPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnByb3BzLmdldFNob3J0T3B0aW9uKHRoaXMucHJvcHMudmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5jaGlsZHJlbkJ5S2V5W3RoaXMucHJvcHMudmFsdWVdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Ecm9wZG93bl9vcHRpb25cIiBpZD17YCR7dGhpcy5wcm9wcy5pZH1fdmFsdWVgfT5cbiAgICAgICAgICAgICAgICAgICAge3NlbGVjdGVkQ2hpbGQgfHwgdGhpcy5wcm9wcy5wbGFjZWhvbGRlcn1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkcm9wZG93bkNsYXNzZXMgPSBjbGFzc25hbWVzKFwibXhfRHJvcGRvd25cIiwgdGhpcy5wcm9wcy5jbGFzc05hbWUsIHtcbiAgICAgICAgICAgIG14X0Ryb3Bkb3duX2Rpc2FibGVkOiAhIXRoaXMucHJvcHMuZGlzYWJsZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE5vdGUgdGhlIG1lbnUgc2l0cyBpbnNpZGUgdGhlIEFjY2Vzc2libGVCdXR0b24gZGl2IHNvIGl0J3MgYW5jaG9yZWRcbiAgICAgICAgLy8gdG8gdGhlIGlucHV0LCBidXQgb3ZlcmZsb3dzIGJlbG93IGl0LiBUaGUgcm9vdCBjb250YWlucyBib3RoLlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ryb3Bkb3duQ2xhc3Nlc30gcmVmPXt0aGlzLmNvbGxlY3RSb290fT5cbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Ecm9wZG93bl9pbnB1dCBteF9ub190ZXh0aW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uQWNjZXNzaWJsZUJ1dHRvbkNsaWNrfVxuICAgICAgICAgICAgICAgICAgICBhcmlhLWhhc3BvcHVwPVwibGlzdGJveFwiXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9e3RoaXMuc3RhdGUuZXhwYW5kZWR9XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnByb3BzLmRpc2FibGVkfVxuICAgICAgICAgICAgICAgICAgICByZWY9e3RoaXMuYnV0dG9uUmVmfVxuICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXt0aGlzLnByb3BzLmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICBhcmlhLWRlc2NyaWJlZGJ5PXtgJHt0aGlzLnByb3BzLmlkfV92YWx1ZWB9XG4gICAgICAgICAgICAgICAgICAgIGFyaWEtb3ducz17YCR7dGhpcy5wcm9wcy5pZH1faW5wdXRgfVxuICAgICAgICAgICAgICAgICAgICBvbktleURvd249e3RoaXMub25LZXlEb3dufVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge2N1cnJlbnRWYWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwibXhfRHJvcGRvd25fYXJyb3dcIiAvPlxuICAgICAgICAgICAgICAgICAgICB7bWVudX1cbiAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBU0EsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsV0FBQSxHQUFBQyxzQkFBQSxDQUFBRixPQUFBO0FBRUEsSUFBQUcsaUJBQUEsR0FBQUQsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFJLGdCQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxtQkFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sa0JBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FBQVAsT0FBQTtBQUF1RCxTQUFBUSx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBVix3QkFBQVUsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUwsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3QkFBQSxXQUFBQyxDQUFBLElBQUFkLENBQUEsb0JBQUFjLENBQUEsT0FBQUMsY0FBQSxDQUFBQyxJQUFBLENBQUFoQixDQUFBLEVBQUFjLENBQUEsU0FBQUcsQ0FBQSxHQUFBUCxDQUFBLEdBQUFDLE1BQUEsQ0FBQUUsd0JBQUEsQ0FBQWIsQ0FBQSxFQUFBYyxDQUFBLFVBQUFHLENBQUEsS0FBQUEsQ0FBQSxDQUFBVixHQUFBLElBQUFVLENBQUEsQ0FBQUMsR0FBQSxJQUFBUCxNQUFBLENBQUFDLGNBQUEsQ0FBQUosQ0FBQSxFQUFBTSxDQUFBLEVBQUFHLENBQUEsSUFBQVQsQ0FBQSxDQUFBTSxDQUFBLElBQUFkLENBQUEsQ0FBQWMsQ0FBQSxZQUFBTixDQUFBLENBQUFILE9BQUEsR0FBQUwsQ0FBQSxFQUFBRyxDQUFBLElBQUFBLENBQUEsQ0FBQWUsR0FBQSxDQUFBbEIsQ0FBQSxFQUFBUSxDQUFBLEdBQUFBLENBQUE7QUFoQnZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBc0JBLE1BQU1XLFVBQVUsU0FBU0MsY0FBSyxDQUFDQyxTQUFTLENBQW1CO0VBQUFDLFlBQUEsR0FBQUMsSUFBQTtJQUFBLFNBQUFBLElBQUE7SUFBQSxJQUFBQyxnQkFBQSxDQUFBbkIsT0FBQSx3QkFLaEMsTUFBWTtNQUMvQixJQUFJLENBQUNvQixLQUFLLENBQUNDLFlBQVksQ0FBQyxJQUFJLENBQUNELEtBQUssQ0FBQ0UsV0FBVyxDQUFDO0lBQ25ELENBQUM7SUFBQSxJQUFBSCxnQkFBQSxDQUFBbkIsT0FBQSxtQkFFa0JMLENBQW1CLElBQVc7TUFDN0NBLENBQUMsQ0FBQzRCLGNBQWMsQ0FBQyxDQUFDO01BQ2xCNUIsQ0FBQyxDQUFDNkIsZUFBZSxDQUFDLENBQUM7TUFDbkIsSUFBSSxDQUFDSixLQUFLLENBQUNLLE9BQU8sQ0FBQyxJQUFJLENBQUNMLEtBQUssQ0FBQ0UsV0FBVyxDQUFDO0lBQzlDLENBQUM7RUFBQTtFQUVNSSxNQUFNQSxDQUFBLEVBQW9CO0lBQzdCLE1BQU1DLFVBQVUsR0FBRyxJQUFBQyxtQkFBVSxFQUFDO01BQzFCQyxrQkFBa0IsRUFBRSxJQUFJO01BQ3hCQyw0QkFBNEIsRUFBRSxJQUFJLENBQUNWLEtBQUssQ0FBQ1c7SUFDN0MsQ0FBQyxDQUFDO0lBRUYsb0JBQ0kvQyxNQUFBLENBQUFnQixPQUFBLENBQUFnQyxhQUFBO01BQ0lDLEVBQUUsRUFBRSxJQUFJLENBQUNiLEtBQUssQ0FBQ2EsRUFBRztNQUNsQkMsU0FBUyxFQUFFUCxVQUFXO01BQ3RCRixPQUFPLEVBQUUsSUFBSSxDQUFDQSxPQUFRO01BQ3RCSixZQUFZLEVBQUUsSUFBSSxDQUFDQSxZQUFhO01BQ2hDYyxJQUFJLEVBQUMsUUFBUTtNQUNiLGlCQUFlLElBQUksQ0FBQ2YsS0FBSyxDQUFDVyxXQUFZO01BQ3RDSyxHQUFHLEVBQUUsSUFBSSxDQUFDaEIsS0FBSyxDQUFDaUI7SUFBUyxHQUV4QixJQUFJLENBQUNqQixLQUFLLENBQUNrQixRQUNaLENBQUM7RUFFYjtBQUNKO0FBQUMsSUFBQW5CLGdCQUFBLENBQUFuQixPQUFBLEVBbkNLYyxVQUFVLGtCQUNpQjtFQUN6QnlCLFFBQVEsRUFBRTtBQUNkLENBQUM7QUFzRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLE1BQU1DLFFBQVEsU0FBU3pCLGNBQUssQ0FBQ0MsU0FBUyxDQUF3QjtFQU1sRUMsV0FBV0EsQ0FBQ0csS0FBb0IsRUFBRTtJQUNyQyxLQUFLLENBQUNBLEtBQUssQ0FBQztJQUFDLElBQUFELGdCQUFBLENBQUFuQixPQUFBLGtDQU5ZLElBQUF5QyxnQkFBUyxFQUFpQixDQUFDO0lBQUEsSUFBQXRCLGdCQUFBLENBQUFuQixPQUFBLCtCQUNILElBQUk7SUFBQSxJQUFBbUIsZ0JBQUEsQ0FBQW5CLE9BQUEsdUJBQ2hCLElBQUk7SUFBQSxJQUFBbUIsZ0JBQUEsQ0FBQW5CLE9BQUEseUJBQ00sQ0FBQyxDQUFDO0lBQUEsSUFBQW1CLGdCQUFBLENBQUFuQixPQUFBLDJCQTZDMUIwQyxFQUFjLElBQVc7TUFDaEQ7TUFDQTtNQUNBLElBQUlBLEVBQUUsS0FBSyxJQUFJLENBQUNDLFdBQVcsRUFBRTtRQUN6QixJQUFJLENBQUNDLFFBQVEsQ0FBQztVQUNWQyxRQUFRLEVBQUU7UUFDZCxDQUFDLENBQUM7TUFDTjtJQUNKLENBQUM7SUFBQSxJQUFBMUIsZ0JBQUEsQ0FBQW5CLE9BQUEsdUJBRXNCMEMsRUFBYyxJQUFXO01BQzVDO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQTtNQUNBLElBQUksQ0FBQ0MsV0FBVyxHQUFHRCxFQUFFO0lBQ3pCLENBQUM7SUFBQSxJQUFBdkIsZ0JBQUEsQ0FBQW5CLE9BQUEsbUNBRWtDMEMsRUFBZSxJQUFXO01BQ3pELElBQUksSUFBSSxDQUFDdEIsS0FBSyxDQUFDbUIsUUFBUSxFQUFFO01BRXpCLE1BQU1PLE1BQU0sR0FBRyxJQUFBQyx5Q0FBcUIsRUFBQyxDQUFDLENBQUNDLHNCQUFzQixDQUFDTixFQUF5QixDQUFDO01BRXhGLElBQUksQ0FBQyxJQUFJLENBQUNPLEtBQUssQ0FBQ0osUUFBUSxFQUFFO1FBQ3RCLElBQUksQ0FBQ0QsUUFBUSxDQUFDO1VBQUVDLFFBQVEsRUFBRTtRQUFLLENBQUMsQ0FBQztRQUNqQ0gsRUFBRSxDQUFDbkIsY0FBYyxDQUFDLENBQUM7TUFDdkIsQ0FBQyxNQUFNLElBQUl1QixNQUFNLEtBQUtJLG1DQUFnQixDQUFDQyxLQUFLLEVBQUU7UUFDMUM7UUFDQSxJQUFJLENBQUMvQixLQUFLLENBQUNnQyxjQUFjLENBQUMsSUFBSSxDQUFDSCxLQUFLLENBQUNJLGlCQUFpQixDQUFDO1FBQ3ZELElBQUksQ0FBQ0MsS0FBSyxDQUFDLENBQUM7TUFDaEIsQ0FBQyxNQUFNLElBQUksQ0FBRVosRUFBRSxDQUF5QmEsR0FBRyxFQUFFO1FBQ3pDO1FBQ0EsSUFBSSxDQUFDWCxRQUFRLENBQUM7VUFBRUMsUUFBUSxFQUFFO1FBQU0sQ0FBQyxDQUFDO1FBQ2xDSCxFQUFFLENBQUNuQixjQUFjLENBQUMsQ0FBQztNQUN2QjtJQUNKLENBQUM7SUFBQSxJQUFBSixnQkFBQSxDQUFBbkIsT0FBQSw2QkFZNEJzQixXQUFtQixJQUFXO01BQ3ZELElBQUksQ0FBQ2dDLEtBQUssQ0FBQyxDQUFDO01BQ1osSUFBSSxDQUFDbEMsS0FBSyxDQUFDZ0MsY0FBYyxDQUFDOUIsV0FBVyxDQUFDO0lBQzFDLENBQUM7SUFBQSxJQUFBSCxnQkFBQSxDQUFBbkIsT0FBQSxxQkFFb0JMLENBQXNCLElBQVc7TUFDbEQsSUFBSTZELE9BQU8sR0FBRyxJQUFJOztNQUVsQjtNQUNBLE1BQU1WLE1BQU0sR0FBRyxJQUFBQyx5Q0FBcUIsRUFBQyxDQUFDLENBQUNDLHNCQUFzQixDQUFDckQsQ0FBQyxDQUFDO01BQ2hFLFFBQVFtRCxNQUFNO1FBQ1YsS0FBS0ksbUNBQWdCLENBQUNDLEtBQUs7VUFDdkIsSUFBSSxDQUFDL0IsS0FBSyxDQUFDZ0MsY0FBYyxDQUFDLElBQUksQ0FBQ0gsS0FBSyxDQUFDSSxpQkFBaUIsQ0FBQztRQUMzRDtRQUNBLEtBQUtILG1DQUFnQixDQUFDTyxNQUFNO1VBQ3hCLElBQUksQ0FBQ0gsS0FBSyxDQUFDLENBQUM7VUFDWjtRQUNKLEtBQUtKLG1DQUFnQixDQUFDUSxTQUFTO1VBQzNCLElBQUksSUFBSSxDQUFDVCxLQUFLLENBQUNKLFFBQVEsRUFBRTtZQUNyQixJQUFJLENBQUNELFFBQVEsQ0FBQztjQUNWUyxpQkFBaUIsRUFBRSxJQUFJLENBQUNNLFVBQVUsQ0FBQyxJQUFJLENBQUNWLEtBQUssQ0FBQ0ksaUJBQWlCO1lBQ25FLENBQUMsQ0FBQztVQUNOLENBQUMsTUFBTTtZQUNILElBQUksQ0FBQ1QsUUFBUSxDQUFDO2NBQUVDLFFBQVEsRUFBRTtZQUFLLENBQUMsQ0FBQztVQUNyQztVQUNBO1FBQ0osS0FBS0ssbUNBQWdCLENBQUNVLE9BQU87VUFDekIsSUFBSSxJQUFJLENBQUNYLEtBQUssQ0FBQ0osUUFBUSxFQUFFO1lBQ3JCLElBQUksQ0FBQ0QsUUFBUSxDQUFDO2NBQ1ZTLGlCQUFpQixFQUFFLElBQUksQ0FBQ1EsVUFBVSxDQUFDLElBQUksQ0FBQ1osS0FBSyxDQUFDSSxpQkFBaUI7WUFDbkUsQ0FBQyxDQUFDO1VBQ04sQ0FBQyxNQUFNO1lBQ0gsSUFBSSxDQUFDVCxRQUFRLENBQUM7Y0FBRUMsUUFBUSxFQUFFO1lBQUssQ0FBQyxDQUFDO1VBQ3JDO1VBQ0E7UUFDSjtVQUNJVyxPQUFPLEdBQUcsS0FBSztNQUN2QjtNQUVBLElBQUlBLE9BQU8sRUFBRTtRQUNUN0QsQ0FBQyxDQUFDNEIsY0FBYyxDQUFDLENBQUM7UUFDbEI1QixDQUFDLENBQUM2QixlQUFlLENBQUMsQ0FBQztNQUN2QjtJQUNKLENBQUM7SUFBQSxJQUFBTCxnQkFBQSxDQUFBbkIsT0FBQSx5QkFFd0JMLENBQWdDLElBQVc7TUFDaEUsSUFBSSxDQUFDaUQsUUFBUSxDQUFDO1FBQ1ZrQixXQUFXLEVBQUVuRSxDQUFDLENBQUNvRSxhQUFhLENBQUNDO01BQ2pDLENBQUMsQ0FBQztNQUNGLElBQUksSUFBSSxDQUFDNUMsS0FBSyxDQUFDNkMsY0FBYyxFQUFFO1FBQzNCLElBQUksQ0FBQzdDLEtBQUssQ0FBQzZDLGNBQWMsQ0FBQ3RFLENBQUMsQ0FBQ29FLGFBQWEsQ0FBQ0MsS0FBSyxDQUFDO01BQ3BEO0lBQ0osQ0FBQztJQUFBLElBQUE3QyxnQkFBQSxDQUFBbkIsT0FBQSx1QkFFc0JMLENBQWlCLElBQVc7TUFDL0MsSUFBSSxJQUFJLENBQUN1RSxtQkFBbUIsRUFBRTtRQUMxQixJQUFJLENBQUNBLG1CQUFtQixDQUFDQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDQyxXQUFXLEVBQUUsS0FBSyxDQUFDO01BQ2xGO01BQ0EsSUFBSXpFLENBQUMsRUFBRTtRQUNIQSxDQUFDLENBQUMwRSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDRCxXQUFXLEVBQUUsS0FBSyxDQUFDO01BQ3hEO01BQ0EsSUFBSSxDQUFDRixtQkFBbUIsR0FBR3ZFLENBQUM7SUFDaEMsQ0FBQztJQUFBLElBQUF3QixnQkFBQSxDQUFBbkIsT0FBQSxnQ0FFK0JzRSxTQUFpQixJQUFXO01BQ3hELElBQUksQ0FBQzFCLFFBQVEsQ0FBQztRQUNWUyxpQkFBaUIsRUFBRWlCO01BQ3ZCLENBQUMsQ0FBQztJQUNOLENBQUM7SUE3SkcsSUFBSSxDQUFDQyxlQUFlLENBQUMsSUFBSSxDQUFDbkQsS0FBSyxDQUFDa0IsUUFBUSxDQUFDO0lBRXpDLE1BQU1rQyxVQUFVLEdBQUdwRCxLQUFLLENBQUNrQixRQUFRLENBQUMsQ0FBQyxDQUFDO0lBRXBDLElBQUksQ0FBQ1csS0FBSyxHQUFHO01BQ1Q7TUFDQUosUUFBUSxFQUFFLEtBQUs7TUFDZjtNQUNBO01BQ0FRLGlCQUFpQixFQUFFbUIsVUFBVSxDQUFDakIsR0FBRztNQUNqQztNQUNBTyxXQUFXLEVBQUU7SUFDakIsQ0FBQzs7SUFFRDtJQUNBO0lBQ0FXLFFBQVEsQ0FBQ0osZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQ0ssZUFBZSxFQUFFLEtBQUssQ0FBQztFQUNuRTtFQUVPQyxrQkFBa0JBLENBQUNDLFNBQWtDLEVBQVE7SUFDaEUsSUFBSSxJQUFBQyxzQkFBYSxFQUFDLElBQUksQ0FBQ3pELEtBQUssRUFBRXdELFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQ3hELEtBQUssQ0FBQ2tCLFFBQVEsRUFBRXdDLE1BQU0sRUFBRTtNQUNyRSxJQUFJLENBQUNQLGVBQWUsQ0FBQyxJQUFJLENBQUNuRCxLQUFLLENBQUNrQixRQUFRLENBQUM7TUFDekMsTUFBTWtDLFVBQVUsR0FBRyxJQUFJLENBQUNwRCxLQUFLLENBQUNrQixRQUFRLENBQUMsQ0FBQyxDQUFDO01BQ3pDLElBQUksQ0FBQ00sUUFBUSxDQUFDO1FBQ1ZTLGlCQUFpQixFQUFFbUIsVUFBVSxDQUFDakI7TUFDbEMsQ0FBQyxDQUFDO0lBQ047RUFDSjtFQUVPd0Isb0JBQW9CQSxDQUFBLEVBQVM7SUFDaENOLFFBQVEsQ0FBQ04sbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQ08sZUFBZSxFQUFFLEtBQUssQ0FBQztFQUN0RTtFQUVRSCxlQUFlQSxDQUFDakMsUUFBd0IsRUFBUTtJQUNwRCxJQUFJLENBQUMwQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCakUsY0FBSyxDQUFDa0UsUUFBUSxDQUFDQyxPQUFPLENBQUM1QyxRQUFRLEVBQUc2QyxLQUFLLElBQUs7TUFDeEMsSUFBSSxDQUFDSCxhQUFhLENBQUVHLEtBQUssQ0FBdUM1QixHQUFHLENBQUMsR0FBRzRCLEtBQUs7SUFDaEYsQ0FBQyxDQUFDO0VBQ047RUF5Q1E3QixLQUFLQSxDQUFBLEVBQVM7SUFDbEIsSUFBSSxDQUFDVixRQUFRLENBQUM7TUFDVkMsUUFBUSxFQUFFO0lBQ2QsQ0FBQyxDQUFDO0lBQ0Y7SUFDQSxJQUFJLElBQUksQ0FBQ3VDLFNBQVMsQ0FBQ0MsT0FBTyxFQUFFO01BQ3hCLElBQUksQ0FBQ0QsU0FBUyxDQUFDQyxPQUFPLENBQUNDLEtBQUssQ0FBQyxDQUFDO0lBQ2xDO0VBQ0o7RUF3RVEzQixVQUFVQSxDQUFDVyxTQUFpQixFQUFVO0lBQzFDLE1BQU1pQixJQUFJLEdBQUdqRixNQUFNLENBQUNpRixJQUFJLENBQUMsSUFBSSxDQUFDUCxhQUFhLENBQUM7SUFDNUMsTUFBTVEsS0FBSyxHQUFHRCxJQUFJLENBQUNFLE9BQU8sQ0FBQ25CLFNBQVMsQ0FBQztJQUNyQyxPQUFPaUIsSUFBSSxDQUFDLENBQUNDLEtBQUssR0FBRyxDQUFDLElBQUlELElBQUksQ0FBQ1QsTUFBTSxDQUFDO0VBQzFDO0VBRVFqQixVQUFVQSxDQUFDUyxTQUFpQixFQUFVO0lBQzFDLE1BQU1pQixJQUFJLEdBQUdqRixNQUFNLENBQUNpRixJQUFJLENBQUMsSUFBSSxDQUFDUCxhQUFhLENBQUM7SUFDNUMsTUFBTVEsS0FBSyxHQUFHRCxJQUFJLENBQUNFLE9BQU8sQ0FBQ25CLFNBQVMsQ0FBQztJQUNyQyxPQUFPaUIsSUFBSSxDQUFDQyxLQUFLLElBQUksQ0FBQyxHQUFHRCxJQUFJLENBQUNULE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQ1UsS0FBSyxHQUFHLENBQUMsSUFBSUQsSUFBSSxDQUFDVCxNQUFNLENBQUM7RUFDekU7RUFFUVksY0FBY0EsQ0FBQ0MsSUFBb0IsRUFBUTtJQUMvQ0EsSUFBSSxFQUFFRCxjQUFjLENBQUM7TUFDakJFLEtBQUssRUFBRSxTQUFTO01BQ2hCQyxRQUFRLEVBQUU7SUFDZCxDQUFDLENBQUM7RUFDTjtFQUVRQyxjQUFjQSxDQUFBLEVBQWtCO0lBQ3BDLE1BQU1DLE9BQU8sR0FBR2hGLGNBQUssQ0FBQ2tFLFFBQVEsQ0FBQ2UsR0FBRyxDQUFDLElBQUksQ0FBQzVFLEtBQUssQ0FBQ2tCLFFBQVEsRUFBRzZDLEtBQW1CLElBQUs7TUFDN0UsTUFBTXBELFdBQVcsR0FBRyxJQUFJLENBQUNrQixLQUFLLENBQUNJLGlCQUFpQixLQUFLOEIsS0FBSyxDQUFDNUIsR0FBRztNQUM5RCxvQkFDSXZFLE1BQUEsQ0FBQWdCLE9BQUEsQ0FBQWdDLGFBQUEsQ0FBQ2xCLFVBQVU7UUFDUG1CLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQ2IsS0FBSyxDQUFDYSxFQUFFLEtBQUtrRCxLQUFLLENBQUM1QixHQUFHLEVBQUc7UUFDckNBLEdBQUcsRUFBRTRCLEtBQUssQ0FBQzVCLEdBQUk7UUFDZmpDLFdBQVcsRUFBRTZELEtBQUssQ0FBQzVCLEdBQWM7UUFDakN4QixXQUFXLEVBQUVBLFdBQVk7UUFDekJWLFlBQVksRUFBRSxJQUFJLENBQUM0RSxvQkFBcUI7UUFDeEN4RSxPQUFPLEVBQUUsSUFBSSxDQUFDeUUsaUJBQWtCO1FBQ2hDN0QsUUFBUSxFQUFFTixXQUFXLEdBQUcsSUFBSSxDQUFDMkQsY0FBYyxHQUFHUztNQUFVLEdBRXZEaEIsS0FDTyxDQUFDO0lBRXJCLENBQUMsQ0FBQztJQUNGLElBQUksQ0FBQ1ksT0FBTyxFQUFFakIsTUFBTSxFQUFFO01BQ2xCLE9BQU8sY0FDSDlGLE1BQUEsQ0FBQWdCLE9BQUEsQ0FBQWdDLGFBQUE7UUFBSXVCLEdBQUcsRUFBQyxHQUFHO1FBQUNyQixTQUFTLEVBQUMsb0JBQW9CO1FBQUNDLElBQUksRUFBQyxRQUFRO1FBQUMsaUJBQWU7TUFBTSxHQUN6RSxJQUFBaUUsbUJBQUUsRUFBQyxtQkFBbUIsQ0FDdkIsQ0FBQyxDQUNSO0lBQ0w7SUFDQSxPQUFPTCxPQUFPO0VBQ2xCO0VBRU9yRSxNQUFNQSxDQUFBLEVBQW9CO0lBQzdCLElBQUkyRSxZQUFxQztJQUV6QyxNQUFNQyxTQUF3QixHQUFHLENBQUMsQ0FBQztJQUNuQyxJQUFJLElBQUksQ0FBQ2xGLEtBQUssQ0FBQ21GLFNBQVMsRUFBRUQsU0FBUyxDQUFDRSxLQUFLLEdBQUcsSUFBSSxDQUFDcEYsS0FBSyxDQUFDbUYsU0FBUztJQUVoRSxJQUFJRSxJQUE2QjtJQUNqQyxJQUFJLElBQUksQ0FBQ3hELEtBQUssQ0FBQ0osUUFBUSxFQUFFO01BQ3JCLElBQUksSUFBSSxDQUFDekIsS0FBSyxDQUFDc0YsYUFBYSxFQUFFO1FBQzFCTCxZQUFZLGdCQUNSckgsTUFBQSxDQUFBZ0IsT0FBQSxDQUFBZ0MsYUFBQTtVQUNJQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUNiLEtBQUssQ0FBQ2EsRUFBRSxRQUFTO1VBQzdCMEUsSUFBSSxFQUFDLE1BQU07VUFDWEMsU0FBUyxFQUFFLElBQUs7VUFDaEJDLFlBQVksRUFBRSxJQUFJLENBQUN6RixLQUFLLENBQUN5RixZQUFhO1VBQ3RDM0UsU0FBUyxFQUFDLG9CQUFvQjtVQUM5QjRFLFFBQVEsRUFBRSxJQUFJLENBQUNDLGFBQWM7VUFDN0IvQyxLQUFLLEVBQUUsSUFBSSxDQUFDZixLQUFLLENBQUNhLFdBQVk7VUFDOUIzQixJQUFJLEVBQUMsVUFBVTtVQUNmLHFCQUFrQixNQUFNO1VBQ3hCLHlCQUF1QixHQUFHLElBQUksQ0FBQ2YsS0FBSyxDQUFDYSxFQUFFLEtBQUssSUFBSSxDQUFDZ0IsS0FBSyxDQUFDSSxpQkFBaUIsRUFBRztVQUMzRSxpQkFBZSxJQUFJLENBQUNKLEtBQUssQ0FBQ0osUUFBUztVQUNuQyxpQkFBZSxHQUFHLElBQUksQ0FBQ3pCLEtBQUssQ0FBQ2EsRUFBRSxVQUFXO1VBQzFDLGlCQUFlLElBQUksQ0FBQ2IsS0FBSyxDQUFDbUIsUUFBUztVQUNuQyxjQUFZLElBQUksQ0FBQ25CLEtBQUssQ0FBQzRGLEtBQU07VUFDN0JDLFNBQVMsRUFBRSxJQUFJLENBQUNBO1FBQVUsQ0FDN0IsQ0FDSjtNQUNMO01BQ0FSLElBQUksZ0JBQ0F6SCxNQUFBLENBQUFnQixPQUFBLENBQUFnQyxhQUFBO1FBQUlFLFNBQVMsRUFBQyxrQkFBa0I7UUFBQ2dGLEtBQUssRUFBRVosU0FBVTtRQUFDbkUsSUFBSSxFQUFDLFNBQVM7UUFBQ0YsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDYixLQUFLLENBQUNhLEVBQUU7TUFBVyxHQUM1RixJQUFJLENBQUM2RCxjQUFjLENBQUMsQ0FDckIsQ0FDUDtJQUNMO0lBRUEsSUFBSSxDQUFDTyxZQUFZLEVBQUU7TUFDZixJQUFJYyxhQUFvQztNQUN4QyxJQUFJLElBQUksQ0FBQy9GLEtBQUssQ0FBQzRDLEtBQUssRUFBRTtRQUNsQm1ELGFBQWEsR0FBRyxJQUFJLENBQUMvRixLQUFLLENBQUNnRyxjQUFjLEdBQ25DLElBQUksQ0FBQ2hHLEtBQUssQ0FBQ2dHLGNBQWMsQ0FBQyxJQUFJLENBQUNoRyxLQUFLLENBQUM0QyxLQUFLLENBQUMsR0FDM0MsSUFBSSxDQUFDZ0IsYUFBYSxDQUFDLElBQUksQ0FBQzVELEtBQUssQ0FBQzRDLEtBQUssQ0FBQztNQUM5QztNQUVBcUMsWUFBWSxnQkFDUnJILE1BQUEsQ0FBQWdCLE9BQUEsQ0FBQWdDLGFBQUE7UUFBS0UsU0FBUyxFQUFDLG9CQUFvQjtRQUFDRCxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUNiLEtBQUssQ0FBQ2EsRUFBRTtNQUFTLEdBQzVEa0YsYUFBYSxJQUFJLElBQUksQ0FBQy9GLEtBQUssQ0FBQ2lHLFdBQzVCLENBQ1I7SUFDTDtJQUVBLE1BQU1DLGVBQWUsR0FBRyxJQUFBMUYsbUJBQVUsRUFBQyxhQUFhLEVBQUUsSUFBSSxDQUFDUixLQUFLLENBQUNjLFNBQVMsRUFBRTtNQUNwRXFGLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUNuRyxLQUFLLENBQUNtQjtJQUN2QyxDQUFDLENBQUM7O0lBRUY7SUFDQTtJQUNBLG9CQUNJdkQsTUFBQSxDQUFBZ0IsT0FBQSxDQUFBZ0MsYUFBQTtNQUFLRSxTQUFTLEVBQUVvRixlQUFnQjtNQUFDbEYsR0FBRyxFQUFFLElBQUksQ0FBQ29GO0lBQVksZ0JBQ25EeEksTUFBQSxDQUFBZ0IsT0FBQSxDQUFBZ0MsYUFBQSxDQUFDM0MsaUJBQUEsQ0FBQVcsT0FBZ0I7TUFDYmtDLFNBQVMsRUFBQyxtQ0FBbUM7TUFDN0NULE9BQU8sRUFBRSxJQUFJLENBQUNnRyx1QkFBd0I7TUFDdEMsaUJBQWMsU0FBUztNQUN2QixpQkFBZSxJQUFJLENBQUN4RSxLQUFLLENBQUNKLFFBQVM7TUFDbkNOLFFBQVEsRUFBRSxJQUFJLENBQUNuQixLQUFLLENBQUNtQixRQUFTO01BQzlCSCxHQUFHLEVBQUUsSUFBSSxDQUFDZ0QsU0FBVTtNQUNwQixjQUFZLElBQUksQ0FBQ2hFLEtBQUssQ0FBQzRGLEtBQU07TUFDN0Isb0JBQWtCLEdBQUcsSUFBSSxDQUFDNUYsS0FBSyxDQUFDYSxFQUFFLFFBQVM7TUFDM0MsYUFBVyxHQUFHLElBQUksQ0FBQ2IsS0FBSyxDQUFDYSxFQUFFLFFBQVM7TUFDcENnRixTQUFTLEVBQUUsSUFBSSxDQUFDQTtJQUFVLEdBRXpCWixZQUFZLGVBQ2JySCxNQUFBLENBQUFnQixPQUFBLENBQUFnQyxhQUFBO01BQU1FLFNBQVMsRUFBQztJQUFtQixDQUFFLENBQUMsRUFDckN1RSxJQUNhLENBQ2pCLENBQUM7RUFFZDtBQUNKO0FBQUNpQixPQUFBLENBQUExSCxPQUFBLEdBQUF3QyxRQUFBIiwiaWdub3JlTGlzdCI6W119