Files
dnd-claw/agent-console/.electron-userdata/Cache/Cache_Data/f_00000a
T

520 lines
52 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/components/ChatPanel.vue");import { defineComponent as _defineComponent } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811";
import { computed, nextTick, onMounted, reactive, ref, watch } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811";
import { marked } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/marked.js?v=4266a811";
const _sfc_main = /* @__PURE__ */ _defineComponent({
__name: "ChatPanel",
props: {
conversation: { type: Object, required: true }
},
emits: ["openPreview"],
setup(__props, { expose: __expose, emit: __emit }) {
__expose();
const props = __props;
const emit = __emit;
const input = ref("");
const listRef = ref();
const streaming = ref(false);
const messages = reactive([...props.conversation.messages]);
watch(
() => props.conversation.id,
() => {
messages.splice(0, messages.length, ...props.conversation.messages);
}
);
marked.setOptions({ breaks: true, headerIds: false, mangle: false });
function renderMd(text) {
if (!text) return '<span class="cursor">▍</span>';
return marked.parse(text);
}
const savedApis = ref([]);
const currentApiId = ref("");
const currentModelName = computed(() => {
const api = savedApis.value.find((a) => a.id === currentApiId.value);
return api ? String(api.model) : "未选择模型";
});
async function loadApis() {
try {
const list = await window.electronAPI.callAgent("llm:list");
savedApis.value = (list || []).map((r) => ({
id: r.id,
name: r.name,
provider: r.provider,
...r.config
}));
if (!currentApiId.value) {
const active = await window.electronAPI.callAgent("llm:getActive");
if (active) {
currentApiId.value = active.id;
} else {
currentApiId.value = savedApis.value[0]?.id || "";
}
}
} catch (e) {
console.error("[ChatPanel] 加载 API 列表失败:", e);
savedApis.value = [];
}
}
async function onApiChange() {
if (currentApiId.value) {
try {
await window.electronAPI.callAgent("llm:setActive", { id: currentApiId.value });
} catch (e) {
console.error("[ChatPanel] 设置激活 API 失败:", e);
}
}
}
onMounted(loadApis);
function statusText(s) {
return {
pending: "待执行",
running: "执行中",
done: "完成",
error: "失败"
}[s] ?? s;
}
function canPreview(t) {
return /file|read|write/i.test(t.name);
}
function openPreview(t) {
const name = t.params.path || t.params.file || `output_${t.id}.md`;
const content = [
`# ${name.split("/").pop()}`,
"",
`> 由工具 \`${t.name}\` 读取(耗时 ${t.durationMs ?? 0}ms)`,
"",
"---",
t.result ?? "(无返回内容)",
"",
"## 示例内容",
"这是从工具调用结果中提取的文件预览内容,真实项目中可替换为后端返回的完整文本。"
].join("\n");
emit("openPreview", { name, content });
}
function scrollToBottom() {
nextTick(() => {
if (listRef.value) listRef.value.scrollTop = listRef.value.scrollHeight;
});
}
async function send() {
const text = input.value.trim();
if (!text || streaming.value) return;
const api = savedApis.value.find((a) => a.id === currentApiId.value);
if (!api) {
alert("请先在「大模型 API 设置」中保存并测试通过一个 API 配置");
return;
}
messages.push({
id: `u-${Date.now()}`,
role: "user",
content: text,
time: nowTime(),
toolCalls: []
});
input.value = "";
scrollToBottom();
const assistantMsg = reactive({
id: `a-${Date.now()}`,
role: "assistant",
content: "",
time: nowTime(),
toolCalls: [],
loading: true
});
messages.push(assistantMsg);
streaming.value = true;
try {
await streamChat(api, assistantMsg);
} catch (e) {
assistantMsg.loading = false;
assistantMsg.content = `⚠️ 调用失败:${e?.message || String(e)}`;
} finally {
assistantMsg.loading = false;
streaming.value = false;
}
}
function nowTime() {
return (/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", {
hour: "2-digit",
minute: "2-digit"
});
}
async function streamChat(api, assistantMsg) {
const isQianfan = api.provider === "qianfan_v2";
let url = String(api.baseUrl);
const headers = { "Content-Type": "application/json" };
if (isQianfan) {
headers["Authorization"] = String(api.authorization || "");
} else {
if (!url.endsWith("/chat/completions")) {
url = url.replace(/\/$/, "") + "/chat/completions";
}
headers["Authorization"] = "Bearer " + String(api.apiKey || "");
}
const history = messages.filter((m) => m.role !== "system").slice(-10).map((m) => ({ role: m.role, content: m.content }));
const body = {
model: String(api.model),
messages: history,
temperature: Number(api.temperature ?? 0.7),
stream: true
};
const res = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body)
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(`HTTP ${res.status} ${err?.error?.message || res.statusText}`);
}
const reader = res.body.getReader();
const decoder = new TextDecoder();
let rawBuffer = "";
let typeBuffer = "";
let typeTimer = null;
const TYPE_INTERVAL = 12;
function startTypewriter() {
if (typeTimer) return;
typeTimer = window.setInterval(() => {
if (typeBuffer.length > 0) {
const chunk = typeBuffer.slice(0, 2);
typeBuffer = typeBuffer.slice(2);
assistantMsg.content += chunk;
scrollToBottom();
} else if (!streaming.value) {
if (typeTimer) {
clearInterval(typeTimer);
typeTimer = null;
}
}
}, TYPE_INTERVAL);
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
rawBuffer += decoder.decode(value, { stream: true });
const lines = rawBuffer.split("\n");
rawBuffer = lines.pop() || "";
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed.startsWith("data:")) continue;
const data = trimmed.slice(5).trim();
if (data === "[DONE]") {
await waitTypewriterDone();
return;
}
try {
const json = JSON.parse(data);
const delta = json.choices?.[0]?.delta?.content;
if (delta && delta.trim()) {
if (assistantMsg.loading) assistantMsg.loading = false;
typeBuffer += delta;
startTypewriter();
}
} catch {
}
}
}
await waitTypewriterDone();
function waitTypewriterDone() {
return new Promise((resolve) => {
const check = () => {
if (typeBuffer.length === 0) {
if (typeTimer) {
clearInterval(typeTimer);
typeTimer = null;
}
resolve();
} else {
setTimeout(check, 30);
}
};
check();
});
}
}
function runAgent() {
scrollToBottom();
}
const __returned__ = { props, emit, input, listRef, streaming, messages, renderMd, savedApis, currentApiId, currentModelName, loadApis, onApiChange, statusText, canPreview, openPreview, scrollToBottom, send, nowTime, streamChat, runAgent };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
import { createCommentVNode as _createCommentVNode, toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, normalizeClass as _normalizeClass, vModelText as _vModelText, withModifiers as _withModifiers, withKeys as _withKeys, withDirectives as _withDirectives, vModelSelect as _vModelSelect } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811";
const _hoisted_1 = { class: "chat" };
const _hoisted_2 = { class: "header" };
const _hoisted_3 = { class: "chat-title" };
const _hoisted_4 = { class: "chat-sub" };
const _hoisted_5 = {
ref: "listRef",
class: "messages"
};
const _hoisted_6 = {
key: 0,
class: "role-tag"
};
const _hoisted_7 = {
key: 1,
class: "loading-dots"
};
const _hoisted_8 = ["innerHTML"];
const _hoisted_9 = {
key: 3,
class: "tools"
};
const _hoisted_10 = { class: "tool-head" };
const _hoisted_11 = { class: "tool-name" };
const _hoisted_12 = { class: "tool-params" };
const _hoisted_13 = ["onClick"];
const _hoisted_14 = { class: "input-bar" };
const _hoisted_15 = ["onKeydown"];
const _hoisted_16 = { class: "input-actions" };
const _hoisted_17 = { class: "right-actions" };
const _hoisted_18 = {
key: 0,
value: ""
};
const _hoisted_19 = ["value"];
const _hoisted_20 = ["disabled"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return _openBlock(), _createElementBlock("section", _hoisted_1, [
_createCommentVNode(" 顶部:会话模型信息 "),
_createElementVNode("header", _hoisted_2, [
_createElementVNode("div", null, [
_createElementVNode(
"div",
_hoisted_3,
_toDisplayString($props.conversation.title),
1
/* TEXT */
),
_createElementVNode("div", _hoisted_4, [
_cache[2] || (_cache[2] = _createTextVNode(
" 模型 ",
-1
/* CACHED */
)),
_createElementVNode(
"b",
null,
_toDisplayString($setup.currentModelName),
1
/* TEXT */
),
_createTextVNode(
" · " + _toDisplayString($setup.messages.length) + " 条消息 ",
1
/* TEXT */
)
])
]),
_createElementVNode("button", {
class: "run-btn",
onClick: $setup.runAgent
}, "▶ 运行")
]),
_createCommentVNode(" 消息列表 "),
_createElementVNode(
"div",
_hoisted_5,
[
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList($setup.messages, (msg) => {
return _openBlock(), _createElementBlock(
"div",
{
key: msg.id,
class: _normalizeClass(["msg", msg.role])
},
[
_createElementVNode(
"div",
{
class: _normalizeClass(["bubble", { user: msg.role === "user" }])
},
[
msg.role !== "user" ? (_openBlock(), _createElementBlock(
"div",
_hoisted_6,
_toDisplayString(msg.role === "assistant" ? "dndClaw" : "系统"),
1
/* TEXT */
)) : _createCommentVNode("v-if", true),
msg.loading ? (_openBlock(), _createElementBlock("div", _hoisted_7, [..._cache[3] || (_cache[3] = [
_createElementVNode(
"span",
null,
null,
-1
/* CACHED */
),
_createElementVNode(
"span",
null,
null,
-1
/* CACHED */
),
_createElementVNode(
"span",
null,
null,
-1
/* CACHED */
)
])])) : (_openBlock(), _createElementBlock("div", {
key: 2,
class: "content markdown-body",
innerHTML: $setup.renderMd(msg.content)
}, null, 8, _hoisted_8)),
_createCommentVNode(" 工具调用 "),
msg.toolCalls?.length ? (_openBlock(), _createElementBlock("div", _hoisted_9, [
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList(msg.toolCalls, (t) => {
return _openBlock(), _createElementBlock("div", {
key: t.id,
class: "tool"
}, [
_createElementVNode("div", _hoisted_10, [
_createElementVNode(
"span",
_hoisted_11,
"🔧 " + _toDisplayString(t.name),
1
/* TEXT */
),
_createElementVNode(
"span",
{
class: _normalizeClass(["tool-status", t.status])
},
_toDisplayString($setup.statusText(t.status)),
3
/* TEXT, CLASS */
)
]),
_createElementVNode("div", _hoisted_12, [
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList(t.params, (v, k) => {
return _openBlock(), _createElementBlock(
"code",
{ key: k },
_toDisplayString(k) + "=" + _toDisplayString(v),
1
/* TEXT */
);
}),
128
/* KEYED_FRAGMENT */
))
]),
t.status === "done" && $setup.canPreview(t) ? (_openBlock(), _createElementBlock("button", {
key: 0,
class: "preview-btn",
onClick: ($event) => $setup.openPreview(t)
}, " 预览文件 ", 8, _hoisted_13)) : _createCommentVNode("v-if", true)
]);
}),
128
/* KEYED_FRAGMENT */
))
])) : _createCommentVNode("v-if", true)
],
2
/* CLASS */
)
],
2
/* CLASS */
);
}),
128
/* KEYED_FRAGMENT */
))
],
512
/* NEED_PATCH */
),
_createCommentVNode(" 输入框 "),
_createElementVNode("footer", _hoisted_14, [
_withDirectives(_createElementVNode("textarea", {
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.input = $event),
rows: "2",
placeholder: "输入指令,或要求智能体执行某项任务…",
onKeydown: _withKeys(_withModifiers($setup.send, ["exact", "prevent"]), ["enter"])
}, null, 40, _hoisted_15), [
[_vModelText, $setup.input]
]),
_createElementVNode("div", _hoisted_16, [
_cache[4] || (_cache[4] = _createElementVNode(
"span",
{ class: "hint" },
"Enter 发送 · Shift+Enter 换行",
-1
/* CACHED */
)),
_createElementVNode("div", _hoisted_17, [
_withDirectives(_createElementVNode(
"select",
{
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.currentApiId = $event),
class: "api-select",
title: "选择 LLM API",
onFocus: $setup.loadApis,
onChange: $setup.onApiChange
},
[
!$setup.savedApis.length ? (_openBlock(), _createElementBlock("option", _hoisted_18, "请先在设置中保存 API")) : _createCommentVNode("v-if", true),
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList($setup.savedApis, (a) => {
return _openBlock(), _createElementBlock("option", {
key: a.id,
value: a.id
}, _toDisplayString(a.name), 9, _hoisted_19);
}),
128
/* KEYED_FRAGMENT */
))
],
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[_vModelSelect, $setup.currentApiId]
]),
_createElementVNode("button", {
class: "send-btn",
disabled: $setup.streaming,
onClick: $setup.send
}, _toDisplayString($setup.streaming ? "生成中…" : "发送"), 9, _hoisted_20)
])
])
])
]);
}
import "/components/ChatPanel.vue?vue&type=style&index=0&scoped=2c15c3a8&lang.css";
_sfc_main.__hmrId = "2c15c3a8";
typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main);
import.meta.hot.on("file-changed", ({ file }) => {
__VUE_HMR_RUNTIME__.CHANGED_FILE = file;
});
import.meta.hot.accept((mod) => {
if (!mod) return;
const { default: updated, _rerender_only } = mod;
if (_rerender_only) {
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render);
} else {
__VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated);
}
});
import _export_sfc from "/@id/__x00__plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-2c15c3a8"], ["__file", "D:/dndClaw/agent-console/src/renderer/components/ChatPanel.vue"]]);
//# sourceMappingURL=data:application/json;base64,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Qk07QUFBQSxrQ0FsQko7QUFBQSxVQUFtRDtBQUFBLFlBQTdDLE9BQU0sT0FBTTtBQUFBLFVBQUM7QUFBQSxVQUF5QjtBQUFBO0FBQUE7QUFBQSxRQUM1QyxvQkFnQk0sT0FoQk4sYUFnQk07QUFBQSwwQkFmSjtBQUFBLFlBV1M7QUFBQTtBQUFBLDJFQVZFLHNCQUFZO0FBQUEsY0FDckIsT0FBTTtBQUFBLGNBQ04sT0FBTTtBQUFBLGNBQ0wsU0FBTztBQUFBLGNBQ1AsVUFBUTtBQUFBOztlQUVNLGlCQUFVLHdCQUF6QixvQkFBK0QsVUFBL0QsYUFBMEMsY0FBWTtpQ0FDdEQ7QUFBQSxnQkFFUztBQUFBO0FBQUEsNEJBRlcsa0JBQVMsQ0FBZCxNQUFDO3VDQUFoQixvQkFFUztBQUFBLG9CQUZ1QixLQUFLLEVBQUU7QUFBQSxvQkFBSyxPQUFPLEVBQUU7QUFBQSxzQ0FDaEQsRUFBRSxJQUFJO0FBQUE7Ozs7Ozs7OzRCQVJGLG1CQUFZO0FBQUE7VUFXdkIsb0JBRVM7QUFBQSxZQUZELE9BQU07QUFBQSxZQUFZLFVBQVU7QUFBQSxZQUFZLFNBQU87QUFBQSw4QkFDbEQsbUJBQVM7QUFBQSIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsiQ2hhdFBhbmVsLnZ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XG4gIDxzZWN0aW9uIGNsYXNzPVwiY2hhdFwiPlxuICAgIDwhLS0g6aG26YOo77ya5Lya6K+d5qih5Z6L5L+h5oGvIC0tPlxuICAgIDxoZWFkZXIgY2xhc3M9XCJoZWFkZXJcIj5cbiAgICAgIDxkaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LXRpdGxlXCI+e3sgY29udmVyc2F0aW9uLnRpdGxlIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LXN1YlwiPlxuICAgICAgICAgIOaooeWeiyA8Yj57eyBjdXJyZW50TW9kZWxOYW1lIH19PC9iPiDCt1xuICAgICAgICAgIHt7IG1lc3NhZ2VzLmxlbmd0aCB9fSDmnaHmtojmga9cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJydW4tYnRuXCIgQGNsaWNrPVwicnVuQWdlbnRcIj7ilrYg6L+Q6KGMPC9idXR0b24+XG4gICAgPC9oZWFkZXI+XG5cbiAgICA8IS0tIOa2iOaBr+WIl+ihqCAtLT5cbiAgICA8ZGl2IHJlZj1cImxpc3RSZWZcIiBjbGFzcz1cIm1lc3NhZ2VzXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIHYtZm9yPVwibXNnIGluIG1lc3NhZ2VzXCJcbiAgICAgICAgOmtleT1cIm1zZy5pZFwiXG4gICAgICAgIGNsYXNzPVwibXNnXCJcbiAgICAgICAgOmNsYXNzPVwibXNnLnJvbGVcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYnViYmxlXCIgOmNsYXNzPVwieyB1c2VyOiBtc2cucm9sZSA9PT0gJ3VzZXInIH1cIj5cbiAgICAgICAgICA8ZGl2IHYtaWY9XCJtc2cucm9sZSAhPT0gJ3VzZXInXCIgY2xhc3M9XCJyb2xlLXRhZ1wiPlxuICAgICAgICAgICAge3sgbXNnLnJvbGUgPT09ICdhc3Npc3RhbnQnID8gJ2RuZENsYXcnIDogJ+ezu+e7nycgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHYtaWY9XCJtc2cubG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZy1kb3RzXCI+XG4gICAgICAgICAgICA8c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHYtZWxzZSBjbGFzcz1cImNvbnRlbnQgbWFya2Rvd24tYm9keVwiIHYtaHRtbD1cInJlbmRlck1kKG1zZy5jb250ZW50KVwiPjwvZGl2PlxuXG4gICAgICAgICAgPCEtLSDlt6XlhbfosIPnlKggLS0+XG4gICAgICAgICAgPGRpdiB2LWlmPVwibXNnLnRvb2xDYWxscz8ubGVuZ3RoXCIgY2xhc3M9XCJ0b29sc1wiPlxuICAgICAgICAgICAgPGRpdiB2LWZvcj1cInQgaW4gbXNnLnRvb2xDYWxsc1wiIDprZXk9XCJ0LmlkXCIgY2xhc3M9XCJ0b29sXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sLWhlYWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2wtbmFtZVwiPvCflKcge3sgdC5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9vbC1zdGF0dXNcIiA6Y2xhc3M9XCJ0LnN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAge3sgc3RhdHVzVGV4dCh0LnN0YXR1cykgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbC1wYXJhbXNcIj5cbiAgICAgICAgICAgICAgICA8Y29kZSB2LWZvcj1cIih2LCBrKSBpbiB0LnBhcmFtc1wiIDprZXk9XCJrXCI+e3sgayB9fT17eyB2IH19PC9jb2RlPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHYtaWY9XCJ0LnN0YXR1cyA9PT0gJ2RvbmUnICYmIGNhblByZXZpZXcodClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicHJldmlldy1idG5cIlxuICAgICAgICAgICAgICAgIEBjbGljaz1cIm9wZW5QcmV2aWV3KHQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIOmihOiniOaWh+S7tlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSDovpPlhaXmoYYgLS0+XG4gICAgPGZvb3RlciBjbGFzcz1cImlucHV0LWJhclwiPlxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHYtbW9kZWw9XCJpbnB1dFwiXG4gICAgICAgIHJvd3M9XCIyXCJcbiAgICAgICAgcGxhY2Vob2xkZXI9XCLovpPlhaXmjIfku6TvvIzmiJbopoHmsYLmmbrog73kvZPmiafooYzmn5Dpobnku7vliqHigKZcIlxuICAgICAgICBAa2V5ZG93bi5lbnRlci5leGFjdC5wcmV2ZW50PVwic2VuZFwiXG4gICAgICA+PC90ZXh0YXJlYT5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1hY3Rpb25zXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaGludFwiPkVudGVyIOWPkemAgSDCtyBTaGlmdCtFbnRlciDmjaLooYw8L3NwYW4+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyaWdodC1hY3Rpb25zXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgdi1tb2RlbD1cImN1cnJlbnRBcGlJZFwiXG4gICAgICAgICAgICBjbGFzcz1cImFwaS1zZWxlY3RcIlxuICAgICAgICAgICAgdGl0bGU9XCLpgInmi6kgTExNIEFQSVwiXG4gICAgICAgICAgICBAZm9jdXM9XCJsb2FkQXBpc1wiXG4gICAgICAgICAgICBAY2hhbmdlPVwib25BcGlDaGFuZ2VcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxvcHRpb24gdi1pZj1cIiFzYXZlZEFwaXMubGVuZ3RoXCIgdmFsdWU9XCJcIj7or7flhYjlnKjorr7nva7kuK3kv53lrZggQVBJPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwiYSBpbiBzYXZlZEFwaXNcIiA6a2V5PVwiYS5pZFwiIDp2YWx1ZT1cImEuaWRcIj5cbiAgICAgICAgICAgICAge3sgYS5uYW1lIH19XG4gICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VuZC1idG5cIiA6ZGlzYWJsZWQ9XCJzdHJlYW1pbmdcIiBAY2xpY2s9XCJzZW5kXCI+XG4gICAgICAgICAgICB7eyBzdHJlYW1pbmcgPyAn55Sf5oiQ5Lit4oCmJyA6ICflj5HpgIEnIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9mb290ZXI+XG4gIDwvc2VjdGlvbj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQgc2V0dXAgbGFuZz1cInRzXCI+XG5pbXBvcnQgeyBjb21wdXRlZCwgbmV4dFRpY2ssIG9uTW91bnRlZCwgcmVhY3RpdmUsIHJlZiwgd2F0Y2ggfSBmcm9tICd2dWUnXG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnXG5pbXBvcnQgdHlwZSB7IENoYXRNZXNzYWdlLCBDb252ZXJzYXRpb24sIFRvb2xDYWxsIH0gZnJvbSAnLi4vdHlwZXMnXG5cbmNvbnN0IHByb3BzID0gZGVmaW5lUHJvcHM8e1xuICBjb252ZXJzYXRpb246IENvbnZlcnNhdGlvblxufT4oKVxuXG5jb25zdCBlbWl0ID0gZGVmaW5lRW1pdHM8e1xuICAoZTogJ29wZW5QcmV2aWV3JywgZjogeyBuYW1lOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9KTogdm9pZFxufT4oKVxuXG5jb25zdCBpbnB1dCA9IHJlZignJylcbmNvbnN0IGxpc3RSZWYgPSByZWY8SFRNTEVsZW1lbnQ+KClcbmNvbnN0IHN0cmVhbWluZyA9IHJlZihmYWxzZSlcblxuLy8g5pys5Zyw5ZON5bqU5byP5raI5oGv5YiX6KGo77yM56Gu5L+d6YCQ5a2X5L+u5pS56IO96Kem5Y+R5pu05pawXG5jb25zdCBtZXNzYWdlcyA9IHJlYWN0aXZlPENoYXRNZXNzYWdlW10+KFsuLi5wcm9wcy5jb252ZXJzYXRpb24ubWVzc2FnZXNdKVxuXG4vLyDliIfmjaLkvJror53ml7blkIzmraXmtojmga9cbndhdGNoKFxuICAoKSA9PiBwcm9wcy5jb252ZXJzYXRpb24uaWQsXG4gICgpID0+IHtcbiAgICBtZXNzYWdlcy5zcGxpY2UoMCwgbWVzc2FnZXMubGVuZ3RoLCAuLi5wcm9wcy5jb252ZXJzYXRpb24ubWVzc2FnZXMpXG4gIH1cbilcblxuLy8gbWFya2VkIOmFjee9ru+8muW8gOWQr+aNouihjO+8jOS4jeS9v+eUqOWktOmDqCBpZFxubWFya2VkLnNldE9wdGlvbnMoeyBicmVha3M6IHRydWUsIGhlYWRlcklkczogZmFsc2UsIG1hbmdsZTogZmFsc2UgfSlcblxuZnVuY3Rpb24gcmVuZGVyTWQodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCF0ZXh0KSByZXR1cm4gJzxzcGFuIGNsYXNzPVwiY3Vyc29yXCI+4paNPC9zcGFuPidcbiAgcmV0dXJuIG1hcmtlZC5wYXJzZSh0ZXh0KSBhcyBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIFNhdmVkQXBpIHtcbiAgaWQ6IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgcHJvdmlkZXI6IHN0cmluZ1xuICBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJcbn1cblxuY29uc3Qgc2F2ZWRBcGlzID0gcmVmPFNhdmVkQXBpW10+KFtdKVxuY29uc3QgY3VycmVudEFwaUlkID0gcmVmKCcnKVxuXG4vLyDlvZPliY3pgInkuK0gQVBJIOeahOaooeWei+WQjVxuY29uc3QgY3VycmVudE1vZGVsTmFtZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgY29uc3QgYXBpID0gc2F2ZWRBcGlzLnZhbHVlLmZpbmQoKGEpID0+IGEuaWQgPT09IGN1cnJlbnRBcGlJZC52YWx1ZSlcbiAgcmV0dXJuIGFwaSA/IFN0cmluZyhhcGkubW9kZWwpIDogJ+acqumAieaLqeaooeWeiydcbn0pXG5cbi8qKlxuICog5LuOIGFnZW50LWNvcmXvvIhTUUxpdGXvvInliqDovb0gQVBJIOWIl+ihqFxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkQXBpcygpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBsaXN0ID0gYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOmxpc3QnKVxuICAgIC8vIOi9rOaNouS4uuWJjeerr+agvOW8j++8muaKiiBjb25maWcg5bGV5byA5Yiw6aG25bGCXG4gICAgc2F2ZWRBcGlzLnZhbHVlID0gKGxpc3QgfHwgW10pLm1hcCgocjogYW55KSA9PiAoe1xuICAgICAgaWQ6IHIuaWQsXG4gICAgICBuYW1lOiByLm5hbWUsXG4gICAgICBwcm92aWRlcjogci5wcm92aWRlcixcbiAgICAgIC4uLnIuY29uZmlnXG4gICAgfSkpXG5cbiAgICAvLyDojrflj5blvZPliY3mv4DmtLvnmoTphY3nva5cbiAgICBpZiAoIWN1cnJlbnRBcGlJZC52YWx1ZSkge1xuICAgICAgY29uc3QgYWN0aXZlID0gYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOmdldEFjdGl2ZScpXG4gICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgIGN1cnJlbnRBcGlJZC52YWx1ZSA9IGFjdGl2ZS5pZFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudEFwaUlkLnZhbHVlID0gc2F2ZWRBcGlzLnZhbHVlWzBdPy5pZCB8fCAnJ1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1tDaGF0UGFuZWxdIOWKoOi9vSBBUEkg5YiX6KGo5aSx6LSlOicsIGUpXG4gICAgc2F2ZWRBcGlzLnZhbHVlID0gW11cbiAgfVxufVxuXG4vKipcbiAqIOmAieaLqSBBUEkg5pe277yM5ZCM5q2l5YiwIGFnZW50LWNvcmXvvIjorr7nva7mv4DmtLvnirbmgIHvvIlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gb25BcGlDaGFuZ2UoKSB7XG4gIGlmIChjdXJyZW50QXBpSWQudmFsdWUpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOnNldEFjdGl2ZScsIHsgaWQ6IGN1cnJlbnRBcGlJZC52YWx1ZSB9KVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tDaGF0UGFuZWxdIOiuvue9rua/gOa0uyBBUEkg5aSx6LSlOicsIGUpXG4gICAgfVxuICB9XG59XG5cbm9uTW91bnRlZChsb2FkQXBpcylcblxuZnVuY3Rpb24gc3RhdHVzVGV4dChzOiBzdHJpbmcpIHtcbiAgcmV0dXJuIChcbiAgICB7XG4gICAgICBwZW5kaW5nOiAn5b6F5omn6KGMJyxcbiAgICAgIHJ1bm5pbmc6ICfmiafooYzkuK0nLFxuICAgICAgZG9uZTogJ+WujOaIkCcsXG4gICAgICBlcnJvcjogJ+Wksei0pSdcbiAgICB9W3NdID8/IHNcbiAgKVxufVxuXG5mdW5jdGlvbiBjYW5QcmV2aWV3KHQ6IFRvb2xDYWxsKSB7XG4gIHJldHVybiAvZmlsZXxyZWFkfHdyaXRlL2kudGVzdCh0Lm5hbWUpXG59XG5cbmZ1bmN0aW9uIG9wZW5QcmV2aWV3KHQ6IFRvb2xDYWxsKSB7XG4gIGNvbnN0IG5hbWUgPSB0LnBhcmFtcy5wYXRoIHx8IHQucGFyYW1zLmZpbGUgfHwgYG91dHB1dF8ke3QuaWR9Lm1kYFxuICBjb25zdCBjb250ZW50ID0gW1xuICAgIGAjICR7bmFtZS5zcGxpdCgnLycpLnBvcCgpfWAsXG4gICAgJycsXG4gICAgYD4g55Sx5bel5YW3IFxcYCR7dC5uYW1lfVxcYCDor7vlj5bvvIjogJfml7YgJHt0LmR1cmF0aW9uTXMgPz8gMH1tc++8iWAsXG4gICAgJycsXG4gICAgJy0tLScsXG4gICAgdC5yZXN1bHQgPz8gJ++8iOaXoOi/lOWbnuWGheWuue+8iScsXG4gICAgJycsXG4gICAgJyMjIOekuuS+i+WGheWuuScsXG4gICAgJ+i/meaYr+S7juW3peWFt+iwg+eUqOe7k+aenOS4reaPkOWPlueahOaWh+S7tumihOiniOWGheWuue+8jOecn+WunumhueebruS4reWPr+abv+aNouS4uuWQjuerr+i/lOWbnueahOWujOaVtOaWh+acrOOAgidcbiAgXS5qb2luKCdcXG4nKVxuICBlbWl0KCdvcGVuUHJldmlldycsIHsgbmFtZSwgY29udGVudCB9KVxufVxuXG5mdW5jdGlvbiBzY3JvbGxUb0JvdHRvbSgpIHtcbiAgbmV4dFRpY2soKCkgPT4ge1xuICAgIGlmIChsaXN0UmVmLnZhbHVlKSBsaXN0UmVmLnZhbHVlLnNjcm9sbFRvcCA9IGxpc3RSZWYudmFsdWUuc2Nyb2xsSGVpZ2h0XG4gIH0pXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNlbmQoKSB7XG4gIGNvbnN0IHRleHQgPSBpbnB1dC52YWx1ZS50cmltKClcbiAgaWYgKCF0ZXh0IHx8IHN0cmVhbWluZy52YWx1ZSkgcmV0dXJuXG5cbiAgY29uc3QgYXBpID0gc2F2ZWRBcGlzLnZhbHVlLmZpbmQoKGEpID0+IGEuaWQgPT09IGN1cnJlbnRBcGlJZC52YWx1ZSlcbiAgaWYgKCFhcGkpIHtcbiAgICBhbGVydCgn6K+35YWI5Zyo44CM5aSn5qih5Z6LIEFQSSDorr7nva7jgI3kuK3kv53lrZjlubbmtYvor5XpgJrov4fkuIDkuKogQVBJIOmFjee9ricpXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyDnlKjmiLfmtojmga9cbiAgbWVzc2FnZXMucHVzaCh7XG4gICAgaWQ6IGB1LSR7RGF0ZS5ub3coKX1gLFxuICAgIHJvbGU6ICd1c2VyJyxcbiAgICBjb250ZW50OiB0ZXh0LFxuICAgIHRpbWU6IG5vd1RpbWUoKSxcbiAgICB0b29sQ2FsbHM6IFtdXG4gIH0pXG4gIGlucHV0LnZhbHVlID0gJydcbiAgc2Nyb2xsVG9Cb3R0b20oKVxuXG4gIC8vIOWNoOS9jSBhc3Npc3RhbnQg5raI5oGv77yI5rWB5byP5aGr5YWF77yJXG4gIGNvbnN0IGFzc2lzdGFudE1zZyA9IHJlYWN0aXZlPENoYXRNZXNzYWdlPih7XG4gICAgaWQ6IGBhLSR7RGF0ZS5ub3coKX1gLFxuICAgIHJvbGU6ICdhc3Npc3RhbnQnLFxuICAgIGNvbnRlbnQ6ICcnLFxuICAgIHRpbWU6IG5vd1RpbWUoKSxcbiAgICB0b29sQ2FsbHM6IFtdLFxuICAgIGxvYWRpbmc6IHRydWVcbiAgfSlcbiAgbWVzc2FnZXMucHVzaChhc3Npc3RhbnRNc2cpXG5cbiAgc3RyZWFtaW5nLnZhbHVlID0gdHJ1ZVxuICB0cnkge1xuICAgIGF3YWl0IHN0cmVhbUNoYXQoYXBpLCBhc3Npc3RhbnRNc2cpXG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGFzc2lzdGFudE1zZy5sb2FkaW5nID0gZmFsc2VcbiAgICBhc3Npc3RhbnRNc2cuY29udGVudCA9IGDimqDvuI8g6LCD55So5aSx6LSl77yaJHtlPy5tZXNzYWdlIHx8IFN0cmluZyhlKX1gXG4gIH0gZmluYWxseSB7XG4gICAgYXNzaXN0YW50TXNnLmxvYWRpbmcgPSBmYWxzZVxuICAgIHN0cmVhbWluZy52YWx1ZSA9IGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24gbm93VGltZSgpIHtcbiAgcmV0dXJuIG5ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCd6aC1DTicsIHtcbiAgICBob3VyOiAnMi1kaWdpdCcsXG4gICAgbWludXRlOiAnMi1kaWdpdCdcbiAgfSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3RyZWFtQ2hhdChhcGk6IFNhdmVkQXBpLCBhc3Npc3RhbnRNc2c6IENoYXRNZXNzYWdlKSB7XG4gIGNvbnN0IGlzUWlhbmZhbiA9IGFwaS5wcm92aWRlciA9PT0gJ3FpYW5mYW5fdjInXG4gIGxldCB1cmwgPSBTdHJpbmcoYXBpLmJhc2VVcmwpXG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfVxuXG4gIGlmIChpc1FpYW5mYW4pIHtcbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSBTdHJpbmcoYXBpLmF1dGhvcml6YXRpb24gfHwgJycpXG4gIH0gZWxzZSB7XG4gICAgaWYgKCF1cmwuZW5kc1dpdGgoJy9jaGF0L2NvbXBsZXRpb25zJykpIHtcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlKC9cXC8kLywgJycpICsgJy9jaGF0L2NvbXBsZXRpb25zJ1xuICAgIH1cbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAnQmVhcmVyICcgKyBTdHJpbmcoYXBpLmFwaUtleSB8fCAnJylcbiAgfVxuXG4gIC8vIOaehOmAoOa2iOaBr+S4iuS4i+aWh++8iOacgOi/kSAxMCDmnaHvvIlcbiAgY29uc3QgaGlzdG9yeSA9IG1lc3NhZ2VzXG4gICAgLmZpbHRlcigobSkgPT4gbS5yb2xlICE9PSAnc3lzdGVtJylcbiAgICAuc2xpY2UoLTEwKVxuICAgIC5tYXAoKG0pID0+ICh7IHJvbGU6IG0ucm9sZSwgY29udGVudDogbS5jb250ZW50IH0pKVxuXG4gIGNvbnN0IGJvZHkgPSB7XG4gICAgbW9kZWw6IFN0cmluZyhhcGkubW9kZWwpLFxuICAgIG1lc3NhZ2VzOiBoaXN0b3J5LFxuICAgIHRlbXBlcmF0dXJlOiBOdW1iZXIoYXBpLnRlbXBlcmF0dXJlID8/IDAuNyksXG4gICAgc3RyZWFtOiB0cnVlXG4gIH1cblxuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpXG4gIH0pXG5cbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCBlcnIgPSBhd2FpdCByZXMuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c30gJHtlcnI/LmVycm9yPy5tZXNzYWdlIHx8IHJlcy5zdGF0dXNUZXh0fWApXG4gIH1cblxuICBjb25zdCByZWFkZXIgPSByZXMuYm9keSEuZ2V0UmVhZGVyKClcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpXG4gIGxldCByYXdCdWZmZXIgPSAnJ1xuXG4gIC8vIOaJk+Wtl+acuue8k+WGsu+8muaUtuWIsOeahOWGheWuueWFiOaUvui/memHjO+8jOeUqOWumuaXtuWZqOmAkOWtl+aYvuekulxuICBsZXQgdHlwZUJ1ZmZlciA9ICcnXG4gIGxldCB0eXBlVGltZXI6IG51bWJlciB8IG51bGwgPSBudWxsXG4gIGNvbnN0IFRZUEVfSU5URVJWQUwgPSAxMiAvLyDmr48gMTJtcyDmmL7npLrkuIDkuKrlrZfnrKZcblxuICBmdW5jdGlvbiBzdGFydFR5cGV3cml0ZXIoKSB7XG4gICAgaWYgKHR5cGVUaW1lcikgcmV0dXJuXG4gICAgdHlwZVRpbWVyID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICh0eXBlQnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8g5q+P5qyh5Y+WIDF+MyDkuKrlrZfnrKbvvIzpgJ/luqbmm7Toh6rnhLZcbiAgICAgICAgY29uc3QgY2h1bmsgPSB0eXBlQnVmZmVyLnNsaWNlKDAsIDIpXG4gICAgICAgIHR5cGVCdWZmZXIgPSB0eXBlQnVmZmVyLnNsaWNlKDIpXG4gICAgICAgIGFzc2lzdGFudE1zZy5jb250ZW50ICs9IGNodW5rXG4gICAgICAgIHNjcm9sbFRvQm90dG9tKClcbiAgICAgIH0gZWxzZSBpZiAoIXN0cmVhbWluZy52YWx1ZSkge1xuICAgICAgICAvLyDmtYHlt7Lnu5PmnZ/kuJTnvJPlhrLljLrmuIXnqbrvvIzlgZzmraLlrprml7blmahcbiAgICAgICAgaWYgKHR5cGVUaW1lcikgeyBjbGVhckludGVydmFsKHR5cGVUaW1lcik7IHR5cGVUaW1lciA9IG51bGwgfVxuICAgICAgfVxuICAgIH0sIFRZUEVfSU5URVJWQUwpXG4gIH1cblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKClcbiAgICBpZiAoZG9uZSkgYnJlYWtcbiAgICByYXdCdWZmZXIgKz0gZGVjb2Rlci5kZWNvZGUodmFsdWUsIHsgc3RyZWFtOiB0cnVlIH0pXG5cbiAgICAvLyBTU0Ug5oyJ6KGM6Kej5p6QXG4gICAgY29uc3QgbGluZXMgPSByYXdCdWZmZXIuc3BsaXQoJ1xcbicpXG4gICAgcmF3QnVmZmVyID0gbGluZXMucG9wKCkgfHwgJydcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSBsaW5lLnRyaW0oKVxuICAgICAgaWYgKCF0cmltbWVkLnN0YXJ0c1dpdGgoJ2RhdGE6JykpIGNvbnRpbnVlXG4gICAgICBjb25zdCBkYXRhID0gdHJpbW1lZC5zbGljZSg1KS50cmltKClcbiAgICAgIGlmIChkYXRhID09PSAnW0RPTkVdJykge1xuICAgICAgICAvLyDmtYHnu5PmnZ/vvIznrYnmiZPlrZfmnLrmiornvJPlhrLljLrmuIXnqbpcbiAgICAgICAgYXdhaXQgd2FpdFR5cGV3cml0ZXJEb25lKClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShkYXRhKVxuICAgICAgICBjb25zdCBkZWx0YSA9IGpzb24uY2hvaWNlcz8uWzBdPy5kZWx0YT8uY29udGVudFxuICAgICAgICBpZiAoZGVsdGEgJiYgZGVsdGEudHJpbSgpKSB7XG4gICAgICAgICAgaWYgKGFzc2lzdGFudE1zZy5sb2FkaW5nKSBhc3Npc3RhbnRNc2cubG9hZGluZyA9IGZhbHNlXG4gICAgICAgICAgdHlwZUJ1ZmZlciArPSBkZWx0YVxuICAgICAgICAgIHN0YXJ0VHlwZXdyaXRlcigpXG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyDlv73nlaXpnZ4gSlNPTiDooYxcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy8g5rWB5q2j5bi457uT5p2f77yM562J5omT5a2X5py65riF56m657yT5Yay5Yy6XG4gIGF3YWl0IHdhaXRUeXBld3JpdGVyRG9uZSgpXG5cbiAgZnVuY3Rpb24gd2FpdFR5cGV3cml0ZXJEb25lKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0eXBlQnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGlmICh0eXBlVGltZXIpIHsgY2xlYXJJbnRlcnZhbCh0eXBlVGltZXIpOyB0eXBlVGltZXIgPSBudWxsIH1cbiAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGNoZWNrLCAzMClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2hlY2soKVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gcnVuQWdlbnQoKSB7XG4gIHNjcm9sbFRvQm90dG9tKClcbn1cbjwvc2NyaXB0PlxuXG48c3R5bGUgc2NvcGVkPlxuLmNoYXQge1xuICBmbGV4OiAxO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1wYW5lbCk7XG4gIG1pbi13aWR0aDogMDtcbn1cbi5oZWFkZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIHBhZGRpbmc6IDE0cHggMjBweDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG59XG4uY2hhdC10aXRsZSB7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGZvbnQtc2l6ZTogMTVweDtcbn1cbi5jaGF0LXN1YiB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xuICBtYXJnaW4tdG9wOiAycHg7XG59XG4ucnVuLWJ0biB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICBjb2xvcjogI2ZmZjtcbiAgcGFkZGluZzogN3B4IDE2cHg7XG4gIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBmb250LXdlaWdodDogNTAwO1xufVxuLnJ1bi1idG46aG92ZXIge1xuICBvcGFjaXR5OiAwLjk7XG59XG4ubWVzc2FnZXMge1xuICBmbGV4OiAxO1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICBwYWRkaW5nOiAxOHB4IDIwcHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogMTZweDtcbn1cbi5tc2cge1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLm1zZy51c2VyIHtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbn1cbi5idWJibGUge1xuICBtYXgtd2lkdGg6IDgyJTtcbiAgcGFkZGluZzogMTFweCAxNHB4O1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1zaWRlYmFyKTtcbiAgbGluZS1oZWlnaHQ6IDEuNjU7XG59XG4uYnViYmxlLnVzZXIge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTtcbiAgY29sb3I6ICNmZmY7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tcHJpbWFyeSk7XG59XG4ucm9sZS10YWcge1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgbWFyZ2luLWJvdHRvbTogNHB4O1xufVxuLnRvb2xzIHtcbiAgbWFyZ2luLXRvcDogMTBweDtcbiAgYm9yZGVyLXRvcDogMXB4IGRhc2hlZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nLXRvcDogOHB4O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDZweDtcbn1cbi50b29sIHtcbiAgcGFkZGluZzogOHB4IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tY29kZS1iZyk7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG59XG4udG9vbC1oZWFkIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLnRvb2wtbmFtZSB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbn1cbi50b29sLXN0YXR1cyB7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgcGFkZGluZzogMnB4IDhweDtcbiAgYm9yZGVyLXJhZGl1czogOTlweDtcbn1cbi50b29sLXN0YXR1cy5kb25lIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tc3VjY2Vzcyk7XG4gIGNvbG9yOiAjZmZmO1xufVxuLnRvb2wtc3RhdHVzLnJ1bm5pbmcge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS13YXJuaW5nKTtcbiAgY29sb3I6ICNmZmY7XG59XG4udG9vbC1zdGF0dXMuZXJyb3Ige1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kYW5nZXIpO1xuICBjb2xvcjogI2ZmZjtcbn1cbi50b29sLXBhcmFtcyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtd3JhcDogd3JhcDtcbiAgZ2FwOiA0cHggMTJweDtcbiAgbWFyZ2luLXRvcDogNnB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LXNlY29uZGFyeSk7XG59XG4ucHJldmlldy1idG4ge1xuICBtYXJnaW4tdG9wOiA4cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xufVxuLmlucHV0LWJhciB7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nOiAxMnB4IDE0cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogOHB4O1xufVxuLmlucHV0LWJhciB0ZXh0YXJlYSB7XG4gIHJlc2l6ZTogbm9uZTtcbiAgcGFkZGluZzogMTBweCAxMnB4O1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1pbnB1dCk7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uaW5wdXQtYmFyIHRleHRhcmVhOmZvY3VzIHtcbiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbn1cbi5pbnB1dC1hY3Rpb25zIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLnJpZ2h0LWFjdGlvbnMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDEwcHg7XG59XG4uYXBpLXNlbGVjdCB7XG4gIHBhZGRpbmc6IDVweCAxMHB4O1xuICBib3JkZXItcmFkaXVzOiA3cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIGJhY2tncm91bmQ6IHZhcigtLWJnLWlucHV0KTtcbiAgY29sb3I6IHZhcigtLXRleHQtcHJpbWFyeSk7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbWF4LXdpZHRoOiAyMDBweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuLmFwaS1zZWxlY3Q6Zm9jdXMge1xuICBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpO1xuICBvdXRsaW5lOiBub25lO1xufVxuLmhpbnQge1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbn1cbi5zZW5kLWJ0biB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICBjb2xvcjogI2ZmZjtcbiAgcGFkZGluZzogNnB4IDE4cHg7XG4gIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuLnNlbmQtYnRuOmhvdmVyIHtcbiAgb3BhY2l0eTogMC45O1xufVxuLnNlbmQtYnRuOmRpc2FibGVkIHtcbiAgb3BhY2l0eTogMC42O1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4vKiDliqDovb3liqjmlYjvvIjkuInngrnot7PliqjvvIkgKi9cbi5sb2FkaW5nLWRvdHMge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgZ2FwOiA0cHg7XG4gIHBhZGRpbmc6IDRweCAwO1xufVxuLmxvYWRpbmctZG90cyBzcGFuIHtcbiAgd2lkdGg6IDdweDtcbiAgaGVpZ2h0OiA3cHg7XG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeSk7XG4gIG9wYWNpdHk6IDAuNDtcbiAgYW5pbWF0aW9uOiBkb3QtYm91bmNlIDEuMnMgaW5maW5pdGUgZWFzZS1pbi1vdXQ7XG59XG4ubG9hZGluZy1kb3RzIHNwYW46bnRoLWNoaWxkKDIpIHsgYW5pbWF0aW9uLWRlbGF5OiAwLjE1czsgfVxuLmxvYWRpbmctZG90cyBzcGFuOm50aC1jaGlsZCgzKSB7IGFuaW1hdGlvbi1kZWxheTogMC4zczsgfVxuQGtleWZyYW1lcyBkb3QtYm91bmNlIHtcbiAgMCUsIDgwJSwgMTAwJSB7IG9wYWNpdHk6IDAuMzsgdHJhbnNmb3JtOiBzY2FsZSgwLjgpOyB9XG4gIDQwJSB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogc2NhbGUoMS4yKTsgfVxufVxuXG4vKiDmtYHlvI/lhYnmoIcgKi9cbi5jdXJzb3Ige1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbiAgYW5pbWF0aW9uOiBibGluayAxcyBzdGVwLWVuZCBpbmZpbml0ZTtcbn1cbkBrZXlmcmFtZXMgYmxpbmsge1xuICA1MCUgeyBvcGFjaXR5OiAwOyB9XG59XG5cbi8qIE1hcmtkb3duIOa4suafk+agt+W8jyAqL1xuLm1hcmtkb3duLWJvZHkge1xuICBmb250LXNpemU6IDE0cHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjc7XG4gIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChwKSB7IG1hcmdpbjogMCAwIDEwcHg7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHA6bGFzdC1jaGlsZCkgeyBtYXJnaW4tYm90dG9tOiAwOyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMSksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMiksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMykge1xuICBtYXJnaW46IDE0cHggMCA4cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMSkgeyBmb250LXNpemU6IDE4cHg7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgyKSB7IGZvbnQtc2l6ZTogMTZweDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoaDMpIHsgZm9udC1zaXplOiAxNXB4OyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcCh1bCksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChvbCkge1xuICBtYXJnaW46IDhweCAwO1xuICBwYWRkaW5nLWxlZnQ6IDIycHg7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChsaSkgeyBtYXJnaW46IDNweCAwOyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChzdHJvbmcpIHsgZm9udC13ZWlnaHQ6IDYwMDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoYmxvY2txdW90ZSkge1xuICBtYXJnaW46IDhweCAwO1xuICBwYWRkaW5nOiA2cHggMTJweDtcbiAgYm9yZGVyLWxlZnQ6IDNweCBzb2xpZCB2YXIoLS1wcmltYXJ5KTtcbiAgYmFja2dyb3VuZDogdmFyKC0tYmctaG92ZXIpO1xuICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoY29kZSkge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1jb2RlLWJnKTtcbiAgcGFkZGluZzogMnB4IDZweDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGZvbnQtZmFtaWx5OiAnQ29uc29sYXMnLCAnTW9uYWNvJywgbW9ub3NwYWNlO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlKSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWNvZGUtYmcpO1xuICBwYWRkaW5nOiAxMnB4O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIG92ZXJmbG93LXg6IGF1dG87XG4gIG1hcmdpbjogMTBweCAwO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlIGNvZGUpIHtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoYSkge1xuICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XG4gIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAodGFibGUpIHtcbiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTtcbiAgbWFyZ2luOiAxMHB4IDA7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcCh0aCksXG4ubWFya2Rvd24tYm9keSA6ZGVlcCh0ZCkge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nOiA2cHggMTBweDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGhyKSB7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIG1hcmdpbjogMTJweCAwO1xufVxuXG4vKiDnlKjmiLfmsJTms6HlhoXnmoQgTWFya2Rvd24g6aKc6Imy6KaG55uWICovXG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoY29kZSksXG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlKSB7XG4gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgY29sb3I6ICNmZmY7XG59XG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoYmxvY2txdW90ZSkge1xuICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTUpO1xuICBjb2xvcjogI2ZmZjtcbiAgYm9yZGVyLWNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSk7XG59XG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoYSkgeyBjb2xvcjogI2ZmZjsgfVxuPC9zdHlsZT5cbiJdLCJmaWxlIjoiRDovZG5kQ2xhdy9hZ2VudC1jb25zb2xlL3NyYy9yZW5kZXJlci9jb21wb25lbnRzL0NoYXRQYW5lbC52dWUifQ==