matrix-react-sdk
Version:
SDK for matrix.org using React
323 lines (272 loc) • 46.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _languageHandler = require("../../../../../languageHandler");
var _SdkConfig = _interopRequireDefault(require("../../../../../SdkConfig"));
var _Mjolnir = require("../../../../../mjolnir/Mjolnir");
var _BanList = require("../../../../../mjolnir/BanList");
var _Modal = _interopRequireDefault(require("../../../../../Modal"));
var _MatrixClientPeg = require("../../../../../MatrixClientPeg");
var sdk = _interopRequireWildcard(require("../../../../../index"));
var _replaceableComponent = require("../../../../../utils/replaceableComponent");
var _dec, _class, _temp;
let MjolnirUserSettingsTab = (_dec = (0, _replaceableComponent.replaceableComponent)("views.settings.tabs.user.MjolnirUserSettingsTab"), _dec(_class = (_temp = class MjolnirUserSettingsTab extends _react.default.Component
/*:: <{}, IState>*/
{
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onPersonalRuleChanged", e => {
this.setState({
newPersonalRule: e.target.value
});
});
(0, _defineProperty2.default)(this, "onNewListChanged", e => {
this.setState({
newList: e.target.value
});
});
(0, _defineProperty2.default)(this, "onAddPersonalRule", async e => {
e.preventDefault();
e.stopPropagation();
let kind = _BanList.RULE_SERVER;
if (this.state.newPersonalRule.startsWith("@")) {
kind = _BanList.RULE_USER;
}
this.setState({
busy: true
});
try {
const list = await _Mjolnir.Mjolnir.sharedInstance().getOrCreatePersonalList();
await list.banEntity(kind, this.state.newPersonalRule, (0, _languageHandler._t)("Ignored/Blocked"));
this.setState({
newPersonalRule: ""
}); // this will also cause the new rule to be rendered
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
_Modal.default.createTrackedDialog('Failed to add Mjolnir rule', '', ErrorDialog, {
title: (0, _languageHandler._t)('Error adding ignored user/server'),
description: (0, _languageHandler._t)('Something went wrong. Please try again or view your console for hints.')
});
} finally {
this.setState({
busy: false
});
}
});
(0, _defineProperty2.default)(this, "onSubscribeList", async e => {
e.preventDefault();
e.stopPropagation();
this.setState({
busy: true
});
try {
const room = await _MatrixClientPeg.MatrixClientPeg.get().joinRoom(this.state.newList);
await _Mjolnir.Mjolnir.sharedInstance().subscribeToList(room.roomId);
this.setState({
newList: ""
}); // this will also cause the new rule to be rendered
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
_Modal.default.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, {
title: (0, _languageHandler._t)('Error subscribing to list'),
description: (0, _languageHandler._t)('Please verify the room ID or address and try again.')
});
} finally {
this.setState({
busy: false
});
}
});
this.state = {
busy: false,
newPersonalRule: "",
newList: ""
};
}
async removePersonalRule(rule
/*: ListRule*/
) {
this.setState({
busy: true
});
try {
const list = _Mjolnir.Mjolnir.sharedInstance().getPersonalList();
await list.unbanEntity(rule.kind, rule.entity);
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
_Modal.default.createTrackedDialog('Failed to remove Mjolnir rule', '', ErrorDialog, {
title: (0, _languageHandler._t)('Error removing ignored user/server'),
description: (0, _languageHandler._t)('Something went wrong. Please try again or view your console for hints.')
});
} finally {
this.setState({
busy: false
});
}
}
async unsubscribeFromList(list
/*: BanList*/
) {
this.setState({
busy: true
});
try {
await _Mjolnir.Mjolnir.sharedInstance().unsubscribeFromList(list.roomId);
await _MatrixClientPeg.MatrixClientPeg.get().leave(list.roomId);
} catch (e) {
console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
_Modal.default.createTrackedDialog('Failed to unsubscribe from Mjolnir list', '', ErrorDialog, {
title: (0, _languageHandler._t)('Error unsubscribing from list'),
description: (0, _languageHandler._t)('Please try again or view your console for hints.')
});
} finally {
this.setState({
busy: false
});
}
}
viewListRules(list
/*: BanList*/
) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const room = _MatrixClientPeg.MatrixClientPeg.get().getRoom(list.roomId);
const name = room ? room.name : list.roomId;
const renderRules = (rules
/*: ListRule[]*/
) => {
if (rules.length === 0) return /*#__PURE__*/_react.default.createElement("i", null, (0, _languageHandler._t)("None"));
const tiles = [];
for (const rule of rules) {
tiles.push( /*#__PURE__*/_react.default.createElement("li", {
key: rule.kind + rule.entity
}, /*#__PURE__*/_react.default.createElement("code", null, rule.entity)));
}
return /*#__PURE__*/_react.default.createElement("ul", null, tiles);
};
_Modal.default.createTrackedDialog('View Mjolnir list rules', '', QuestionDialog, {
title: (0, _languageHandler._t)("Ban list rules - %(roomName)s", {
roomName: name
}),
description: /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("Server rules")), renderRules(list.serverRules), /*#__PURE__*/_react.default.createElement("h3", null, (0, _languageHandler._t)("User rules")), renderRules(list.userRules)),
button: (0, _languageHandler._t)("Close"),
hasCancelButton: false
});
}
renderPersonalBanListRules() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const list = _Mjolnir.Mjolnir.sharedInstance().getPersonalList();
const rules = list ? [...list.userRules, ...list.serverRules] : [];
if (!list || rules.length <= 0) return /*#__PURE__*/_react.default.createElement("i", null, (0, _languageHandler._t)("You have not ignored anyone."));
const tiles = [];
for (const rule of rules) {
tiles.push( /*#__PURE__*/_react.default.createElement("li", {
key: rule.entity,
className: "mx_MjolnirUserSettingsTab_listItem"
}, /*#__PURE__*/_react.default.createElement(AccessibleButton, {
kind: "danger_sm",
onClick: () => this.removePersonalRule(rule),
disabled: this.state.busy
}, (0, _languageHandler._t)("Remove")), "\xA0", /*#__PURE__*/_react.default.createElement("code", null, rule.entity)));
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("You are currently ignoring:")), /*#__PURE__*/_react.default.createElement("ul", null, tiles));
}
renderSubscribedBanLists() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const personalList = _Mjolnir.Mjolnir.sharedInstance().getPersonalList();
const lists = _Mjolnir.Mjolnir.sharedInstance().lists.filter(b => {
return personalList ? personalList.roomId !== b.roomId : true;
});
if (!lists || lists.length <= 0) return /*#__PURE__*/_react.default.createElement("i", null, (0, _languageHandler._t)("You are not subscribed to any lists"));
const tiles = [];
for (const list of lists) {
const room = _MatrixClientPeg.MatrixClientPeg.get().getRoom(list.roomId);
const name = room ? /*#__PURE__*/_react.default.createElement("span", null, room.name, " (", /*#__PURE__*/_react.default.createElement("code", null, list.roomId), ")") : /*#__PURE__*/_react.default.createElement("code", null, "list.roomId");
tiles.push( /*#__PURE__*/_react.default.createElement("li", {
key: list.roomId,
className: "mx_MjolnirUserSettingsTab_listItem"
}, /*#__PURE__*/_react.default.createElement(AccessibleButton, {
kind: "danger_sm",
onClick: () => this.unsubscribeFromList(list),
disabled: this.state.busy
}, (0, _languageHandler._t)("Unsubscribe")), "\xA0", /*#__PURE__*/_react.default.createElement(AccessibleButton, {
kind: "primary_sm",
onClick: () => this.viewListRules(list),
disabled: this.state.busy
}, (0, _languageHandler._t)("View rules")), "\xA0", name));
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("You are currently subscribed to:")), /*#__PURE__*/_react.default.createElement("ul", null, tiles));
}
render() {
const Field = sdk.getComponent('elements.Field');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const brand = _SdkConfig.default.get().brand;
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab mx_MjolnirUserSettingsTab"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_heading"
}, (0, _languageHandler._t)("Ignored users")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_section"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_subsectionText"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "warning"
}, (0, _languageHandler._t)("⚠ These settings are meant for advanced users.")), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("br", null), (0, _languageHandler._t)("Add users and servers you want to ignore here. Use asterisks " + "to have %(brand)s match any characters. For example, <code>@bot:*</code> " + "would ignore all users that have the name 'bot' on any server.", {
brand
}, {
code: s => /*#__PURE__*/_react.default.createElement("code", null, s)
}), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("br", null), (0, _languageHandler._t)("Ignoring people is done through ban lists which contain rules for " + "who to ban. Subscribing to a ban list means the users/servers blocked by " + "that list will be hidden from you."))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_section"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_SettingsTab_subheading"
}, (0, _languageHandler._t)("Personal ban list")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_subsectionText"
}, (0, _languageHandler._t)("Your personal ban list holds all the users/servers you personally don't " + "want to see messages from. After ignoring your first user/server, a new room " + "will show up in your room list named 'My Ban List' - stay in this room to keep " + "the ban list in effect.")), /*#__PURE__*/_react.default.createElement("div", null, this.renderPersonalBanListRules()), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("form", {
onSubmit: this.onAddPersonalRule,
autoComplete: "off"
}, /*#__PURE__*/_react.default.createElement(Field, {
type: "text",
label: (0, _languageHandler._t)("Server or user ID to ignore"),
placeholder: (0, _languageHandler._t)("eg: @bot:* or example.org"),
value: this.state.newPersonalRule,
onChange: this.onPersonalRuleChanged
}), /*#__PURE__*/_react.default.createElement(AccessibleButton, {
type: "submit",
kind: "primary",
onClick: this.onAddPersonalRule,
disabled: this.state.busy
}, (0, _languageHandler._t)("Ignore"))))), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_section"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_SettingsTab_subheading"
}, (0, _languageHandler._t)("Subscribed lists")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SettingsTab_subsectionText"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "warning"
}, (0, _languageHandler._t)("Subscribing to a ban list will cause you to join it!")), "\xA0", /*#__PURE__*/_react.default.createElement("span", null, (0, _languageHandler._t)("If this isn't what you want, please use a different tool to ignore users."))), /*#__PURE__*/_react.default.createElement("div", null, this.renderSubscribedBanLists()), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("form", {
onSubmit: this.onSubscribeList,
autoComplete: "off"
}, /*#__PURE__*/_react.default.createElement(Field, {
type: "text",
label: (0, _languageHandler._t)("Room ID or address of ban list"),
value: this.state.newList,
onChange: this.onNewListChanged
}), /*#__PURE__*/_react.default.createElement(AccessibleButton, {
type: "submit",
kind: "primary",
onClick: this.onSubscribeList,
disabled: this.state.busy
}, (0, _languageHandler._t)("Subscribe"))))));
}
}, _temp)) || _class);
exports.default = MjolnirUserSettingsTab;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3NldHRpbmdzL3RhYnMvdXNlci9Nam9sbmlyVXNlclNldHRpbmdzVGFiLnRzeCJdLCJuYW1lcyI6WyJNam9sbmlyVXNlclNldHRpbmdzVGFiIiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsInByb3BzIiwiZSIsInNldFN0YXRlIiwibmV3UGVyc29uYWxSdWxlIiwidGFyZ2V0IiwidmFsdWUiLCJuZXdMaXN0IiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJraW5kIiwiUlVMRV9TRVJWRVIiLCJzdGF0ZSIsInN0YXJ0c1dpdGgiLCJSVUxFX1VTRVIiLCJidXN5IiwibGlzdCIsIk1qb2xuaXIiLCJzaGFyZWRJbnN0YW5jZSIsImdldE9yQ3JlYXRlUGVyc29uYWxMaXN0IiwiYmFuRW50aXR5IiwiY29uc29sZSIsImVycm9yIiwiRXJyb3JEaWFsb2ciLCJzZGsiLCJnZXRDb21wb25lbnQiLCJNb2RhbCIsImNyZWF0ZVRyYWNrZWREaWFsb2ciLCJ0aXRsZSIsImRlc2NyaXB0aW9uIiwicm9vbSIsIk1hdHJpeENsaWVudFBlZyIsImdldCIsImpvaW5Sb29tIiwic3Vic2NyaWJlVG9MaXN0Iiwicm9vbUlkIiwicmVtb3ZlUGVyc29uYWxSdWxlIiwicnVsZSIsImdldFBlcnNvbmFsTGlzdCIsInVuYmFuRW50aXR5IiwiZW50aXR5IiwidW5zdWJzY3JpYmVGcm9tTGlzdCIsImxlYXZlIiwidmlld0xpc3RSdWxlcyIsIlF1ZXN0aW9uRGlhbG9nIiwiZ2V0Um9vbSIsIm5hbWUiLCJyZW5kZXJSdWxlcyIsInJ1bGVzIiwibGVuZ3RoIiwidGlsZXMiLCJwdXNoIiwicm9vbU5hbWUiLCJzZXJ2ZXJSdWxlcyIsInVzZXJSdWxlcyIsImJ1dHRvbiIsImhhc0NhbmNlbEJ1dHRvbiIsInJlbmRlclBlcnNvbmFsQmFuTGlzdFJ1bGVzIiwiQWNjZXNzaWJsZUJ1dHRvbiIsInJlbmRlclN1YnNjcmliZWRCYW5MaXN0cyIsInBlcnNvbmFsTGlzdCIsImxpc3RzIiwiZmlsdGVyIiwiYiIsInJlbmRlciIsIkZpZWxkIiwiYnJhbmQiLCJTZGtDb25maWciLCJjb2RlIiwicyIsIm9uQWRkUGVyc29uYWxSdWxlIiwib25QZXJzb25hbFJ1bGVDaGFuZ2VkIiwib25TdWJzY3JpYmVMaXN0Iiwib25OZXdMaXN0Q2hhbmdlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQWdCQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztJQVNxQkEsc0IsV0FEcEIsZ0RBQXFCLGlEQUFyQixDLHlCQUFELE1BQ3FCQSxzQkFEckIsU0FDb0RDLGVBQU1DO0FBRDFEO0FBQ2dGO0FBQzVFQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUTtBQUNmLFVBQU1BLEtBQU47QUFEZSxpRUFVY0MsQ0FBRCxJQUFPO0FBQ25DLFdBQUtDLFFBQUwsQ0FBYztBQUFDQyxRQUFBQSxlQUFlLEVBQUVGLENBQUMsQ0FBQ0csTUFBRixDQUFTQztBQUEzQixPQUFkO0FBQ0gsS0Faa0I7QUFBQSw0REFjU0osQ0FBRCxJQUFPO0FBQzlCLFdBQUtDLFFBQUwsQ0FBYztBQUFDSSxRQUFBQSxPQUFPLEVBQUVMLENBQUMsQ0FBQ0csTUFBRixDQUFTQztBQUFuQixPQUFkO0FBQ0gsS0FoQmtCO0FBQUEsNkRBa0JTLE1BQU9KLENBQVAsSUFBYTtBQUNyQ0EsTUFBQUEsQ0FBQyxDQUFDTSxjQUFGO0FBQ0FOLE1BQUFBLENBQUMsQ0FBQ08sZUFBRjtBQUVBLFVBQUlDLElBQUksR0FBR0Msb0JBQVg7O0FBQ0EsVUFBSSxLQUFLQyxLQUFMLENBQVdSLGVBQVgsQ0FBMkJTLFVBQTNCLENBQXNDLEdBQXRDLENBQUosRUFBZ0Q7QUFDNUNILFFBQUFBLElBQUksR0FBR0ksa0JBQVA7QUFDSDs7QUFFRCxXQUFLWCxRQUFMLENBQWM7QUFBQ1ksUUFBQUEsSUFBSSxFQUFFO0FBQVAsT0FBZDs7QUFDQSxV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QUEzQixDQURKLHVCQUdJLDJDQUFPLHlCQUNILDJFQURHLENBQVAsQ0FISixDQUZKLGVBU0ksMENBQ0ssS0FBSzRDLHdCQUFMLEVBREwsQ0FUSixlQVlJLHVEQUNJO0FBQU0sTUFBQSxRQUFRLEVBQUUsS0FBS2EsZUFBckI7QUFBc0MsTUFBQSxZQUFZLEVBQUM7QUFBbkQsb0JBQ0ksNkJBQUMsS0FBRDtBQUNJLE1BQUEsSUFBSSxFQUFDLE1BRFQ7QUFFSSxNQUFBLEtBQUssRUFBRSx5QkFBRyxnQ0FBSCxDQUZYO0FBR0ksTUFBQSxLQUFLLEVBQUUsS0FBSzVELEtBQUwsQ0FBV0wsT0FIdEI7QUFJSSxNQUFBLFFBQVEsRUFBRSxLQUFLa0U7QUFKbkIsTUFESixlQU9JLDZCQUFDLGdCQUFEO0FBQ0ksTUFBQSxJQUFJLEVBQUMsUUFEVDtBQUVJLE1BQUEsSUFBSSxFQUFDLFNBRlQ7QUFHSSxNQUFBLE9BQU8sRUFBRSxLQUFLRCxlQUhsQjtBQUlJLE1BQUEsUUFBUSxFQUFFLEtBQUs1RCxLQUFMLENBQVdHO0FBSnpCLE9BTUsseUJBQUcsV0FBSCxDQU5MLENBUEosQ0FESixDQVpKLENBckRKLENBREo7QUF1Rkg7O0FBNVMyRSxDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE5LTIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qL1xuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHtfdH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlclwiO1xuaW1wb3J0IFNka0NvbmZpZyBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vU2RrQ29uZmlnXCI7XG5pbXBvcnQge01qb2xuaXJ9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9tam9sbmlyL01qb2xuaXJcIjtcbmltcG9ydCB7TGlzdFJ1bGV9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9tam9sbmlyL0xpc3RSdWxlXCI7XG5pbXBvcnQge0Jhbkxpc3QsIFJVTEVfU0VSVkVSLCBSVUxFX1VTRVJ9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9tam9sbmlyL0Jhbkxpc3RcIjtcbmltcG9ydCBNb2RhbCBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vTW9kYWxcIjtcbmltcG9ydCB7TWF0cml4Q2xpZW50UGVnfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgKiBhcyBzZGsgZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2luZGV4XCI7XG5pbXBvcnQge3JlcGxhY2VhYmxlQ29tcG9uZW50fSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vdXRpbHMvcmVwbGFjZWFibGVDb21wb25lbnRcIjtcblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgYnVzeTogYm9vbGVhbjtcbiAgICBuZXdQZXJzb25hbFJ1bGU6IHN0cmluZztcbiAgICBuZXdMaXN0OiBzdHJpbmc7XG59XG5cbkByZXBsYWNlYWJsZUNvbXBvbmVudChcInZpZXdzLnNldHRpbmdzLnRhYnMudXNlci5Nam9sbmlyVXNlclNldHRpbmdzVGFiXCIpXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNam9sbmlyVXNlclNldHRpbmdzVGFiIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PHt9LCBJU3RhdGU+IHtcbiAgICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGJ1c3k6IGZhbHNlLFxuICAgICAgICAgICAgbmV3UGVyc29uYWxSdWxlOiBcIlwiLFxuICAgICAgICAgICAgbmV3TGlzdDogXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUGVyc29uYWxSdWxlQ2hhbmdlZCA9IChlKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe25ld1BlcnNvbmFsUnVsZTogZS50YXJnZXQudmFsdWV9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbk5ld0xpc3RDaGFuZ2VkID0gKGUpID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bmV3TGlzdDogZS50YXJnZXQudmFsdWV9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkFkZFBlcnNvbmFsUnVsZSA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBsZXQga2luZCA9IFJVTEVfU0VSVkVSO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5uZXdQZXJzb25hbFJ1bGUuc3RhcnRzV2l0aChcIkBcIikpIHtcbiAgICAgICAgICAgIGtpbmQgPSBSVUxFX1VTRVI7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtidXN5OiB0cnVlfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ID0gYXdhaXQgTWpvbG5pci5zaGFyZWRJbnN0YW5jZSgpLmdldE9yQ3JlYXRlUGVyc29uYWxMaXN0KCk7XG4gICAgICAgICAgICBhd2FpdCBsaXN0LmJhbkVudGl0eShraW5kLCB0aGlzLnN0YXRlLm5ld1BlcnNvbmFsUnVsZSwgX3QoXCJJZ25vcmVkL0Jsb2NrZWRcIikpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bmV3UGVyc29uYWxSdWxlOiBcIlwifSk7IC8vIHRoaXMgd2lsbCBhbHNvIGNhdXNlIHRoZSBuZXcgcnVsZSB0byBiZSByZW5kZXJlZFxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuXG4gICAgICAgICAgICBjb25zdCBFcnJvckRpYWxvZyA9IHNkay5nZXRDb21wb25lbnQoXCJkaWFsb2dzLkVycm9yRGlhbG9nXCIpO1xuICAgICAgICAgICAgTW9kYWwuY3JlYXRlVHJhY2tlZERpYWxvZygnRmFpbGVkIHRvIGFkZCBNam9sbmlyIHJ1bGUnLCAnJywgRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogX3QoJ0Vycm9yIGFkZGluZyBpZ25vcmVkIHVzZXIvc2VydmVyJyksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IF90KCdTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2FpbiBvciB2aWV3IHlvdXIgY29uc29sZSBmb3IgaGludHMuJyksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe2J1c3k6IGZhbHNlfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblN1YnNjcmliZUxpc3QgPSBhc3luYyAoZSkgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7YnVzeTogdHJ1ZX0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgcm9vbSA9IGF3YWl0IE1hdHJpeENsaWVudFBlZy5nZXQoKS5qb2luUm9vbSh0aGlzLnN0YXRlLm5ld0xpc3QpO1xuICAgICAgICAgICAgYXdhaXQgTWpvbG5pci5zaGFyZWRJbnN0YW5jZSgpLnN1YnNjcmliZVRvTGlzdChyb29tLnJvb21JZCk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtuZXdMaXN0OiBcIlwifSk7IC8vIHRoaXMgd2lsbCBhbHNvIGNhdXNlIHRoZSBuZXcgcnVsZSB0byBiZSByZW5kZXJlZFxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuXG4gICAgICAgICAgICBjb25zdCBFcnJvckRpYWxvZyA9IHNkay5nZXRDb21wb25lbnQoXCJkaWFsb2dzLkVycm9yRGlhbG9nXCIpO1xuICAgICAgICAgICAgTW9kYWwuY3JlYXRlVHJhY2tlZERpYWxvZygnRmFpbGVkIHRvIHN1YnNjcmliZSB0byBNam9sbmlyIGxpc3QnLCAnJywgRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogX3QoJ0Vycm9yIHN1YnNjcmliaW5nIHRvIGxpc3QnKSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogX3QoJ1BsZWFzZSB2ZXJpZnkgdGhlIHJvb20gSUQgb3IgYWRkcmVzcyBhbmQgdHJ5IGFnYWluLicpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtidXN5OiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByaXZhdGUgYXN5bmMgcmVtb3ZlUGVyc29uYWxSdWxlKHJ1bGU6IExpc3RSdWxlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2J1c3k6IHRydWV9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGxpc3QgPSBNam9sbmlyLnNoYXJlZEluc3RhbmNlKCkuZ2V0UGVyc29uYWxMaXN0KCk7XG4gICAgICAgICAgICBhd2FpdCBsaXN0LnVuYmFuRW50aXR5KHJ1bGUua2luZCwgcnVsZS5lbnRpdHkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuXG4gICAgICAgICAgICBjb25zdCBFcnJvckRpYWxvZyA9IHNkay5nZXRDb21wb25lbnQoXCJkaWFsb2dzLkVycm9yRGlhbG9nXCIpO1xuICAgICAgICAgICAgTW9kYWwuY3JlYXRlVHJhY2tlZERpYWxvZygnRmFpbGVkIHRvIHJlbW92ZSBNam9sbmlyIHJ1bGUnLCAnJywgRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogX3QoJ0Vycm9yIHJlbW92aW5nIGlnbm9yZWQgdXNlci9zZXJ2ZXInKSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogX3QoJ1NvbWV0aGluZyB3ZW50IHdyb25nLiBQbGVhc2UgdHJ5IGFnYWluIG9yIHZpZXcgeW91ciBjb25zb2xlIGZvciBoaW50cy4nKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7YnVzeTogZmFsc2V9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgdW5zdWJzY3JpYmVGcm9tTGlzdChsaXN0OiBCYW5MaXN0KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2J1c3k6IHRydWV9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IE1qb2xuaXIuc2hhcmVkSW5zdGFuY2UoKS51bnN1YnNjcmliZUZyb21MaXN0KGxpc3Qucm9vbUlkKTtcbiAgICAgICAgICAgIGF3YWl0IE1hdHJpeENsaWVudFBlZy5nZXQoKS5sZWF2ZShsaXN0LnJvb21JZCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IEVycm9yRGlhbG9nID0gc2RrLmdldENvbXBvbmVudChcImRpYWxvZ3MuRXJyb3JEaWFsb2dcIik7XG4gICAgICAgICAgICBNb2RhbC5jcmVhdGVUcmFja2VkRGlhbG9nKCdGYWlsZWQgdG8gdW5zdWJzY3JpYmUgZnJvbSBNam9sbmlyIGxpc3QnLCAnJywgRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogX3QoJ0Vycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSBsaXN0JyksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IF90KCdQbGVhc2UgdHJ5IGFnYWluIG9yIHZpZXcgeW91ciBjb25zb2xlIGZvciBoaW50cy4nKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7YnVzeTogZmFsc2V9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdmlld0xpc3RSdWxlcyhsaXN0OiBCYW5MaXN0KSB7XG4gICAgICAgIGNvbnN0IFF1ZXN0aW9uRGlhbG9nID0gc2RrLmdldENvbXBvbmVudChcImRpYWxvZ3MuUXVlc3Rpb25EaWFsb2dcIik7XG5cbiAgICAgICAgY29uc3Qgcm9vbSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKS5nZXRSb29tKGxpc3Qucm9vbUlkKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IHJvb20gPyByb29tLm5hbWUgOiBsaXN0LnJvb21JZDtcblxuICAgICAgICBjb25zdCByZW5kZXJSdWxlcyA9IChydWxlczogTGlzdFJ1bGVbXSkgPT4ge1xuICAgICAgICAgICAgaWYgKHJ1bGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDxpPntfdChcIk5vbmVcIil9PC9pPjtcblxuICAgICAgICAgICAgY29uc3QgdGlsZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcnVsZSBvZiBydWxlcykge1xuICAgICAgICAgICAgICAgIHRpbGVzLnB1c2goPGxpIGtleT17cnVsZS5raW5kICsgcnVsZS5lbnRpdHl9Pjxjb2RlPntydWxlLmVudGl0eX08L2NvZGU+PC9saT4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIDx1bD57dGlsZXN9PC91bD47XG4gICAgICAgIH07XG5cbiAgICAgICAgTW9kYWwuY3JlYXRlVHJhY2tlZERpYWxvZygnVmlldyBNam9sbmlyIGxpc3QgcnVsZXMnLCAnJywgUXVlc3Rpb25EaWFsb2csIHtcbiAgICAgICAgICAgIHRpdGxlOiBfdChcIkJhbiBsaXN0IHJ1bGVzIC0gJShyb29tTmFtZSlzXCIsIHtyb29tTmFtZTogbmFtZX0pLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IChcbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICA8aDM+e190KFwiU2VydmVyIHJ1bGVzXCIpfTwvaDM+XG4gICAgICAgICAgICAgICAgICAgIHtyZW5kZXJSdWxlcyhsaXN0LnNlcnZlclJ1bGVzKX1cbiAgICAgICAgICAgICAgICAgICAgPGgzPntfdChcIlVzZXIgcnVsZXNcIil9PC9oMz5cbiAgICAgICAgICAgICAgICAgICAge3JlbmRlclJ1bGVzKGxpc3QudXNlclJ1bGVzKX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBidXR0b246IF90KFwiQ2xvc2VcIiksXG4gICAgICAgICAgICBoYXNDYW5jZWxCdXR0b246IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbmRlclBlcnNvbmFsQmFuTGlzdFJ1bGVzKCkge1xuICAgICAgICBjb25zdCBBY2Nlc3NpYmxlQnV0dG9uID0gc2RrLmdldENvbXBvbmVudCgnZWxlbWVudHMuQWNjZXNzaWJsZUJ1dHRvbicpO1xuXG4gICAgICAgIGNvbnN0IGxpc3QgPSBNam9sbmlyLnNoYXJlZEluc3RhbmNlKCkuZ2V0UGVyc29uYWxMaXN0KCk7XG4gICAgICAgIGNvbnN0IHJ1bGVzID0gbGlzdCA/IFsuLi5saXN0LnVzZXJSdWxlcywgLi4ubGlzdC5zZXJ2ZXJSdWxlc10gOiBbXTtcbiAgICAgICAgaWYgKCFsaXN0IHx8IHJ1bGVzLmxlbmd0aCA8PSAwKSByZXR1cm4gPGk+e190KFwiWW91IGhhdmUgbm90IGlnbm9yZWQgYW55b25lLlwiKX08L2k+O1xuXG4gICAgICAgIGNvbnN0IHRpbGVzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcnVsZSBvZiBydWxlcykge1xuICAgICAgICAgICAgdGlsZXMucHVzaChcbiAgICAgICAgICAgICAgICA8bGkga2V5PXtydWxlLmVudGl0eX0gY2xhc3NOYW1lPVwibXhfTWpvbG5pclVzZXJTZXR0aW5nc1RhYl9saXN0SXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cImRhbmdlcl9zbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB0aGlzLnJlbW92ZVBlcnNvbmFsUnVsZShydWxlKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnN0YXRlLmJ1c3l9XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcIlJlbW92ZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPiZuYnNwO1xuICAgICAgICAgICAgICAgICAgICA8Y29kZT57cnVsZS5lbnRpdHl9PC9jb2RlPlxuICAgICAgICAgICAgICAgIDwvbGk+LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxwPntfdChcIllvdSBhcmUgY3VycmVudGx5IGlnbm9yaW5nOlwiKX08L3A+XG4gICAgICAgICAgICAgICAgPHVsPnt0aWxlc308L3VsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW5kZXJTdWJzY3JpYmVkQmFuTGlzdHMoKSB7XG4gICAgICAgIGNvbnN0IEFjY2Vzc2libGVCdXR0b24gPSBzZGsuZ2V0Q29tcG9uZW50KCdlbGVtZW50cy5BY2Nlc3NpYmxlQnV0dG9uJyk7XG5cbiAgICAgICAgY29uc3QgcGVyc29uYWxMaXN0ID0gTWpvbG5pci5zaGFyZWRJbnN0YW5jZSgpLmdldFBlcnNvbmFsTGlzdCgpO1xuICAgICAgICBjb25zdCBsaXN0cyA9IE1qb2xuaXIuc2hhcmVkSW5zdGFuY2UoKS5saXN0cy5maWx0ZXIoYiA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcGVyc29uYWxMaXN0PyBwZXJzb25hbExpc3Qucm9vbUlkICE9PSBiLnJvb21JZCA6IHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWxpc3RzIHx8IGxpc3RzLmxlbmd0aCA8PSAwKSByZXR1cm4gPGk+e190KFwiWW91IGFyZSBub3Qgc3Vic2NyaWJlZCB0byBhbnkgbGlzdHNcIil9PC9pPjtcblxuICAgICAgICBjb25zdCB0aWxlcyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGxpc3Qgb2YgbGlzdHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvb20gPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCkuZ2V0Um9vbShsaXN0LnJvb21JZCk7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gcm9vbSA/IDxzcGFuPntyb29tLm5hbWV9ICg8Y29kZT57bGlzdC5yb29tSWR9PC9jb2RlPik8L3NwYW4+IDogPGNvZGU+bGlzdC5yb29tSWQ8L2NvZGU+O1xuICAgICAgICAgICAgdGlsZXMucHVzaChcbiAgICAgICAgICAgICAgICA8bGkga2V5PXtsaXN0LnJvb21JZH0gY2xhc3NOYW1lPVwibXhfTWpvbG5pclVzZXJTZXR0aW5nc1RhYl9saXN0SXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cImRhbmdlcl9zbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB0aGlzLnVuc3Vic2NyaWJlRnJvbUxpc3QobGlzdCl9XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17dGhpcy5zdGF0ZS5idXN5fVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJVbnN1YnNjcmliZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPiZuYnNwO1xuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlfc21cIlxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy52aWV3TGlzdFJ1bGVzKGxpc3QpfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMuc3RhdGUuYnVzeX1cbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwiVmlldyBydWxlc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPiZuYnNwO1xuICAgICAgICAgICAgICAgICAgICB7bmFtZX1cbiAgICAgICAgICAgICAgICA8L2xpPixcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8cD57X3QoXCJZb3UgYXJlIGN1cnJlbnRseSBzdWJzY3JpYmVkIHRvOlwiKX08L3A+XG4gICAgICAgICAgICAgICAgPHVsPnt0aWxlc308L3VsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBGaWVsZCA9IHNkay5nZXRDb21wb25lbnQoJ2VsZW1lbnRzLkZpZWxkJyk7XG4gICAgICAgIGNvbnN0IEFjY2Vzc2libGVCdXR0b24gPSBzZGsuZ2V0Q29tcG9uZW50KCdlbGVtZW50cy5BY2Nlc3NpYmxlQnV0dG9uJyk7XG4gICAgICAgIGNvbnN0IGJyYW5kID0gU2RrQ29uZmlnLmdldCgpLmJyYW5kO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1NldHRpbmdzVGFiIG14X01qb2xuaXJVc2VyU2V0dGluZ3NUYWJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1NldHRpbmdzVGFiX2hlYWRpbmdcIj57X3QoXCJJZ25vcmVkIHVzZXJzXCIpfTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfU2V0dGluZ3NUYWJfc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbXhfU2V0dGluZ3NUYWJfc3Vic2VjdGlvblRleHQnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd3YXJuaW5nJz57X3QoXCLimqAgVGhlc2Ugc2V0dGluZ3MgYXJlIG1lYW50IGZvciBhZHZhbmNlZCB1c2Vycy5cIil9PC9zcGFuPjxiciAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJyIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB7X3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJBZGQgdXNlcnMgYW5kIHNlcnZlcnMgeW91IHdhbnQgdG8gaWdub3JlIGhlcmUuIFVzZSBhc3Rlcmlza3MgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwidG8gaGF2ZSAlKGJyYW5kKXMgbWF0Y2ggYW55IGNoYXJhY3RlcnMuIEZvciBleGFtcGxlLCA8Y29kZT5AYm90Oio8L2NvZGU+IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIndvdWxkIGlnbm9yZSBhbGwgdXNlcnMgdGhhdCBoYXZlIHRoZSBuYW1lICdib3QnIG9uIGFueSBzZXJ2ZXIuXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBicmFuZCB9LCB7Y29kZTogKHMpID0+IDxjb2RlPntzfTwvY29kZT59LFxuICAgICAgICAgICAgICAgICAgICAgICAgKX08YnIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxiciAvPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiSWdub3JpbmcgcGVvcGxlIGlzIGRvbmUgdGhyb3VnaCBiYW4gbGlzdHMgd2hpY2ggY29udGFpbiBydWxlcyBmb3IgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwid2hvIHRvIGJhbi4gU3Vic2NyaWJpbmcgdG8gYSBiYW4gbGlzdCBtZWFucyB0aGUgdXNlcnMvc2VydmVycyBibG9ja2VkIGJ5IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInRoYXQgbGlzdCB3aWxsIGJlIGhpZGRlbiBmcm9tIHlvdS5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfU2V0dGluZ3NUYWJfc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9TZXR0aW5nc1RhYl9zdWJoZWFkaW5nXCI+e190KFwiUGVyc29uYWwgYmFuIGxpc3RcIil9PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbXhfU2V0dGluZ3NUYWJfc3Vic2VjdGlvblRleHQnPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91ciBwZXJzb25hbCBiYW4gbGlzdCBob2xkcyBhbGwgdGhlIHVzZXJzL3NlcnZlcnMgeW91IHBlcnNvbmFsbHkgZG9uJ3QgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwid2FudCB0byBzZWUgbWVzc2FnZXMgZnJvbS4gQWZ0ZXIgaWdub3JpbmcgeW91ciBmaXJzdCB1c2VyL3NlcnZlciwgYSBuZXcgcm9vbSBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJ3aWxsIHNob3cgdXAgaW4geW91ciByb29tIGxpc3QgbmFtZWQgJ015IEJhbiBMaXN0JyAtIHN0YXkgaW4gdGhpcyByb29tIHRvIGtlZXAgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwidGhlIGJhbiBsaXN0IGluIGVmZmVjdC5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAge3RoaXMucmVuZGVyUGVyc29uYWxCYW5MaXN0UnVsZXMoKX1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybSBvblN1Ym1pdD17dGhpcy5vbkFkZFBlcnNvbmFsUnVsZX0gYXV0b0NvbXBsZXRlPVwib2ZmXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwiU2VydmVyIG9yIHVzZXIgSUQgdG8gaWdub3JlXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17X3QoXCJlZzogQGJvdDoqIG9yIGV4YW1wbGUub3JnXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5uZXdQZXJzb25hbFJ1bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uUGVyc29uYWxSdWxlQ2hhbmdlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25BZGRQZXJzb25hbFJ1bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnN0YXRlLmJ1c3l9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJJZ25vcmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1NldHRpbmdzVGFiX3NlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwibXhfU2V0dGluZ3NUYWJfc3ViaGVhZGluZ1wiPntfdChcIlN1YnNjcmliZWQgbGlzdHNcIil9PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbXhfU2V0dGluZ3NUYWJfc3Vic2VjdGlvblRleHQnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd3YXJuaW5nJz57X3QoXCJTdWJzY3JpYmluZyB0byBhIGJhbiBsaXN0IHdpbGwgY2F1c2UgeW91IHRvIGpvaW4gaXQhXCIpfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e190KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiSWYgdGhpcyBpc24ndCB3aGF0IHlvdSB3YW50LCBwbGVhc2UgdXNlIGEgZGlmZmVyZW50IHRvb2wgdG8gaWdub3JlIHVzZXJzLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgKX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAge3RoaXMucmVuZGVyU3Vic2NyaWJlZEJhbkxpc3RzKCl9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gb25TdWJtaXQ9e3RoaXMub25TdWJzY3JpYmVMaXN0fSBhdXRvQ29tcGxldGU9XCJvZmZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJSb29tIElEIG9yIGFkZHJlc3Mgb2YgYmFuIGxpc3RcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnN0YXRlLm5ld0xpc3R9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uTmV3TGlzdENoYW5nZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwic3VibWl0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uU3Vic2NyaWJlTGlzdH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMuc3RhdGUuYnVzeX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcIlN1YnNjcmliZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl19