504 lines
50 KiB
Plaintext
504 lines
50 KiB
Plaintext
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 STORAGE_KEY = "agent-console-api-list";
|
||
const ACTIVE_KEY = "agent-console-api-active";
|
||
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) : "未选择模型";
|
||
});
|
||
function loadApis() {
|
||
try {
|
||
savedApis.value = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]");
|
||
} catch {
|
||
savedApis.value = [];
|
||
}
|
||
if (!currentApiId.value) {
|
||
currentApiId.value = localStorage.getItem(ACTIVE_KEY) || savedApis.value[0]?.id || "";
|
||
}
|
||
}
|
||
function onApiChange() {
|
||
localStorage.setItem(ACTIVE_KEY, currentApiId.value);
|
||
}
|
||
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, STORAGE_KEY, ACTIVE_KEY, 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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O0FBQUEsb0JBQUssT0FBTyxFQUFFO0FBQUEsc0NBQ2hELEVBQUUsSUFBSTtBQUFBOzs7Ozs7Ozs0QkFSRixtQkFBWTtBQUFBO1VBV3ZCLG9CQUVTO0FBQUEsWUFGRCxPQUFNO0FBQUEsWUFBWSxVQUFVO0FBQUEsWUFBWSxTQUFPO0FBQUEsOEJBQ2xELG1CQUFTO0FBQUEiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbIkNoYXRQYW5lbC52dWUiXSwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlPlxuICA8c2VjdGlvbiBjbGFzcz1cImNoYXRcIj5cbiAgICA8IS0tIOmhtumDqO+8muS8muivneaooeWei+S/oeaBryAtLT5cbiAgICA8aGVhZGVyIGNsYXNzPVwiaGVhZGVyXCI+XG4gICAgICA8ZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhdC10aXRsZVwiPnt7IGNvbnZlcnNhdGlvbi50aXRsZSB9fTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhdC1zdWJcIj5cbiAgICAgICAgICDmqKHlnosgPGI+e3sgY3VycmVudE1vZGVsTmFtZSB9fTwvYj4gwrdcbiAgICAgICAgICB7eyBtZXNzYWdlcy5sZW5ndGggfX0g5p2h5raI5oGvXG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwicnVuLWJ0blwiIEBjbGljaz1cInJ1bkFnZW50XCI+4pa2IOi/kOihjDwvYnV0dG9uPlxuICAgIDwvaGVhZGVyPlxuXG4gICAgPCEtLSDmtojmga/liJfooaggLS0+XG4gICAgPGRpdiByZWY9XCJsaXN0UmVmXCIgY2xhc3M9XCJtZXNzYWdlc1wiPlxuICAgICAgPGRpdlxuICAgICAgICB2LWZvcj1cIm1zZyBpbiBtZXNzYWdlc1wiXG4gICAgICAgIDprZXk9XCJtc2cuaWRcIlxuICAgICAgICBjbGFzcz1cIm1zZ1wiXG4gICAgICAgIDpjbGFzcz1cIm1zZy5yb2xlXCJcbiAgICAgID5cbiAgICAgICAgPGRpdiBjbGFzcz1cImJ1YmJsZVwiIDpjbGFzcz1cInsgdXNlcjogbXNnLnJvbGUgPT09ICd1c2VyJyB9XCI+XG4gICAgICAgICAgPGRpdiB2LWlmPVwibXNnLnJvbGUgIT09ICd1c2VyJ1wiIGNsYXNzPVwicm9sZS10YWdcIj5cbiAgICAgICAgICAgIHt7IG1zZy5yb2xlID09PSAnYXNzaXN0YW50JyA/ICdkbmRDbGF3JyA6ICfns7vnu58nIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiB2LWlmPVwibXNnLmxvYWRpbmdcIiBjbGFzcz1cImxvYWRpbmctZG90c1wiPlxuICAgICAgICAgICAgPHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiB2LWVsc2UgY2xhc3M9XCJjb250ZW50IG1hcmtkb3duLWJvZHlcIiB2LWh0bWw9XCJyZW5kZXJNZChtc2cuY29udGVudClcIj48L2Rpdj5cblxuICAgICAgICAgIDwhLS0g5bel5YW36LCD55SoIC0tPlxuICAgICAgICAgIDxkaXYgdi1pZj1cIm1zZy50b29sQ2FsbHM/Lmxlbmd0aFwiIGNsYXNzPVwidG9vbHNcIj5cbiAgICAgICAgICAgIDxkaXYgdi1mb3I9XCJ0IGluIG1zZy50b29sQ2FsbHNcIiA6a2V5PVwidC5pZFwiIGNsYXNzPVwidG9vbFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbC1oZWFkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sLW5hbWVcIj7wn5SnIHt7IHQubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2wtc3RhdHVzXCIgOmNsYXNzPVwidC5zdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHN0YXR1c1RleHQodC5zdGF0dXMpIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvb2wtcGFyYW1zXCI+XG4gICAgICAgICAgICAgICAgPGNvZGUgdi1mb3I9XCIodiwgaykgaW4gdC5wYXJhbXNcIiA6a2V5PVwia1wiPnt7IGsgfX09e3sgdiB9fTwvY29kZT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB2LWlmPVwidC5zdGF0dXMgPT09ICdkb25lJyAmJiBjYW5QcmV2aWV3KHQpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInByZXZpZXctYnRuXCJcbiAgICAgICAgICAgICAgICBAY2xpY2s9XCJvcGVuUHJldmlldyh0KVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICDpooTop4jmlofku7ZcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0g6L6T5YWl5qGGIC0tPlxuICAgIDxmb290ZXIgY2xhc3M9XCJpbnB1dC1iYXJcIj5cbiAgICAgIDx0ZXh0YXJlYVxuICAgICAgICB2LW1vZGVsPVwiaW5wdXRcIlxuICAgICAgICByb3dzPVwiMlwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwi6L6T5YWl5oyH5Luk77yM5oiW6KaB5rGC5pm66IO95L2T5omn6KGM5p+Q6aG55Lu75Yqh4oCmXCJcbiAgICAgICAgQGtleWRvd24uZW50ZXIuZXhhY3QucHJldmVudD1cInNlbmRcIlxuICAgICAgPjwvdGV4dGFyZWE+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtYWN0aW9uc1wiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImhpbnRcIj5FbnRlciDlj5HpgIEgwrcgU2hpZnQrRW50ZXIg5o2i6KGMPC9zcGFuPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmlnaHQtYWN0aW9uc1wiPlxuICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgIHYtbW9kZWw9XCJjdXJyZW50QXBpSWRcIlxuICAgICAgICAgICAgY2xhc3M9XCJhcGktc2VsZWN0XCJcbiAgICAgICAgICAgIHRpdGxlPVwi6YCJ5oupIExMTSBBUElcIlxuICAgICAgICAgICAgQGZvY3VzPVwibG9hZEFwaXNcIlxuICAgICAgICAgICAgQGNoYW5nZT1cIm9uQXBpQ2hhbmdlXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8b3B0aW9uIHYtaWY9XCIhc2F2ZWRBcGlzLmxlbmd0aFwiIHZhbHVlPVwiXCI+6K+35YWI5Zyo6K6+572u5Lit5L+d5a2YIEFQSTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2LWZvcj1cImEgaW4gc2F2ZWRBcGlzXCIgOmtleT1cImEuaWRcIiA6dmFsdWU9XCJhLmlkXCI+XG4gICAgICAgICAgICAgIHt7IGEubmFtZSB9fVxuICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNlbmQtYnRuXCIgOmRpc2FibGVkPVwic3RyZWFtaW5nXCIgQGNsaWNrPVwic2VuZFwiPlxuICAgICAgICAgICAge3sgc3RyZWFtaW5nID8gJ+eUn+aIkOS4reKApicgOiAn5Y+R6YCBJyB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZm9vdGVyPlxuICA8L3NlY3Rpb24+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0IHNldHVwIGxhbmc9XCJ0c1wiPlxuaW1wb3J0IHsgY29tcHV0ZWQsIG5leHRUaWNrLCBvbk1vdW50ZWQsIHJlYWN0aXZlLCByZWYsIHdhdGNoIH0gZnJvbSAndnVlJ1xuaW1wb3J0IHsgbWFya2VkIH0gZnJvbSAnbWFya2VkJ1xuaW1wb3J0IHR5cGUgeyBDaGF0TWVzc2FnZSwgQ29udmVyc2F0aW9uLCBUb29sQ2FsbCB9IGZyb20gJy4uL3R5cGVzJ1xuXG5jb25zdCBwcm9wcyA9IGRlZmluZVByb3BzPHtcbiAgY29udmVyc2F0aW9uOiBDb252ZXJzYXRpb25cbn0+KClcblxuY29uc3QgZW1pdCA9IGRlZmluZUVtaXRzPHtcbiAgKGU6ICdvcGVuUHJldmlldycsIGY6IHsgbmFtZTogc3RyaW5nOyBjb250ZW50OiBzdHJpbmcgfSk6IHZvaWRcbn0+KClcblxuY29uc3QgaW5wdXQgPSByZWYoJycpXG5jb25zdCBsaXN0UmVmID0gcmVmPEhUTUxFbGVtZW50PigpXG5jb25zdCBzdHJlYW1pbmcgPSByZWYoZmFsc2UpXG5cbi8vIOacrOWcsOWTjeW6lOW8j+a2iOaBr+WIl+ihqO+8jOehruS/nemAkOWtl+S/ruaUueiDveinpuWPkeabtOaWsFxuY29uc3QgbWVzc2FnZXMgPSByZWFjdGl2ZTxDaGF0TWVzc2FnZVtdPihbLi4ucHJvcHMuY29udmVyc2F0aW9uLm1lc3NhZ2VzXSlcblxuLy8g5YiH5o2i5Lya6K+d5pe25ZCM5q2l5raI5oGvXG53YXRjaChcbiAgKCkgPT4gcHJvcHMuY29udmVyc2F0aW9uLmlkLFxuICAoKSA9PiB7XG4gICAgbWVzc2FnZXMuc3BsaWNlKDAsIG1lc3NhZ2VzLmxlbmd0aCwgLi4ucHJvcHMuY29udmVyc2F0aW9uLm1lc3NhZ2VzKVxuICB9XG4pXG5cbi8vIG1hcmtlZCDphY3nva7vvJrlvIDlkK/mjaLooYzvvIzkuI3kvb/nlKjlpLTpg6ggaWRcbm1hcmtlZC5zZXRPcHRpb25zKHsgYnJlYWtzOiB0cnVlLCBoZWFkZXJJZHM6IGZhbHNlLCBtYW5nbGU6IGZhbHNlIH0pXG5cbmZ1bmN0aW9uIHJlbmRlck1kKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmICghdGV4dCkgcmV0dXJuICc8c3BhbiBjbGFzcz1cImN1cnNvclwiPuKWjTwvc3Bhbj4nXG4gIHJldHVybiBtYXJrZWQucGFyc2UodGV4dCkgYXMgc3RyaW5nXG59XG5cbmludGVyZmFjZSBTYXZlZEFwaSB7XG4gIGlkOiBzdHJpbmdcbiAgbmFtZTogc3RyaW5nXG4gIHByb3ZpZGVyOiBzdHJpbmdcbiAgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyXG59XG5cbmNvbnN0IHNhdmVkQXBpcyA9IHJlZjxTYXZlZEFwaVtdPihbXSlcbmNvbnN0IGN1cnJlbnRBcGlJZCA9IHJlZignJylcblxuLy8g5b2T5YmN6YCJ5LitIEFQSSDnmoTmqKHlnovlkI1cbmNvbnN0IGN1cnJlbnRNb2RlbE5hbWUgPSBjb21wdXRlZCgoKSA9PiB7XG4gIGNvbnN0IGFwaSA9IHNhdmVkQXBpcy52YWx1ZS5maW5kKChhKSA9PiBhLmlkID09PSBjdXJyZW50QXBpSWQudmFsdWUpXG4gIHJldHVybiBhcGkgPyBTdHJpbmcoYXBpLm1vZGVsKSA6ICfmnKrpgInmi6nmqKHlnosnXG59KVxuXG5jb25zdCBTVE9SQUdFX0tFWSA9ICdhZ2VudC1jb25zb2xlLWFwaS1saXN0J1xuY29uc3QgQUNUSVZFX0tFWSA9ICdhZ2VudC1jb25zb2xlLWFwaS1hY3RpdmUnXG5cbmZ1bmN0aW9uIGxvYWRBcGlzKCkge1xuICB0cnkge1xuICAgIHNhdmVkQXBpcy52YWx1ZSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oU1RPUkFHRV9LRVkpIHx8ICdbXScpXG4gIH0gY2F0Y2gge1xuICAgIHNhdmVkQXBpcy52YWx1ZSA9IFtdXG4gIH1cbiAgaWYgKCFjdXJyZW50QXBpSWQudmFsdWUpIHtcbiAgICBjdXJyZW50QXBpSWQudmFsdWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShBQ1RJVkVfS0VZKSB8fCBzYXZlZEFwaXMudmFsdWVbMF0/LmlkIHx8ICcnXG4gIH1cbn1cblxuZnVuY3Rpb24gb25BcGlDaGFuZ2UoKSB7XG4gIGxvY2FsU3RvcmFnZS5zZXRJdGVtKEFDVElWRV9LRVksIGN1cnJlbnRBcGlJZC52YWx1ZSlcbn1cblxub25Nb3VudGVkKGxvYWRBcGlzKVxuXG5mdW5jdGlvbiBzdGF0dXNUZXh0KHM6IHN0cmluZykge1xuICByZXR1cm4gKFxuICAgIHtcbiAgICAgIHBlbmRpbmc6ICflvoXmiafooYwnLFxuICAgICAgcnVubmluZzogJ+aJp+ihjOS4rScsXG4gICAgICBkb25lOiAn5a6M5oiQJyxcbiAgICAgIGVycm9yOiAn5aSx6LSlJ1xuICAgIH1bc10gPz8gc1xuICApXG59XG5cbmZ1bmN0aW9uIGNhblByZXZpZXcodDogVG9vbENhbGwpIHtcbiAgcmV0dXJuIC9maWxlfHJlYWR8d3JpdGUvaS50ZXN0KHQubmFtZSlcbn1cblxuZnVuY3Rpb24gb3BlblByZXZpZXcodDogVG9vbENhbGwpIHtcbiAgY29uc3QgbmFtZSA9IHQucGFyYW1zLnBhdGggfHwgdC5wYXJhbXMuZmlsZSB8fCBgb3V0cHV0XyR7dC5pZH0ubWRgXG4gIGNvbnN0IGNvbnRlbnQgPSBbXG4gICAgYCMgJHtuYW1lLnNwbGl0KCcvJykucG9wKCl9YCxcbiAgICAnJyxcbiAgICBgPiDnlLHlt6XlhbcgXFxgJHt0Lm5hbWV9XFxgIOivu+WPlu+8iOiAl+aXtiAke3QuZHVyYXRpb25NcyA/PyAwfW1z77yJYCxcbiAgICAnJyxcbiAgICAnLS0tJyxcbiAgICB0LnJlc3VsdCA/PyAn77yI5peg6L+U5Zue5YaF5a6577yJJyxcbiAgICAnJyxcbiAgICAnIyMg56S65L6L5YaF5a65JyxcbiAgICAn6L+Z5piv5LuO5bel5YW36LCD55So57uT5p6c5Lit5o+Q5Y+W55qE5paH5Lu26aKE6KeI5YaF5a6577yM55yf5a6e6aG555uu5Lit5Y+v5pu/5o2i5Li65ZCO56uv6L+U5Zue55qE5a6M5pW05paH5pys44CCJ1xuICBdLmpvaW4oJ1xcbicpXG4gIGVtaXQoJ29wZW5QcmV2aWV3JywgeyBuYW1lLCBjb250ZW50IH0pXG59XG5cbmZ1bmN0aW9uIHNjcm9sbFRvQm90dG9tKCkge1xuICBuZXh0VGljaygoKSA9PiB7XG4gICAgaWYgKGxpc3RSZWYudmFsdWUpIGxpc3RSZWYudmFsdWUuc2Nyb2xsVG9wID0gbGlzdFJlZi52YWx1ZS5zY3JvbGxIZWlnaHRcbiAgfSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2VuZCgpIHtcbiAgY29uc3QgdGV4dCA9IGlucHV0LnZhbHVlLnRyaW0oKVxuICBpZiAoIXRleHQgfHwgc3RyZWFtaW5nLnZhbHVlKSByZXR1cm5cblxuICBjb25zdCBhcGkgPSBzYXZlZEFwaXMudmFsdWUuZmluZCgoYSkgPT4gYS5pZCA9PT0gY3VycmVudEFwaUlkLnZhbHVlKVxuICBpZiAoIWFwaSkge1xuICAgIGFsZXJ0KCfor7flhYjlnKjjgIzlpKfmqKHlnosgQVBJIOiuvue9ruOAjeS4reS/neWtmOW5tua1i+ivlemAmui/h+S4gOS4qiBBUEkg6YWN572uJylcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIOeUqOaIt+a2iOaBr1xuICBtZXNzYWdlcy5wdXNoKHtcbiAgICBpZDogYHUtJHtEYXRlLm5vdygpfWAsXG4gICAgcm9sZTogJ3VzZXInLFxuICAgIGNvbnRlbnQ6IHRleHQsXG4gICAgdGltZTogbm93VGltZSgpLFxuICAgIHRvb2xDYWxsczogW11cbiAgfSlcbiAgaW5wdXQudmFsdWUgPSAnJ1xuICBzY3JvbGxUb0JvdHRvbSgpXG5cbiAgLy8g5Y2g5L2NIGFzc2lzdGFudCDmtojmga/vvIjmtYHlvI/loavlhYXvvIlcbiAgY29uc3QgYXNzaXN0YW50TXNnID0gcmVhY3RpdmU8Q2hhdE1lc3NhZ2U+KHtcbiAgICBpZDogYGEtJHtEYXRlLm5vdygpfWAsXG4gICAgcm9sZTogJ2Fzc2lzdGFudCcsXG4gICAgY29udGVudDogJycsXG4gICAgdGltZTogbm93VGltZSgpLFxuICAgIHRvb2xDYWxsczogW10sXG4gICAgbG9hZGluZzogdHJ1ZVxuICB9KVxuICBtZXNzYWdlcy5wdXNoKGFzc2lzdGFudE1zZylcblxuICBzdHJlYW1pbmcudmFsdWUgPSB0cnVlXG4gIHRyeSB7XG4gICAgYXdhaXQgc3RyZWFtQ2hhdChhcGksIGFzc2lzdGFudE1zZylcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgYXNzaXN0YW50TXNnLmxvYWRpbmcgPSBmYWxzZVxuICAgIGFzc2lzdGFudE1zZy5jb250ZW50ID0gYOKaoO+4jyDosIPnlKjlpLHotKXvvJoke2U/Lm1lc3NhZ2UgfHwgU3RyaW5nKGUpfWBcbiAgfSBmaW5hbGx5IHtcbiAgICBhc3Npc3RhbnRNc2cubG9hZGluZyA9IGZhbHNlXG4gICAgc3RyZWFtaW5nLnZhbHVlID0gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBub3dUaW1lKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS50b0xvY2FsZVRpbWVTdHJpbmcoJ3poLUNOJywge1xuICAgIGhvdXI6ICcyLWRpZ2l0JyxcbiAgICBtaW51dGU6ICcyLWRpZ2l0J1xuICB9KVxufVxuXG5hc3luYyBmdW5jdGlvbiBzdHJlYW1DaGF0KGFwaTogU2F2ZWRBcGksIGFzc2lzdGFudE1zZzogQ2hhdE1lc3NhZ2UpIHtcbiAgY29uc3QgaXNRaWFuZmFuID0gYXBpLnByb3ZpZGVyID09PSAncWlhbmZhbl92MidcbiAgbGV0IHVybCA9IFN0cmluZyhhcGkuYmFzZVVybClcbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9XG5cbiAgaWYgKGlzUWlhbmZhbikge1xuICAgIGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9IFN0cmluZyhhcGkuYXV0aG9yaXphdGlvbiB8fCAnJylcbiAgfSBlbHNlIHtcbiAgICBpZiAoIXVybC5lbmRzV2l0aCgnL2NoYXQvY29tcGxldGlvbnMnKSkge1xuICAgICAgdXJsID0gdXJsLnJlcGxhY2UoL1xcLyQvLCAnJykgKyAnL2NoYXQvY29tcGxldGlvbnMnXG4gICAgfVxuICAgIGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9ICdCZWFyZXIgJyArIFN0cmluZyhhcGkuYXBpS2V5IHx8ICcnKVxuICB9XG5cbiAgLy8g5p6E6YCg5raI5oGv5LiK5LiL5paH77yI5pyA6L+RIDEwIOadoe+8iVxuICBjb25zdCBoaXN0b3J5ID0gbWVzc2FnZXNcbiAgICAuZmlsdGVyKChtKSA9PiBtLnJvbGUgIT09ICdzeXN0ZW0nKVxuICAgIC5zbGljZSgtMTApXG4gICAgLm1hcCgobSkgPT4gKHsgcm9sZTogbS5yb2xlLCBjb250ZW50OiBtLmNvbnRlbnQgfSkpXG5cbiAgY29uc3QgYm9keSA9IHtcbiAgICBtb2RlbDogU3RyaW5nKGFwaS5tb2RlbCksXG4gICAgbWVzc2FnZXM6IGhpc3RvcnksXG4gICAgdGVtcGVyYXR1cmU6IE51bWJlcihhcGkudGVtcGVyYXR1cmUgPz8gMC43KSxcbiAgICBzdHJlYW06IHRydWVcbiAgfVxuXG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnMsXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSlcbiAgfSlcblxuICBpZiAoIXJlcy5vaykge1xuICAgIGNvbnN0IGVyciA9IGF3YWl0IHJlcy5qc29uKCkuY2F0Y2goKCkgPT4gKHt9KSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgJHtyZXMuc3RhdHVzfSAke2Vycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgcmVzLnN0YXR1c1RleHR9YClcbiAgfVxuXG4gIGNvbnN0IHJlYWRlciA9IHJlcy5ib2R5IS5nZXRSZWFkZXIoKVxuICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKClcbiAgbGV0IHJhd0J1ZmZlciA9ICcnXG5cbiAgLy8g5omT5a2X5py657yT5Yay77ya5pS25Yiw55qE5YaF5a655YWI5pS+6L+Z6YeM77yM55So5a6a5pe25Zmo6YCQ5a2X5pi+56S6XG4gIGxldCB0eXBlQnVmZmVyID0gJydcbiAgbGV0IHR5cGVUaW1lcjogbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgY29uc3QgVFlQRV9JTlRFUlZBTCA9IDEyIC8vIOavjyAxMm1zIOaYvuekuuS4gOS4quWtl+esplxuXG4gIGZ1bmN0aW9uIHN0YXJ0VHlwZXdyaXRlcigpIHtcbiAgICBpZiAodHlwZVRpbWVyKSByZXR1cm5cbiAgICB0eXBlVGltZXIgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgaWYgKHR5cGVCdWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyDmr4/mrKHlj5YgMX4zIOS4quWtl+espu+8jOmAn+W6puabtOiHqueEtlxuICAgICAgICBjb25zdCBjaHVuayA9IHR5cGVCdWZmZXIuc2xpY2UoMCwgMilcbiAgICAgICAgdHlwZUJ1ZmZlciA9IHR5cGVCdWZmZXIuc2xpY2UoMilcbiAgICAgICAgYXNzaXN0YW50TXNnLmNvbnRlbnQgKz0gY2h1bmtcbiAgICAgICAgc2Nyb2xsVG9Cb3R0b20oKVxuICAgICAgfSBlbHNlIGlmICghc3RyZWFtaW5nLnZhbHVlKSB7XG4gICAgICAgIC8vIOa1geW3sue7k+adn+S4lOe8k+WGsuWMuua4heepuu+8jOWBnOatouWumuaXtuWZqFxuICAgICAgICBpZiAodHlwZVRpbWVyKSB7IGNsZWFySW50ZXJ2YWwodHlwZVRpbWVyKTsgdHlwZVRpbWVyID0gbnVsbCB9XG4gICAgICB9XG4gICAgfSwgVFlQRV9JTlRFUlZBTClcbiAgfVxuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKVxuICAgIGlmIChkb25lKSBicmVha1xuICAgIHJhd0J1ZmZlciArPSBkZWNvZGVyLmRlY29kZSh2YWx1ZSwgeyBzdHJlYW06IHRydWUgfSlcblxuICAgIC8vIFNTRSDmjInooYzop6PmnpBcbiAgICBjb25zdCBsaW5lcyA9IHJhd0J1ZmZlci5zcGxpdCgnXFxuJylcbiAgICByYXdCdWZmZXIgPSBsaW5lcy5wb3AoKSB8fCAnJ1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgY29uc3QgdHJpbW1lZCA9IGxpbmUudHJpbSgpXG4gICAgICBpZiAoIXRyaW1tZWQuc3RhcnRzV2l0aCgnZGF0YTonKSkgY29udGludWVcbiAgICAgIGNvbnN0IGRhdGEgPSB0cmltbWVkLnNsaWNlKDUpLnRyaW0oKVxuICAgICAgaWYgKGRhdGEgPT09ICdbRE9ORV0nKSB7XG4gICAgICAgIC8vIOa1gee7k+adn++8jOetieaJk+Wtl+acuuaKiue8k+WGsuWMuua4heepulxuICAgICAgICBhd2FpdCB3YWl0VHlwZXdyaXRlckRvbmUoKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKGRhdGEpXG4gICAgICAgIGNvbnN0IGRlbHRhID0ganNvbi5jaG9pY2VzPy5bMF0/LmRlbHRhPy5jb250ZW50XG4gICAgICAgIGlmIChkZWx0YSAmJiBkZWx0YS50cmltKCkpIHtcbiAgICAgICAgICBpZiAoYXNzaXN0YW50TXNnLmxvYWRpbmcpIGFzc2lzdGFudE1zZy5sb2FkaW5nID0gZmFsc2VcbiAgICAgICAgICB0eXBlQnVmZmVyICs9IGRlbHRhXG4gICAgICAgICAgc3RhcnRUeXBld3JpdGVyKClcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIOW/veeVpemdniBKU09OIOihjFxuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyDmtYHmraPluLjnu5PmnZ/vvIznrYnmiZPlrZfmnLrmuIXnqbrnvJPlhrLljLpcbiAgYXdhaXQgd2FpdFR5cGV3cml0ZXJEb25lKClcblxuICBmdW5jdGlvbiB3YWl0VHlwZXdyaXRlckRvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBjb25zdCBjaGVjayA9ICgpID0+IHtcbiAgICAgICAgaWYgKHR5cGVCdWZmZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgaWYgKHR5cGVUaW1lcikgeyBjbGVhckludGVydmFsKHR5cGVUaW1lcik7IHR5cGVUaW1lciA9IG51bGwgfVxuICAgICAgICAgIHJlc29sdmUoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2ssIDMwKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjaGVjaygpXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBydW5BZ2VudCgpIHtcbiAgc2Nyb2xsVG9Cb3R0b20oKVxufVxuPC9zY3JpcHQ+XG5cbjxzdHlsZSBzY29wZWQ+XG4uY2hhdCB7XG4gIGZsZXg6IDE7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGJhY2tncm91bmQ6IHZhcigtLWJnLXBhbmVsKTtcbiAgbWluLXdpZHRoOiAwO1xufVxuLmhlYWRlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgcGFkZGluZzogMTRweCAyMHB4O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbn1cbi5jaGF0LXRpdGxlIHtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgZm9udC1zaXplOiAxNXB4O1xufVxuLmNoYXQtc3ViIHtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gIG1hcmdpbi10b3A6IDJweDtcbn1cbi5ydW4tYnRuIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeSk7XG4gIGNvbG9yOiAjZmZmO1xuICBwYWRkaW5nOiA3cHggMTZweDtcbiAgYm9yZGVyLXJhZGl1czogN3B4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7XG59XG4ucnVuLWJ0bjpob3ZlciB7XG4gIG9wYWNpdHk6IDAuOTtcbn1cbi5tZXNzYWdlcyB7XG4gIGZsZXg6IDE7XG4gIG92ZXJmbG93LXk6IGF1dG87XG4gIHBhZGRpbmc6IDE4cHggMjBweDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAxNnB4O1xufVxuLm1zZyB7XG4gIGRpc3BsYXk6IGZsZXg7XG59XG4ubXNnLnVzZXIge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuLmJ1YmJsZSB7XG4gIG1heC13aWR0aDogODIlO1xuICBwYWRkaW5nOiAxMXB4IDE0cHg7XG4gIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIGJhY2tncm91bmQ6IHZhcigtLWJnLXNpZGViYXIpO1xuICBsaW5lLWhlaWdodDogMS42NTtcbn1cbi5idWJibGUudXNlciB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICBjb2xvcjogI2ZmZjtcbiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbn1cbi5yb2xlLXRhZyB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xuICBtYXJnaW4tYm90dG9tOiA0cHg7XG59XG4udG9vbHMge1xuICBtYXJnaW4tdG9wOiAxMHB4O1xuICBib3JkZXItdG9wOiAxcHggZGFzaGVkIHZhcigtLWJvcmRlcik7XG4gIHBhZGRpbmctdG9wOiA4cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNnB4O1xufVxuLnRvb2wge1xuICBwYWRkaW5nOiA4cHggMTBweDtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1jb2RlLWJnKTtcbiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbn1cbi50b29sLWhlYWQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG4udG9vbC1uYW1lIHtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBmb250LXdlaWdodDogNTAwO1xufVxuLnRvb2wtc3RhdHVzIHtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBwYWRkaW5nOiAycHggOHB4O1xuICBib3JkZXItcmFkaXVzOiA5OXB4O1xufVxuLnRvb2wtc3RhdHVzLmRvbmUge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1zdWNjZXNzKTtcbiAgY29sb3I6ICNmZmY7XG59XG4udG9vbC1zdGF0dXMucnVubmluZyB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXdhcm5pbmcpO1xuICBjb2xvcjogI2ZmZjtcbn1cbi50b29sLXN0YXR1cy5lcnJvciB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRhbmdlcik7XG4gIGNvbG9yOiAjZmZmO1xufVxuLnRvb2wtcGFyYW1zIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC13cmFwOiB3cmFwO1xuICBnYXA6IDRweCAxMnB4O1xuICBtYXJnaW4tdG9wOiA2cHg7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgY29sb3I6IHZhcigtLXRleHQtc2Vjb25kYXJ5KTtcbn1cbi5wcmV2aWV3LWJ0biB7XG4gIG1hcmdpbi10b3A6IDhweDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XG59XG4uaW5wdXQtYmFyIHtcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIHBhZGRpbmc6IDEycHggMTRweDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiA4cHg7XG59XG4uaW5wdXQtYmFyIHRleHRhcmVhIHtcbiAgcmVzaXplOiBub25lO1xuICBwYWRkaW5nOiAxMHB4IDEycHg7XG4gIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWJnLWlucHV0KTtcbiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgbGluZS1oZWlnaHQ6IDEuNTtcbn1cbi5pbnB1dC1iYXIgdGV4dGFyZWE6Zm9jdXMge1xuICBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpO1xufVxuLmlucHV0LWFjdGlvbnMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG4ucmlnaHQtYWN0aW9ucyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMTBweDtcbn1cbi5hcGktc2VsZWN0IHtcbiAgcGFkZGluZzogNXB4IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tYmctaW5wdXQpO1xuICBjb2xvcjogdmFyKC0tdGV4dC1wcmltYXJ5KTtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBtYXgtd2lkdGg6IDIwMHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4uYXBpLXNlbGVjdDpmb2N1cyB7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tcHJpbWFyeSk7XG4gIG91dGxpbmU6IG5vbmU7XG59XG4uaGludCB7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xufVxuLnNlbmQtYnRuIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeSk7XG4gIGNvbG9yOiAjZmZmO1xuICBwYWRkaW5nOiA2cHggMThweDtcbiAgYm9yZGVyLXJhZGl1czogN3B4O1xuICBmb250LXNpemU6IDEzcHg7XG59XG4uc2VuZC1idG46aG92ZXIge1xuICBvcGFjaXR5OiAwLjk7XG59XG4uc2VuZC1idG46ZGlzYWJsZWQge1xuICBvcGFjaXR5OiAwLjY7XG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XG59XG5cbi8qIOWKoOi9veWKqOaViO+8iOS4ieeCuei3s+WKqO+8iSAqL1xuLmxvYWRpbmctZG90cyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBnYXA6IDRweDtcbiAgcGFkZGluZzogNHB4IDA7XG59XG4ubG9hZGluZy1kb3RzIHNwYW4ge1xuICB3aWR0aDogN3B4O1xuICBoZWlnaHQ6IDdweDtcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTtcbiAgb3BhY2l0eTogMC40O1xuICBhbmltYXRpb246IGRvdC1ib3VuY2UgMS4ycyBpbmZpbml0ZSBlYXNlLWluLW91dDtcbn1cbi5sb2FkaW5nLWRvdHMgc3BhbjpudGgtY2hpbGQoMikgeyBhbmltYXRpb24tZGVsYXk6IDAuMTVzOyB9XG4ubG9hZGluZy1kb3RzIHNwYW46bnRoLWNoaWxkKDMpIHsgYW5pbWF0aW9uLWRlbGF5OiAwLjNzOyB9XG5Aa2V5ZnJhbWVzIGRvdC1ib3VuY2Uge1xuICAwJSwgODAlLCAxMDAlIHsgb3BhY2l0eTogMC4zOyB0cmFuc2Zvcm06IHNjYWxlKDAuOCk7IH1cbiAgNDAlIHsgb3BhY2l0eTogMTsgdHJhbnNmb3JtOiBzY2FsZSgxLjIpOyB9XG59XG5cbi8qIOa1geW8j+WFieaghyAqL1xuLmN1cnNvciB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xuICBhbmltYXRpb246IGJsaW5rIDFzIHN0ZXAtZW5kIGluZmluaXRlO1xufVxuQGtleWZyYW1lcyBibGluayB7XG4gIDUwJSB7IG9wYWNpdHk6IDA7IH1cbn1cblxuLyogTWFya2Rvd24g5riy5p+T5qC35byPICovXG4ubWFya2Rvd24tYm9keSB7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgbGluZS1oZWlnaHQ6IDEuNztcbiAgd29yZC1icmVhazogYnJlYWstd29yZDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHApIHsgbWFyZ2luOiAwIDAgMTBweDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAocDpsYXN0LWNoaWxkKSB7IG1hcmdpbi1ib3R0b206IDA7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgxKSxcbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgyKSxcbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgzKSB7XG4gIG1hcmdpbjogMTRweCAwIDhweDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgxKSB7IGZvbnQtc2l6ZTogMThweDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoaDIpIHsgZm9udC1zaXplOiAxNnB4OyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMykgeyBmb250LXNpemU6IDE1cHg7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHVsKSxcbi5tYXJrZG93bi1ib2R5IDpkZWVwKG9sKSB7XG4gIG1hcmdpbjogOHB4IDA7XG4gIHBhZGRpbmctbGVmdDogMjJweDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGxpKSB7IG1hcmdpbjogM3B4IDA7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHN0cm9uZykgeyBmb250LXdlaWdodDogNjAwOyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChibG9ja3F1b3RlKSB7XG4gIG1hcmdpbjogOHB4IDA7XG4gIHBhZGRpbmc6IDZweCAxMnB4O1xuICBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLXByaW1hcnkpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1ob3Zlcik7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LXNlY29uZGFyeSk7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChjb2RlKSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWNvZGUtYmcpO1xuICBwYWRkaW5nOiAycHggNnB4O1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgZm9udC1mYW1pbHk6ICdDb25zb2xhcycsICdNb25hY28nLCBtb25vc3BhY2U7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChwcmUpIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tY29kZS1iZyk7XG4gIHBhZGRpbmc6IDEycHg7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgb3ZlcmZsb3cteDogYXV0bztcbiAgbWFyZ2luOiAxMHB4IDA7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChwcmUgY29kZSkge1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBwYWRkaW5nOiAwO1xuICBmb250LXNpemU6IDEzcHg7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChhKSB7XG4gIGNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcCh0YWJsZSkge1xuICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICBtYXJnaW46IDEwcHggMDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHRoKSxcbi5tYXJrZG93bi1ib2R5IDpkZWVwKHRkKSB7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIHBhZGRpbmc6IDZweCAxMHB4O1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoaHIpIHtcbiAgYm9yZGVyOiBub25lO1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgbWFyZ2luOiAxMnB4IDA7XG59XG5cbi8qIOeUqOaIt+awlOazoeWGheeahCBNYXJrZG93biDpopzoibLopobnm5YgKi9cbi5idWJibGUudXNlciAubWFya2Rvd24tYm9keSA6ZGVlcChjb2RlKSxcbi5idWJibGUudXNlciAubWFya2Rvd24tYm9keSA6ZGVlcChwcmUpIHtcbiAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjIpO1xuICBjb2xvcjogI2ZmZjtcbn1cbi5idWJibGUudXNlciAubWFya2Rvd24tYm9keSA6ZGVlcChibG9ja3F1b3RlKSB7XG4gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNSk7XG4gIGNvbG9yOiAjZmZmO1xuICBib3JkZXItY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC41KTtcbn1cbi5idWJibGUudXNlciAubWFya2Rvd24tYm9keSA6ZGVlcChhKSB7IGNvbG9yOiAjZmZmOyB9XG48L3N0eWxlPlxuIl0sImZpbGUiOiJEOi9kbmRDbGF3L2FnZW50LWNvbnNvbGUvc3JjL3JlbmRlcmVyL2NvbXBvbmVudHMvQ2hhdFBhbmVsLnZ1ZSJ9 |