UNPKG

matrix-react-sdk

Version:
385 lines (380 loc) 67.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _MatrixClientPeg = require("../../MatrixClientPeg"); var _dispatcher = _interopRequireDefault(require("../../dispatcher/dispatcher")); var _actions = require("../../dispatcher/actions"); var _languageHandler = require("../../languageHandler"); var _ContextMenu = require("./ContextMenu"); var _UserTab = require("../views/dialogs/UserTab"); var _FeedbackDialog = _interopRequireDefault(require("../views/dialogs/FeedbackDialog")); var _Modal = _interopRequireDefault(require("../../Modal")); var _LogoutDialog = _interopRequireWildcard(require("../views/dialogs/LogoutDialog")); var _SettingsStore = _interopRequireDefault(require("../../settings/SettingsStore")); var _theme = require("../../theme"); var _RovingTabIndex = require("../../accessibility/RovingTabIndex"); var _AccessibleButton = _interopRequireDefault(require("../views/elements/AccessibleButton")); var _SdkConfig = _interopRequireDefault(require("../../SdkConfig")); var _pages = require("../../utils/pages"); var _OwnProfileStore = require("../../stores/OwnProfileStore"); var _AsyncStore = require("../../stores/AsyncStore"); var _BaseAvatar = _interopRequireDefault(require("../views/avatars/BaseAvatar")); var _SettingLevel = require("../../settings/SettingLevel"); var _IconizedContextMenu = _interopRequireWildcard(require("../views/context_menus/IconizedContextMenu")); var _UIFeature = require("../../settings/UIFeature"); var _SpaceStore = _interopRequireDefault(require("../../stores/spaces/SpaceStore")); var _spaces = require("../../stores/spaces"); var _UserIdentifier = _interopRequireDefault(require("../../customisations/UserIdentifier")); var _PosthogTrackers = _interopRequireDefault(require("../../PosthogTrackers")); var _live8px = require("../../../res/img/compound/live-8px.svg"); var _voiceBroadcast = require("../../voice-broadcast"); var _SDKContext = require("../../contexts/SDKContext"); var _Feedback = require("../../utils/Feedback"); 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 2020, 2021 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. */ const toRightOf = rect => { return { left: rect.width + rect.left + 8, top: rect.top, chevronFace: _ContextMenu.ChevronFace.None }; }; const below = rect => { return { left: rect.left, top: rect.top + rect.height, chevronFace: _ContextMenu.ChevronFace.None }; }; class UserMenu extends _react.default.Component { constructor(_props, context) { super(_props, context); (0, _defineProperty2.default)(this, "dispatcherRef", void 0); (0, _defineProperty2.default)(this, "themeWatcherRef", void 0); (0, _defineProperty2.default)(this, "dndWatcherRef", void 0); (0, _defineProperty2.default)(this, "buttonRef", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "onCurrentVoiceBroadcastRecordingChanged", recording => { this.setState({ showLiveAvatarAddon: recording !== null }); }); (0, _defineProperty2.default)(this, "onProfileUpdate", async () => { // the store triggered an update, so force a layout update. We don't // have any state to store here for that to magically happen. this.forceUpdate(); }); (0, _defineProperty2.default)(this, "onSelectedSpaceUpdate", async () => { this.setState({ selectedSpace: _SpaceStore.default.instance.activeSpaceRoom }); }); (0, _defineProperty2.default)(this, "onThemeChanged", () => { this.setState({ isDarkTheme: this.isUserOnDarkTheme(), isHighContrast: this.isUserOnHighContrastTheme() }); }); (0, _defineProperty2.default)(this, "onAction", payload => { switch (payload.action) { case _actions.Action.ToggleUserMenu: if (this.state.contextMenuPosition) { this.setState({ contextMenuPosition: null }); } else { if (this.buttonRef.current) this.buttonRef.current.click(); } break; } }); (0, _defineProperty2.default)(this, "onOpenMenuClick", ev => { ev.preventDefault(); ev.stopPropagation(); this.setState({ contextMenuPosition: ev.currentTarget.getBoundingClientRect() }); }); (0, _defineProperty2.default)(this, "onContextMenu", ev => { ev.preventDefault(); ev.stopPropagation(); this.setState({ contextMenuPosition: { left: ev.clientX, top: ev.clientY, width: 20, height: 0 } }); }); (0, _defineProperty2.default)(this, "onCloseMenu", () => { this.setState({ contextMenuPosition: null }); }); (0, _defineProperty2.default)(this, "onSwitchThemeClick", ev => { ev.preventDefault(); ev.stopPropagation(); _PosthogTrackers.default.trackInteraction("WebUserMenuThemeToggleButton", ev); // Disable system theme matching if the user hits this button _SettingsStore.default.setValue("use_system_theme", null, _SettingLevel.SettingLevel.DEVICE, false); let newTheme = this.state.isDarkTheme ? "light" : "dark"; if (this.state.isHighContrast) { const hcTheme = (0, _theme.findHighContrastTheme)(newTheme); if (hcTheme) { newTheme = hcTheme; } } _SettingsStore.default.setValue("theme", null, _SettingLevel.SettingLevel.DEVICE, newTheme); // set at same level as Appearance tab }); (0, _defineProperty2.default)(this, "onSettingsOpen", (ev, tabId, props) => { ev.preventDefault(); ev.stopPropagation(); const payload = { action: _actions.Action.ViewUserSettings, initialTabId: tabId, props }; _dispatcher.default.dispatch(payload); this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "onProvideFeedback", ev => { ev.preventDefault(); ev.stopPropagation(); _Modal.default.createDialog(_FeedbackDialog.default); this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "onSignOutClick", async ev => { ev.preventDefault(); ev.stopPropagation(); if (await (0, _LogoutDialog.shouldShowLogoutDialog)(_MatrixClientPeg.MatrixClientPeg.safeGet())) { _Modal.default.createDialog(_LogoutDialog.default); } else { _dispatcher.default.dispatch({ action: "logout" }); } this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "onSignInClick", () => { _dispatcher.default.dispatch({ action: "start_login" }); this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "onRegisterClick", () => { _dispatcher.default.dispatch({ action: "start_registration" }); this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "onHomeClick", ev => { ev.preventDefault(); ev.stopPropagation(); _dispatcher.default.dispatch({ action: _actions.Action.ViewHomePage }); this.setState({ contextMenuPosition: null }); // also close the menu }); (0, _defineProperty2.default)(this, "renderContextMenu", () => { if (!this.state.contextMenuPosition) return null; let topSection; if (_MatrixClientPeg.MatrixClientPeg.safeGet().isGuest()) { topSection = /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_contextMenu_header mx_UserMenu_contextMenu_guestPrompts" }, (0, _languageHandler._t)("auth|sign_in_prompt", {}, { a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "link_inline", onClick: this.onSignInClick }, sub) }), _SettingsStore.default.getValue(_UIFeature.UIFeature.Registration) ? (0, _languageHandler._t)("auth|create_account_prompt", {}, { a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "link_inline", onClick: this.onRegisterClick }, sub) }) : null); } let homeButton; if (this.hasHomePage) { homeButton = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconHome", label: (0, _languageHandler._t)("common|home"), onClick: this.onHomeClick }); } let feedbackButton; if ((0, _Feedback.shouldShowFeedback)()) { feedbackButton = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconMessage", label: (0, _languageHandler._t)("common|feedback"), onClick: this.onProvideFeedback }); } const linkNewDeviceButton = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconQr", label: (0, _languageHandler._t)("user_menu|link_new_device"), onClick: e => this.onSettingsOpen(e, _UserTab.UserTab.SessionManager, { showMsc4108QrCode: true }) }); let primaryOptionList = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, null, homeButton, linkNewDeviceButton, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconBell", label: (0, _languageHandler._t)("notifications|enable_prompt_toast_title"), onClick: e => this.onSettingsOpen(e, _UserTab.UserTab.Notifications) }), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconLock", label: (0, _languageHandler._t)("room_settings|security|title"), onClick: e => this.onSettingsOpen(e, _UserTab.UserTab.Security) }), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconSettings", label: (0, _languageHandler._t)("user_menu|settings"), onClick: e => this.onSettingsOpen(e) }), feedbackButton, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { className: "mx_IconizedContextMenu_option_red", iconClassName: "mx_UserMenu_iconSignOut", label: (0, _languageHandler._t)("action|sign_out"), onClick: this.onSignOutClick })); if (_MatrixClientPeg.MatrixClientPeg.safeGet().isGuest()) { primaryOptionList = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, null, homeButton, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, { iconClassName: "mx_UserMenu_iconSettings", label: (0, _languageHandler._t)("common|settings"), onClick: e => this.onSettingsOpen(e) }), feedbackButton); } const position = this.props.isPanelCollapsed ? toRightOf(this.state.contextMenuPosition) : below(this.state.contextMenuPosition); return /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.default, (0, _extends2.default)({}, position, { onFinished: this.onCloseMenu, className: "mx_UserMenu_contextMenu" }), /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_contextMenu_header" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_contextMenu_name" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_UserMenu_contextMenu_displayName" }, _OwnProfileStore.OwnProfileStore.instance.displayName), /*#__PURE__*/_react.default.createElement("span", { className: "mx_UserMenu_contextMenu_userId" }, _UserIdentifier.default.getDisplayUserIdentifier(_MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId(), { withDisplayName: true }))), /*#__PURE__*/_react.default.createElement(_RovingTabIndex.RovingAccessibleButton, { className: "mx_UserMenu_contextMenu_themeButton", onClick: this.onSwitchThemeClick, title: this.state.isDarkTheme ? (0, _languageHandler._t)("user_menu|switch_theme_light") : (0, _languageHandler._t)("user_menu|switch_theme_dark") }, /*#__PURE__*/_react.default.createElement("img", { src: require("../../../res/img/element-icons/roomlist/dark-light-mode.svg").default, role: "presentation", alt: "", width: 16 }))), topSection, primaryOptionList); }); this.state = { contextMenuPosition: null, isDarkTheme: this.isUserOnDarkTheme(), isHighContrast: this.isUserOnHighContrastTheme(), selectedSpace: _SpaceStore.default.instance.activeSpaceRoom, showLiveAvatarAddon: this.context.voiceBroadcastRecordingsStore.hasCurrent() }; _OwnProfileStore.OwnProfileStore.instance.on(_AsyncStore.UPDATE_EVENT, this.onProfileUpdate); _SpaceStore.default.instance.on(_spaces.UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate); } get hasHomePage() { return !!(0, _pages.getHomePageUrl)(_SdkConfig.default.get(), this.context.client); } componentDidMount() { this.context.voiceBroadcastRecordingsStore.on(_voiceBroadcast.VoiceBroadcastRecordingsStoreEvent.CurrentChanged, this.onCurrentVoiceBroadcastRecordingChanged); this.dispatcherRef = _dispatcher.default.register(this.onAction); this.themeWatcherRef = _SettingsStore.default.watchSetting("theme", null, this.onThemeChanged); } componentWillUnmount() { if (this.themeWatcherRef) _SettingsStore.default.unwatchSetting(this.themeWatcherRef); if (this.dndWatcherRef) _SettingsStore.default.unwatchSetting(this.dndWatcherRef); if (this.dispatcherRef) _dispatcher.default.unregister(this.dispatcherRef); _OwnProfileStore.OwnProfileStore.instance.off(_AsyncStore.UPDATE_EVENT, this.onProfileUpdate); _SpaceStore.default.instance.off(_spaces.UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate); this.context.voiceBroadcastRecordingsStore.off(_voiceBroadcast.VoiceBroadcastRecordingsStoreEvent.CurrentChanged, this.onCurrentVoiceBroadcastRecordingChanged); } isUserOnDarkTheme() { if (_SettingsStore.default.getValue("use_system_theme")) { return window.matchMedia("(prefers-color-scheme: dark)").matches; } else { const theme = _SettingsStore.default.getValue("theme"); if (theme.startsWith("custom-")) { return !!(0, _theme.getCustomTheme)(theme.substring("custom-".length)).is_dark; } return theme === "dark"; } } isUserOnHighContrastTheme() { if (_SettingsStore.default.getValue("use_system_theme")) { return window.matchMedia("(prefers-contrast: more)").matches; } else { const theme = _SettingsStore.default.getValue("theme"); if (theme.startsWith("custom-")) { return false; } return (0, _theme.isHighContrastTheme)(theme); } } render() { const avatarSize = 32; // should match border-radius of the avatar const userId = _MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId(); const displayName = _OwnProfileStore.OwnProfileStore.instance.displayName || userId; const avatarUrl = _OwnProfileStore.OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); let name; if (!this.props.isPanelCollapsed) { name = /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_name" }, displayName); } const liveAvatarAddon = this.state.showLiveAvatarAddon ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_userAvatarLive", "data-testid": "user-menu-live-vb" }, /*#__PURE__*/_react.default.createElement(_live8px.Icon, { className: "mx_Icon_8" })) : null; return /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu" }, /*#__PURE__*/_react.default.createElement(_ContextMenu.ContextMenuButton, { className: "mx_UserMenu_contextMenuButton", onClick: this.onOpenMenuClick, ref: this.buttonRef, label: (0, _languageHandler._t)("a11y|user_menu"), isExpanded: !!this.state.contextMenuPosition, onContextMenu: this.onContextMenu }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_UserMenu_userAvatar" }, /*#__PURE__*/_react.default.createElement(_BaseAvatar.default, { idName: userId, name: displayName, url: avatarUrl, size: avatarSize + "px", className: "mx_UserMenu_userAvatar_BaseAvatar" }), liveAvatarAddon), name, this.renderContextMenu()), this.props.children); } } exports.default = UserMenu; (0, _defineProperty2.default)(UserMenu, "contextType", _SDKContext.SDKContext); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfTWF0cml4Q2xpZW50UGVnIiwiX2Rpc3BhdGNoZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2FjdGlvbnMiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX0NvbnRleHRNZW51IiwiX1VzZXJUYWIiLCJfRmVlZGJhY2tEaWFsb2ciLCJfTW9kYWwiLCJfTG9nb3V0RGlhbG9nIiwiX1NldHRpbmdzU3RvcmUiLCJfdGhlbWUiLCJfUm92aW5nVGFiSW5kZXgiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9TZGtDb25maWciLCJfcGFnZXMiLCJfT3duUHJvZmlsZVN0b3JlIiwiX0FzeW5jU3RvcmUiLCJfQmFzZUF2YXRhciIsIl9TZXR0aW5nTGV2ZWwiLCJfSWNvbml6ZWRDb250ZXh0TWVudSIsIl9VSUZlYXR1cmUiLCJfU3BhY2VTdG9yZSIsIl9zcGFjZXMiLCJfVXNlcklkZW50aWZpZXIiLCJfUG9zdGhvZ1RyYWNrZXJzIiwiX2xpdmU4cHgiLCJfdm9pY2VCcm9hZGNhc3QiLCJfU0RLQ29udGV4dCIsIl9GZWVkYmFjayIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsInRvUmlnaHRPZiIsInJlY3QiLCJsZWZ0Iiwid2lkdGgiLCJ0b3AiLCJjaGV2cm9uRmFjZSIsIkNoZXZyb25GYWNlIiwiTm9uZSIsImJlbG93IiwiaGVpZ2h0IiwiVXNlck1lbnUiLCJSZWFjdCIsIkNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJjb250ZXh0IiwiX2RlZmluZVByb3BlcnR5MiIsImNyZWF0ZVJlZiIsInJlY29yZGluZyIsInNldFN0YXRlIiwic2hvd0xpdmVBdmF0YXJBZGRvbiIsImZvcmNlVXBkYXRlIiwic2VsZWN0ZWRTcGFjZSIsIlNwYWNlU3RvcmUiLCJpbnN0YW5jZSIsImFjdGl2ZVNwYWNlUm9vbSIsImlzRGFya1RoZW1lIiwiaXNVc2VyT25EYXJrVGhlbWUiLCJpc0hpZ2hDb250cmFzdCIsImlzVXNlck9uSGlnaENvbnRyYXN0VGhlbWUiLCJwYXlsb2FkIiwiYWN0aW9uIiwiQWN0aW9uIiwiVG9nZ2xlVXNlck1lbnUiLCJzdGF0ZSIsImNvbnRleHRNZW51UG9zaXRpb24iLCJidXR0b25SZWYiLCJjdXJyZW50IiwiY2xpY2siLCJldiIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwiY3VycmVudFRhcmdldCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsImNsaWVudFgiLCJjbGllbnRZIiwiUG9zdGhvZ1RyYWNrZXJzIiwidHJhY2tJbnRlcmFjdGlvbiIsIlNldHRpbmdzU3RvcmUiLCJzZXRWYWx1ZSIsIlNldHRpbmdMZXZlbCIsIkRFVklDRSIsIm5ld1RoZW1lIiwiaGNUaGVtZSIsImZpbmRIaWdoQ29udHJhc3RUaGVtZSIsInRhYklkIiwiVmlld1VzZXJTZXR0aW5ncyIsImluaXRpYWxUYWJJZCIsImRlZmF1bHREaXNwYXRjaGVyIiwiZGlzcGF0Y2giLCJNb2RhbCIsImNyZWF0ZURpYWxvZyIsIkZlZWRiYWNrRGlhbG9nIiwic2hvdWxkU2hvd0xvZ291dERpYWxvZyIsIk1hdHJpeENsaWVudFBlZyIsInNhZmVHZXQiLCJMb2dvdXREaWFsb2ciLCJWaWV3SG9tZVBhZ2UiLCJ0b3BTZWN0aW9uIiwiaXNHdWVzdCIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJfdCIsInN1YiIsImtpbmQiLCJvbkNsaWNrIiwib25TaWduSW5DbGljayIsImdldFZhbHVlIiwiVUlGZWF0dXJlIiwiUmVnaXN0cmF0aW9uIiwib25SZWdpc3RlckNsaWNrIiwiaG9tZUJ1dHRvbiIsImhhc0hvbWVQYWdlIiwiSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbiIsImljb25DbGFzc05hbWUiLCJsYWJlbCIsIm9uSG9tZUNsaWNrIiwiZmVlZGJhY2tCdXR0b24iLCJzaG91bGRTaG93RmVlZGJhY2siLCJvblByb3ZpZGVGZWVkYmFjayIsImxpbmtOZXdEZXZpY2VCdXR0b24iLCJvblNldHRpbmdzT3BlbiIsIlVzZXJUYWIiLCJTZXNzaW9uTWFuYWdlciIsInNob3dNc2M0MTA4UXJDb2RlIiwicHJpbWFyeU9wdGlvbkxpc3QiLCJJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdCIsIk5vdGlmaWNhdGlvbnMiLCJTZWN1cml0eSIsIm9uU2lnbk91dENsaWNrIiwicG9zaXRpb24iLCJpc1BhbmVsQ29sbGFwc2VkIiwiX2V4dGVuZHMyIiwib25GaW5pc2hlZCIsIm9uQ2xvc2VNZW51IiwiT3duUHJvZmlsZVN0b3JlIiwiZGlzcGxheU5hbWUiLCJVc2VySWRlbnRpZmllckN1c3RvbWlzYXRpb25zIiwiZ2V0RGlzcGxheVVzZXJJZGVudGlmaWVyIiwiZ2V0U2FmZVVzZXJJZCIsIndpdGhEaXNwbGF5TmFtZSIsIlJvdmluZ0FjY2Vzc2libGVCdXR0b24iLCJvblN3aXRjaFRoZW1lQ2xpY2siLCJ0aXRsZSIsInNyYyIsInJvbGUiLCJhbHQiLCJ2b2ljZUJyb2FkY2FzdFJlY29yZGluZ3NTdG9yZSIsImhhc0N1cnJlbnQiLCJvbiIsIlVQREFURV9FVkVOVCIsIm9uUHJvZmlsZVVwZGF0ZSIsIlVQREFURV9TRUxFQ1RFRF9TUEFDRSIsIm9uU2VsZWN0ZWRTcGFjZVVwZGF0ZSIsImdldEhvbWVQYWdlVXJsIiwiU2RrQ29uZmlnIiwiY2xpZW50IiwiY29tcG9uZW50RGlkTW91bnQiLCJWb2ljZUJyb2FkY2FzdFJlY29yZGluZ3NTdG9yZUV2ZW50IiwiQ3VycmVudENoYW5nZWQiLCJvbkN1cnJlbnRWb2ljZUJyb2FkY2FzdFJlY29yZGluZ0NoYW5nZWQiLCJkaXNwYXRjaGVyUmVmIiwicmVnaXN0ZXIiLCJvbkFjdGlvbiIsInRoZW1lV2F0Y2hlclJlZiIsIndhdGNoU2V0dGluZyIsIm9uVGhlbWVDaGFuZ2VkIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJ1bndhdGNoU2V0dGluZyIsImRuZFdhdGNoZXJSZWYiLCJ1bnJlZ2lzdGVyIiwib2ZmIiwid2luZG93IiwibWF0Y2hNZWRpYSIsIm1hdGNoZXMiLCJ0aGVtZSIsInN0YXJ0c1dpdGgiLCJnZXRDdXN0b21UaGVtZSIsInN1YnN0cmluZyIsImxlbmd0aCIsImlzX2RhcmsiLCJpc0hpZ2hDb250cmFzdFRoZW1lIiwicmVuZGVyIiwiYXZhdGFyU2l6ZSIsInVzZXJJZCIsImF2YXRhclVybCIsImdldEh0dHBBdmF0YXJVcmwiLCJuYW1lIiwibGl2ZUF2YXRhckFkZG9uIiwiSWNvbiIsIkNvbnRleHRNZW51QnV0dG9uIiwib25PcGVuTWVudUNsaWNrIiwicmVmIiwiaXNFeHBhbmRlZCIsIm9uQ29udGV4dE1lbnUiLCJpZE5hbWUiLCJ1cmwiLCJzaXplIiwicmVuZGVyQ29udGV4dE1lbnUiLCJjaGlsZHJlbiIsImV4cG9ydHMiLCJTREtDb250ZXh0Il0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc3RydWN0dXJlcy9Vc2VyTWVudS50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAsIDIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUmVhY3ROb2RlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBSb29tIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuXG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgZGVmYXVsdERpc3BhdGNoZXIgZnJvbSBcIi4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgQWN0aW9uUGF5bG9hZCB9IGZyb20gXCIuLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzXCI7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi4vLi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCB7IENoZXZyb25GYWNlLCBDb250ZXh0TWVudUJ1dHRvbiwgTWVudVByb3BzIH0gZnJvbSBcIi4vQ29udGV4dE1lbnVcIjtcbmltcG9ydCB7IFVzZXJUYWIgfSBmcm9tIFwiLi4vdmlld3MvZGlhbG9ncy9Vc2VyVGFiXCI7XG5pbXBvcnQgeyBPcGVuVG9UYWJQYXlsb2FkIH0gZnJvbSBcIi4uLy4uL2Rpc3BhdGNoZXIvcGF5bG9hZHMvT3BlblRvVGFiUGF5bG9hZFwiO1xuaW1wb3J0IEZlZWRiYWNrRGlhbG9nIGZyb20gXCIuLi92aWV3cy9kaWFsb2dzL0ZlZWRiYWNrRGlhbG9nXCI7XG5pbXBvcnQgTW9kYWwgZnJvbSBcIi4uLy4uL01vZGFsXCI7XG5pbXBvcnQgTG9nb3V0RGlhbG9nLCB7IHNob3VsZFNob3dMb2dvdXREaWFsb2cgfSBmcm9tIFwiLi4vdmlld3MvZGlhbG9ncy9Mb2dvdXREaWFsb2dcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBmaW5kSGlnaENvbnRyYXN0VGhlbWUsIGdldEN1c3RvbVRoZW1lLCBpc0hpZ2hDb250cmFzdFRoZW1lIH0gZnJvbSBcIi4uLy4uL3RoZW1lXCI7XG5pbXBvcnQgeyBSb3ZpbmdBY2Nlc3NpYmxlQnV0dG9uIH0gZnJvbSBcIi4uLy4uL2FjY2Vzc2liaWxpdHkvUm92aW5nVGFiSW5kZXhcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uLCB7IEJ1dHRvbkV2ZW50IH0gZnJvbSBcIi4uL3ZpZXdzL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4uLy4uL1Nka0NvbmZpZ1wiO1xuaW1wb3J0IHsgZ2V0SG9tZVBhZ2VVcmwgfSBmcm9tIFwiLi4vLi4vdXRpbHMvcGFnZXNcIjtcbmltcG9ydCB7IE93blByb2ZpbGVTdG9yZSB9IGZyb20gXCIuLi8uLi9zdG9yZXMvT3duUHJvZmlsZVN0b3JlXCI7XG5pbXBvcnQgeyBVUERBVEVfRVZFTlQgfSBmcm9tIFwiLi4vLi4vc3RvcmVzL0FzeW5jU3RvcmVcIjtcbmltcG9ydCBCYXNlQXZhdGFyIGZyb20gXCIuLi92aWV3cy9hdmF0YXJzL0Jhc2VBdmF0YXJcIjtcbmltcG9ydCB7IFNldHRpbmdMZXZlbCB9IGZyb20gXCIuLi8uLi9zZXR0aW5ncy9TZXR0aW5nTGV2ZWxcIjtcbmltcG9ydCBJY29uaXplZENvbnRleHRNZW51LCB7XG4gICAgSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbixcbiAgICBJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdCxcbn0gZnJvbSBcIi4uL3ZpZXdzL2NvbnRleHRfbWVudXMvSWNvbml6ZWRDb250ZXh0TWVudVwiO1xuaW1wb3J0IHsgVUlGZWF0dXJlIH0gZnJvbSBcIi4uLy4uL3NldHRpbmdzL1VJRmVhdHVyZVwiO1xuaW1wb3J0IFNwYWNlU3RvcmUgZnJvbSBcIi4uLy4uL3N0b3Jlcy9zcGFjZXMvU3BhY2VTdG9yZVwiO1xuaW1wb3J0IHsgVVBEQVRFX1NFTEVDVEVEX1NQQUNFIH0gZnJvbSBcIi4uLy4uL3N0b3Jlcy9zcGFjZXNcIjtcbmltcG9ydCBVc2VySWRlbnRpZmllckN1c3RvbWlzYXRpb25zIGZyb20gXCIuLi8uLi9jdXN0b21pc2F0aW9ucy9Vc2VySWRlbnRpZmllclwiO1xuaW1wb3J0IFBvc3Rob2dUcmFja2VycyBmcm9tIFwiLi4vLi4vUG9zdGhvZ1RyYWNrZXJzXCI7XG5pbXBvcnQgeyBWaWV3SG9tZVBhZ2VQYXlsb2FkIH0gZnJvbSBcIi4uLy4uL2Rpc3BhdGNoZXIvcGF5bG9hZHMvVmlld0hvbWVQYWdlUGF5bG9hZFwiO1xuaW1wb3J0IHsgSWNvbiBhcyBMaXZlSWNvbiB9IGZyb20gXCIuLi8uLi8uLi9yZXMvaW1nL2NvbXBvdW5kL2xpdmUtOHB4LnN2Z1wiO1xuaW1wb3J0IHsgVm9pY2VCcm9hZGNhc3RSZWNvcmRpbmcsIFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nc1N0b3JlRXZlbnQgfSBmcm9tIFwiLi4vLi4vdm9pY2UtYnJvYWRjYXN0XCI7XG5pbXBvcnQgeyBTREtDb250ZXh0IH0gZnJvbSBcIi4uLy4uL2NvbnRleHRzL1NES0NvbnRleHRcIjtcbmltcG9ydCB7IHNob3VsZFNob3dGZWVkYmFjayB9IGZyb20gXCIuLi8uLi91dGlscy9GZWVkYmFja1wiO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICBpc1BhbmVsQ29sbGFwc2VkOiBib29sZWFuO1xuICAgIGNoaWxkcmVuPzogUmVhY3ROb2RlO1xufVxuXG50eXBlIFBhcnRpYWxET01SZWN0ID0gUGljazxET01SZWN0LCBcIndpZHRoXCIgfCBcImxlZnRcIiB8IFwidG9wXCIgfCBcImhlaWdodFwiPjtcblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgY29udGV4dE1lbnVQb3NpdGlvbjogUGFydGlhbERPTVJlY3QgfCBudWxsO1xuICAgIGlzRGFya1RoZW1lOiBib29sZWFuO1xuICAgIGlzSGlnaENvbnRyYXN0OiBib29sZWFuO1xuICAgIHNlbGVjdGVkU3BhY2U/OiBSb29tIHwgbnVsbDtcbiAgICBzaG93TGl2ZUF2YXRhckFkZG9uOiBib29sZWFuO1xufVxuXG5jb25zdCB0b1JpZ2h0T2YgPSAocmVjdDogUGFydGlhbERPTVJlY3QpOiBNZW51UHJvcHMgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxlZnQ6IHJlY3Qud2lkdGggKyByZWN0LmxlZnQgKyA4LFxuICAgICAgICB0b3A6IHJlY3QudG9wLFxuICAgICAgICBjaGV2cm9uRmFjZTogQ2hldnJvbkZhY2UuTm9uZSxcbiAgICB9O1xufTtcblxuY29uc3QgYmVsb3cgPSAocmVjdDogUGFydGlhbERPTVJlY3QpOiBNZW51UHJvcHMgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxlZnQ6IHJlY3QubGVmdCxcbiAgICAgICAgdG9wOiByZWN0LnRvcCArIHJlY3QuaGVpZ2h0LFxuICAgICAgICBjaGV2cm9uRmFjZTogQ2hldnJvbkZhY2UuTm9uZSxcbiAgICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVXNlck1lbnUgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwdWJsaWMgc3RhdGljIGNvbnRleHRUeXBlID0gU0RLQ29udGV4dDtcbiAgICBwdWJsaWMgZGVjbGFyZSBjb250ZXh0OiBSZWFjdC5Db250ZXh0VHlwZTx0eXBlb2YgU0RLQ29udGV4dD47XG5cbiAgICBwcml2YXRlIGRpc3BhdGNoZXJSZWY/OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB0aGVtZVdhdGNoZXJSZWY/OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkbmRXYXRjaGVyUmVmPzogc3RyaW5nO1xuICAgIHByaXZhdGUgYnV0dG9uUmVmOiBSZWFjdC5SZWZPYmplY3Q8SFRNTEJ1dHRvbkVsZW1lbnQ+ID0gY3JlYXRlUmVmKCk7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcywgY29udGV4dDogUmVhY3QuQ29udGV4dFR5cGU8dHlwZW9mIFNES0NvbnRleHQ+KSB7XG4gICAgICAgIHN1cGVyKHByb3BzLCBjb250ZXh0KTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgY29udGV4dE1lbnVQb3NpdGlvbjogbnVsbCxcbiAgICAgICAgICAgIGlzRGFya1RoZW1lOiB0aGlzLmlzVXNlck9uRGFya1RoZW1lKCksXG4gICAgICAgICAgICBpc0hpZ2hDb250cmFzdDogdGhpcy5pc1VzZXJPbkhpZ2hDb250cmFzdFRoZW1lKCksXG4gICAgICAgICAgICBzZWxlY3RlZFNwYWNlOiBTcGFjZVN0b3JlLmluc3RhbmNlLmFjdGl2ZVNwYWNlUm9vbSxcbiAgICAgICAgICAgIHNob3dMaXZlQXZhdGFyQWRkb246IHRoaXMuY29udGV4dC52b2ljZUJyb2FkY2FzdFJlY29yZGluZ3NTdG9yZS5oYXNDdXJyZW50KCksXG4gICAgICAgIH07XG5cbiAgICAgICAgT3duUHJvZmlsZVN0b3JlLmluc3RhbmNlLm9uKFVQREFURV9FVkVOVCwgdGhpcy5vblByb2ZpbGVVcGRhdGUpO1xuICAgICAgICBTcGFjZVN0b3JlLmluc3RhbmNlLm9uKFVQREFURV9TRUxFQ1RFRF9TUEFDRSwgdGhpcy5vblNlbGVjdGVkU3BhY2VVcGRhdGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0IGhhc0hvbWVQYWdlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISFnZXRIb21lUGFnZVVybChTZGtDb25maWcuZ2V0KCksIHRoaXMuY29udGV4dC5jbGllbnQhKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uQ3VycmVudFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nQ2hhbmdlZCA9IChyZWNvcmRpbmc6IFZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nIHwgbnVsbCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNob3dMaXZlQXZhdGFyQWRkb246IHJlY29yZGluZyAhPT0gbnVsbCxcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHB1YmxpYyBjb21wb25lbnREaWRNb3VudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nc1N0b3JlLm9uKFxuICAgICAgICAgICAgVm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdzU3RvcmVFdmVudC5DdXJyZW50Q2hhbmdlZCxcbiAgICAgICAgICAgIHRoaXMub25DdXJyZW50Vm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdDaGFuZ2VkLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmRpc3BhdGNoZXJSZWYgPSBkZWZhdWx0RGlzcGF0Y2hlci5yZWdpc3Rlcih0aGlzLm9uQWN0aW9uKTtcbiAgICAgICAgdGhpcy50aGVtZVdhdGNoZXJSZWYgPSBTZXR0aW5nc1N0b3JlLndhdGNoU2V0dGluZyhcInRoZW1lXCIsIG51bGwsIHRoaXMub25UaGVtZUNoYW5nZWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudGhlbWVXYXRjaGVyUmVmKSBTZXR0aW5nc1N0b3JlLnVud2F0Y2hTZXR0aW5nKHRoaXMudGhlbWVXYXRjaGVyUmVmKTtcbiAgICAgICAgaWYgKHRoaXMuZG5kV2F0Y2hlclJlZikgU2V0dGluZ3NTdG9yZS51bndhdGNoU2V0dGluZyh0aGlzLmRuZFdhdGNoZXJSZWYpO1xuICAgICAgICBpZiAodGhpcy5kaXNwYXRjaGVyUmVmKSBkZWZhdWx0RGlzcGF0Y2hlci51bnJlZ2lzdGVyKHRoaXMuZGlzcGF0Y2hlclJlZik7XG4gICAgICAgIE93blByb2ZpbGVTdG9yZS5pbnN0YW5jZS5vZmYoVVBEQVRFX0VWRU5ULCB0aGlzLm9uUHJvZmlsZVVwZGF0ZSk7XG4gICAgICAgIFNwYWNlU3RvcmUuaW5zdGFuY2Uub2ZmKFVQREFURV9TRUxFQ1RFRF9TUEFDRSwgdGhpcy5vblNlbGVjdGVkU3BhY2VVcGRhdGUpO1xuICAgICAgICB0aGlzLmNvbnRleHQudm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdzU3RvcmUub2ZmKFxuICAgICAgICAgICAgVm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdzU3RvcmVFdmVudC5DdXJyZW50Q2hhbmdlZCxcbiAgICAgICAgICAgIHRoaXMub25DdXJyZW50Vm9pY2VCcm9hZGNhc3RSZWNvcmRpbmdDaGFuZ2VkLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNVc2VyT25EYXJrVGhlbWUoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwidXNlX3N5c3RlbV90aGVtZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKFwiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKVwiKS5tYXRjaGVzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdGhlbWUgPSBTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwidGhlbWVcIik7XG4gICAgICAgICAgICBpZiAodGhlbWUuc3RhcnRzV2l0aChcImN1c3RvbS1cIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gISFnZXRDdXN0b21UaGVtZSh0aGVtZS5zdWJzdHJpbmcoXCJjdXN0b20tXCIubGVuZ3RoKSkuaXNfZGFyaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGVtZSA9PT0gXCJkYXJrXCI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzVXNlck9uSGlnaENvbnRyYXN0VGhlbWUoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwidXNlX3N5c3RlbV90aGVtZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKFwiKHByZWZlcnMtY29udHJhc3Q6IG1vcmUpXCIpLm1hdGNoZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0aGVtZSA9IFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJ0aGVtZVwiKTtcbiAgICAgICAgICAgIGlmICh0aGVtZS5zdGFydHNXaXRoKFwiY3VzdG9tLVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpc0hpZ2hDb250cmFzdFRoZW1lKHRoZW1lKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25Qcm9maWxlVXBkYXRlID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAvLyB0aGUgc3RvcmUgdHJpZ2dlcmVkIGFuIHVwZGF0ZSwgc28gZm9yY2UgYSBsYXlvdXQgdXBkYXRlLiBXZSBkb24ndFxuICAgICAgICAvLyBoYXZlIGFueSBzdGF0ZSB0byBzdG9yZSBoZXJlIGZvciB0aGF0IHRvIG1hZ2ljYWxseSBoYXBwZW4uXG4gICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblNlbGVjdGVkU3BhY2VVcGRhdGUgPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRTcGFjZTogU3BhY2VTdG9yZS5pbnN0YW5jZS5hY3RpdmVTcGFjZVJvb20sXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uVGhlbWVDaGFuZ2VkID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzRGFya1RoZW1lOiB0aGlzLmlzVXNlck9uRGFya1RoZW1lKCksXG4gICAgICAgICAgICBpc0hpZ2hDb250cmFzdDogdGhpcy5pc1VzZXJPbkhpZ2hDb250cmFzdFRoZW1lKCksXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQWN0aW9uID0gKHBheWxvYWQ6IEFjdGlvblBheWxvYWQpOiB2b2lkID0+IHtcbiAgICAgICAgc3dpdGNoIChwYXlsb2FkLmFjdGlvbikge1xuICAgICAgICAgICAgY2FzZSBBY3Rpb24uVG9nZ2xlVXNlck1lbnU6XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuY29udGV4dE1lbnVQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29udGV4dE1lbnVQb3NpdGlvbjogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5idXR0b25SZWYuY3VycmVudCkgdGhpcy5idXR0b25SZWYuY3VycmVudC5jbGljaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uT3Blbk1lbnVDbGljayA9IChldjogQnV0dG9uRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250ZXh0TWVudVBvc2l0aW9uOiBldi5jdXJyZW50VGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uQ29udGV4dE1lbnUgPSAoZXY6IFJlYWN0Lk1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgY29udGV4dE1lbnVQb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIGxlZnQ6IGV2LmNsaWVudFgsXG4gICAgICAgICAgICAgICAgdG9wOiBldi5jbGllbnRZLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAyMCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkNsb3NlTWVudSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvbnRleHRNZW51UG9zaXRpb246IG51bGwgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Td2l0Y2hUaGVtZUNsaWNrID0gKGV2OiBCdXR0b25FdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBQb3N0aG9nVHJhY2tlcnMudHJhY2tJbnRlcmFjdGlvbihcIldlYlVzZXJNZW51VGhlbWVUb2dnbGVCdXR0b25cIiwgZXYpO1xuXG4gICAgICAgIC8vIERpc2FibGUgc3lzdGVtIHRoZW1lIG1hdGNoaW5nIGlmIHRoZSB1c2VyIGhpdHMgdGhpcyBidXR0b25cbiAgICAgICAgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInVzZV9zeXN0ZW1fdGhlbWVcIiwgbnVsbCwgU2V0dGluZ0xldmVsLkRFVklDRSwgZmFsc2UpO1xuXG4gICAgICAgIGxldCBuZXdUaGVtZSA9IHRoaXMuc3RhdGUuaXNEYXJrVGhlbWUgPyBcImxpZ2h0XCIgOiBcImRhcmtcIjtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuaXNIaWdoQ29udHJhc3QpIHtcbiAgICAgICAgICAgIGNvbnN0IGhjVGhlbWUgPSBmaW5kSGlnaENvbnRyYXN0VGhlbWUobmV3VGhlbWUpO1xuICAgICAgICAgICAgaWYgKGhjVGhlbWUpIHtcbiAgICAgICAgICAgICAgICBuZXdUaGVtZSA9IGhjVGhlbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInRoZW1lXCIsIG51bGwsIFNldHRpbmdMZXZlbC5ERVZJQ0UsIG5ld1RoZW1lKTsgLy8gc2V0IGF0IHNhbWUgbGV2ZWwgYXMgQXBwZWFyYW5jZSB0YWJcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblNldHRpbmdzT3BlbiA9IChldjogQnV0dG9uRXZlbnQsIHRhYklkPzogc3RyaW5nLCBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4pOiB2b2lkID0+IHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgY29uc3QgcGF5bG9hZDogT3BlblRvVGFiUGF5bG9hZCA9IHsgYWN0aW9uOiBBY3Rpb24uVmlld1VzZXJTZXR0aW5ncywgaW5pdGlhbFRhYklkOiB0YWJJZCwgcHJvcHMgfTtcbiAgICAgICAgZGVmYXVsdERpc3BhdGNoZXIuZGlzcGF0Y2gocGF5bG9hZCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250ZXh0TWVudVBvc2l0aW9uOiBudWxsIH0pOyAvLyBhbHNvIGNsb3NlIHRoZSBtZW51XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Qcm92aWRlRmVlZGJhY2sgPSAoZXY6IEJ1dHRvbkV2ZW50KTogdm9pZCA9PiB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhGZWVkYmFja0RpYWxvZyk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250ZXh0TWVudVBvc2l0aW9uOiBudWxsIH0pOyAvLyBhbHNvIGNsb3NlIHRoZSBtZW51XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25TaWduT3V0Q2xpY2sgPSBhc3luYyAoZXY6IEJ1dHRvbkV2ZW50KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGlmIChhd2FpdCBzaG91bGRTaG93TG9nb3V0RGlhbG9nKE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkpKSB7XG4gICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coTG9nb3V0RGlhbG9nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlZmF1bHREaXNwYXRjaGVyLmRpc3BhdGNoKHsgYWN0aW9uOiBcImxvZ291dFwiIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvbnRleHRNZW51UG9zaXRpb246IG51bGwgfSk7IC8vIGFsc28gY2xvc2UgdGhlIG1lbnVcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblNpZ25JbkNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaCh7IGFjdGlvbjogXCJzdGFydF9sb2dpblwiIH0pO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29udGV4dE1lbnVQb3NpdGlvbjogbnVsbCB9KTsgLy8gYWxzbyBjbG9zZSB0aGUgbWVudVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uUmVnaXN0ZXJDbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgZGVmYXVsdERpc3BhdGNoZXIuZGlzcGF0Y2goeyBhY3Rpb246IFwic3RhcnRfcmVnaXN0cmF0aW9uXCIgfSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250ZXh0TWVudVBvc2l0aW9uOiBudWxsIH0pOyAvLyBhbHNvIGNsb3NlIHRoZSBtZW51XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Ib21lQ2xpY2sgPSAoZXY6IEJ1dHRvbkV2ZW50KTogdm9pZCA9PiB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGRlZmF1bHREaXNwYXRjaGVyLmRpc3BhdGNoPFZpZXdIb21lUGFnZVBheWxvYWQ+KHsgYWN0aW9uOiBBY3Rpb24uVmlld0hvbWVQYWdlIH0pO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29udGV4dE1lbnVQb3NpdGlvbjogbnVsbCB9KTsgLy8gYWxzbyBjbG9zZSB0aGUgbWVudVxuICAgIH07XG5cbiAgICBwcml2YXRlIHJlbmRlckNvbnRleHRNZW51ID0gKCk6IFJlYWN0LlJlYWN0Tm9kZSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZS5jb250ZXh0TWVudVBvc2l0aW9uKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBsZXQgdG9wU2VjdGlvbjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmlzR3Vlc3QoKSkge1xuICAgICAgICAgICAgdG9wU2VjdGlvbiA9IChcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1VzZXJNZW51X2NvbnRleHRNZW51X2hlYWRlciBteF9Vc2VyTWVudV9jb250ZXh0TWVudV9ndWVzdFByb21wdHNcIj5cbiAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJhdXRofHNpZ25faW5fcHJvbXB0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiAoc3ViKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJsaW5rX2lubGluZVwiIG9uQ2xpY2s9e3RoaXMub25TaWduSW5DbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7c3VifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgICAgIHtTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFVJRmVhdHVyZS5SZWdpc3RyYXRpb24pXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF90KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhdXRofGNyZWF0ZV9hY2NvdW50X3Byb21wdFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYTogKHN1YikgPT4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvbiBraW5kPVwibGlua19pbmxpbmVcIiBvbkNsaWNrPXt0aGlzLm9uUmVnaXN0ZXJDbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7c3VifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaG9tZUJ1dHRvbjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLmhhc0hvbWVQYWdlKSB7XG4gICAgICAgICAgICBob21lQnV0dG9uID0gKFxuICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Vc2VyTWVudV9pY29uSG9tZVwiXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNvbW1vbnxob21lXCIpfVxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uSG9tZUNsaWNrfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZlZWRiYWNrQnV0dG9uOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHNob3VsZFNob3dGZWVkYmFjaygpKSB7XG4gICAgICAgICAgICBmZWVkYmFja0J1dHRvbiA9IChcbiAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfVXNlck1lbnVfaWNvbk1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJjb21tb258ZmVlZGJhY2tcIil9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25Qcm92aWRlRmVlZGJhY2t9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaW5rTmV3RGV2aWNlQnV0dG9uID0gKFxuICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25cbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfVXNlck1lbnVfaWNvblFyXCJcbiAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJ1c2VyX21lbnV8bGlua19uZXdfZGV2aWNlXCIpfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB0aGlzLm9uU2V0dGluZ3NPcGVuKGUsIFVzZXJUYWIuU2Vzc2lvbk1hbmFnZXIsIHsgc2hvd01zYzQxMDhRckNvZGU6IHRydWUgfSl9XG4gICAgICAgICAgICAvPlxuICAgICAgICApO1xuXG4gICAgICAgIGxldCBwcmltYXJ5T3B0aW9uTGlzdCA9IChcbiAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdD5cbiAgICAgICAgICAgICAgICB7aG9tZUJ1dHRvbn1cbiAgICAgICAgICAgICAgICB7bGlua05ld0RldmljZUJ1dHRvbn1cbiAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfVXNlck1lbnVfaWNvbkJlbGxcIlxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJub3RpZmljYXRpb25zfGVuYWJsZV9wcm9tcHRfdG9hc3RfdGl0bGVcIil9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB0aGlzLm9uU2V0dGluZ3NPcGVuKGUsIFVzZXJUYWIuTm90aWZpY2F0aW9ucyl9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfVXNlck1lbnVfaWNvbkxvY2tcIlxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJyb29tX3NldHRpbmdzfHNlY3VyaXR5fHRpdGxlXCIpfVxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4gdGhpcy5vblNldHRpbmdzT3BlbihlLCBVc2VyVGFiLlNlY3VyaXR5KX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Vc2VyTWVudV9pY29uU2V0dGluZ3NcIlxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJ1c2VyX21lbnV8c2V0dGluZ3NcIil9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB0aGlzLm9uU2V0dGluZ3NPcGVuKGUpfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAge2ZlZWRiYWNrQnV0dG9ufVxuICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0ljb25pemVkQ29udGV4dE1lbnVfb3B0aW9uX3JlZFwiXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Vc2VyTWVudV9pY29uU2lnbk91dFwiXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImFjdGlvbnxzaWduX291dFwiKX1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5vblNpZ25PdXRDbGlja31cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdD5cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5pc0d1ZXN0KCkpIHtcbiAgICAgICAgICAgIHByaW1hcnlPcHRpb25MaXN0ID0gKFxuICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdD5cbiAgICAgICAgICAgICAgICAgICAge2hvbWVCdXR0b259XG4gICAgICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfVXNlck1lbnVfaWNvblNldHRpbmdzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNvbW1vbnxzZXR0aW5nc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB0aGlzLm9uU2V0dGluZ3NPcGVuKGUpfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7ZmVlZGJhY2tCdXR0b259XG4gICAgICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdD5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMucHJvcHMuaXNQYW5lbENvbGxhcHNlZFxuICAgICAgICAgICAgPyB0b1JpZ2h0T2YodGhpcy5zdGF0ZS5jb250ZXh0TWVudVBvc2l0aW9uKVxuICAgICAgICAgICAgOiBiZWxvdyh0aGlzLnN0YXRlLmNvbnRleHRNZW51UG9zaXRpb24pO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudSB7Li4ucG9zaXRpb259IG9uRmluaXNoZWQ9e3RoaXMub25DbG9zZU1lbnV9IGNsYXNzTmFtZT1cIm14X1VzZXJNZW51X2NvbnRleHRNZW51XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Vc2VyTWVudV9jb250ZXh0TWVudV9oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Vc2VyTWVudV9jb250ZXh0TWVudV9uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9Vc2VyTWVudV9jb250ZXh0TWVudV9kaXNwbGF5TmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtPd25Qcm9maWxlU3RvcmUuaW5zdGFuY2UuZGlzcGxheU5hbWV9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9Vc2VyTWVudV9jb250ZXh0TWVudV91c2VySWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7VXNlcklkZW50aWZpZXJDdXN0b21pc2F0aW9ucy5nZXREaXNwbGF5VXNlcklkZW50aWZpZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkuZ2V0U2FmZVVzZXJJZCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoRGlzcGxheU5hbWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPFJvdmluZ0FjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1VzZXJNZW51X2NvbnRleHRNZW51X3RoZW1lQnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25Td2l0Y2hUaGVtZUNsaWNrfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuaXNEYXJrVGhlbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBfdChcInVzZXJfbWVudXxzd2l0Y2hfdGhlbWVfbGlnaHRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInVzZXJfbWVudXxzd2l0Y2hfdGhlbWVfZGFya1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPXtyZXF1aXJlKFwiLi4vLi4vLi4vcmVzL2ltZy9lbGVtZW50LWljb25zL3Jvb21saXN0L2RhcmstbGlnaHQtbW9kZS5zdmdcIikuZGVmYXVsdH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlPVwicHJlc2VudGF0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPXsxNn1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvUm92aW5nQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB7dG9wU2VjdGlvbn1cbiAgICAgICAgICAgICAgICB7cHJpbWFyeU9wdGlvbkxpc3R9XG4gICAgICAgICAgICA8L0ljb25pemVkQ29udGV4dE1lbnU+XG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3QgYXZhdGFyU2l6ZSA9IDMyOyAvLyBzaG91bGQgbWF0Y2ggYm9yZGVyLXJhZGl1cyBvZiB0aGUgYXZhdGFyXG5cbiAgICAgICAgY29uc3QgdXNlcklkID0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRTYWZlVXNlcklkKCk7XG4gICAgICAgIGNvbnN0IGRpc3BsYXlOYW1lID0gT3duUHJvZmlsZVN0b3JlLmluc3RhbmNlLmRpc3BsYXlOYW1lIHx8IHVzZXJJZDtcbiAgICAgICAgY29uc3QgYXZhdGFyVXJsID0gT3duUHJvZmlsZVN0b3JlLmluc3RhbmNlLmdldEh0dHBBdmF0YXJVcmwoYXZhdGFyU2l6ZSk7XG5cbiAgICAgICAgbGV0IG5hbWU6IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMuaXNQYW5lbENvbGxhcHNlZCkge1xuICAgICAgICAgICAgbmFtZSA9IDxkaXYgY2xhc3NOYW1lPVwibXhfVXNlck1lbnVfbmFtZVwiPntkaXNwbGF5TmFtZX08L2Rpdj47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaXZlQXZhdGFyQWRkb24gPSB0aGlzLnN0YXRlLnNob3dMaXZlQXZhdGFyQWRkb24gPyAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1VzZXJNZW51X3VzZXJBdmF0YXJMaXZlXCIgZGF0YS10ZXN0aWQ9XCJ1c2VyLW1lbnUtbGl2ZS12YlwiPlxuICAgICAgICAgICAgICAgIDxMaXZlSWNvbiBjbGFzc05hbWU9XCJteF9JY29uXzhcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICkgOiBudWxsO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1VzZXJNZW51XCI+XG4gICAgICAgICAgICAgICAgPENvbnRleHRNZW51QnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1VzZXJNZW51X2NvbnRleHRNZW51QnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5vbk9wZW5NZW51Q2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIHJlZj17dGhpcy5idXR0b25SZWZ9XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImExMXl8dXNlcl9tZW51XCIpfVxuICAgICAgICAgICAgICAgICAgICBpc0V4cGFuZGVkPXshIXRoaXMuc3RhdGUuY29udGV4dE1lbnVQb3NpdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgb25Db250ZXh0TWVudT17dGhpcy5vbkNvbnRleHRNZW51fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Vc2VyTWVudV91c2VyQXZhdGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QmFzZUF2YXRhclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkTmFtZT17dXNlcklkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9e2Rpc3BsYXlOYW1lfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybD17YXZhdGFyVXJsfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9e2F2YXRhclNpemUgKyBcInB4XCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfVXNlck1lbnVfdXNlckF2YXRhcl9CYXNlQXZhdGFyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB7bGl2ZUF2YXRhckFkZG9ufVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAge25hbWV9XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnJlbmRlckNvbnRleHRNZW51KCl9XG4gICAgICAgICAgICAgICAgPC9Db250ZXh0TWVudUJ1dHRvbj5cblxuICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLmNoaWxkcmVufVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFHQSxJQUFBQyxnQkFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsV0FBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBRUEsSUFBQUksUUFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssZ0JBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLFlBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FBQVAsT0FBQTtBQUVBLElBQUFRLGVBQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFTLE1BQUEsR0FBQU4sc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFVLGFBQUEsR0FBQVgsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFXLGNBQUEsR0FBQVIsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFZLE1BQUEsR0FBQVosT0FBQTtBQUNBLElBQUFhLGVBQUEsR0FBQWIsT0FBQTtBQUNBLElBQUFjLGlCQUFBLEdBQUFYLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBZSxVQUFBLEdBQUFaLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBZ0IsTUFBQSxHQUFBaEIsT0FBQTtBQUNBLElBQUFpQixnQkFBQSxHQUFBakIsT0FBQTtBQUNBLElBQUFrQixXQUFBLEdBQUFsQixPQUFBO0FBQ0EsSUFBQW1CLFdBQUEsR0FBQWhCLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBb0IsYUFBQSxHQUFBcEIsT0FBQTtBQUNBLElBQUFxQixvQkFBQSxHQUFBdEIsdUJBQUEsQ0FBQUMsT0FBQTtBQUlBLElBQUFzQixVQUFBLEdBQUF0QixPQUFBO0FBQ0EsSUFBQXVCLFdBQUEsR0FBQXBCLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBd0IsT0FBQSxHQUFBeEIsT0FBQTtBQUNBLElBQUF5QixlQUFBLEdBQUF0QixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQTBCLGdCQUFBLEdBQUF2QixzQkFBQSxDQUFBSCxPQUFBO0FBRUEsSUFBQTJCLFFBQUEsR0FBQTNCLE9BQUE7QUFDQSxJQUFBNEIsZUFBQSxHQ