UNPKG

matrix-react-sdk

Version:
371 lines (367 loc) 61.3 kB
"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 _matrix = require("matrix-js-sdk/src/matrix"); var _logger = require("matrix-js-sdk/src/logger"); var _EditableItemList = _interopRequireDefault(require("../elements/EditableItemList")); var _languageHandler = require("../../../languageHandler"); var _Field = _interopRequireDefault(require("../elements/Field")); var _Spinner = _interopRequireDefault(require("../elements/Spinner")); var _ErrorDialog = _interopRequireDefault(require("../dialogs/ErrorDialog")); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _Modal = _interopRequireDefault(require("../../../Modal")); var _RoomPublishSetting = _interopRequireDefault(require("./RoomPublishSetting")); var _RoomAliasField = _interopRequireDefault(require("../elements/RoomAliasField")); var _MatrixClientContext = _interopRequireDefault(require("../../../contexts/MatrixClientContext")); var _SettingsFieldset = _interopRequireDefault(require("../settings/SettingsFieldset")); 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 2016-2023 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ class EditableAliasesList extends _EditableItemList.default { constructor(...args) { super(...args); (0, _defineProperty2.default)(this, "aliasField", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "onAliasAdded", async ev => { ev.preventDefault(); if (!this.aliasField.current) return; await this.aliasField.current.validate({ allowEmpty: false }); if (this.aliasField.current.isValid) { if (this.props.onItemAdded) this.props.onItemAdded(this.props.newItem); return; } this.aliasField.current.focus(); this.aliasField.current.validate({ allowEmpty: false, focused: true }); }); } renderNewItemField() { const onChange = alias => this.props.onNewItemChanged?.(alias); return /*#__PURE__*/_react.default.createElement("form", { onSubmit: this.onAliasAdded, autoComplete: "off", noValidate: true, className: "mx_EditableItemList_newItem" }, /*#__PURE__*/_react.default.createElement(_RoomAliasField.default, { ref: this.aliasField, onChange: onChange, value: this.props.newItem || "", domain: this.props.domain, roomId: this.props.roomId }), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: this.onAliasAdded, kind: "primary" }, (0, _languageHandler._t)("action|add"))); } } class AliasSettings extends _react.default.Component { constructor(props, context) { super(props, context); (0, _defineProperty2.default)(this, "onNewAliasChanged", value => { this.setState({ newAlias: value }); }); (0, _defineProperty2.default)(this, "onLocalAliasAdded", alias => { if (!alias || alias.length === 0) return; // ignore attempts to create blank aliases const localDomain = this.context.getDomain(); if (!alias.includes(":")) alias += ":" + localDomain; this.context.createAlias(alias, this.props.roomId).then(() => { this.setState({ localAliases: this.state.localAliases.concat(alias), newAlias: undefined }); if (!this.state.canonicalAlias) { this.changeCanonicalAlias(alias); } }).catch(err => { _logger.logger.error(err); _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("room_settings|general|error_creating_alias_title"), description: (0, _languageHandler._t)("room_settings|general|error_creating_alias_description") }); }); }); (0, _defineProperty2.default)(this, "onLocalAliasDeleted", index => { const alias = this.state.localAliases[index]; // TODO: In future, we should probably be making sure that the alias actually belongs // to this room. See https://github.com/vector-im/element-web/issues/7353 this.context.deleteAlias(alias).then(() => { const localAliases = this.state.localAliases.filter(a => a !== alias); this.setState({ localAliases }); if (this.state.canonicalAlias === alias) { this.changeCanonicalAlias(null); } }).catch(err => { _logger.logger.error(err); let description; if (err.errcode === "M_FORBIDDEN") { description = (0, _languageHandler._t)("room_settings|general|error_deleting_alias_description_forbidden"); } else { description = (0, _languageHandler._t)("room_settings|general|error_deleting_alias_description"); } _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("room_settings|general|error_deleting_alias_title"), description }); }); }); (0, _defineProperty2.default)(this, "onLocalAliasesToggled", event => { // expanded if (event.target.open) { // if local aliases haven't been preloaded yet at component mount if (!this.props.canSetCanonicalAlias && this.state.localAliases.length === 0) { this.loadLocalAliases(); } } this.setState({ detailsOpen: event.currentTarget.open }); }); (0, _defineProperty2.default)(this, "onCanonicalAliasChange", event => { this.changeCanonicalAlias(event.target.value); }); (0, _defineProperty2.default)(this, "onNewAltAliasChanged", value => { this.setState({ newAltAlias: value }); }); (0, _defineProperty2.default)(this, "onAltAliasAdded", alias => { const altAliases = this.state.altAliases.slice(); if (!altAliases.some(a => a.trim() === alias.trim())) { altAliases.push(alias.trim()); this.changeAltAliases(altAliases); this.setState({ newAltAlias: "" }); } }); (0, _defineProperty2.default)(this, "onAltAliasDeleted", index => { const altAliases = this.state.altAliases.slice(); altAliases.splice(index, 1); this.changeAltAliases(altAliases); }); const state = { altAliases: [], localAliases: [], canonicalAlias: null, updatingCanonicalAlias: false, localAliasesLoading: false, detailsOpen: false }; if (props.canonicalAliasEvent) { const content = props.canonicalAliasEvent.getContent(); const altAliases = content.alt_aliases; if (Array.isArray(altAliases)) { state.altAliases = altAliases.slice(); } state.canonicalAlias = content.alias; } this.state = state; } componentDidMount() { if (this.props.canSetCanonicalAlias) { // load local aliases for providing recommendations // for the canonical alias and alt_aliases this.loadLocalAliases(); } } async loadLocalAliases() { this.setState({ localAliasesLoading: true }); try { const mxClient = this.context; let localAliases = []; const response = await mxClient.getLocalAliases(this.props.roomId); if (Array.isArray(response?.aliases)) { localAliases = response.aliases; } this.setState({ localAliases }); if (localAliases.length === 0) { this.setState({ detailsOpen: true }); } } finally { this.setState({ localAliasesLoading: false }); } } changeCanonicalAlias(alias) { if (!this.props.canSetCanonicalAlias) return; const oldAlias = this.state.canonicalAlias; this.setState({ canonicalAlias: alias, updatingCanonicalAlias: true }); const eventContent = { alt_aliases: this.state.altAliases }; if (alias) eventContent["alias"] = alias; this.context.sendStateEvent(this.props.roomId, _matrix.EventType.RoomCanonicalAlias, eventContent, "").catch(err => { _logger.logger.error(err); _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("room_settings|general|error_updating_canonical_alias_title"), description: (0, _languageHandler._t)("room_settings|general|error_updating_canonical_alias_description") }); this.setState({ canonicalAlias: oldAlias }); }).finally(() => { this.setState({ updatingCanonicalAlias: false }); }); } changeAltAliases(altAliases) { if (!this.props.canSetCanonicalAlias) return; this.setState({ updatingCanonicalAlias: true }); const eventContent = {}; if (this.state.canonicalAlias) { eventContent["alias"] = this.state.canonicalAlias; } if (altAliases) { eventContent["alt_aliases"] = altAliases; } this.context.sendStateEvent(this.props.roomId, _matrix.EventType.RoomCanonicalAlias, eventContent, "").then(() => { this.setState({ altAliases }); }).catch(err => { // TODO: Add error handling based upon server validation _logger.logger.error(err); _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("room_settings|general|error_updating_canonical_alias_title"), description: (0, _languageHandler._t)("room_settings|general|error_updating_alias_description") }); }).finally(() => { this.setState({ updatingCanonicalAlias: false }); }); } getAliases() { return this.state.altAliases.concat(this.getLocalNonAltAliases()); } getLocalNonAltAliases() { const { altAliases } = this.state; return this.state.localAliases.filter(alias => !altAliases.includes(alias)); } render() { const mxClient = this.context; const localDomain = mxClient.getDomain(); const isSpaceRoom = mxClient.getRoom(this.props.roomId)?.isSpaceRoom(); let found = false; const canonicalValue = this.state.canonicalAlias || ""; const canonicalAliasSection = /*#__PURE__*/_react.default.createElement(_Field.default, { onChange: this.onCanonicalAliasChange, value: canonicalValue, disabled: this.state.updatingCanonicalAlias || !this.props.canSetCanonicalAlias, element: "select", id: "canonicalAlias", label: (0, _languageHandler._t)("room_settings|general|canonical_alias_field_label") }, /*#__PURE__*/_react.default.createElement("option", { value: "", key: "unset" }, (0, _languageHandler._t)("room_settings|alias_not_specified")), this.getAliases().map((alias, i) => { if (alias === this.state.canonicalAlias) found = true; return /*#__PURE__*/_react.default.createElement("option", { value: alias, key: i }, alias); }), found || !this.state.canonicalAlias ? "" : /*#__PURE__*/_react.default.createElement("option", { value: this.state.canonicalAlias, key: "arbitrary" }, this.state.canonicalAlias)); let localAliasesList; if (this.state.localAliasesLoading) { localAliasesList = /*#__PURE__*/_react.default.createElement(_Spinner.default, null); } else { localAliasesList = /*#__PURE__*/_react.default.createElement(EditableAliasesList, { id: "roomAliases", items: this.state.localAliases, newItem: this.state.newAlias, onNewItemChanged: this.onNewAliasChanged, canRemove: this.props.canSetAliases, canEdit: this.props.canSetAliases, onItemAdded: this.onLocalAliasAdded, onItemRemoved: this.onLocalAliasDeleted, noItemsLabel: isSpaceRoom ? (0, _languageHandler._t)("room_settings|general|no_aliases_space") : (0, _languageHandler._t)("room_settings|general|no_aliases_room"), placeholder: (0, _languageHandler._t)("room_settings|general|local_alias_field_label"), domain: localDomain }); } return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SettingsFieldset.default, { "data-testid": "published-address-fieldset", legend: (0, _languageHandler._t)("room_settings|general|published_aliases_section"), description: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isSpaceRoom ? (0, _languageHandler._t)("room_settings|general|published_aliases_explainer_space") : (0, _languageHandler._t)("room_settings|general|published_aliases_explainer_room"), "\xA0", (0, _languageHandler._t)("room_settings|general|published_aliases_description")) }, canonicalAliasSection, this.props.hidePublishSetting ? null : /*#__PURE__*/_react.default.createElement(_RoomPublishSetting.default, { roomId: this.props.roomId, canSetCanonicalAlias: this.props.canSetCanonicalAlias }), /*#__PURE__*/_react.default.createElement("datalist", { id: "mx_AliasSettings_altRecommendations" }, this.getLocalNonAltAliases().map(alias => { return /*#__PURE__*/_react.default.createElement("option", { value: alias, key: alias }); }), ";"), /*#__PURE__*/_react.default.createElement(EditableAliasesList, { id: "roomAltAliases", items: this.state.altAliases, newItem: this.state.newAltAlias, onNewItemChanged: this.onNewAltAliasChanged, canRemove: this.props.canSetCanonicalAlias, canEdit: this.props.canSetCanonicalAlias, onItemAdded: this.onAltAliasAdded, onItemRemoved: this.onAltAliasDeleted, suggestionsListId: "mx_AliasSettings_altRecommendations", itemsLabel: (0, _languageHandler._t)("room_settings|general|aliases_items_label"), noItemsLabel: (0, _languageHandler._t)("room_settings|general|aliases_no_items_label"), placeholder: (0, _languageHandler._t)("room_settings|general|new_alias_placeholder"), roomId: this.props.roomId })), /*#__PURE__*/_react.default.createElement(_SettingsFieldset.default, { "data-testid": "local-address-fieldset", legend: (0, _languageHandler._t)("room_settings|general|local_aliases_section"), description: isSpaceRoom ? (0, _languageHandler._t)("room_settings|general|local_aliases_explainer_space", { localDomain }) : (0, _languageHandler._t)("room_settings|general|local_aliases_explainer_room", { localDomain }) }, /*#__PURE__*/_react.default.createElement("details", { onToggle: this.onLocalAliasesToggled, open: this.state.detailsOpen }, /*#__PURE__*/_react.default.createElement("summary", { className: "mx_AliasSettings_localAddresses" }, this.state.detailsOpen ? (0, _languageHandler._t)("room_list|show_less") : (0, _languageHandler._t)("common|show_more")), localAliasesList))); } } exports.default = AliasSettings; (0, _defineProperty2.default)(AliasSettings, "contextType", _MatrixClientContext.default); (0, _defineProperty2.default)(AliasSettings, "defaultProps", { canSetAliases: false, canSetCanonicalAlias: false }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfbWF0cml4IiwiX2xvZ2dlciIsIl9FZGl0YWJsZUl0ZW1MaXN0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfRmllbGQiLCJfU3Bpbm5lciIsIl9FcnJvckRpYWxvZyIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX01vZGFsIiwiX1Jvb21QdWJsaXNoU2V0dGluZyIsIl9Sb29tQWxpYXNGaWVsZCIsIl9NYXRyaXhDbGllbnRDb250ZXh0IiwiX1NldHRpbmdzRmllbGRzZXQiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJFZGl0YWJsZUFsaWFzZXNMaXN0IiwiRWRpdGFibGVJdGVtTGlzdCIsImNvbnN0cnVjdG9yIiwiYXJncyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJjcmVhdGVSZWYiLCJldiIsInByZXZlbnREZWZhdWx0IiwiYWxpYXNGaWVsZCIsImN1cnJlbnQiLCJ2YWxpZGF0ZSIsImFsbG93RW1wdHkiLCJpc1ZhbGlkIiwicHJvcHMiLCJvbkl0ZW1BZGRlZCIsIm5ld0l0ZW0iLCJmb2N1cyIsImZvY3VzZWQiLCJyZW5kZXJOZXdJdGVtRmllbGQiLCJvbkNoYW5nZSIsImFsaWFzIiwib25OZXdJdGVtQ2hhbmdlZCIsImNyZWF0ZUVsZW1lbnQiLCJvblN1Ym1pdCIsIm9uQWxpYXNBZGRlZCIsImF1dG9Db21wbGV0ZSIsIm5vVmFsaWRhdGUiLCJjbGFzc05hbWUiLCJyZWYiLCJ2YWx1ZSIsImRvbWFpbiIsInJvb21JZCIsIm9uQ2xpY2siLCJraW5kIiwiX3QiLCJBbGlhc1NldHRpbmdzIiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb250ZXh0Iiwic2V0U3RhdGUiLCJuZXdBbGlhcyIsImxlbmd0aCIsImxvY2FsRG9tYWluIiwiZ2V0RG9tYWluIiwiaW5jbHVkZXMiLCJjcmVhdGVBbGlhcyIsInRoZW4iLCJsb2NhbEFsaWFzZXMiLCJzdGF0ZSIsImNvbmNhdCIsInVuZGVmaW5lZCIsImNhbm9uaWNhbEFsaWFzIiwiY2hhbmdlQ2Fub25pY2FsQWxpYXMiLCJjYXRjaCIsImVyciIsImxvZ2dlciIsImVycm9yIiwiTW9kYWwiLCJjcmVhdGVEaWFsb2ciLCJFcnJvckRpYWxvZyIsInRpdGxlIiwiZGVzY3JpcHRpb24iLCJpbmRleCIsImRlbGV0ZUFsaWFzIiwiZmlsdGVyIiwiZXJyY29kZSIsImV2ZW50IiwidGFyZ2V0Iiwib3BlbiIsImNhblNldENhbm9uaWNhbEFsaWFzIiwibG9hZExvY2FsQWxpYXNlcyIsImRldGFpbHNPcGVuIiwiY3VycmVudFRhcmdldCIsIm5ld0FsdEFsaWFzIiwiYWx0QWxpYXNlcyIsInNsaWNlIiwic29tZSIsInRyaW0iLCJwdXNoIiwiY2hhbmdlQWx0QWxpYXNlcyIsInNwbGljZSIsInVwZGF0aW5nQ2Fub25pY2FsQWxpYXMiLCJsb2NhbEFsaWFzZXNMb2FkaW5nIiwiY2Fub25pY2FsQWxpYXNFdmVudCIsImNvbnRlbnQiLCJnZXRDb250ZW50IiwiYWx0X2FsaWFzZXMiLCJBcnJheSIsImlzQXJyYXkiLCJjb21wb25lbnREaWRNb3VudCIsIm14Q2xpZW50IiwicmVzcG9uc2UiLCJnZXRMb2NhbEFsaWFzZXMiLCJhbGlhc2VzIiwib2xkQWxpYXMiLCJldmVudENvbnRlbnQiLCJzZW5kU3RhdGVFdmVudCIsIkV2ZW50VHlwZSIsIlJvb21DYW5vbmljYWxBbGlhcyIsImZpbmFsbHkiLCJnZXRBbGlhc2VzIiwiZ2V0TG9jYWxOb25BbHRBbGlhc2VzIiwicmVuZGVyIiwiaXNTcGFjZVJvb20iLCJnZXRSb29tIiwiZm91bmQiLCJjYW5vbmljYWxWYWx1ZSIsImNhbm9uaWNhbEFsaWFzU2VjdGlvbiIsIm9uQ2Fub25pY2FsQWxpYXNDaGFuZ2UiLCJkaXNhYmxlZCIsImVsZW1lbnQiLCJpZCIsImxhYmVsIiwia2V5IiwibWFwIiwibG9jYWxBbGlhc2VzTGlzdCIsIml0ZW1zIiwib25OZXdBbGlhc0NoYW5nZWQiLCJjYW5SZW1vdmUiLCJjYW5TZXRBbGlhc2VzIiwiY2FuRWRpdCIsIm9uTG9jYWxBbGlhc0FkZGVkIiwib25JdGVtUmVtb3ZlZCIsIm9uTG9jYWxBbGlhc0RlbGV0ZWQiLCJub0l0ZW1zTGFiZWwiLCJwbGFjZWhvbGRlciIsIkZyYWdtZW50IiwibGVnZW5kIiwiaGlkZVB1Ymxpc2hTZXR0aW5nIiwib25OZXdBbHRBbGlhc0NoYW5nZWQiLCJvbkFsdEFsaWFzQWRkZWQiLCJvbkFsdEFsaWFzRGVsZXRlZCIsInN1Z2dlc3Rpb25zTGlzdElkIiwiaXRlbXNMYWJlbCIsIm9uVG9nZ2xlIiwib25Mb2NhbEFsaWFzZXNUb2dnbGVkIiwiZXhwb3J0cyIsIk1hdHJpeENsaWVudENvbnRleHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9yb29tX3NldHRpbmdzL0FsaWFzU2V0dGluZ3MudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE2LTIwMjMgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IENoYW5nZUV2ZW50LCBDb250ZXh0VHlwZSwgY3JlYXRlUmVmLCBTeW50aGV0aWNFdmVudCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgTWF0cml4RXZlbnQsIEV2ZW50VHlwZSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcbmltcG9ydCB7IFJvb21DYW5vbmljYWxBbGlhc0V2ZW50Q29udGVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuXG5pbXBvcnQgRWRpdGFibGVJdGVtTGlzdCBmcm9tIFwiLi4vZWxlbWVudHMvRWRpdGFibGVJdGVtTGlzdFwiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgRmllbGQgZnJvbSBcIi4uL2VsZW1lbnRzL0ZpZWxkXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi4vZWxlbWVudHMvU3Bpbm5lclwiO1xuaW1wb3J0IEVycm9yRGlhbG9nIGZyb20gXCIuLi9kaWFsb2dzL0Vycm9yRGlhbG9nXCI7XG5pbXBvcnQgQWNjZXNzaWJsZUJ1dHRvbiBmcm9tIFwiLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IE1vZGFsIGZyb20gXCIuLi8uLi8uLi9Nb2RhbFwiO1xuaW1wb3J0IFJvb21QdWJsaXNoU2V0dGluZyBmcm9tIFwiLi9Sb29tUHVibGlzaFNldHRpbmdcIjtcbmltcG9ydCBSb29tQWxpYXNGaWVsZCBmcm9tIFwiLi4vZWxlbWVudHMvUm9vbUFsaWFzRmllbGRcIjtcbmltcG9ydCBNYXRyaXhDbGllbnRDb250ZXh0IGZyb20gXCIuLi8uLi8uLi9jb250ZXh0cy9NYXRyaXhDbGllbnRDb250ZXh0XCI7XG5pbXBvcnQgU2V0dGluZ3NGaWVsZHNldCBmcm9tIFwiLi4vc2V0dGluZ3MvU2V0dGluZ3NGaWVsZHNldFwiO1xuXG5pbnRlcmZhY2UgSUVkaXRhYmxlQWxpYXNlc0xpc3RQcm9wcyB7XG4gICAgcm9vbUlkPzogc3RyaW5nO1xuICAgIGRvbWFpbj86IHN0cmluZztcbn1cblxuY2xhc3MgRWRpdGFibGVBbGlhc2VzTGlzdCBleHRlbmRzIEVkaXRhYmxlSXRlbUxpc3Q8SUVkaXRhYmxlQWxpYXNlc0xpc3RQcm9wcz4ge1xuICAgIHByaXZhdGUgYWxpYXNGaWVsZCA9IGNyZWF0ZVJlZjxSb29tQWxpYXNGaWVsZD4oKTtcblxuICAgIHByaXZhdGUgb25BbGlhc0FkZGVkID0gYXN5bmMgKGV2OiBTeW50aGV0aWNFdmVudCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGlmICghdGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQudmFsaWRhdGUoeyBhbGxvd0VtcHR5OiBmYWxzZSB9KTtcblxuICAgICAgICBpZiAodGhpcy5hbGlhc0ZpZWxkLmN1cnJlbnQuaXNWYWxpZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25JdGVtQWRkZWQpIHRoaXMucHJvcHMub25JdGVtQWRkZWQodGhpcy5wcm9wcy5uZXdJdGVtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWxpYXNGaWVsZC5jdXJyZW50LmZvY3VzKCk7XG4gICAgICAgIHRoaXMuYWxpYXNGaWVsZC5jdXJyZW50LnZhbGlkYXRlKHsgYWxsb3dFbXB0eTogZmFsc2UsIGZvY3VzZWQ6IHRydWUgfSk7XG4gICAgfTtcblxuICAgIHByb3RlY3RlZCByZW5kZXJOZXdJdGVtRmllbGQoKTogSlNYLkVsZW1lbnQge1xuICAgICAgICBjb25zdCBvbkNoYW5nZSA9IChhbGlhczogc3RyaW5nKTogdm9pZCA9PiB0aGlzLnByb3BzLm9uTmV3SXRlbUNoYW5nZWQ/LihhbGlhcyk7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8Zm9ybVxuICAgICAgICAgICAgICAgIG9uU3VibWl0PXt0aGlzLm9uQWxpYXNBZGRlZH1cbiAgICAgICAgICAgICAgICBhdXRvQ29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgIG5vVmFsaWRhdGU9e3RydWV9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfRWRpdGFibGVJdGVtTGlzdF9uZXdJdGVtXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8Um9vbUFsaWFzRmllbGRcbiAgICAgICAgICAgICAgICAgICAgcmVmPXt0aGlzLmFsaWFzRmllbGR9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMucHJvcHMubmV3SXRlbSB8fCBcIlwifVxuICAgICAgICAgICAgICAgICAgICBkb21haW49e3RoaXMucHJvcHMuZG9tYWlufVxuICAgICAgICAgICAgICAgICAgICByb29tSWQ9e3RoaXMucHJvcHMucm9vbUlkfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24gb25DbGljaz17dGhpcy5vbkFsaWFzQWRkZWR9IGtpbmQ9XCJwcmltYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImFjdGlvbnxhZGRcIil9XG4gICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICApO1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgcm9vbUlkOiBzdHJpbmc7XG4gICAgY2FuU2V0Q2Fub25pY2FsQWxpYXM6IGJvb2xlYW47XG4gICAgY2FuU2V0QWxpYXNlczogYm9vbGVhbjtcbiAgICBjYW5vbmljYWxBbGlhc0V2ZW50PzogTWF0cml4RXZlbnQ7XG4gICAgaGlkZVB1Ymxpc2hTZXR0aW5nPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgLy8gWyAjYWxpYXM6ZG9tYWluLnRsZCwgLi4uIF1cbiAgICBhbHRBbGlhc2VzOiBzdHJpbmdbXTtcbiAgICAvLyBbICNhbGlhczpteS1ocy50bGQsIC4uLiBdXG4gICAgbG9jYWxBbGlhc2VzOiBzdHJpbmdbXTtcbiAgICAvLyAjY2Fub25pY2FsOmRvbWFpbi50bGRcbiAgICBjYW5vbmljYWxBbGlhczogc3RyaW5nIHwgbnVsbDtcbiAgICB1cGRhdGluZ0Nhbm9uaWNhbEFsaWFzOiBib29sZWFuO1xuICAgIGxvY2FsQWxpYXNlc0xvYWRpbmc6IGJvb2xlYW47XG4gICAgZGV0YWlsc09wZW46IGJvb2xlYW47XG4gICAgbmV3QWxpYXM/OiBzdHJpbmc7XG4gICAgbmV3QWx0QWxpYXM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFsaWFzU2V0dGluZ3MgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwdWJsaWMgc3RhdGljIGNvbnRleHRUeXBlID0gTWF0cml4Q2xpZW50Q29udGV4dDtcbiAgICBwdWJsaWMgZGVjbGFyZSBjb250ZXh0OiBDb250ZXh0VHlwZTx0eXBlb2YgTWF0cml4Q2xpZW50Q29udGV4dD47XG5cbiAgICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wcyA9IHtcbiAgICAgICAgY2FuU2V0QWxpYXNlczogZmFsc2UsXG4gICAgICAgIGNhblNldENhbm9uaWNhbEFsaWFzOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBJUHJvcHMsIGNvbnRleHQ6IENvbnRleHRUeXBlPHR5cGVvZiBNYXRyaXhDbGllbnRDb250ZXh0Pikge1xuICAgICAgICBzdXBlcihwcm9wcywgY29udGV4dCk7XG5cbiAgICAgICAgY29uc3Qgc3RhdGU6IElTdGF0ZSA9IHtcbiAgICAgICAgICAgIGFsdEFsaWFzZXM6IFtdLFxuICAgICAgICAgICAgbG9jYWxBbGlhc2VzOiBbXSxcbiAgICAgICAgICAgIGNhbm9uaWNhbEFsaWFzOiBudWxsLFxuICAgICAgICAgICAgdXBkYXRpbmdDYW5vbmljYWxBbGlhczogZmFsc2UsXG4gICAgICAgICAgICBsb2NhbEFsaWFzZXNMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGRldGFpbHNPcGVuOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocHJvcHMuY2Fub25pY2FsQWxpYXNFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IHByb3BzLmNhbm9uaWNhbEFsaWFzRXZlbnQuZ2V0Q29udGVudCgpO1xuICAgICAgICAgICAgY29uc3QgYWx0QWxpYXNlcyA9IGNvbnRlbnQuYWx0X2FsaWFzZXM7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhbHRBbGlhc2VzKSkge1xuICAgICAgICAgICAgICAgIHN0YXRlLmFsdEFsaWFzZXMgPSBhbHRBbGlhc2VzLnNsaWNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGF0ZS5jYW5vbmljYWxBbGlhcyA9IGNvbnRlbnQuYWxpYXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5jYW5TZXRDYW5vbmljYWxBbGlhcykge1xuICAgICAgICAgICAgLy8gbG9hZCBsb2NhbCBhbGlhc2VzIGZvciBwcm92aWRpbmcgcmVjb21tZW5kYXRpb25zXG4gICAgICAgICAgICAvLyBmb3IgdGhlIGNhbm9uaWNhbCBhbGlhcyBhbmQgYWx0X2FsaWFzZXNcbiAgICAgICAgICAgIHRoaXMubG9hZExvY2FsQWxpYXNlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBsb2FkTG9jYWxBbGlhc2VzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9jYWxBbGlhc2VzTG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IG14Q2xpZW50ID0gdGhpcy5jb250ZXh0O1xuXG4gICAgICAgICAgICBsZXQgbG9jYWxBbGlhc2VzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBteENsaWVudC5nZXRMb2NhbEFsaWFzZXModGhpcy5wcm9wcy5yb29tSWQpO1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2U/LmFsaWFzZXMpKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxBbGlhc2VzID0gcmVzcG9uc2UuYWxpYXNlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2NhbEFsaWFzZXMgfSk7XG5cbiAgICAgICAgICAgIGlmIChsb2NhbEFsaWFzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRldGFpbHNPcGVuOiB0cnVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxvY2FsQWxpYXNlc0xvYWRpbmc6IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGFuZ2VDYW5vbmljYWxBbGlhcyhhbGlhczogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMuY2FuU2V0Q2Fub25pY2FsQWxpYXMpIHJldHVybjtcblxuICAgICAgICBjb25zdCBvbGRBbGlhcyA9IHRoaXMuc3RhdGUuY2Fub25pY2FsQWxpYXM7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgY2Fub25pY2FsQWxpYXM6IGFsaWFzLFxuICAgICAgICAgICAgdXBkYXRpbmdDYW5vbmljYWxBbGlhczogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZXZlbnRDb250ZW50OiBSb29tQ2Fub25pY2FsQWxpYXNFdmVudENvbnRlbnQgPSB7XG4gICAgICAgICAgICBhbHRfYWxpYXNlczogdGhpcy5zdGF0ZS5hbHRBbGlhc2VzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChhbGlhcykgZXZlbnRDb250ZW50W1wiYWxpYXNcIl0gPSBhbGlhcztcblxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICAgICAgIC5zZW5kU3RhdGVFdmVudCh0aGlzLnByb3BzLnJvb21JZCwgRXZlbnRUeXBlLlJvb21DYW5vbmljYWxBbGlhcywgZXZlbnRDb250ZW50LCBcIlwiKVxuICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IF90KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfGVycm9yX3VwZGF0aW5nX2Nhbm9uaWNhbF9hbGlhc190aXRsZVwiKSxcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IF90KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfGVycm9yX3VwZGF0aW5nX2Nhbm9uaWNhbF9hbGlhc19kZXNjcmlwdGlvblwiKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY2Fub25pY2FsQWxpYXM6IG9sZEFsaWFzIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgdXBkYXRpbmdDYW5vbmljYWxBbGlhczogZmFsc2UgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoYW5nZUFsdEFsaWFzZXMoYWx0QWxpYXNlczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmNhblNldENhbm9uaWNhbEFsaWFzKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICB1cGRhdGluZ0Nhbm9uaWNhbEFsaWFzOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBldmVudENvbnRlbnQ6IFJvb21DYW5vbmljYWxBbGlhc0V2ZW50Q29udGVudCA9IHt9O1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmNhbm9uaWNhbEFsaWFzKSB7XG4gICAgICAgICAgICBldmVudENvbnRlbnRbXCJhbGlhc1wiXSA9IHRoaXMuc3RhdGUuY2Fub25pY2FsQWxpYXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsdEFsaWFzZXMpIHtcbiAgICAgICAgICAgIGV2ZW50Q29udGVudFtcImFsdF9hbGlhc2VzXCJdID0gYWx0QWxpYXNlcztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29udGV4dFxuICAgICAgICAgICAgLnNlbmRTdGF0ZUV2ZW50KHRoaXMucHJvcHMucm9vbUlkLCBFdmVudFR5cGUuUm9vbUNhbm9uaWNhbEFsaWFzLCBldmVudENvbnRlbnQsIFwiXCIpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGFsdEFsaWFzZXMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBZGQgZXJyb3IgaGFuZGxpbmcgYmFzZWQgdXBvbiBzZXJ2ZXIgdmFsaWRhdGlvblxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhFcnJvckRpYWxvZywge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfdXBkYXRpbmdfY2Fub25pY2FsX2FsaWFzX3RpdGxlXCIpLFxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfdXBkYXRpbmdfYWxpYXNfZGVzY3JpcHRpb25cIiksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyB1cGRhdGluZ0Nhbm9uaWNhbEFsaWFzOiBmYWxzZSB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25OZXdBbGlhc0NoYW5nZWQgPSAodmFsdWU6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbmV3QWxpYXM6IHZhbHVlIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTG9jYWxBbGlhc0FkZGVkID0gKGFsaWFzPzogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGlmICghYWxpYXMgfHwgYWxpYXMubGVuZ3RoID09PSAwKSByZXR1cm47IC8vIGlnbm9yZSBhdHRlbXB0cyB0byBjcmVhdGUgYmxhbmsgYWxpYXNlc1xuXG4gICAgICAgIGNvbnN0IGxvY2FsRG9tYWluID0gdGhpcy5jb250ZXh0LmdldERvbWFpbigpO1xuICAgICAgICBpZiAoIWFsaWFzLmluY2x1ZGVzKFwiOlwiKSkgYWxpYXMgKz0gXCI6XCIgKyBsb2NhbERvbWFpbjtcblxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICAgICAgIC5jcmVhdGVBbGlhcyhhbGlhcywgdGhpcy5wcm9wcy5yb29tSWQpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsQWxpYXNlczogdGhpcy5zdGF0ZS5sb2NhbEFsaWFzZXMuY29uY2F0KGFsaWFzISksXG4gICAgICAgICAgICAgICAgICAgIG5ld0FsaWFzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmNhbm9uaWNhbEFsaWFzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlQ2Fub25pY2FsQWxpYXMoYWxpYXMhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IF90KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfGVycm9yX2NyZWF0aW5nX2FsaWFzX3RpdGxlXCIpLFxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfY3JlYXRpbmdfYWxpYXNfZGVzY3JpcHRpb25cIiksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkxvY2FsQWxpYXNEZWxldGVkID0gKGluZGV4OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgYWxpYXMgPSB0aGlzLnN0YXRlLmxvY2FsQWxpYXNlc1tpbmRleF07XG4gICAgICAgIC8vIFRPRE86IEluIGZ1dHVyZSwgd2Ugc2hvdWxkIHByb2JhYmx5IGJlIG1ha2luZyBzdXJlIHRoYXQgdGhlIGFsaWFzIGFjdHVhbGx5IGJlbG9uZ3NcbiAgICAgICAgLy8gdG8gdGhpcyByb29tLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvNzM1M1xuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICAgICAgIC5kZWxldGVBbGlhcyhhbGlhcylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBsb2NhbEFsaWFzZXMgPSB0aGlzLnN0YXRlLmxvY2FsQWxpYXNlcy5maWx0ZXIoKGEpID0+IGEgIT09IGFsaWFzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9jYWxBbGlhc2VzIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2Fub25pY2FsQWxpYXMgPT09IGFsaWFzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlQ2Fub25pY2FsQWxpYXMobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgbGV0IGRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgIGlmIChlcnIuZXJyY29kZSA9PT0gXCJNX0ZPUkJJRERFTlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfZGVsZXRpbmdfYWxpYXNfZGVzY3JpcHRpb25fZm9yYmlkZGVuXCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfZGVsZXRpbmdfYWxpYXNfZGVzY3JpcHRpb25cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhFcnJvckRpYWxvZywge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8ZXJyb3JfZGVsZXRpbmdfYWxpYXNfdGl0bGVcIiksXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Mb2NhbEFsaWFzZXNUb2dnbGVkID0gKGV2ZW50OiBDaGFuZ2VFdmVudDxIVE1MRGV0YWlsc0VsZW1lbnQ+KTogdm9pZCA9PiB7XG4gICAgICAgIC8vIGV4cGFuZGVkXG4gICAgICAgIGlmIChldmVudC50YXJnZXQub3Blbikge1xuICAgICAgICAgICAgLy8gaWYgbG9jYWwgYWxpYXNlcyBoYXZlbid0IGJlZW4gcHJlbG9hZGVkIHlldCBhdCBjb21wb25lbnQgbW91bnRcbiAgICAgICAgICAgIGlmICghdGhpcy5wcm9wcy5jYW5TZXRDYW5vbmljYWxBbGlhcyAmJiB0aGlzLnN0YXRlLmxvY2FsQWxpYXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRMb2NhbEFsaWFzZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGV0YWlsc09wZW46IGV2ZW50LmN1cnJlbnRUYXJnZXQub3BlbiB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkNhbm9uaWNhbEFsaWFzQ2hhbmdlID0gKGV2ZW50OiBDaGFuZ2VFdmVudDxIVE1MU2VsZWN0RWxlbWVudD4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5jaGFuZ2VDYW5vbmljYWxBbGlhcyhldmVudC50YXJnZXQudmFsdWUpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTmV3QWx0QWxpYXNDaGFuZ2VkID0gKHZhbHVlOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG5ld0FsdEFsaWFzOiB2YWx1ZSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkFsdEFsaWFzQWRkZWQgPSAoYWxpYXM6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBhbHRBbGlhc2VzID0gdGhpcy5zdGF0ZS5hbHRBbGlhc2VzLnNsaWNlKCk7XG4gICAgICAgIGlmICghYWx0QWxpYXNlcy5zb21lKChhKSA9PiBhLnRyaW0oKSA9PT0gYWxpYXMudHJpbSgpKSkge1xuICAgICAgICAgICAgYWx0QWxpYXNlcy5wdXNoKGFsaWFzLnRyaW0oKSk7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZUFsdEFsaWFzZXMoYWx0QWxpYXNlcyk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbmV3QWx0QWxpYXM6IFwiXCIgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkFsdEFsaWFzRGVsZXRlZCA9IChpbmRleDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IGFsdEFsaWFzZXMgPSB0aGlzLnN0YXRlLmFsdEFsaWFzZXMuc2xpY2UoKTtcbiAgICAgICAgYWx0QWxpYXNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB0aGlzLmNoYW5nZUFsdEFsaWFzZXMoYWx0QWxpYXNlcyk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgZ2V0QWxpYXNlcygpOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmFsdEFsaWFzZXMuY29uY2F0KHRoaXMuZ2V0TG9jYWxOb25BbHRBbGlhc2VzKCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0TG9jYWxOb25BbHRBbGlhc2VzKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgeyBhbHRBbGlhc2VzIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5sb2NhbEFsaWFzZXMuZmlsdGVyKChhbGlhcykgPT4gIWFsdEFsaWFzZXMuaW5jbHVkZXMoYWxpYXMpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IG14Q2xpZW50ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBjb25zdCBsb2NhbERvbWFpbiA9IG14Q2xpZW50LmdldERvbWFpbigpITtcbiAgICAgICAgY29uc3QgaXNTcGFjZVJvb20gPSBteENsaWVudC5nZXRSb29tKHRoaXMucHJvcHMucm9vbUlkKT8uaXNTcGFjZVJvb20oKTtcblxuICAgICAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgY2Fub25pY2FsVmFsdWUgPSB0aGlzLnN0YXRlLmNhbm9uaWNhbEFsaWFzIHx8IFwiXCI7XG4gICAgICAgIGNvbnN0IGNhbm9uaWNhbEFsaWFzU2VjdGlvbiA9IChcbiAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uQ2Fub25pY2FsQWxpYXNDaGFuZ2V9XG4gICAgICAgICAgICAgICAgdmFsdWU9e2Nhbm9uaWNhbFZhbHVlfVxuICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnN0YXRlLnVwZGF0aW5nQ2Fub25pY2FsQWxpYXMgfHwgIXRoaXMucHJvcHMuY2FuU2V0Q2Fub25pY2FsQWxpYXN9XG4gICAgICAgICAgICAgICAgZWxlbWVudD1cInNlbGVjdFwiXG4gICAgICAgICAgICAgICAgaWQ9XCJjYW5vbmljYWxBbGlhc1wiXG4gICAgICAgICAgICAgICAgbGFiZWw9e190KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfGNhbm9uaWNhbF9hbGlhc19maWVsZF9sYWJlbFwiKX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIga2V5PVwidW5zZXRcIj5cbiAgICAgICAgICAgICAgICAgICAge190KFwicm9vbV9zZXR0aW5nc3xhbGlhc19ub3Rfc3BlY2lmaWVkXCIpfVxuICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIHt0aGlzLmdldEFsaWFzZXMoKS5tYXAoKGFsaWFzLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbGlhcyA9PT0gdGhpcy5zdGF0ZS5jYW5vbmljYWxBbGlhcykgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT17YWxpYXN9IGtleT17aX0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge2FsaWFzfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAge2ZvdW5kIHx8ICF0aGlzLnN0YXRlLmNhbm9uaWNhbEFsaWFzID8gKFxuICAgICAgICAgICAgICAgICAgICBcIlwiXG4gICAgICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT17dGhpcy5zdGF0ZS5jYW5vbmljYWxBbGlhc30ga2V5PVwiYXJiaXRyYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5zdGF0ZS5jYW5vbmljYWxBbGlhc31cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDwvRmllbGQ+XG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGxvY2FsQWxpYXNlc0xpc3Q6IEpTWC5FbGVtZW50O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5sb2NhbEFsaWFzZXNMb2FkaW5nKSB7XG4gICAgICAgICAgICBsb2NhbEFsaWFzZXNMaXN0ID0gPFNwaW5uZXIgLz47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2NhbEFsaWFzZXNMaXN0ID0gKFxuICAgICAgICAgICAgICAgIDxFZGl0YWJsZUFsaWFzZXNMaXN0XG4gICAgICAgICAgICAgICAgICAgIGlkPVwicm9vbUFsaWFzZXNcIlxuICAgICAgICAgICAgICAgICAgICBpdGVtcz17dGhpcy5zdGF0ZS5sb2NhbEFsaWFzZXN9XG4gICAgICAgICAgICAgICAgICAgIG5ld0l0ZW09e3RoaXMuc3RhdGUubmV3QWxpYXN9XG4gICAgICAgICAgICAgICAgICAgIG9uTmV3SXRlbUNoYW5nZWQ9e3RoaXMub25OZXdBbGlhc0NoYW5nZWR9XG4gICAgICAgICAgICAgICAgICAgIGNhblJlbW92ZT17dGhpcy5wcm9wcy5jYW5TZXRBbGlhc2VzfVxuICAgICAgICAgICAgICAgICAgICBjYW5FZGl0PXt0aGlzLnByb3BzLmNhblNldEFsaWFzZXN9XG4gICAgICAgICAgICAgICAgICAgIG9uSXRlbUFkZGVkPXt0aGlzLm9uTG9jYWxBbGlhc0FkZGVkfVxuICAgICAgICAgICAgICAgICAgICBvbkl0ZW1SZW1vdmVkPXt0aGlzLm9uTG9jYWxBbGlhc0RlbGV0ZWR9XG4gICAgICAgICAgICAgICAgICAgIG5vSXRlbXNMYWJlbD17XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1NwYWNlUm9vbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8bm9fYWxpYXNlc19zcGFjZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8bm9fYWxpYXNlc19yb29tXCIpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9e190KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfGxvY2FsX2FsaWFzX2ZpZWxkX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICBkb21haW49e2xvY2FsRG9tYWlufVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPFNldHRpbmdzRmllbGRzZXRcbiAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJwdWJsaXNoZWQtYWRkcmVzcy1maWVsZHNldFwiXG4gICAgICAgICAgICAgICAgICAgIGxlZ2VuZD17X3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8cHVibGlzaGVkX2FsaWFzZXNfc2VjdGlvblwiKX1cbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb249e1xuICAgICAgICAgICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aXNTcGFjZVJvb21cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBfdChcInJvb21fc2V0dGluZ3N8Z2VuZXJhbHxwdWJsaXNoZWRfYWxpYXNlc19leHBsYWluZXJfc3BhY2VcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInJvb21fc2V0dGluZ3N8Z2VuZXJhbHxwdWJsaXNoZWRfYWxpYXNlc19leHBsYWluZXJfcm9vbVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmJzcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8cHVibGlzaGVkX2FsaWFzZXNfZGVzY3JpcHRpb25cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8Lz5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge2Nhbm9uaWNhbEFsaWFzU2VjdGlvbn1cbiAgICAgICAgICAgICAgICAgICAge3RoaXMucHJvcHMuaGlkZVB1Ymxpc2hTZXR0aW5nID8gbnVsbCA6IChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxSb29tUHVibGlzaFNldHRpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb29tSWQ9e3RoaXMucHJvcHMucm9vbUlkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhblNldENhbm9uaWNhbEFsaWFzPXt0aGlzLnByb3BzLmNhblNldENhbm9uaWNhbEFsaWFzfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgPGRhdGFsaXN0IGlkPVwibXhfQWxpYXNTZXR0aW5nc19hbHRSZWNvbW1lbmRhdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLmdldExvY2FsTm9uQWx0QWxpYXNlcygpLm1hcCgoYWxpYXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gPG9wdGlvbiB2YWx1ZT17YWxpYXN9IGtleT17YWxpYXN9IC8+O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgICAgICAgICA7XG4gICAgICAgICAgICAgICAgICAgIDwvZGF0YWxpc3Q+XG4gICAgICAgICAgICAgICAgICAgIDxFZGl0YWJsZUFsaWFzZXNMaXN0XG4gICAgICAgICAgICAgICAgICAgICAgICBpZD1cInJvb21BbHRBbGlhc2VzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zPXt0aGlzLnN0YXRlLmFsdEFsaWFzZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdJdGVtPXt0aGlzLnN0YXRlLm5ld0FsdEFsaWFzfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25OZXdJdGVtQ2hhbmdlZD17dGhpcy5vbk5ld0FsdEFsaWFzQ2hhbmdlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhblJlbW92ZT17dGhpcy5wcm9wcy5jYW5TZXRDYW5vbmljYWxBbGlhc31cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbkVkaXQ9e3RoaXMucHJvcHMuY2FuU2V0Q2Fub25pY2FsQWxpYXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkl0ZW1BZGRlZD17dGhpcy5vbkFsdEFsaWFzQWRkZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkl0ZW1SZW1vdmVkPXt0aGlzLm9uQWx0QWxpYXNEZWxldGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgc3VnZ2VzdGlvbnNMaXN0SWQ9XCJteF9BbGlhc1NldHRpbmdzX2FsdFJlY29tbWVuZGF0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtc0xhYmVsPXtfdChcInJvb21fc2V0dGluZ3N8Z2VuZXJhbHxhbGlhc2VzX2l0ZW1zX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgbm9JdGVtc0xhYmVsPXtfdChcInJvb21fc2V0dGluZ3N8Z2VuZXJhbHxhbGlhc2VzX25vX2l0ZW1zX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9e190KFwicm9vbV9zZXR0aW5nc3xnZW5lcmFsfG5ld19hbGlhc19wbGFjZWhvbGRlclwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJvb21JZD17dGhpcy5wcm9wcy5yb29tSWR9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPC9TZXR0aW5nc0ZpZWxkc2V0PlxuICAgICAgICAgICAgICAgIDxTZXR0aW5nc0ZpZWxkc2V0XG4gICAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwibG9jYWwtYWRkcmVzcy1maWVsZHNldFwiXG4gICAgICAgICAgICAgICAgICAgIGxlZ2VuZD17X3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8bG9jYWxfYWxpYXNlc19zZWN0aW9uXCIpfVxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbj17XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1NwYWNlUm9vbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8bG9jYWxfYWxpYXNlc19leHBsYWluZXJfc3BhY2VcIiwgeyBsb2NhbERvbWFpbiB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogX3QoXCJyb29tX3NldHRpbmdzfGdlbmVyYWx8bG9jYWxfYWxpYXNlc19leHBsYWluZXJfcm9vbVwiLCB7IGxvY2FsRG9tYWluIH0pXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkZXRhaWxzIG9uVG9nZ2xlPXt0aGlzLm9uTG9jYWxBbGlhc2VzVG9nZ2xlZH0gb3Blbj17dGhpcy5zdGF0ZS5kZXRhaWxzT3Blbn0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3VtbWFyeSBjbGFzc05hbWU9XCJteF9BbGlhc1NldHRpbmdzX2xvY2FsQWRkcmVzc2VzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3RoaXMuc3RhdGUuZGV0YWlsc09wZW4gPyBfdChcInJvb21fbGlzdHxzaG93X2xlc3NcIikgOiBfdChcImNvbW1vbnxzaG93X21vcmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3N1bW1hcnk+XG4gICAgICAgICAgICAgICAgICAgICAgICB7bG9jYWxBbGlhc2VzTGlzdH1cbiAgICAgICAgICAgICAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgICAgICAgICAgIDwvU2V0dGluZ3NGaWVsZHNldD5cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFHQSxJQUFBRyxpQkFBQSxHQUFBQyxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQUssZ0JBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLE1BQUEsR0FBQUYsc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FBQUgsc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFRLFlBQUEsR0FBQUosc0JBQUEsQ0FBQUosT0FBQTtBQUNBLElBQUFTLGlCQUFBLEdBQUFMLHNCQUFBLENBQUFKLE9BQUE7QUFDQSxJQUFBVSxNQUFBLEdBQUFOLHNCQUFBLENBQUFKLE9BQUE7QUFDQSxJQUFBVyxtQkFBQSxHQUFBUCxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQVksZUFBQSxHQUFBUixzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQWEsb0JBQUEsR0FBQVQsc0JBQUEsQ0FBQUos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