flipper-plugin-react-native-mmkv-storage
Version:
Developer tools for React Native MMKV Storage
494 lines (488 loc) • 47.7 kB
JavaScript
"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=