UNPKG

flipper-plugin-react-native-mmkv-storage

Version:

Developer tools for React Native MMKV Storage

494 lines (488 loc) 47.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b ||= {}) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.tsx var src_exports = {}; __export(src_exports, { Component: () => Component, plugin: () => plugin }); module.exports = __toCommonJS(src_exports); var import_icons = require("@ant-design/icons"); var import_antd2 = require("antd"); var import_flipper_plugin3 = require("flipper-plugin"); var import_react2 = __toESM(require("react")); // src/styles.ts var import_flipper_plugin = require("flipper-plugin"); var styles = { error: { color: import_flipper_plugin.theme.errorColor }, errorBold: { color: import_flipper_plugin.theme.errorColor, fontWeight: "bold" }, errorBG: { backgroundColor: import_flipper_plugin.theme.errorColor }, whiteText: { color: "white" }, yellowText: { color: "yellow" } }; var styles_default = styles; // src/helpers.ts function isNumeric(str) { if (typeof str !== "string") return false; return !isNaN(str) && !isNaN(parseFloat(str)); } function getRowStyle(row) { return row.mode === "DELETE" ? styles_default.error : void 0; } var BOOLEAN_OPTIONS = [ { label: "true", value: true }, { label: "false", value: false } ]; var SIDEBAR_COLUMNS = [ { key: "key", width: 100, title: "Title" }, { key: "value", title: "Value", wrap: true } ]; var MAIN_COLUMNS = [ { key: "time", title: "Time", formatters: (value) => { const d = new Date(value); return d.toLocaleString(); } }, { key: "instanceID", title: "Instance ID", width: 120 }, { key: "mode", title: "Mode", width: 80 }, { key: "key", title: "Key", width: 120 }, { key: "type", title: "Type", width: 80 }, { key: "value", title: "Value" }, { key: "empty", title: "", visible: false } ]; var BODY_OPTIONS = ["formatted", "parsed"].map((value) => ({ label: value, value })); // src/norecord.tsx var import_antd = require("antd"); var import_flipper_plugin2 = require("flipper-plugin"); var import_react = __toESM(require("react")); var NoRecord = /* @__PURE__ */ import_react.default.createElement(import_flipper_plugin2.Layout.Container, { center: true, grow: true, pad: true }, /* @__PURE__ */ import_react.default.createElement(import_antd.Typography.Text, { type: "secondary" }, "No record selected")); // src/index.tsx var LOCALSTORAGE_OBJECT_FORMAT_KEY = "MMKV_OBJECT_FORMAT"; function plugin(client) { const data = (0, import_flipper_plugin3.createDataSource)([], { key: "dkey" }); const supportStatus = (0, import_flipper_plugin3.createState)(null); const selectedDataID = (0, import_flipper_plugin3.createState)(null); const showEditDialog = (0, import_flipper_plugin3.createState)(false); const detailBodyFormat = (0, import_flipper_plugin3.createState)( localStorage.getItem(LOCALSTORAGE_OBJECT_FORMAT_KEY) || "parsed" ); client.onConnect(() => { console.log("connected"); }); client.onMessage("newData", (newData) => { data.append(__spreadProps(__spreadValues({}, newData), { dkey: newData.instanceID + newData.key + newData.time })); }); client.onMessage("supportStatus", (status) => { if (status.reason) { supportStatus.set(status.reason); } else { supportStatus.set(null); } }); client.addMenuEntry({ action: "clear", handler: () => { data.clear(); } }); function clearLogs() { data.clear(); } function onSelect(d) { selectedDataID.set(d); } function openEditDialog() { showEditDialog.set(true); } function closeEditDialog() { showEditDialog.set(false); } function onEditValue(newValue) { const id = selectedDataID.get(); if (id) { const d = data.getById(id); if (d) { void client.send("editValue", { data: d, newValue }); showEditDialog.set(false); selectedDataID.set(null); } } } function onDelete() { const id = selectedDataID.get(); if (id) { const d = data.getById(id); if (d) { void client.send("deleteItem", { data: d }); showEditDialog.set(false); selectedDataID.set(null); } } } function onSelectFormat(bodyFormat) { detailBodyFormat.set(bodyFormat); localStorage.setItem(LOCALSTORAGE_OBJECT_FORMAT_KEY, bodyFormat); } return { data, supportStatus, selectedDataID, showEditDialog, detailBodyFormat, onEditValue, onDelete, onSelect, onSelectFormat, openEditDialog, closeEditDialog, clearLogs }; } function Component() { const instance = (0, import_flipper_plugin3.usePlugin)(plugin); const supportStatus = (0, import_flipper_plugin3.useValue)(instance.supportStatus); const extraActions = /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Layout.Horizontal, { gap: true }, /* @__PURE__ */ import_react2.default.createElement(import_antd2.Button, { title: "Clear logs", onClick: instance.clearLogs }, "Clear logs")); const onSelect = (record) => { if (record) { instance.onSelect(record.dkey); } else { instance.onSelect(null); } }; return /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Layout.Container, { grow: true }, !!supportStatus && /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Layout.Container, { pad: true, style: styles_default.errorBG }, /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, { style: styles_default.whiteText }, supportStatus)), /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.DataTable, { enableAutoScroll: true, columns: MAIN_COLUMNS, dataSource: instance.data, enableHorizontalScroll: false, extraActions, onRowStyle: getRowStyle, onSelect }), /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.DetailSidebar, null, /* @__PURE__ */ import_react2.default.createElement(Sidebar, null)), /* @__PURE__ */ import_react2.default.createElement(EditModal, null)); } function EditModal() { const instance = (0, import_flipper_plugin3.usePlugin)(plugin); const showEditDialog = (0, import_flipper_plugin3.useValue)(instance.showEditDialog); const selectedDataID = (0, import_flipper_plugin3.useValue)(instance.selectedDataID); const [selectedData, setSelectedData] = (0, import_react2.useState)(null); const [newBoolValue, setNewBoolValue] = (0, import_react2.useState)(true); const [newStringValue, setNewStringValue] = (0, import_react2.useState)(""); const [errorText, setErrorText] = (0, import_react2.useState)(""); (0, import_react2.useEffect)(() => { if (selectedDataID) { const d = instance.data.getById(selectedDataID); if (d) { setNewValue(d); setSelectedData(d); } else { setSelectedData(null); } } else { setSelectedData(null); } }, [selectedDataID]); function setNewValue(d) { switch (typeof d.value) { case "boolean": setNewBoolValue(d.value); break; case "string": case "number": setNewStringValue(`${d.value}`); break; case "object": setNewStringValue(JSON.stringify(d.value, null, 2)); break; default: break; } } function onOK() { if (selectedData) { switch (selectedData.type) { case "boolean": instance.onEditValue(newBoolValue); break; case "string": instance.onEditValue(newStringValue); break; case "number": if (isNumeric(newStringValue)) { instance.onEditValue(parseFloat(newStringValue)); } else { setErrorText("Your input is not number!"); } break; case "array": { try { const arr = JSON.parse(newStringValue); if (Array.isArray(arr)) { instance.onEditValue(arr); } else { setErrorText("Syntax error: this isn't an array!"); } } catch (error) { if (error instanceof Error) { setErrorText("Syntax error: " + error.message); } else { setErrorText("Syntax error"); } } } break; case "object": { try { const obj = JSON.parse(newStringValue); if (typeof obj === "object" && !Array.isArray(obj)) { instance.onEditValue(obj); } else { setErrorText("Syntax error: this isn't an object!"); } } catch (error) { if (error instanceof Error) { setErrorText("Syntax error: " + error.message); } else { setErrorText("Syntax error"); } } } break; default: break; } } } function onCancel() { instance.closeEditDialog(); setErrorText(""); if (selectedData) { setNewValue(selectedData); } } const onChangeNumber = (e) => { if (isNumeric(e.target.value)) { setErrorText(""); setNewStringValue(e.target.value); } }; const onChangeString = (e) => { setErrorText(""); setNewStringValue(e.target.value); }; return /* @__PURE__ */ import_react2.default.createElement(import_antd2.Modal, { title: "Edit value", visible: showEditDialog, onCancel, onOk: onOK }, /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, null, "Instance ID: ", selectedData == null ? void 0 : selectedData.instanceID), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, null, "Key: ", selectedData == null ? void 0 : selectedData.key), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, null, "Type: ", selectedData == null ? void 0 : selectedData.type), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, { style: styles_default.yellowText }, "Make sure you enter correct type of value!"), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement("br", null), (selectedData == null ? void 0 : selectedData.type) === "boolean" && /* @__PURE__ */ import_react2.default.createElement(import_antd2.Select, { options: BOOLEAN_OPTIONS, value: newBoolValue, onChange: (v) => { setNewBoolValue(v); } }), (selectedData == null ? void 0 : selectedData.type) === "number" && /* @__PURE__ */ import_react2.default.createElement(import_antd2.Input, { value: newStringValue, onChange: onChangeNumber }), ((selectedData == null ? void 0 : selectedData.type) === "string" || (selectedData == null ? void 0 : selectedData.type) === "array" || (selectedData == null ? void 0 : selectedData.type) === "object") && /* @__PURE__ */ import_react2.default.createElement(import_antd2.Input.TextArea, { autoSize: { minRows: 2, maxRows: 6 }, style: selectedData.type !== "string" ? import_flipper_plugin3.theme.monospace : void 0, value: newStringValue, onChange: onChangeString }), !!errorText && /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, { style: styles_default.errorBold }, errorText), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement("br", null), /* @__PURE__ */ import_react2.default.createElement(import_antd2.Button, { danger: true, onClick: instance.onDelete }, "Delete item")); } function Sidebar() { const instance = (0, import_flipper_plugin3.usePlugin)(plugin); const selectedDataID = (0, import_flipper_plugin3.useValue)(instance.selectedDataID); const detailBodyFormat = (0, import_flipper_plugin3.useValue)(instance.detailBodyFormat); if (!selectedDataID) { return NoRecord; } const selectedData = instance.data.getById(selectedDataID); const formattedText = (selectedData == null ? void 0 : selectedData.type) === "object" && detailBodyFormat === "parsed"; if (!selectedData) { return NoRecord; } const records = selectedData.mode === "DELETE" ? [ { key: "Instance ID", value: selectedData.instanceID }, { key: "Mode", value: selectedData.mode }, { key: "Key", value: selectedData.key } ] : [ { key: "Instance ID", value: selectedData.instanceID }, { key: "Mode", value: selectedData.mode }, { key: "Key", value: selectedData.key }, { key: "Type", value: selectedData.type } ]; function parsedValue() { const v = selectedData == null ? void 0 : selectedData.value; const t = selectedData == null ? void 0 : selectedData.type; if (v === null) { return "null"; } if (v === void 0) { return "undefined"; } switch (t) { case "array": case "object": return JSON.stringify(v, null, 2); case "boolean": if (v) { return "true"; } return "false"; case "number": return `${v}`; case "string": return v; default: return ""; } } return /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Layout.Container, { grow: true }, /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.DataTable, { columns: SIDEBAR_COLUMNS, enableHorizontalScroll: false, enableSearchbar: false, records, scrollable: false }), selectedData.mode !== "DELETE" && /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Panel, { pad: true, collapsible: false, extraActions: /* @__PURE__ */ import_react2.default.createElement(import_icons.EditOutlined, { title: "Edit this value", onClick: instance.openEditDialog }), title: "Value" }, formattedText ? /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.DataInspector, { collapsed: true, expandRoot: true, data: selectedData.value }) : /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.CodeBlock, null, parsedValue())), selectedData.type === "object" && /* @__PURE__ */ import_react2.default.createElement(import_flipper_plugin3.Panel, { key: "options", collapsed: true, pad: true, title: "Options" }, /* @__PURE__ */ import_react2.default.createElement(import_antd2.Typography.Text, null, "Object formatting:"), /* @__PURE__ */ import_react2.default.createElement(import_antd2.Select, { options: BODY_OPTIONS, value: detailBodyFormat, onChange: instance.onSelectFormat }))); } //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzeCIsICIuLi9zcmMvc3R5bGVzLnRzIiwgIi4uL3NyYy9oZWxwZXJzLnRzIiwgIi4uL3NyYy9ub3JlY29yZC50c3giXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7RWRpdE91dGxpbmVkfSBmcm9tICdAYW50LWRlc2lnbi9pY29ucyc7XG5pbXBvcnQge0J1dHRvbiwgSW5wdXQsIE1vZGFsLCBTZWxlY3QsIFR5cG9ncmFwaHl9IGZyb20gJ2FudGQnO1xuaW1wb3J0IHtcbiAgQ29kZUJsb2NrLFxuICBEYXRhSW5zcGVjdG9yLFxuICBEYXRhVGFibGUsXG4gIERldGFpbFNpZGViYXIsXG4gIExheW91dCxcbiAgUGFuZWwsXG4gIGNyZWF0ZURhdGFTb3VyY2UsXG4gIGNyZWF0ZVN0YXRlLFxuICB0aGVtZSxcbiAgdXNlUGx1Z2luLFxuICB1c2VWYWx1ZSxcbn0gZnJvbSAnZmxpcHBlci1wbHVnaW4nO1xuaW1wb3J0IFJlYWN0LCB7dXNlRWZmZWN0LCB1c2VTdGF0ZX0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHtcbiAgQk9EWV9PUFRJT05TLFxuICBCT09MRUFOX09QVElPTlMsXG4gIE1BSU5fQ09MVU1OUyxcbiAgU0lERUJBUl9DT0xVTU5TLFxuICBnZXRSb3dTdHlsZSxcbiAgaXNOdW1lcmljLFxufSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHtOb1JlY29yZH0gZnJvbSAnLi9ub3JlY29yZCc7XG5pbXBvcnQgc3R5bGVzIGZyb20gJy4vc3R5bGVzJztcbmltcG9ydCB0eXBlIHtQbHVnaW5DbGllbnR9IGZyb20gJ2ZsaXBwZXItcGx1Z2luJztcblxuY29uc3QgTE9DQUxTVE9SQUdFX09CSkVDVF9GT1JNQVRfS0VZID0gJ01NS1ZfT0JKRUNUX0ZPUk1BVCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwbHVnaW4oY2xpZW50OiBQbHVnaW5DbGllbnQ8RXZlbnRzLCBNZXRob2RzPikge1xuICBjb25zdCBkYXRhID0gY3JlYXRlRGF0YVNvdXJjZTxEYXRhLCAnZGtleSc+KFtdLCB7a2V5OiAnZGtleSd9KTtcbiAgY29uc3Qgc3VwcG9ydFN0YXR1cyA9IGNyZWF0ZVN0YXRlPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBjb25zdCBzZWxlY3RlZERhdGFJRCA9IGNyZWF0ZVN0YXRlPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBjb25zdCBzaG93RWRpdERpYWxvZyA9IGNyZWF0ZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgZGV0YWlsQm9keUZvcm1hdCA9IGNyZWF0ZVN0YXRlPHN0cmluZz4oXG4gICAgbG9jYWxTdG9yYWdlLmdldEl0ZW0oTE9DQUxTVE9SQUdFX09CSkVDVF9GT1JNQVRfS0VZKSB8fCAncGFyc2VkJyxcbiAgKTtcblxuICBjbGllbnQub25Db25uZWN0KCgpID0+IHtcbiAgICBjb25zb2xlLmxvZygnY29ubmVjdGVkJyk7XG4gIH0pO1xuXG4gIGNsaWVudC5vbk1lc3NhZ2UoJ25ld0RhdGEnLCBuZXdEYXRhID0+IHtcbiAgICBkYXRhLmFwcGVuZCh7XG4gICAgICAuLi5uZXdEYXRhLFxuICAgICAgZGtleTogbmV3RGF0YS5pbnN0YW5jZUlEICsgbmV3RGF0YS5rZXkgKyBuZXdEYXRhLnRpbWUsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGNsaWVudC5vbk1lc3NhZ2UoJ3N1cHBvcnRTdGF0dXMnLCBzdGF0dXMgPT4ge1xuICAgIGlmIChzdGF0dXMucmVhc29uKSB7XG4gICAgICBzdXBwb3J0U3RhdHVzLnNldChzdGF0dXMucmVhc29uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3VwcG9ydFN0YXR1cy5zZXQobnVsbCk7XG4gICAgfVxuICB9KTtcblxuICBjbGllbnQuYWRkTWVudUVudHJ5KHtcbiAgICBhY3Rpb246ICdjbGVhcicsXG4gICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgZGF0YS5jbGVhcigpO1xuICAgIH0sXG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGNsZWFyTG9ncygpIHtcbiAgICBkYXRhLmNsZWFyKCk7XG4gIH1cblxuICBmdW5jdGlvbiBvblNlbGVjdChkOiBzdHJpbmcgfCBudWxsKSB7XG4gICAgc2VsZWN0ZWREYXRhSUQuc2V0KGQpO1xuICB9XG5cbiAgZnVuY3Rpb24gb3BlbkVkaXREaWFsb2coKSB7XG4gICAgc2hvd0VkaXREaWFsb2cuc2V0KHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xvc2VFZGl0RGlhbG9nKCkge1xuICAgIHNob3dFZGl0RGlhbG9nLnNldChmYWxzZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVkaXRWYWx1ZShuZXdWYWx1ZTogdW5rbm93bikge1xuICAgIGNvbnN0IGlkID0gc2VsZWN0ZWREYXRhSUQuZ2V0KCk7XG4gICAgaWYgKGlkKSB7XG4gICAgICBjb25zdCBkID0gZGF0YS5nZXRCeUlkKGlkKTtcbiAgICAgIGlmIChkKSB7XG4gICAgICAgIHZvaWQgY2xpZW50LnNlbmQoJ2VkaXRWYWx1ZScsIHtkYXRhOiBkLCBuZXdWYWx1ZX0pO1xuICAgICAgICBzaG93RWRpdERpYWxvZy5zZXQoZmFsc2UpO1xuICAgICAgICBzZWxlY3RlZERhdGFJRC5zZXQobnVsbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25EZWxldGUoKSB7XG4gICAgY29uc3QgaWQgPSBzZWxlY3RlZERhdGFJRC5nZXQoKTtcbiAgICBpZiAoaWQpIHtcbiAgICAgIGNvbnN0IGQgPSBkYXRhLmdldEJ5SWQoaWQpO1xuICAgICAgaWYgKGQpIHtcbiAgICAgICAgdm9pZCBjbGllbnQuc2VuZCgnZGVsZXRlSXRlbScsIHtkYXRhOiBkfSk7XG4gICAgICAgIHNob3dFZGl0RGlhbG9nLnNldChmYWxzZSk7XG4gICAgICAgIHNlbGVjdGVkRGF0YUlELnNldChudWxsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvblNlbGVjdEZvcm1hdChib2R5Rm9ybWF0OiBzdHJpbmcpIHtcbiAgICBkZXRhaWxCb2R5Rm9ybWF0LnNldChib2R5Rm9ybWF0KTtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShMT0NBTFNUT1JBR0VfT0JKRUNUX0ZPUk1BVF9LRVksIGJvZHlGb3JtYXQpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBkYXRhLFxuICAgIHN1cHBvcnRTdGF0dXMsXG4gICAgc2VsZWN0ZWREYXRhSUQsXG4gICAgc2hvd0VkaXREaWFsb2csXG4gICAgZGV0YWlsQm9keUZvcm1hdCxcbiAgICBvbkVkaXRWYWx1ZSxcbiAgICBvbkRlbGV0ZSxcbiAgICBvblNlbGVjdCxcbiAgICBvblNlbGVjdEZvcm1hdCxcbiAgICBvcGVuRWRpdERpYWxvZyxcbiAgICBjbG9zZUVkaXREaWFsb2csXG4gICAgY2xlYXJMb2dzLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gQ29tcG9uZW50KCkge1xuICBjb25zdCBpbnN0YW5jZSA9IHVzZVBsdWdpbihwbHVnaW4pO1xuICBjb25zdCBzdXBwb3J0U3RhdHVzID0gdXNlVmFsdWUoaW5zdGFuY2Uuc3VwcG9ydFN0YXR1cyk7XG4gIGNvbnN0IGV4dHJhQWN0aW9ucyA9IChcbiAgICA8TGF5b3V0Lkhvcml6b250YWwgZ2FwPlxuICAgICAgPEJ1dHRvbiB0aXRsZT1cIkNsZWFyIGxvZ3NcIiBvbkNsaWNrPXtpbnN0YW5jZS5jbGVhckxvZ3N9PlxuICAgICAgICBDbGVhciBsb2dzXG4gICAgICA8L0J1dHRvbj5cbiAgICA8L0xheW91dC5Ib3Jpem9udGFsPlxuICApO1xuXG4gIGNvbnN0IG9uU2VsZWN0ID0gKHJlY29yZDogRGF0YSB8IHVuZGVmaW5lZCkgPT4ge1xuICAgIGlmIChyZWNvcmQpIHtcbiAgICAgIGluc3RhbmNlLm9uU2VsZWN0KHJlY29yZC5ka2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5zdGFuY2Uub25TZWxlY3QobnVsbCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiAoXG4gICAgPExheW91dC5Db250YWluZXIgZ3Jvdz5cbiAgICAgIHshIXN1cHBvcnRTdGF0dXMgJiYgKFxuICAgICAgICA8TGF5b3V0LkNvbnRhaW5lciBwYWQgc3R5bGU9e3N0eWxlcy5lcnJvckJHfT5cbiAgICAgICAgICA8VHlwb2dyYXBoeS5UZXh0IHN0eWxlPXtzdHlsZXMud2hpdGVUZXh0fT5cbiAgICAgICAgICAgIHtzdXBwb3J0U3RhdHVzfVxuICAgICAgICAgIDwvVHlwb2dyYXBoeS5UZXh0PlxuICAgICAgICA8L0xheW91dC5Db250YWluZXI+XG4gICAgICApfVxuICAgICAgPERhdGFUYWJsZVxuICAgICAgICBlbmFibGVBdXRvU2Nyb2xsXG4gICAgICAgIGNvbHVtbnM9e01BSU5fQ09MVU1OU31cbiAgICAgICAgZGF0YVNvdXJjZT17aW5zdGFuY2UuZGF0YX1cbiAgICAgICAgZW5hYmxlSG9yaXpvbnRhbFNjcm9sbD17ZmFsc2V9XG4gICAgICAgIGV4dHJhQWN0aW9ucz17ZXh0cmFBY3Rpb25zfVxuICAgICAgICBvblJvd1N0eWxlPXtnZXRSb3dTdHlsZX1cbiAgICAgICAgb25TZWxlY3Q9e29uU2VsZWN0fVxuICAgICAgLz5cbiAgICAgIDxEZXRhaWxTaWRlYmFyPlxuICAgICAgICA8U2lkZWJhciAvPlxuICAgICAgPC9EZXRhaWxTaWRlYmFyPlxuICAgICAgPEVkaXRNb2RhbCAvPlxuICAgIDwvTGF5b3V0LkNvbnRhaW5lcj5cbiAgKTtcbn1cblxuZnVuY3Rpb24gRWRpdE1vZGFsKCkge1xuICBjb25zdCBpbnN0YW5jZSA9IHVzZVBsdWdpbihwbHVnaW4pO1xuICBjb25zdCBzaG93RWRpdERpYWxvZyA9IHVzZVZhbHVlKGluc3RhbmNlLnNob3dFZGl0RGlhbG9nKTtcbiAgY29uc3Qgc2VsZWN0ZWREYXRhSUQgPSB1c2VWYWx1ZShpbnN0YW5jZS5zZWxlY3RlZERhdGFJRCk7XG4gIGNvbnN0IFtzZWxlY3RlZERhdGEsIHNldFNlbGVjdGVkRGF0YV0gPSB1c2VTdGF0ZTxEYXRhIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IFtuZXdCb29sVmFsdWUsIHNldE5ld0Jvb2xWYWx1ZV0gPSB1c2VTdGF0ZSh0cnVlKTtcbiAgY29uc3QgW25ld1N0cmluZ1ZhbHVlLCBzZXROZXdTdHJpbmdWYWx1ZV0gPSB1c2VTdGF0ZSgnJyk7XG4gIGNvbnN0IFtlcnJvclRleHQsIHNldEVycm9yVGV4dF0gPSB1c2VTdGF0ZSgnJyk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoc2VsZWN0ZWREYXRhSUQpIHtcbiAgICAgIGNvbnN0IGQgPSBpbnN0YW5jZS5kYXRhLmdldEJ5SWQoc2VsZWN0ZWREYXRhSUQpO1xuICAgICAgaWYgKGQpIHtcbiAgICAgICAgc2V0TmV3VmFsdWUoZCk7XG4gICAgICAgIHNldFNlbGVjdGVkRGF0YShkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFNlbGVjdGVkRGF0YShudWxsKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2V0U2VsZWN0ZWREYXRhKG51bGwpO1xuICAgIH1cbiAgfSwgW3NlbGVjdGVkRGF0YUlEXSk7XG5cbiAgZnVuY3Rpb24gc2V0TmV3VmFsdWUoZDogRGF0YSkge1xuICAgIHN3aXRjaCAodHlwZW9mIGQudmFsdWUpIHtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgICBzZXROZXdCb29sVmFsdWUoZC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgIHNldE5ld1N0cmluZ1ZhbHVlKGAke2QudmFsdWV9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgc2V0TmV3U3RyaW5nVmFsdWUoSlNPTi5zdHJpbmdpZnkoZC52YWx1ZSwgbnVsbCwgMikpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uT0soKSB7XG4gICAgaWYgKHNlbGVjdGVkRGF0YSkge1xuICAgICAgc3dpdGNoIChzZWxlY3RlZERhdGEudHlwZSkge1xuICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICBpbnN0YW5jZS5vbkVkaXRWYWx1ZShuZXdCb29sVmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICAgIGluc3RhbmNlLm9uRWRpdFZhbHVlKG5ld1N0cmluZ1ZhbHVlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgICBpZiAoaXNOdW1lcmljKG5ld1N0cmluZ1ZhbHVlKSkge1xuICAgICAgICAgICAgaW5zdGFuY2Uub25FZGl0VmFsdWUocGFyc2VGbG9hdChuZXdTdHJpbmdWYWx1ZSkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRFcnJvclRleHQoJ1lvdXIgaW5wdXQgaXMgbm90IG51bWJlciEnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBhcnIgPSBKU09OLnBhcnNlKG5ld1N0cmluZ1ZhbHVlKTtcbiAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLm9uRWRpdFZhbHVlKGFycik7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3JUZXh0KFwiU3ludGF4IGVycm9yOiB0aGlzIGlzbid0IGFuIGFycmF5IVwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvclRleHQoJ1N5bnRheCBlcnJvcjogJyArIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldEVycm9yVGV4dCgnU3ludGF4IGVycm9yJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3Qgb2JqID0gSlNPTi5wYXJzZShuZXdTdHJpbmdWYWx1ZSk7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2Uub25FZGl0VmFsdWUob2JqKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvclRleHQoXCJTeW50YXggZXJyb3I6IHRoaXMgaXNuJ3QgYW4gb2JqZWN0IVwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBzZXRFcnJvclRleHQoJ1N5bnRheCBlcnJvcjogJyArIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldEVycm9yVGV4dCgnU3ludGF4IGVycm9yJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25DYW5jZWwoKSB7XG4gICAgaW5zdGFuY2UuY2xvc2VFZGl0RGlhbG9nKCk7XG4gICAgc2V0RXJyb3JUZXh0KCcnKTtcbiAgICBpZiAoc2VsZWN0ZWREYXRhKSB7XG4gICAgICBzZXROZXdWYWx1ZShzZWxlY3RlZERhdGEpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9uQ2hhbmdlTnVtYmVyID0gKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxJbnB1dEVsZW1lbnQ+KSA9PiB7XG4gICAgaWYgKGlzTnVtZXJpYyhlLnRhcmdldC52YWx1ZSkpIHtcbiAgICAgIHNldEVycm9yVGV4dCgnJyk7XG4gICAgICBzZXROZXdTdHJpbmdWYWx1ZShlLnRhcmdldC52YWx1ZSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IG9uQ2hhbmdlU3RyaW5nID0gKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxUZXh0QXJlYUVsZW1lbnQ+KSA9PiB7XG4gICAgc2V0RXJyb3JUZXh0KCcnKTtcbiAgICBzZXROZXdTdHJpbmdWYWx1ZShlLnRhcmdldC52YWx1ZSk7XG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8TW9kYWxcbiAgICAgIHRpdGxlPVwiRWRpdCB2YWx1ZVwiXG4gICAgICB2aXNpYmxlPXtzaG93RWRpdERpYWxvZ31cbiAgICAgIG9uQ2FuY2VsPXtvbkNhbmNlbH1cbiAgICAgIG9uT2s9e29uT0t9PlxuICAgICAgPFR5cG9ncmFwaHkuVGV4dD5JbnN0YW5jZSBJRDoge3NlbGVjdGVkRGF0YT8uaW5zdGFuY2VJRH08L1R5cG9ncmFwaHkuVGV4dD5cbiAgICAgIDxiciAvPlxuICAgICAgPFR5cG9ncmFwaHkuVGV4dD5LZXk6IHtzZWxlY3RlZERhdGE/LmtleX08L1R5cG9ncmFwaHkuVGV4dD5cbiAgICAgIDxiciAvPlxuICAgICAgPFR5cG9ncmFwaHkuVGV4dD5UeXBlOiB7c2VsZWN0ZWREYXRhPy50eXBlfTwvVHlwb2dyYXBoeS5UZXh0PlxuICAgICAgPGJyIC8+XG4gICAgICA8VHlwb2dyYXBoeS5UZXh0IHN0eWxlPXtzdHlsZXMueWVsbG93VGV4dH0+XG4gICAgICAgIE1ha2Ugc3VyZSB5b3UgZW50ZXIgY29ycmVjdCB0eXBlIG9mIHZhbHVlIVxuICAgICAgPC9UeXBvZ3JhcGh5LlRleHQ+XG4gICAgICA8YnIgLz5cbiAgICAgIDxiciAvPlxuICAgICAge3NlbGVjdGVkRGF0YT8udHlwZSA9PT0gJ2Jvb2xlYW4nICYmIChcbiAgICAgICAgPFNlbGVjdFxuICAgICAgICAgIG9wdGlvbnM9e0JPT0xFQU5fT1BUSU9OU31cbiAgICAgICAgICB2YWx1ZT17bmV3Qm9vbFZhbHVlfVxuICAgICAgICAgIG9uQ2hhbmdlPXt2ID0+IHtcbiAgICAgICAgICAgIHNldE5ld0Jvb2xWYWx1ZSh2KTtcbiAgICAgICAgICB9fVxuICAgICAgICAvPlxuICAgICAgKX1cbiAgICAgIHtzZWxlY3RlZERhdGE/LnR5cGUgPT09ICdudW1iZXInICYmIChcbiAgICAgICAgPElucHV0IHZhbHVlPXtuZXdTdHJpbmdWYWx1ZX0gb25DaGFuZ2U9e29uQ2hhbmdlTnVtYmVyfSAvPlxuICAgICAgKX1cbiAgICAgIHsoc2VsZWN0ZWREYXRhPy50eXBlID09PSAnc3RyaW5nJyB8fFxuICAgICAgICBzZWxlY3RlZERhdGE/LnR5cGUgPT09ICdhcnJheScgfHxcbiAgICAgICAgc2VsZWN0ZWREYXRhPy50eXBlID09PSAnb2JqZWN0JykgJiYgKFxuICAgICAgICA8SW5wdXQuVGV4dEFyZWFcbiAgICAgICAgICBhdXRvU2l6ZT17e21pblJvd3M6IDIsIG1heFJvd3M6IDZ9fVxuICAgICAgICAgIHN0eWxlPXtzZWxlY3RlZERhdGEudHlwZSAhPT0gJ3N0cmluZycgPyB0aGVtZS5tb25vc3BhY2UgOiB1bmRlZmluZWR9XG4gICAgICAgICAgdmFsdWU9e25ld1N0cmluZ1ZhbHVlfVxuICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZVN0cmluZ31cbiAgICAgICAgLz5cbiAgICAgICl9XG4gICAgICB7ISFlcnJvclRleHQgJiYgKFxuICAgICAgICA8VHlwb2dyYXBoeS5UZXh0IHN0eWxlPXtzdHlsZXMuZXJyb3JCb2xkfT57ZXJyb3JUZXh0fTwvVHlwb2dyYXBoeS5UZXh0PlxuICAgICAgKX1cbiAgICAgIDxiciAvPlxuICAgICAgPGJyIC8+XG4gICAgICA8QnV0dG9uIGRhbmdlciBvbkNsaWNrPXtpbnN0YW5jZS5vbkRlbGV0ZX0+XG4gICAgICAgIERlbGV0ZSBpdGVtXG4gICAgICA8L0J1dHRvbj5cbiAgICA8L01vZGFsPlxuICApO1xufVxuXG5mdW5jdGlvbiBTaWRlYmFyKCkge1xuICBjb25zdCBpbnN0YW5jZSA9IHVzZVBsdWdpbihwbHVnaW4pO1xuICBjb25zdCBzZWxlY3RlZERhdGFJRCA9IHVzZVZhbHVlKGluc3RhbmNlLnNlbGVjdGVkRGF0YUlEKTtcbiAgY29uc3QgZGV0YWlsQm9keUZvcm1hdCA9IHVzZVZhbHVlKGluc3RhbmNlLmRldGFpbEJvZHlGb3JtYXQpO1xuXG4gIGlmICghc2VsZWN0ZWREYXRhSUQpIHtcbiAgICByZXR1cm4gTm9SZWNvcmQ7XG4gIH1cblxuICBjb25zdCBzZWxlY3RlZERhdGEgPSBpbnN0YW5jZS5kYXRhLmdldEJ5SWQoc2VsZWN0ZWREYXRhSUQpO1xuICBjb25zdCBmb3JtYXR0ZWRUZXh0ID1cbiAgICBzZWxlY3RlZERhdGE/LnR5cGUgPT09ICdvYmplY3QnICYmIGRldGFpbEJvZHlGb3JtYXQgPT09ICdwYXJzZWQnO1xuXG4gIGlmICghc2VsZWN0ZWREYXRhKSB7XG4gICAgcmV0dXJuIE5vUmVjb3JkO1xuICB9XG5cbiAgY29uc3QgcmVjb3JkcyA9XG4gICAgc2VsZWN0ZWREYXRhLm1vZGUgPT09ICdERUxFVEUnXG4gICAgICA/IFtcbiAgICAgICAgICB7a2V5OiAnSW5zdGFuY2UgSUQnLCB2YWx1ZTogc2VsZWN0ZWREYXRhLmluc3RhbmNlSUR9LFxuICAgICAgICAgIHtrZXk6ICdNb2RlJywgdmFsdWU6IHNlbGVjdGVkRGF0YS5tb2RlfSxcbiAgICAgICAgICB7a2V5OiAnS2V5JywgdmFsdWU6IHNlbGVjdGVkRGF0YS5rZXl9LFxuICAgICAgICBdXG4gICAgICA6IFtcbiAgICAgICAgICB7a2V5OiAnSW5zdGFuY2UgSUQnLCB2YWx1ZTogc2VsZWN0ZWREYXRhLmluc3RhbmNlSUR9LFxuICAgICAgICAgIHtrZXk6ICdNb2RlJywgdmFsdWU6IHNlbGVjdGVkRGF0YS5tb2RlfSxcbiAgICAgICAgICB7a2V5OiAnS2V5JywgdmFsdWU6IHNlbGVjdGVkRGF0YS5rZXl9LFxuICAgICAgICAgIHtrZXk6ICdUeXBlJywgdmFsdWU6IHNlbGVjdGVkRGF0YS50eXBlfSxcbiAgICAgICAgXTtcblxuICBmdW5jdGlvbiBwYXJzZWRWYWx1ZSgpIHtcbiAgICBjb25zdCB2ID0gc2VsZWN0ZWREYXRhPy52YWx1ZTtcbiAgICBjb25zdCB0ID0gc2VsZWN0ZWREYXRhPy50eXBlO1xuICAgIGlmICh2ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gJ251bGwnO1xuICAgIH1cbiAgICBpZiAodiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJ3VuZGVmaW5lZCc7XG4gICAgfVxuICAgIHN3aXRjaCAodCkge1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYsIG51bGwsIDIpO1xuICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgcmV0dXJuICd0cnVlJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ2ZhbHNlJztcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgIHJldHVybiBgJHt2IGFzIG51bWJlcn1gO1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIHYgYXMgc3RyaW5nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPExheW91dC5Db250YWluZXIgZ3Jvdz5cbiAgICAgIDxEYXRhVGFibGVcbiAgICAgICAgY29sdW1ucz17U0lERUJBUl9DT0xVTU5TfVxuICAgICAgICBlbmFibGVIb3Jpem9udGFsU2Nyb2xsPXtmYWxzZX1cbiAgICAgICAgZW5hYmxlU2VhcmNoYmFyPXtmYWxzZX1cbiAgICAgICAgcmVjb3Jkcz17cmVjb3Jkc31cbiAgICAgICAgc2Nyb2xsYWJsZT17ZmFsc2V9XG4gICAgICAvPlxuICAgICAgey8qIERBVEEgUEFORUwgKi99XG4gICAgICB7c2VsZWN0ZWREYXRhLm1vZGUgIT09ICdERUxFVEUnICYmIChcbiAgICAgICAgPFBhbmVsXG4gICAgICAgICAgcGFkXG4gICAgICAgICAgY29sbGFwc2libGU9e2ZhbHNlfVxuICAgICAgICAgIGV4dHJhQWN0aW9ucz17XG4gICAgICAgICAgICA8RWRpdE91dGxpbmVkXG4gICAgICAgICAgICAgIHRpdGxlPVwiRWRpdCB0aGlzIHZhbHVlXCJcbiAgICAgICAgICAgICAgb25DbGljaz17aW5zdGFuY2Uub3BlbkVkaXREaWFsb2d9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICB0aXRsZT1cIlZhbHVlXCI+XG4gICAgICAgICAge2Zvcm1hdHRlZFRleHQgPyAoXG4gICAgICAgICAgICA8RGF0YUluc3BlY3RvciBjb2xsYXBzZWQgZXhwYW5kUm9vdCBkYXRhPXtzZWxlY3RlZERhdGEudmFsdWV9IC8+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxDb2RlQmxvY2s+e3BhcnNlZFZhbHVlKCl9PC9Db2RlQmxvY2s+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9QYW5lbD5cbiAgICAgICl9XG4gICAgICB7LyogT1BUSU9OUyBQQU5FTCAqL31cbiAgICAgIHtzZWxlY3RlZERhdGEudHlwZSA9PT0gJ29iamVjdCcgJiYgKFxuICAgICAgICA8UGFuZWwga2V5PVwib3B0aW9uc1wiIGNvbGxhcHNlZCBwYWQgdGl0bGU9eydPcHRpb25zJ30+XG4gICAgICAgICAgPFR5cG9ncmFwaHkuVGV4dD5PYmplY3QgZm9ybWF0dGluZzo8L1R5cG9ncmFwaHkuVGV4dD5cbiAgICAgICAgICA8U2VsZWN0XG4gICAgICAgICAgICBvcHRpb25zPXtCT0RZX09QVElPTlN9XG4gICAgICAgICAgICB2YWx1ZT17ZGV0YWlsQm9keUZvcm1hdH1cbiAgICAgICAgICAgIG9uQ2hhbmdlPXtpbnN0YW5jZS5vblNlbGVjdEZvcm1hdH1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1BhbmVsPlxuICAgICAgKX1cbiAgICA8L0xheW91dC5Db250YWluZXI+XG4gICk7XG59XG4iLCAiaW1wb3J0IHt0aGVtZX0gZnJvbSAnZmxpcHBlci1wbHVnaW4nO1xuXG5jb25zdCBzdHlsZXMgPSB7XG4gIGVycm9yOiB7XG4gICAgY29sb3I6IHRoZW1lLmVycm9yQ29sb3IsXG4gIH0sXG4gIGVycm9yQm9sZDoge1xuICAgIGNvbG9yOiB0aGVtZS5lcnJvckNvbG9yLFxuICAgIGZvbnRXZWlnaHQ6ICdib2xkJyxcbiAgfSxcbiAgZXJyb3JCRzoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuZXJyb3JDb2xvcixcbiAgfSxcbiAgd2hpdGVUZXh0OiB7XG4gICAgY29sb3I6ICd3aGl0ZScsXG4gIH0sXG4gIHllbGxvd1RleHQ6IHtcbiAgICBjb2xvcjogJ3llbGxvdycsXG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBzdHlsZXM7XG4iLCAiaW1wb3J0IHN0eWxlcyBmcm9tICcuL3N0eWxlcyc7XG5pbXBvcnQgdHlwZSB7RGF0YVRhYmxlQ29sdW1ufSBmcm9tICdmbGlwcGVyLXBsdWdpbic7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWVyaWMoc3RyOiBzdHJpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7IC8vIHdlIG9ubHkgcHJvY2VzcyBzdHJpbmdzIVxuICByZXR1cm4gKFxuICAgIC8vQHRzLWlnbm9yZVxuICAgICFpc05hTihzdHIpICYmIC8vIHVzZSB0eXBlIGNvZXJjaW9uIHRvIHBhcnNlIHRoZSBfZW50aXJldHlfIG9mIHRoZSBzdHJpbmcgKGBwYXJzZUZsb2F0YCBhbG9uZSBkb2VzIG5vdCBkbyB0aGlzKS4uLlxuICAgICFpc05hTihwYXJzZUZsb2F0KHN0cikpXG4gICk7IC8vIC4uLmFuZCBlbnN1cmUgc3RyaW5ncyBvZiB3aGl0ZXNwYWNlIGZhaWxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd1N0eWxlKHJvdzogRGF0YSkge1xuICByZXR1cm4gcm93Lm1vZGUgPT09ICdERUxFVEUnID8gc3R5bGVzLmVycm9yIDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY29uc3QgQk9PTEVBTl9PUFRJT05TID0gW1xuICB7bGFiZWw6ICd0cnVlJywgdmFsdWU6IHRydWV9LFxuICB7bGFiZWw6ICdmYWxzZScsIHZhbHVlOiBmYWxzZX0sXG5dO1xuXG5leHBvcnQgY29uc3QgU0lERUJBUl9DT0xVTU5TOiBEYXRhVGFibGVDb2x1bW5bXSA9IFtcbiAge1xuICAgIGtleTogJ2tleScsXG4gICAgd2lkdGg6IDEwMCxcbiAgICB0aXRsZTogJ1RpdGxlJyxcbiAgfSxcbiAge1xuICAgIGtleTogJ3ZhbHVlJyxcbiAgICB0aXRsZTogJ1ZhbHVlJyxcbiAgICB3cmFwOiB0cnVlLFxuICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IE1BSU5fQ09MVU1OUzogRGF0YVRhYmxlQ29sdW1uPERhdGE+W10gPSBbXG4gIHtcbiAgICBrZXk6ICd0aW1lJyxcbiAgICB0aXRsZTogJ1RpbWUnLFxuICAgIGZvcm1hdHRlcnM6ICh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBkID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgcmV0dXJuIGQudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9LFxuICB9LFxuICB7XG4gICAga2V5OiAnaW5zdGFuY2VJRCcsXG4gICAgdGl0bGU6ICdJbnN0YW5jZSBJRCcsXG4gICAgd2lkdGg6IDEyMCxcbiAgfSxcbiAge1xuICAgIGtleTogJ21vZGUnLFxuICAgIHRpdGxlOiAnTW9kZScsXG4gICAgd2lkdGg6IDgwLFxuICB9LFxuICB7XG4gICAga2V5OiAna2V5JyxcbiAgICB0aXRsZTogJ0tleScsXG4gICAgd2lkdGg6IDEyMCxcbiAgfSxcbiAge1xuICAgIGtleTogJ3R5cGUnLFxuICAgIHRpdGxlOiAnVHlwZScsXG4gICAgd2lkdGg6IDgwLFxuICB9LFxuICB7XG4gICAga2V5OiAndmFsdWUnLFxuICAgIHRpdGxlOiAnVmFsdWUnLFxuICB9LFxuICB7XG4gICAgLy9AdHMtaWdub3JlIGEgdHJpY2sgdG8gZ2V0IHRoZSB2YWx1ZSBjb2x1bW4gd2lkdGggY2FuIGJlIGNoYW5nZWRcbiAgICBrZXk6ICdlbXB0eScsXG4gICAgdGl0bGU6ICcnLFxuICAgIHZpc2libGU6IGZhbHNlLFxuICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEJPRFlfT1BUSU9OUyA9IFsnZm9ybWF0dGVkJywgJ3BhcnNlZCddLm1hcCh2YWx1ZSA9PiAoe1xuICBsYWJlbDogdmFsdWUsXG4gIHZhbHVlLFxufSkpO1xuIiwgImltcG9ydCB7VHlwb2dyYXBoeX0gZnJvbSAnYW50ZCc7XG5pbXBvcnQge0xheW91dH0gZnJvbSAnZmxpcHBlci1wbHVnaW4nO1xuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGNvbnN0IE5vUmVjb3JkID0gKFxuICA8TGF5b3V0LkNvbnRhaW5lciBjZW50ZXIgZ3JvdyBwYWQ+XG4gICAgPFR5cG9ncmFwaHkuVGV4dCB0eXBlPVwic2Vjb25kYXJ5XCI+Tm8gcmVjb3JkIHNlbGVjdGVkPC9UeXBvZ3JhcGh5LlRleHQ+XG4gIDwvTGF5b3V0LkNvbnRhaW5lcj5cbik7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsbUJBQTJCO0FBQzNCLElBQUFBLGVBQXVEO0FBQ3ZELElBQUFDLHlCQVlPO0FBQ1AsSUFBQUMsZ0JBQXlDOzs7QUNmekMsNEJBQW9CO0FBRXBCLElBQU0sU0FBUztBQUFBLEVBQ2IsT0FBTztBQUFBLElBQ0wsT0FBTyw0QkFBTTtBQUFBLEVBQ2Y7QUFBQSxFQUNBLFdBQVc7QUFBQSxJQUNULE9BQU8sNEJBQU07QUFBQSxJQUNiLFlBQVk7QUFBQSxFQUNkO0FBQUEsRUFD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QUFBLFFBQUEsY0FBQztBQUFBLE1BQ0MsT0FBTTtBQUFBLE1BQ04sU0FBUyxTQUFTO0FBQUEsS0FDcEI7QUFBQSxJQUVGLE9BQU07QUFBQSxLQUNMLGdCQUNDLDhCQUFBQSxRQUFBLGNBQUM7QUFBQSxJQUFjLFdBQVM7QUFBQSxJQUFDLFlBQVU7QUFBQSxJQUFDLE1BQU0sYUFBYTtBQUFBLEdBQU8sSUFFOUQsOEJBQUFBLFFBQUEsY0FBQyx3Q0FBVyxZQUFZLENBQUUsQ0FFOUIsR0FHRCxhQUFhLFNBQVMsWUFDckIsOEJBQUFBLFFBQUEsY0FBQztBQUFBLElBQU0sS0FBSTtBQUFBLElBQVUsV0FBUztBQUFBLElBQUMsS0FBRztBQUFBLElBQUMsT0FBTztBQUFBLEtBQ3hDLDhCQUFBQSxRQUFBLGNBQUMsd0JBQVcsTUFBWCxNQUFnQixvQkFBa0IsR0FDbkMsOEJBQUFBLFFBQUEsY0FBQztBQUFBLElBQ0MsU0FBUztBQUFBLElBQ1QsT0FBTztBQUFBLElBQ1AsVUFBVSxTQUFTO0FBQUEsR0FDckIsQ0FDRixDQUVKO0FBRUo7IiwKICAibmFtZXMiOiBbImltcG9ydF9hbnRkIiwgImltcG9ydF9mbGlwcGVyX3BsdWdpbiIsICJpbXBvcnRfcmVhY3QiLCAiaW1wb3J0X2ZsaXBwZXJfcGx1Z2luIiwgIlJlYWN0IiwgIlJlYWN0Il0KfQo=