matrix-react-sdk
Version:
SDK for matrix.org using React
293 lines (277 loc) • 49 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ThemeChoicePanel = ThemeChoicePanel;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _compoundWeb = require("@vector-im/compound-web");
var _delete = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/delete"));
var _classnames = _interopRequireDefault(require("classnames"));
var _logger = require("matrix-js-sdk/src/logger");
var _languageHandler = require("../../../languageHandler");
var _SettingsSubsection = _interopRequireDefault(require("./shared/SettingsSubsection"));
var _ThemeWatcher = _interopRequireDefault(require("../../../settings/watchers/ThemeWatcher"));
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _SettingLevel = require("../../../settings/SettingLevel");
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _actions = require("../../../dispatcher/actions");
var _useTheme = require("../../../hooks/useTheme");
var _theme2 = require("../../../theme");
var _useSettings = require("../../../hooks/useSettings");
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; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /*
* Copyright 2024 New Vector Ltd.
* Copyright 2024 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.
*/
/**
* Panel to choose the theme
*/
function ThemeChoicePanel() {
const themeState = (0, _useTheme.useTheme)();
const themeWatcher = (0, _react.useRef)(new _ThemeWatcher.default());
const customThemeEnabled = (0, _useSettings.useSettingValue)("feature_custom_themes");
return /*#__PURE__*/_react.default.createElement(_SettingsSubsection.default, {
heading: (0, _languageHandler._t)("common|theme"),
legacy: false,
"data-testid": "themePanel"
}, themeWatcher.current.isSystemThemeSupported() && /*#__PURE__*/_react.default.createElement(SystemTheme, {
systemThemeActivated: themeState.systemThemeActivated
}), /*#__PURE__*/_react.default.createElement(ThemeSelectors, {
theme: themeState.theme,
disabled: themeState.systemThemeActivated
}), customThemeEnabled && /*#__PURE__*/_react.default.createElement(CustomTheme, {
theme: themeState.theme
}));
}
/**
* Component to toggle the system theme
*/
/**
* Component to toggle the system theme
*/
function SystemTheme({
systemThemeActivated
}) {
return /*#__PURE__*/_react.default.createElement(_compoundWeb.Root, {
onChange: async evt => {
const checked = new FormData(evt.currentTarget).get("systemTheme") === "on";
await _SettingsStore.default.setValue("use_system_theme", null, _SettingLevel.SettingLevel.DEVICE, checked);
_dispatcher.default.dispatch({
action: _actions.Action.RecheckTheme
});
}
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.InlineField, {
name: "systemTheme",
control: /*#__PURE__*/_react.default.createElement(_compoundWeb.ToggleControl, {
name: "systemTheme",
defaultChecked: systemThemeActivated
})
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.Label, null, _SettingsStore.default.getDisplayName("use_system_theme"))));
}
/**
* Component to select the theme
*/
/**
* Component to select the theme
*/
function ThemeSelectors({
theme,
disabled
}) {
const themes = useThemes();
return /*#__PURE__*/_react.default.createElement(_compoundWeb.Root, {
className: "mx_ThemeChoicePanel_ThemeSelectors",
onChange: async evt => {
// We don't have any file in the form, we can cast it as string safely
const newTheme = new FormData(evt.currentTarget).get("themeSelector");
// Do nothing if the same theme is selected
if (!newTheme || theme === newTheme) return;
// doing getValue in the .catch will still return the value we failed to set,
_SettingsStore.default.setValue("theme", null, _SettingLevel.SettingLevel.DEVICE, newTheme).catch(() => {
_dispatcher.default.dispatch({
action: _actions.Action.RecheckTheme
});
});
// The settings watcher doesn't fire until the echo comes back from the
// server, so to make the theme change immediately we need to manually
// do the dispatch now
// XXX: The local echoed value appears to be unreliable, in particular
// when settings custom themes(!) so adding forceTheme to override
// the value from settings.
_dispatcher.default.dispatch({
action: _actions.Action.RecheckTheme,
forceTheme: newTheme
});
}
}, themes.map(_theme => {
const isChecked = theme === _theme.id;
return /*#__PURE__*/_react.default.createElement(_compoundWeb.InlineField, {
className: (0, _classnames.default)("mx_ThemeChoicePanel_themeSelector", {
[`mx_ThemeChoicePanel_themeSelector_enabled`]: !disabled && theme === _theme.id,
[`mx_ThemeChoicePanel_themeSelector_disabled`]: disabled,
// We need to force the compound theme to be light or dark
// The theme selection doesn't depend on the current theme
// For example when the light theme is used, the dark theme selector should be dark
"cpd-theme-light": !_theme.isDark,
"cpd-theme-dark": _theme.isDark
}),
name: "themeSelector",
key: _theme.id,
control: /*#__PURE__*/_react.default.createElement(_compoundWeb.RadioControl, {
name: "themeSelector",
checked: !disabled && isChecked,
disabled: disabled,
value: _theme.id
})
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.Label, {
className: "mx_ThemeChoicePanel_themeSelector_Label"
}, _theme.name));
}));
}
/**
* Return all the available themes
*/
function useThemes() {
const customThemes = (0, _useSettings.useSettingValue)("custom_themes");
return (0, _react.useMemo)(() => {
// Put the custom theme into a map
// To easily find the theme by name when going through the themes list
const checkedCustomThemes = customThemes || [];
const customThemeMap = checkedCustomThemes.reduce((map, theme) => map.set(theme.name, theme), new Map());
const themes = (0, _theme2.getOrderedThemes)();
// Separate the built-in themes from the custom themes
// To insert the high contrast theme between them
const builtInThemes = themes.filter(theme => !customThemeMap.has(theme.name));
const otherThemes = themes.filter(theme => customThemeMap.has(theme.name));
const highContrastTheme = makeHighContrastTheme();
if (highContrastTheme) builtInThemes.push(highContrastTheme);
const allThemes = builtInThemes.concat(otherThemes);
// Check if the themes are dark
return allThemes.map(theme => {
const customTheme = customThemeMap.get(theme.name);
const isDark = (customTheme ? customTheme.is_dark : theme.id.includes("dark")) || false;
return _objectSpread(_objectSpread({}, theme), {}, {
isDark
});
});
}, [customThemes]);
}
/**
* Create the light high contrast theme
*/
function makeHighContrastTheme() {
const lightHighContrastId = (0, _theme2.findHighContrastTheme)("light");
if (lightHighContrastId) {
return {
name: (0, _languageHandler._t)("settings|appearance|high_contrast"),
id: lightHighContrastId
};
}
}
/**
* Add and manager custom themes
*/
function CustomTheme({
theme
}) {
const [customTheme, setCustomTheme] = (0, _react.useState)("");
const [error, setError] = (0, _react.useState)();
const clear = (0, _react.useCallback)(() => {
setError(undefined);
setCustomTheme("");
}, [setError, setCustomTheme]);
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_ThemeChoicePanel_CustomTheme"
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.EditInPlace, {
className: "mx_ThemeChoicePanel_CustomTheme_EditInPlace",
label: (0, _languageHandler._t)("settings|appearance|custom_theme_add"),
cancelButtonLabel: (0, _languageHandler._t)("action|cancel"),
saveButtonLabel: (0, _languageHandler._t)("settings|appearance|custom_theme_add"),
savingLabel: (0, _languageHandler._t)("settings|appearance|custom_theme_downloading"),
value: customTheme,
onChange: e => {
setError(undefined);
setCustomTheme(e.target.value);
},
onSave: async () => {
// The field empty is empty
if (!customTheme) return;
// Get the custom themes and do a cheap clone
// To avoid to mutate the original array in the settings
const currentThemes = _SettingsStore.default.getValue("custom_themes").map(t => t) || [];
try {
const r = await fetch(customTheme);
// XXX: need some schema for this
const themeInfo = await r.json();
if (!themeInfo || typeof themeInfo["name"] !== "string" || typeof themeInfo["colors"] !== "object") {
setError((0, _languageHandler._t)("settings|appearance|custom_theme_invalid"));
return;
}
// Check if the theme is already existing
const isAlreadyExisting = Boolean(currentThemes.find(t => t.name === themeInfo.name));
if (isAlreadyExisting) {
clear();
return;
}
currentThemes.push(themeInfo);
} catch (e) {
_logger.logger.error(e);
setError((0, _languageHandler._t)("settings|appearance|custom_theme_error_downloading"));
return;
}
// Reset the error
clear();
await _SettingsStore.default.setValue("custom_themes", null, _SettingLevel.SettingLevel.ACCOUNT, currentThemes);
},
onCancel: clear
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.HelpMessage, null, (0, _languageHandler._t)("settings|appearance|custom_theme_help")), error && /*#__PURE__*/_react.default.createElement(_compoundWeb.ErrorMessage, null, error)), /*#__PURE__*/_react.default.createElement(CustomThemeList, {
theme: theme
}));
}
/**
* List of the custom themes
*/
function CustomThemeList({
theme: currentTheme
}) {
const customThemes = (0, _useSettings.useSettingValue)("custom_themes") || [];
return /*#__PURE__*/_react.default.createElement("ul", {
className: "mx_ThemeChoicePanel_CustomThemeList"
}, customThemes.map(theme => {
return /*#__PURE__*/_react.default.createElement("li", {
key: theme.name,
className: "mx_ThemeChoicePanel_CustomThemeList_theme",
"aria-label": theme.name
}, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_ThemeChoicePanel_CustomThemeList_name"
}, theme.name), /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
destructive: true,
"aria-label": (0, _languageHandler._t)("action|delete"),
tooltip: (0, _languageHandler._t)("action|delete"),
onClick: async () => {
// Get the custom themes and do a cheap clone
// To avoid to mutate the original array in the settings
const currentThemes = _SettingsStore.default.getValue("custom_themes").map(t => t) || [];
// Remove the theme from the list
const newThemes = currentThemes.filter(t => t.name !== theme.name);
await _SettingsStore.default.setValue("custom_themes", null, _SettingLevel.SettingLevel.ACCOUNT, newThemes);
// If the delete custom theme is the current theme, reset the theme to the default theme
// By settings the theme at null at the device level, we are getting the default theme
if (currentTheme === `custom-${theme.name}`) {
await _SettingsStore.default.setValue("theme", null, _SettingLevel.SettingLevel.DEVICE, null);
_dispatcher.default.dispatch({
action: _actions.Action.RecheckTheme
});
}
}
}, /*#__PURE__*/_react.default.createElement(_delete.default, null)));
}));
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY29tcG91bmRXZWIiLCJfZGVsZXRlIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9jbGFzc25hbWVzIiwiX2xvZ2dlciIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfU2V0dGluZ3NTdWJzZWN0aW9uIiwiX1RoZW1lV2F0Y2hlciIsIl9TZXR0aW5nc1N0b3JlIiwiX1NldHRpbmdMZXZlbCIsIl9kaXNwYXRjaGVyIiwiX2FjdGlvbnMiLCJfdXNlVGhlbWUiLCJfdGhlbWUyIiwiX3VzZVNldHRpbmdzIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiVGhlbWVDaG9pY2VQYW5lbCIsInRoZW1lU3RhdGUiLCJ1c2VUaGVtZSIsInRoZW1lV2F0Y2hlciIsInVzZVJlZiIsIlRoZW1lV2F0Y2hlciIsImN1c3RvbVRoZW1lRW5hYmxlZCIsInVzZVNldHRpbmdWYWx1ZSIsImNyZWF0ZUVsZW1lbnQiLCJoZWFkaW5nIiwiX3QiLCJsZWdhY3kiLCJjdXJyZW50IiwiaXNTeXN0ZW1UaGVtZVN1cHBvcnRlZCIsIlN5c3RlbVRoZW1lIiwic3lzdGVtVGhlbWVBY3RpdmF0ZWQiLCJUaGVtZVNlbGVjdG9ycyIsInRoZW1lIiwiZGlzYWJsZWQiLCJDdXN0b21UaGVtZSIsIlJvb3QiLCJvbkNoYW5nZSIsImV2dCIsImNoZWNrZWQiLCJGb3JtRGF0YSIsImN1cnJlbnRUYXJnZXQiLCJTZXR0aW5nc1N0b3JlIiwic2V0VmFsdWUiLCJTZXR0aW5nTGV2ZWwiLCJERVZJQ0UiLCJkaXMiLCJkaXNwYXRjaCIsImFjdGlvbiIsIkFjdGlvbiIsIlJlY2hlY2tUaGVtZSIsIklubGluZUZpZWxkIiwibmFtZSIsImNvbnRyb2wiLCJUb2dnbGVDb250cm9sIiwiZGVmYXVsdENoZWNrZWQiLCJMYWJlbCIsImdldERpc3BsYXlOYW1lIiwidGhlbWVzIiwidXNlVGhlbWVzIiwiY2xhc3NOYW1lIiwibmV3VGhlbWUiLCJjYXRjaCIsImZvcmNlVGhlbWUiLCJtYXAiLCJfdGhlbWUiLCJpc0NoZWNrZWQiLCJpZCIsImNsYXNzTmFtZXMiLCJpc0RhcmsiLCJrZXkiLCJSYWRpb0NvbnRyb2wiLCJ2YWx1ZSIsImN1c3RvbVRoZW1lcyIsInVzZU1lbW8iLCJjaGVja2VkQ3VzdG9tVGhlbWVzIiwiY3VzdG9tVGhlbWVNYXAiLCJyZWR1Y2UiLCJNYXAiLCJnZXRPcmRlcmVkVGhlbWVzIiwiYnVpbHRJblRoZW1lcyIsIm90aGVyVGhlbWVzIiwiaGlnaENvbnRyYXN0VGhlbWUiLCJtYWtlSGlnaENvbnRyYXN0VGhlbWUiLCJhbGxUaGVtZXMiLCJjb25jYXQiLCJjdXN0b21UaGVtZSIsImlzX2RhcmsiLCJpbmNsdWRlcyIsImxpZ2h0SGlnaENvbnRyYXN0SWQiLCJmaW5kSGlnaENvbnRyYXN0VGhlbWUiLCJzZXRDdXN0b21UaGVtZSIsInVzZVN0YXRlIiwiZXJyb3IiLCJzZXRFcnJvciIsImNsZWFyIiwidXNlQ2FsbGJhY2siLCJ1bmRlZmluZWQiLCJFZGl0SW5QbGFjZSIsImxhYmVsIiwiY2FuY2VsQnV0dG9uTGFiZWwiLCJzYXZlQnV0dG9uTGFiZWwiLCJzYXZpbmdMYWJlbCIsInRhcmdldCIsIm9uU2F2ZSIsImN1cnJlbnRUaGVtZXMiLCJnZXRWYWx1ZSIsImZldGNoIiwidGhlbWVJbmZvIiwianNvbiIsImlzQWxyZWFkeUV4aXN0aW5nIiwiQm9vbGVhbiIsImZpbmQiLCJsb2dnZXIiLCJBQ0NPVU5UIiwib25DYW5jZWwiLCJIZWxwTWVzc2FnZSIsIkVycm9yTWVzc2FnZSIsIkN1c3RvbVRoZW1lTGlzdCIsImN1cnJlbnRUaGVtZSIsIkljb25CdXR0b24iLCJkZXN0cnVjdGl2ZSIsInRvb2x0aXAiLCJvbkNsaWNrIiwibmV3VGhlbWVzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvc2V0dGluZ3MvVGhlbWVDaG9pY2VQYW5lbC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuICogQ29weXJpZ2h0IDIwMjQgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcbiAqIFBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4gKi9cblxuaW1wb3J0IFJlYWN0LCB7IENoYW5nZUV2ZW50LCBKU1gsIHVzZUNhbGxiYWNrLCB1c2VNZW1vLCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQge1xuICAgIElubGluZUZpZWxkLFxuICAgIFRvZ2dsZUNvbnRyb2wsXG4gICAgTGFiZWwsXG4gICAgUm9vdCxcbiAgICBSYWRpb0NvbnRyb2wsXG4gICAgRWRpdEluUGxhY2UsXG4gICAgSWNvbkJ1dHRvbixcbiAgICBFcnJvck1lc3NhZ2UsXG4gICAgSGVscE1lc3NhZ2UsXG59IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuaW1wb3J0IERlbGV0ZUljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2RlbGV0ZVwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgU2V0dGluZ3NTdWJzZWN0aW9uIGZyb20gXCIuL3NoYXJlZC9TZXR0aW5nc1N1YnNlY3Rpb25cIjtcbmltcG9ydCBUaGVtZVdhdGNoZXIgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL3dhdGNoZXJzL1RoZW1lV2F0Y2hlclwiO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCB7IFNldHRpbmdMZXZlbCB9IGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nTGV2ZWxcIjtcbmltcG9ydCBkaXMgZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgUmVjaGVja1RoZW1lUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1JlY2hlY2tUaGVtZVBheWxvYWRcIjtcbmltcG9ydCB7IEFjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2FjdGlvbnNcIjtcbmltcG9ydCB7IHVzZVRoZW1lIH0gZnJvbSBcIi4uLy4uLy4uL2hvb2tzL3VzZVRoZW1lXCI7XG5pbXBvcnQgeyBmaW5kSGlnaENvbnRyYXN0VGhlbWUsIGdldE9yZGVyZWRUaGVtZXMsIEN1c3RvbVRoZW1lIGFzIEN1c3RvbVRoZW1lVHlwZSwgSVRoZW1lIH0gZnJvbSBcIi4uLy4uLy4uL3RoZW1lXCI7XG5pbXBvcnQgeyB1c2VTZXR0aW5nVmFsdWUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlU2V0dGluZ3NcIjtcblxuLyoqXG4gKiBQYW5lbCB0byBjaG9vc2UgdGhlIHRoZW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUaGVtZUNob2ljZVBhbmVsKCk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCB0aGVtZVN0YXRlID0gdXNlVGhlbWUoKTtcbiAgICBjb25zdCB0aGVtZVdhdGNoZXIgPSB1c2VSZWYobmV3IFRoZW1lV2F0Y2hlcigpKTtcbiAgICBjb25zdCBjdXN0b21UaGVtZUVuYWJsZWQgPSB1c2VTZXR0aW5nVmFsdWU8Ym9vbGVhbj4oXCJmZWF0dXJlX2N1c3RvbV90aGVtZXNcIik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8U2V0dGluZ3NTdWJzZWN0aW9uIGhlYWRpbmc9e190KFwiY29tbW9ufHRoZW1lXCIpfSBsZWdhY3k9e2ZhbHNlfSBkYXRhLXRlc3RpZD1cInRoZW1lUGFuZWxcIj5cbiAgICAgICAgICAgIHt0aGVtZVdhdGNoZXIuY3VycmVudC5pc1N5c3RlbVRoZW1lU3VwcG9ydGVkKCkgJiYgKFxuICAgICAgICAgICAgICAgIDxTeXN0ZW1UaGVtZSBzeXN0ZW1UaGVtZUFjdGl2YXRlZD17dGhlbWVTdGF0ZS5zeXN0ZW1UaGVtZUFjdGl2YXRlZH0gLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8VGhlbWVTZWxlY3RvcnMgdGhlbWU9e3RoZW1lU3RhdGUudGhlbWV9IGRpc2FibGVkPXt0aGVtZVN0YXRlLnN5c3RlbVRoZW1lQWN0aXZhdGVkfSAvPlxuICAgICAgICAgICAge2N1c3RvbVRoZW1lRW5hYmxlZCAmJiA8Q3VzdG9tVGhlbWUgdGhlbWU9e3RoZW1lU3RhdGUudGhlbWV9IC8+fVxuICAgICAgICA8L1NldHRpbmdzU3Vic2VjdGlvbj5cbiAgICApO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byB0b2dnbGUgdGhlIHN5c3RlbSB0aGVtZVxuICovXG5pbnRlcmZhY2UgU3lzdGVtVGhlbWVQcm9wcyB7XG4gICAgLyogV2hldGhlciB0aGUgc3lzdGVtIHRoZW1lIGlzIGFjdGl2YXRlZCAqL1xuICAgIHN5c3RlbVRoZW1lQWN0aXZhdGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byB0b2dnbGUgdGhlIHN5c3RlbSB0aGVtZVxuICovXG5mdW5jdGlvbiBTeXN0ZW1UaGVtZSh7IHN5c3RlbVRoZW1lQWN0aXZhdGVkIH06IFN5c3RlbVRoZW1lUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPFJvb3RcbiAgICAgICAgICAgIG9uQ2hhbmdlPXthc3luYyAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IG5ldyBGb3JtRGF0YShldnQuY3VycmVudFRhcmdldCkuZ2V0KFwic3lzdGVtVGhlbWVcIikgPT09IFwib25cIjtcbiAgICAgICAgICAgICAgICBhd2FpdCBTZXR0aW5nc1N0b3JlLnNldFZhbHVlKFwidXNlX3N5c3RlbV90aGVtZVwiLCBudWxsLCBTZXR0aW5nTGV2ZWwuREVWSUNFLCBjaGVja2VkKTtcbiAgICAgICAgICAgICAgICBkaXMuZGlzcGF0Y2g8UmVjaGVja1RoZW1lUGF5bG9hZD4oeyBhY3Rpb246IEFjdGlvbi5SZWNoZWNrVGhlbWUgfSk7XG4gICAgICAgICAgICB9fVxuICAgICAgICA+XG4gICAgICAgICAgICA8SW5saW5lRmllbGRcbiAgICAgICAgICAgICAgICBuYW1lPVwic3lzdGVtVGhlbWVcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2w9ezxUb2dnbGVDb250cm9sIG5hbWU9XCJzeXN0ZW1UaGVtZVwiIGRlZmF1bHRDaGVja2VkPXtzeXN0ZW1UaGVtZUFjdGl2YXRlZH0gLz59XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPExhYmVsPntTZXR0aW5nc1N0b3JlLmdldERpc3BsYXlOYW1lKFwidXNlX3N5c3RlbV90aGVtZVwiKX08L0xhYmVsPlxuICAgICAgICAgICAgPC9JbmxpbmVGaWVsZD5cbiAgICAgICAgPC9Sb290PlxuICAgICk7XG59XG5cbi8qKlxuICogQ29tcG9uZW50IHRvIHNlbGVjdCB0aGUgdGhlbWVcbiAqL1xuaW50ZXJmYWNlIFRoZW1lU2VsZWN0b3JQcm9wcyB7XG4gICAgLyogVGhlIGN1cnJlbnQgdGhlbWUgKi9cbiAgICB0aGVtZTogc3RyaW5nO1xuICAgIC8qIFRoZSB0aGVtZSBjYW4ndCBiZSBzZWxlY3RlZCAqL1xuICAgIGRpc2FibGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB0byBzZWxlY3QgdGhlIHRoZW1lXG4gKi9cbmZ1bmN0aW9uIFRoZW1lU2VsZWN0b3JzKHsgdGhlbWUsIGRpc2FibGVkIH06IFRoZW1lU2VsZWN0b3JQcm9wcyk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCB0aGVtZXMgPSB1c2VUaGVtZXMoKTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDxSb290XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9UaGVtZUNob2ljZVBhbmVsX1RoZW1lU2VsZWN0b3JzXCJcbiAgICAgICAgICAgIG9uQ2hhbmdlPXthc3luYyAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSBhbnkgZmlsZSBpbiB0aGUgZm9ybSwgd2UgY2FuIGNhc3QgaXQgYXMgc3RyaW5nIHNhZmVseVxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1RoZW1lID0gbmV3IEZvcm1EYXRhKGV2dC5jdXJyZW50VGFyZ2V0KS5nZXQoXCJ0aGVtZVNlbGVjdG9yXCIpIGFzIHN0cmluZyB8IG51bGw7XG5cbiAgICAgICAgICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHRoZSBzYW1lIHRoZW1lIGlzIHNlbGVjdGVkXG4gICAgICAgICAgICAgICAgaWYgKCFuZXdUaGVtZSB8fCB0aGVtZSA9PT0gbmV3VGhlbWUpIHJldHVybjtcblxuICAgICAgICAgICAgICAgIC8vIGRvaW5nIGdldFZhbHVlIGluIHRoZSAuY2F0Y2ggd2lsbCBzdGlsbCByZXR1cm4gdGhlIHZhbHVlIHdlIGZhaWxlZCB0byBzZXQsXG4gICAgICAgICAgICAgICAgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInRoZW1lXCIsIG51bGwsIFNldHRpbmdMZXZlbC5ERVZJQ0UsIG5ld1RoZW1lKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRpcy5kaXNwYXRjaDxSZWNoZWNrVGhlbWVQYXlsb2FkPih7IGFjdGlvbjogQWN0aW9uLlJlY2hlY2tUaGVtZSB9KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFRoZSBzZXR0aW5ncyB3YXRjaGVyIGRvZXNuJ3QgZmlyZSB1bnRpbCB0aGUgZWNobyBjb21lcyBiYWNrIGZyb20gdGhlXG4gICAgICAgICAgICAgICAgLy8gc2VydmVyLCBzbyB0byBtYWtlIHRoZSB0aGVtZSBjaGFuZ2UgaW1tZWRpYXRlbHkgd2UgbmVlZCB0byBtYW51YWxseVxuICAgICAgICAgICAgICAgIC8vIGRvIHRoZSBkaXNwYXRjaCBub3dcbiAgICAgICAgICAgICAgICAvLyBYWFg6IFRoZSBsb2NhbCBlY2hvZWQgdmFsdWUgYXBwZWFycyB0byBiZSB1bnJlbGlhYmxlLCBpbiBwYXJ0aWN1bGFyXG4gICAgICAgICAgICAgICAgLy8gd2hlbiBzZXR0aW5ncyBjdXN0b20gdGhlbWVzKCEpIHNvIGFkZGluZyBmb3JjZVRoZW1lIHRvIG92ZXJyaWRlXG4gICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGZyb20gc2V0dGluZ3MuXG4gICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoPFJlY2hlY2tUaGVtZVBheWxvYWQ+KHsgYWN0aW9uOiBBY3Rpb24uUmVjaGVja1RoZW1lLCBmb3JjZVRoZW1lOiBuZXdUaGVtZSB9KTtcbiAgICAgICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICAgIHt0aGVtZXMubWFwKChfdGhlbWUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0NoZWNrZWQgPSB0aGVtZSA9PT0gX3RoZW1lLmlkO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxJbmxpbmVGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYG14X1RoZW1lQ2hvaWNlUGFuZWxfdGhlbWVTZWxlY3Rvcl9lbmFibGVkYF06ICFkaXNhYmxlZCAmJiB0aGVtZSA9PT0gX3RoZW1lLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtgbXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yX2Rpc2FibGVkYF06IGRpc2FibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZm9yY2UgdGhlIGNvbXBvdW5kIHRoZW1lIHRvIGJlIGxpZ2h0IG9yIGRhcmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgdGhlbWUgc2VsZWN0aW9uIGRvZXNuJ3QgZGVwZW5kIG9uIHRoZSBjdXJyZW50IHRoZW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGV4YW1wbGUgd2hlbiB0aGUgbGlnaHQgdGhlbWUgaXMgdXNlZCwgdGhlIGRhcmsgdGhlbWUgc2VsZWN0b3Igc2hvdWxkIGJlIGRhcmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNwZC10aGVtZS1saWdodFwiOiAhX3RoZW1lLmlzRGFyayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNwZC10aGVtZS1kYXJrXCI6IF90aGVtZS5pc0RhcmssXG4gICAgICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0aGVtZVNlbGVjdG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleT17X3RoZW1lLmlkfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbD17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFJhZGlvQ29udHJvbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidGhlbWVTZWxlY3RvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ9eyFkaXNhYmxlZCAmJiBpc0NoZWNrZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXtkaXNhYmxlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e190aGVtZS5pZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8TGFiZWwgY2xhc3NOYW1lPVwibXhfVGhlbWVDaG9pY2VQYW5lbF90aGVtZVNlbGVjdG9yX0xhYmVsXCI+e190aGVtZS5uYW1lfTwvTGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvSW5saW5lRmllbGQ+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pfVxuICAgICAgICA8L1Jvb3Q+XG4gICAgKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYWxsIHRoZSBhdmFpbGFibGUgdGhlbWVzXG4gKi9cbmZ1bmN0aW9uIHVzZVRoZW1lcygpOiBBcnJheTxJVGhlbWUgJiB7IGlzRGFyazogYm9vbGVhbiB9PiB7XG4gICAgY29uc3QgY3VzdG9tVGhlbWVzID0gdXNlU2V0dGluZ1ZhbHVlPEN1c3RvbVRoZW1lVHlwZVtdIHwgdW5kZWZpbmVkPihcImN1c3RvbV90aGVtZXNcIik7XG4gICAgcmV0dXJuIHVzZU1lbW8oKCkgPT4ge1xuICAgICAgICAvLyBQdXQgdGhlIGN1c3RvbSB0aGVtZSBpbnRvIGEgbWFwXG4gICAgICAgIC8vIFRvIGVhc2lseSBmaW5kIHRoZSB0aGVtZSBieSBuYW1lIHdoZW4gZ29pbmcgdGhyb3VnaCB0aGUgdGhlbWVzIGxpc3RcbiAgICAgICAgY29uc3QgY2hlY2tlZEN1c3RvbVRoZW1lcyA9IGN1c3RvbVRoZW1lcyB8fCBbXTtcbiAgICAgICAgY29uc3QgY3VzdG9tVGhlbWVNYXAgPSBjaGVja2VkQ3VzdG9tVGhlbWVzLnJlZHVjZShcbiAgICAgICAgICAgIChtYXAsIHRoZW1lKSA9PiBtYXAuc2V0KHRoZW1lLm5hbWUsIHRoZW1lKSxcbiAgICAgICAgICAgIG5ldyBNYXA8c3RyaW5nLCBDdXN0b21UaGVtZVR5cGU+KCksXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdGhlbWVzID0gZ2V0T3JkZXJlZFRoZW1lcygpO1xuICAgICAgICAvLyBTZXBhcmF0ZSB0aGUgYnVpbHQtaW4gdGhlbWVzIGZyb20gdGhlIGN1c3RvbSB0aGVtZXNcbiAgICAgICAgLy8gVG8gaW5zZXJ0IHRoZSBoaWdoIGNvbnRyYXN0IHRoZW1lIGJldHdlZW4gdGhlbVxuICAgICAgICBjb25zdCBidWlsdEluVGhlbWVzID0gdGhlbWVzLmZpbHRlcigodGhlbWUpID0+ICFjdXN0b21UaGVtZU1hcC5oYXModGhlbWUubmFtZSkpO1xuICAgICAgICBjb25zdCBvdGhlclRoZW1lcyA9IHRoZW1lcy5maWx0ZXIoKHRoZW1lKSA9PiBjdXN0b21UaGVtZU1hcC5oYXModGhlbWUubmFtZSkpO1xuXG4gICAgICAgIGNvbnN0IGhpZ2hDb250cmFzdFRoZW1lID0gbWFrZUhpZ2hDb250cmFzdFRoZW1lKCk7XG4gICAgICAgIGlmIChoaWdoQ29udHJhc3RUaGVtZSkgYnVpbHRJblRoZW1lcy5wdXNoKGhpZ2hDb250cmFzdFRoZW1lKTtcblxuICAgICAgICBjb25zdCBhbGxUaGVtZXMgPSBidWlsdEluVGhlbWVzLmNvbmNhdChvdGhlclRoZW1lcyk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHRoZW1lcyBhcmUgZGFya1xuICAgICAgICByZXR1cm4gYWxsVGhlbWVzLm1hcCgodGhlbWUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbVRoZW1lID0gY3VzdG9tVGhlbWVNYXAuZ2V0KHRoZW1lLm5hbWUpO1xuICAgICAgICAgICAgY29uc3QgaXNEYXJrID0gKGN1c3RvbVRoZW1lID8gY3VzdG9tVGhlbWUuaXNfZGFyayA6IHRoZW1lLmlkLmluY2x1ZGVzKFwiZGFya1wiKSkgfHwgZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4geyAuLi50aGVtZSwgaXNEYXJrIH07XG4gICAgICAgIH0pO1xuICAgIH0sIFtjdXN0b21UaGVtZXNdKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgdGhlIGxpZ2h0IGhpZ2ggY29udHJhc3QgdGhlbWVcbiAqL1xuZnVuY3Rpb24gbWFrZUhpZ2hDb250cmFzdFRoZW1lKCk6IElUaGVtZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbGlnaHRIaWdoQ29udHJhc3RJZCA9IGZpbmRIaWdoQ29udHJhc3RUaGVtZShcImxpZ2h0XCIpO1xuICAgIGlmIChsaWdodEhpZ2hDb250cmFzdElkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lOiBfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8aGlnaF9jb250cmFzdFwiKSxcbiAgICAgICAgICAgIGlkOiBsaWdodEhpZ2hDb250cmFzdElkLFxuICAgICAgICB9O1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIEN1c3RvbVRoZW1lUHJvcHMge1xuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRoZW1lXG4gICAgICovXG4gICAgdGhlbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBZGQgYW5kIG1hbmFnZXIgY3VzdG9tIHRoZW1lc1xuICovXG5mdW5jdGlvbiBDdXN0b21UaGVtZSh7IHRoZW1lIH06IEN1c3RvbVRoZW1lUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgY29uc3QgW2N1c3RvbVRoZW1lLCBzZXRDdXN0b21UaGVtZV0gPSB1c2VTdGF0ZTxzdHJpbmc+KFwiXCIpO1xuICAgIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNsZWFyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICBzZXRFcnJvcih1bmRlZmluZWQpO1xuICAgICAgICBzZXRDdXN0b21UaGVtZShcIlwiKTtcbiAgICB9LCBbc2V0RXJyb3IsIHNldEN1c3RvbVRoZW1lXSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVcIj5cbiAgICAgICAgICAgIDxFZGl0SW5QbGFjZVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVfRWRpdEluUGxhY2VcIlxuICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2FkZFwiKX1cbiAgICAgICAgICAgICAgICBjYW5jZWxCdXR0b25MYWJlbD17X3QoXCJhY3Rpb258Y2FuY2VsXCIpfVxuICAgICAgICAgICAgICAgIHNhdmVCdXR0b25MYWJlbD17X3QoXCJzZXR0aW5nc3xhcHBlYXJhbmNlfGN1c3RvbV90aGVtZV9hZGRcIil9XG4gICAgICAgICAgICAgICAgc2F2aW5nTGFiZWw9e190KFwic2V0dGluZ3N8YXBwZWFyYW5jZXxjdXN0b21fdGhlbWVfZG93bmxvYWRpbmdcIil9XG4gICAgICAgICAgICAgICAgdmFsdWU9e2N1c3RvbVRoZW1lfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoZTogQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0Q3VzdG9tVGhlbWUoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgb25TYXZlPXthc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmaWVsZCBlbXB0eSBpcyBlbXB0eVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN1c3RvbVRoZW1lKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXN0b20gdGhlbWVzIGFuZCBkbyBhIGNoZWFwIGNsb25lXG4gICAgICAgICAgICAgICAgICAgIC8vIFRvIGF2b2lkIHRvIG11dGF0ZSB0aGUgb3JpZ2luYWwgYXJyYXkgaW4gdGhlIHNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaGVtZXMgPVxuICAgICAgICAgICAgICAgICAgICAgICAgU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZTxDdXN0b21UaGVtZVR5cGVbXT4oXCJjdXN0b21fdGhlbWVzXCIpLm1hcCgodCkgPT4gdCkgfHwgW107XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBmZXRjaChjdXN0b21UaGVtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBYWFg6IG5lZWQgc29tZSBzY2hlbWEgZm9yIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRoZW1lSW5mbyA9IGF3YWl0IHIuanNvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICF0aGVtZUluZm8gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdGhlbWVJbmZvW1wibmFtZVwiXSAhPT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGVtZUluZm9bXCJjb2xvcnNcIl0gIT09IFwib2JqZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEVycm9yKF90KFwic2V0dGluZ3N8YXBwZWFyYW5jZXxjdXN0b21fdGhlbWVfaW52YWxpZFwiKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgdGhlbWUgaXMgYWxyZWFkeSBleGlzdGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNBbHJlYWR5RXhpc3RpbmcgPSBCb29sZWFuKGN1cnJlbnRUaGVtZXMuZmluZCgodCkgPT4gdC5uYW1lID09PSB0aGVtZUluZm8ubmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWxyZWFkeUV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUaGVtZXMucHVzaCh0aGVtZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRFcnJvcihfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2Vycm9yX2Rvd25sb2FkaW5nXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBlcnJvclxuICAgICAgICAgICAgICAgICAgICBjbGVhcigpO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBTZXR0aW5nc1N0b3JlLnNldFZhbHVlKFwiY3VzdG9tX3RoZW1lc1wiLCBudWxsLCBTZXR0aW5nTGV2ZWwuQUNDT1VOVCwgY3VycmVudFRoZW1lcyk7XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICBvbkNhbmNlbD17Y2xlYXJ9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPEhlbHBNZXNzYWdlPntfdChcInNldHRpbmdzfGFwcGVhcmFuY2V8Y3VzdG9tX3RoZW1lX2hlbHBcIil9PC9IZWxwTWVzc2FnZT5cbiAgICAgICAgICAgICAgICB7ZXJyb3IgJiYgPEVycm9yTWVzc2FnZT57ZXJyb3J9PC9FcnJvck1lc3NhZ2U+fVxuICAgICAgICAgICAgPC9FZGl0SW5QbGFjZT5cbiAgICAgICAgICAgIDxDdXN0b21UaGVtZUxpc3QgdGhlbWU9e3RoZW1lfSAvPlxuICAgICAgICA8L2Rpdj5cbiAgICApO1xufVxuXG5pbnRlcmZhY2UgQ3VzdG9tVGhlbWVMaXN0UHJvcHMge1xuICAgIC8qXG4gICAgICogVGhlIGN1cnJlbnQgdGhlbWVcbiAgICAgKi9cbiAgICB0aGVtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIExpc3Qgb2YgdGhlIGN1c3RvbSB0aGVtZXNcbiAqL1xuZnVuY3Rpb24gQ3VzdG9tVGhlbWVMaXN0KHsgdGhlbWU6IGN1cnJlbnRUaGVtZSB9OiBDdXN0b21UaGVtZUxpc3RQcm9wcyk6IEpTWC5FbGVtZW50IHtcbiAgICBjb25zdCBjdXN0b21UaGVtZXMgPSB1c2VTZXR0aW5nVmFsdWU8Q3VzdG9tVGhlbWVUeXBlW10+KFwiY3VzdG9tX3RoZW1lc1wiKSB8fCBbXTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDx1bCBjbGFzc05hbWU9XCJteF9UaGVtZUNob2ljZVBhbmVsX0N1c3RvbVRoZW1lTGlzdFwiPlxuICAgICAgICAgICAge2N1c3RvbVRoZW1lcy5tYXAoKHRoZW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGxpIGtleT17dGhlbWUubmFtZX0gY2xhc3NOYW1lPVwibXhfVGhlbWVDaG9pY2VQYW5lbF9DdXN0b21UaGVtZUxpc3RfdGhlbWVcIiBhcmlhLWxhYmVsPXt0aGVtZS5uYW1lfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1RoZW1lQ2hvaWNlUGFuZWxfQ3VzdG9tVGhlbWVMaXN0X25hbWVcIj57dGhlbWUubmFtZX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RydWN0aXZlPXt0cnVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiYWN0aW9ufGRlbGV0ZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwPXtfdChcImFjdGlvbnxkZWxldGVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGN1c3RvbSB0aGVtZXMgYW5kIGRvIGEgY2hlYXAgY2xvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVG8gYXZvaWQgdG8gbXV0YXRlIHRoZSBvcmlnaW5hbCBhcnJheSBpbiB0aGUgc2V0dGluZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRoZW1lcyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXR0aW5nc1N0b3JlLmdldFZhbHVlPEN1c3RvbVRoZW1lVHlwZVtdPihcImN1c3RvbV90aGVtZXNcIikubWFwKCh0KSA9PiB0KSB8fCBbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHRoZW1lIGZyb20gdGhlIGxpc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGhlbWVzID0gY3VycmVudFRoZW1lcy5maWx0ZXIoKHQpID0+IHQubmFtZSAhPT0gdGhlbWUubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IFNldHRpbmdzU3RvcmUuc2V0VmFsdWUoXCJjdXN0b21fdGhlbWVzXCIsIG51bGwsIFNldHRpbmdMZXZlbC5BQ0NPVU5ULCBuZXdUaGVtZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBkZWxldGUgY3VzdG9tIHRoZW1lIGlzIHRoZSBjdXJyZW50IHRoZW1lLCByZXNldCB0aGUgdGhlbWUgdG8gdGhlIGRlZmF1bHQgdGhlbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnkgc2V0dGluZ3MgdGhlIHRoZW1lIGF0IG51bGwgYXQgdGhlIGRldmljZSBsZXZlbCwgd2UgYXJlIGdldHRpbmcgdGhlIGRlZmF1bHQgdGhlbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUaGVtZSA9PT0gYGN1c3RvbS0ke3RoZW1lLm5hbWV9YCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgU2V0dGluZ3NTdG9yZS5zZXRWYWx1ZShcInRoZW1lXCIsIG51bGwsIFNldHRpbmdMZXZlbC5ERVZJQ0UsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoPFJlY2hlY2tUaGVtZVBheWxvYWQ+KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IEFjdGlvbi5SZWNoZWNrVGhlbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPERlbGV0ZUljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSl9XG4gICAgICAgIDwvdWw+XG4gICAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFXQSxJQUFBRSxPQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFELHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSyxPQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxnQkFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sbUJBQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLGFBQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFTLGNBQUEsR0FBQU4sc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFVLGFBQUEsR0FBQVYsT0FBQTtBQUNBLElBQUFXLFdBQUEsR0FBQVIsc0JBQUEsQ0FBQUgsT0FBQTtBQUVBLElBQUFZLFFBQUEsR0FBQVosT0FBQTtBQUNBLElBQUFhLFNBQUEsR0FBQWIsT0FBQTtBQUNBLElBQUFjLE9BQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLFlBQUEsR0FBQWYsT0FBQTtBQUE2RCxTQUFBZ0IseUJBQUFDLENBQUEsNkJBQUFDLE9BQUEsbUJBQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUYsd0JBQUEsWUFBQUEsQ0FBQUMsQ0FBQSxXQUFBQSxDQUFBLEdBQUFHLENBQUEsR0FBQUQsQ0FBQSxLQUFBRixDQUFBO0FBQUEsU0FBQWxCLHdCQUFBa0IsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUws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