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

524 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() {
if (!window.electronAPI) {
console.warn("[ChatPanel] electronAPI 未注入(非 Electron 环境)");
return;
}
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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QUNYLFdBQU8seUJBQXNCLGFBQUk7QUFBQTtzQkFIekIsWUFBSztBQUFBO01BS2hCLG9CQW1CTSxPQW5CTixhQW1CTTtBQUFBLGtDQWxCSjtBQUFBLFVBQW1EO0FBQUEsWUFBN0MsT0FBTSxPQUFNO0FBQUEsVUFBQztBQUFBLFVBQXlCO0FBQUE7QUFBQTtBQUFBLFFBQzVDLG9CQWdCTSxPQWhCTixhQWdCTTtBQUFBLDBCQWZKO0FBQUEsWUFXUztBQUFBO0FBQUEsMkVBVkUsc0JBQVk7QUFBQSxjQUNyQixPQUFNO0FBQUEsY0FDTixPQUFNO0FBQUEsY0FDTCxTQUFPO0FBQUEsY0FDUCxVQUFRO0FBQUE7O2VBRU0saUJBQVUsd0JBQXpCLG9CQUErRCxVQUEvRCxhQUEwQyxjQUFZO2lDQUN0RDtBQUFBLGdCQUVTO0FBQUE7QUFBQSw0QkFGVyxrQkFBUyxDQUFkLE1BQUM7dUNBQWhCLG9CQUVTO0FBQUEsb0JBRnVCLEtBQUssRUFBRTtBQUFBLG9CQUFLLE9BQU8sRUFBRTtBQUFBLHNDQUNoRCxFQUFFLElBQUk7QUFBQTs7Ozs7Ozs7NEJBUkYsbUJBQVk7QUFBQTtVQVd2QixvQkFFUztBQUFBLFlBRkQsT0FBTTtBQUFBLFlBQVksVUFBVTtBQUFBLFlBQVksU0FBTztBQUFBLDhCQUNsRCxtQkFBUztBQUFBIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJDaGF0UGFuZWwudnVlIl0sInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cbiAgPHNlY3Rpb24gY2xhc3M9XCJjaGF0XCI+XG4gICAgPCEtLSDpobbpg6jvvJrkvJror53mqKHlnovkv6Hmga8gLS0+XG4gICAgPGhlYWRlciBjbGFzcz1cImhlYWRlclwiPlxuICAgICAgPGRpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNoYXQtdGl0bGVcIj57eyBjb252ZXJzYXRpb24udGl0bGUgfX08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNoYXQtc3ViXCI+XG4gICAgICAgICAg5qih5Z6LIDxiPnt7IGN1cnJlbnRNb2RlbE5hbWUgfX08L2I+IMK3XG4gICAgICAgICAge3sgbWVzc2FnZXMubGVuZ3RoIH19IOadoea2iOaBr1xuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cInJ1bi1idG5cIiBAY2xpY2s9XCJydW5BZ2VudFwiPuKWtiDov5DooYw8L2J1dHRvbj5cbiAgICA8L2hlYWRlcj5cblxuICAgIDwhLS0g5raI5oGv5YiX6KGoIC0tPlxuICAgIDxkaXYgcmVmPVwibGlzdFJlZlwiIGNsYXNzPVwibWVzc2FnZXNcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgdi1mb3I9XCJtc2cgaW4gbWVzc2FnZXNcIlxuICAgICAgICA6a2V5PVwibXNnLmlkXCJcbiAgICAgICAgY2xhc3M9XCJtc2dcIlxuICAgICAgICA6Y2xhc3M9XCJtc2cucm9sZVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJidWJibGVcIiA6Y2xhc3M9XCJ7IHVzZXI6IG1zZy5yb2xlID09PSAndXNlcicgfVwiPlxuICAgICAgICAgIDxkaXYgdi1pZj1cIm1zZy5yb2xlICE9PSAndXNlcidcIiBjbGFzcz1cInJvbGUtdGFnXCI+XG4gICAgICAgICAgICB7eyBtc2cucm9sZSA9PT0gJ2Fzc2lzdGFudCcgPyAnZG5kQ2xhdycgOiAn57O757ufJyB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgdi1pZj1cIm1zZy5sb2FkaW5nXCIgY2xhc3M9XCJsb2FkaW5nLWRvdHNcIj5cbiAgICAgICAgICAgIDxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgdi1lbHNlIGNsYXNzPVwiY29udGVudCBtYXJrZG93bi1ib2R5XCIgdi1odG1sPVwicmVuZGVyTWQobXNnLmNvbnRlbnQpXCI+PC9kaXY+XG5cbiAgICAgICAgICA8IS0tIOW3peWFt+iwg+eUqCAtLT5cbiAgICAgICAgICA8ZGl2IHYtaWY9XCJtc2cudG9vbENhbGxzPy5sZW5ndGhcIiBjbGFzcz1cInRvb2xzXCI+XG4gICAgICAgICAgICA8ZGl2IHYtZm9yPVwidCBpbiBtc2cudG9vbENhbGxzXCIgOmtleT1cInQuaWRcIiBjbGFzcz1cInRvb2xcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvb2wtaGVhZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9vbC1uYW1lXCI+8J+UpyB7eyB0Lm5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sLXN0YXR1c1wiIDpjbGFzcz1cInQuc3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICB7eyBzdGF0dXNUZXh0KHQuc3RhdHVzKSB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sLXBhcmFtc1wiPlxuICAgICAgICAgICAgICAgIDxjb2RlIHYtZm9yPVwiKHYsIGspIGluIHQucGFyYW1zXCIgOmtleT1cImtcIj57eyBrIH19PXt7IHYgfX08L2NvZGU+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgdi1pZj1cInQuc3RhdHVzID09PSAnZG9uZScgJiYgY2FuUHJldmlldyh0KVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJwcmV2aWV3LWJ0blwiXG4gICAgICAgICAgICAgICAgQGNsaWNrPVwib3BlblByZXZpZXcodClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAg6aKE6KeI5paH5Lu2XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIOi+k+WFpeahhiAtLT5cbiAgICA8Zm9vdGVyIGNsYXNzPVwiaW5wdXQtYmFyXCI+XG4gICAgICA8dGV4dGFyZWFcbiAgICAgICAgdi1tb2RlbD1cImlucHV0XCJcbiAgICAgICAgcm93cz1cIjJcIlxuICAgICAgICBwbGFjZWhvbGRlcj1cIui+k+WFpeaMh+S7pO+8jOaIluimgeaxguaZuuiDveS9k+aJp+ihjOafkOmhueS7u+WKoeKAplwiXG4gICAgICAgIEBrZXlkb3duLmVudGVyLmV4YWN0LnByZXZlbnQ9XCJzZW5kXCJcbiAgICAgID48L3RleHRhcmVhPlxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWFjdGlvbnNcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJoaW50XCI+RW50ZXIg5Y+R6YCBIMK3IFNoaWZ0K0VudGVyIOaNouihjDwvc3Bhbj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0LWFjdGlvbnNcIj5cbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICB2LW1vZGVsPVwiY3VycmVudEFwaUlkXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYXBpLXNlbGVjdFwiXG4gICAgICAgICAgICB0aXRsZT1cIumAieaLqSBMTE0gQVBJXCJcbiAgICAgICAgICAgIEBmb2N1cz1cImxvYWRBcGlzXCJcbiAgICAgICAgICAgIEBjaGFuZ2U9XCJvbkFwaUNoYW5nZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG9wdGlvbiB2LWlmPVwiIXNhdmVkQXBpcy5sZW5ndGhcIiB2YWx1ZT1cIlwiPuivt+WFiOWcqOiuvue9ruS4reS/neWtmCBBUEk8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdi1mb3I9XCJhIGluIHNhdmVkQXBpc1wiIDprZXk9XCJhLmlkXCIgOnZhbHVlPVwiYS5pZFwiPlxuICAgICAgICAgICAgICB7eyBhLm5hbWUgfX1cbiAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzZW5kLWJ0blwiIDpkaXNhYmxlZD1cInN0cmVhbWluZ1wiIEBjbGljaz1cInNlbmRcIj5cbiAgICAgICAgICAgIHt7IHN0cmVhbWluZyA/ICfnlJ/miJDkuK3igKYnIDogJ+WPkemAgScgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Zvb3Rlcj5cbiAgPC9zZWN0aW9uPlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdCBzZXR1cCBsYW5nPVwidHNcIj5cbmltcG9ydCB7IGNvbXB1dGVkLCBuZXh0VGljaywgb25Nb3VudGVkLCByZWFjdGl2ZSwgcmVmLCB3YXRjaCB9IGZyb20gJ3Z1ZSdcbmltcG9ydCB7IG1hcmtlZCB9IGZyb20gJ21hcmtlZCdcbmltcG9ydCB0eXBlIHsgQ2hhdE1lc3NhZ2UsIENvbnZlcnNhdGlvbiwgVG9vbENhbGwgfSBmcm9tICcuLi90eXBlcydcblxuY29uc3QgcHJvcHMgPSBkZWZpbmVQcm9wczx7XG4gIGNvbnZlcnNhdGlvbjogQ29udmVyc2F0aW9uXG59PigpXG5cbmNvbnN0IGVtaXQgPSBkZWZpbmVFbWl0czx7XG4gIChlOiAnb3BlblByZXZpZXcnLCBmOiB7IG5hbWU6IHN0cmluZzsgY29udGVudDogc3RyaW5nIH0pOiB2b2lkXG59PigpXG5cbmNvbnN0IGlucHV0ID0gcmVmKCcnKVxuY29uc3QgbGlzdFJlZiA9IHJlZjxIVE1MRWxlbWVudD4oKVxuY29uc3Qgc3RyZWFtaW5nID0gcmVmKGZhbHNlKVxuXG4vLyDmnKzlnLDlk43lupTlvI/mtojmga/liJfooajvvIznoa7kv53pgJDlrZfkv67mlLnog73op6blj5Hmm7TmlrBcbmNvbnN0IG1lc3NhZ2VzID0gcmVhY3RpdmU8Q2hhdE1lc3NhZ2VbXT4oWy4uLnByb3BzLmNvbnZlcnNhdGlvbi5tZXNzYWdlc10pXG5cbi8vIOWIh+aNouS8muivneaXtuWQjOatpea2iOaBr1xud2F0Y2goXG4gICgpID0+IHByb3BzLmNvbnZlcnNhdGlvbi5pZCxcbiAgKCkgPT4ge1xuICAgIG1lc3NhZ2VzLnNwbGljZSgwLCBtZXNzYWdlcy5sZW5ndGgsIC4uLnByb3BzLmNvbnZlcnNhdGlvbi5tZXNzYWdlcylcbiAgfVxuKVxuXG4vLyBtYXJrZWQg6YWN572u77ya5byA5ZCv5o2i6KGM77yM5LiN5L2/55So5aS06YOoIGlkXG5tYXJrZWQuc2V0T3B0aW9ucyh7IGJyZWFrczogdHJ1ZSwgaGVhZGVySWRzOiBmYWxzZSwgbWFuZ2xlOiBmYWxzZSB9KVxuXG5mdW5jdGlvbiByZW5kZXJNZCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIXRleHQpIHJldHVybiAnPHNwYW4gY2xhc3M9XCJjdXJzb3JcIj7ilo08L3NwYW4+J1xuICByZXR1cm4gbWFya2VkLnBhcnNlKHRleHQpIGFzIHN0cmluZ1xufVxuXG5pbnRlcmZhY2UgU2F2ZWRBcGkge1xuICBpZDogc3RyaW5nXG4gIG5hbWU6IHN0cmluZ1xuICBwcm92aWRlcjogc3RyaW5nXG4gIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlclxufVxuXG5jb25zdCBzYXZlZEFwaXMgPSByZWY8U2F2ZWRBcGlbXT4oW10pXG5jb25zdCBjdXJyZW50QXBpSWQgPSByZWYoJycpXG5cbi8vIOW9k+WJjemAieS4rSBBUEkg55qE5qih5Z6L5ZCNXG5jb25zdCBjdXJyZW50TW9kZWxOYW1lID0gY29tcHV0ZWQoKCkgPT4ge1xuICBjb25zdCBhcGkgPSBzYXZlZEFwaXMudmFsdWUuZmluZCgoYSkgPT4gYS5pZCA9PT0gY3VycmVudEFwaUlkLnZhbHVlKVxuICByZXR1cm4gYXBpID8gU3RyaW5nKGFwaS5tb2RlbCkgOiAn5pyq6YCJ5oup5qih5Z6LJ1xufSlcblxuLyoqXG4gKiDku44gYWdlbnQtY29yZe+8iFNRTGl0Ze+8ieWKoOi9vSBBUEkg5YiX6KGoXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRBcGlzKCkge1xuICBpZiAoIXdpbmRvdy5lbGVjdHJvbkFQSSkge1xuICAgIGNvbnNvbGUud2FybignW0NoYXRQYW5lbF0gZWxlY3Ryb25BUEkg5pyq5rOo5YWl77yI6Z2eIEVsZWN0cm9uIOeOr+Wig++8iScpXG4gICAgcmV0dXJuXG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBsaXN0ID0gYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOmxpc3QnKVxuICAgIC8vIOi9rOaNouS4uuWJjeerr+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==