matrix-react-sdk
Version:
SDK for matrix.org using React
371 lines (367 loc) • 61.3 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 _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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