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 '▍'; 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