From 20fc0a9c6cf5a6ef8cf635b13b940d35cfb8ecf4 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 15 Oct 2026 09:33:16 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20anima-off=20=E6=94=B9=E7=82=BA=E5=95=9F?= =?UTF-8?q?=E5=8B=95=E5=BE=8C=E6=89=8D=E5=8F=AF=E7=94=A8=EF=BC=8Canima-aff?= =?UTF-8?q?inity=20=E4=B8=80=E5=BE=8B=E5=8F=AF=E7=94=A8=EF=BC=9B=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E8=99=9F=E6=94=B9=E7=82=BA=200.0.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- .claude-plugin/plugin.json | 2 +- README.md | 2 +- hooks/register.tsx | 22 +- hooks/skilltool.ts | 2 + node_modules/.vite/vitest/CACHEDIR.TAG | 3 + .../results.json | 1 + .../352ceefbbbc82678f0913a59c4da512bd4c9bd3e | 154 +++++ .../4c2042672310817dab2dc679342b2efbfcc6937b | 558 ++++++++++++++++++ .../525834972c06d5ab6bb7d533090f3ffef02c20b5 | 303 ++++++++++ .../62b7c79e321aca8bdc9ee9230d8f4b803bd74b84 | 203 +++++++ node_modules/.vitest-cache/CACHEDIR.TAG | 3 + node_modules/.vitest-cache/_metadata.json | 3 + .../c2d7f99331c6f1eaefe80824423496e97f064d35 | 190 ++++++ .../e1806f12dd53b604a37aca3018dcd26b7d00ba5f | 104 ++++ .../eed085b873787578cf2924a0270929bf794c74a5 | 150 +++++ 15 files changed, 1688 insertions(+), 12 deletions(-) create mode 100644 node_modules/.vite/vitest/CACHEDIR.TAG create mode 100644 node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json create mode 100644 node_modules/.vitest-cache/352ceefbbbc82678f0913a59c4da512bd4c9bd3e create mode 100644 node_modules/.vitest-cache/4c2042672310817dab2dc679342b2efbfcc6937b create mode 100644 node_modules/.vitest-cache/525834972c06d5ab6bb7d533090f3ffef02c20b5 create mode 100644 node_modules/.vitest-cache/62b7c79e321aca8bdc9ee9230d8f4b803bd74b84 create mode 100644 node_modules/.vitest-cache/CACHEDIR.TAG create mode 100644 node_modules/.vitest-cache/_metadata.json create mode 100644 node_modules/.vitest-cache/c2d7f99331c6f1eaefe80824423496e97f064d35 create mode 100644 node_modules/.vitest-cache/e1806f12dd53b604a37aca3018dcd26b7d00ba5f create mode 100644 node_modules/.vitest-cache/eed085b873787578cf2924a0270929bf794c74a5 diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 2dbbfb3..c229214 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-anima", - "version": "0.0.3", + "version": "0.0.4", "description": "動漫助理:用喜愛角色的口吻互動,附單行狀態列", "license": "MIT", "userConfig": { diff --git a/README.md b/README.md index ba99d7e..42f2b5f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # jsc-anima -目前版本:0.0.3 +目前版本:0.0.4 動漫助理:用喜愛角色的口吻和你互動,並在輸入框上方顯示單行狀態列(角色、模型、目錄、分支、5h/7d 剩餘額度、ctx、系統資源)。 diff --git a/hooks/register.tsx b/hooks/register.tsx index fc91b67..70d2054 100644 --- a/hooks/register.tsx +++ b/hooks/register.tsx @@ -16,10 +16,9 @@ import { CACHE_MS, addEntry, commandName, commitMessage, pageName, parseCatalog, import type { Entry } from './wiki' import { DEFAULT_TYPES, RUN_SYSTEM, TODO_COMMAND, TODO_KEY, TYPES_KEY, USAGE, dueNow, nextId, parseArgs as parseTodo, reminderText, renderList } from './todo' import type { Todo } from './todo' -import { NEED_ACTIVE, TOOL_COMMAND, registerTools, runSkillTool } from './skilltool' +import { NEED_ACTIVE, OFF_COMMAND, TOOL_COMMAND, registerTools, runSkillTool } from './skilltool' const ACTIVE_KEY = 'active' -const OFF_COMMAND = 'anima-off' const AFFINITY_COMMAND = 'anima-affinity' const RAW_LOG_KEY = 'rawlog' const RAW_LOG_MAX = 200 @@ -312,8 +311,7 @@ export const register: Register = (on, options) => { await $.command.register({ name: c.slug, description: `啟動《${c.work}》的${c.name}` }) } await $.command.register({ name: EXTRACT_COMMAND, description: '從輕小說章節萃取作品與角色包,確認後建立 PR' }) - await $.command.register({ name: AFFINITY_COMMAND, description: '重置(reset)或手動設定(0-100)目前角色的好感度' }) - await $.command.register({ name: OFF_COMMAND, description: '離開角色,回到一般的 Claude Code' }) + await $.command.register({ name: AFFINITY_COMMAND, description: '重置(reset)或手動設定(0-100)好感度;未啟動時需指定角色代號' }) const saved = await $.store.get(ACTIVE_KEY) active = flag('persist', true) && typeof saved === 'string' && findCharacter(saved) ? saved : undefined if (active && !toolRegistered) { @@ -331,6 +329,7 @@ export const register: Register = (on, options) => { if (!isEnabled) return next(e) if (e.command === EXTRACT_COMMAND) return { text: await runExtract($, e.args) } if (e.command === OFF_COMMAND) { + if (!findCharacter(active)) return { text: NEED_ACTIVE } active = undefined await $.store.delete(ACTIVE_KEY) return { text: '已離開角色,回到一般模式。' } @@ -343,18 +342,21 @@ export const register: Register = (on, options) => { return { text: c ? await todoRun($, c.name, c.persona, String(e.args ?? '')) : NEED_ACTIVE } } if (e.command === AFFINITY_COMMAND) { - const c = findCharacter(active) - if (!c) return { text: '請先啟動角色。' } - const arg = String(e.args ?? '').trim() + // 第一個字若是角色代號就指定該角色;否則用目前啟動的角色。 + const parts = String(e.args ?? '').trim().split(/\s+/).filter(Boolean) + const named = parts.length ? findCharacter(parts[0]) : undefined + const c = named ?? findCharacter(active) + if (!c) return { text: '未啟動角色時請指定角色代號:anima-affinity <角色代號> [reset|0-100]。' } + const arg = (named ? parts.slice(1) : parts).join(' ') const cur = await loadAffinity($, c.slug) if (arg === 'reset') { await $.store.set(affinityKey(c.slug), initialAffinity()) - return { text: '好感度已重置為 0。' } + return { text: `${c.name}的好感度已重置為 0。` } } const n = Number(arg) - if (arg === '' || !Number.isFinite(n) || n < 0 || n > 100) return { text: `目前好感度 ${cur.score}(${stageName(cur.score)})。用法:reset 或 0-100 的數字。` } + if (arg === '' || !Number.isFinite(n) || n < 0 || n > 100) return { text: `${c.name}目前好感度 ${cur.score}(${stageName(cur.score)})。用法:[角色代號] reset 或 0-100 的數字。` } await $.store.set(affinityKey(c.slug), { ...cur, score: Math.round(n) }) - return { text: `好感度已設為 ${Math.round(n)}(${stageName(n)})。` } + return { text: `${c.name}的好感度已設為 ${Math.round(n)}(${stageName(n)})。` } } const c = findCharacter(e.command) if (!c) { diff --git a/hooks/skilltool.ts b/hooks/skilltool.ts index e54905d..ab104b0 100644 --- a/hooks/skilltool.ts +++ b/hooks/skilltool.ts @@ -7,10 +7,12 @@ import { } from './skillgen' export const TOOL_COMMAND = 'anima-skill' +export const OFF_COMMAND = 'anima-off' export const NEED_ACTIVE = '請先啟動角色(/jsc-anima:{作品代號}-{角色代號})再使用這個工具。' export async function registerTools($: Engine): Promise { await $.command.register({ name: TOOL_COMMAND, description: '依描述產生助理技能並建立 PR:<技能名稱> <描述>' }) + await $.command.register({ name: OFF_COMMAND, description: '離開角色,回到一般的 Claude Code' }) await $.command.register({ name: TODO_COMMAND, description: '待辦事項:add/update/list/type/run/done' }) } diff --git a/node_modules/.vite/vitest/CACHEDIR.TAG b/node_modules/.vite/vitest/CACHEDIR.TAG new file mode 100644 index 0000000..8c1ef4c --- /dev/null +++ b/node_modules/.vite/vitest/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by Vitest. +# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json new file mode 100644 index 0000000..e88f1c3 --- /dev/null +++ b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json @@ -0,0 +1 @@ +{"version":1,"projects":{"":{"files":{"hooks/anima.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/extract.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/persist.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/routing.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/skilltool.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/todo.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665},"hooks/wiki.test.ts":{"failed":true,"duration":0,"lastRun":1792056694665}}}}} \ No newline at end of file diff --git a/node_modules/.vitest-cache/352ceefbbbc82678f0913a59c4da512bd4c9bd3e b/node_modules/.vitest-cache/352ceefbbbc82678f0913a59c4da512bd4c9bd3e new file mode 100644 index 0000000..bff2479 --- /dev/null +++ b/node_modules/.vitest-cache/352ceefbbbc82678f0913a59c4da512bd4c9bd3e @@ -0,0 +1,154 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); +const __vite_ssr_import_1__ = await __vite_ssr_import__("/hooks/skillgen.ts", {"importedNames":["bumpVersion","parseEntries","renderGuide","upsertEntry","validateSkill"]}); + + +const SKILL = "---\nname: anima-greet\ndescription: 打招呼\n---\n\n用角色口吻向使用者打招呼,並簡短說明今天的待辦。\n"; +const GENERATED = JSON.stringify({ + skill: SKILL, + example: "早安" +}); +// 啟動角色並替身所有外部:模型、檔案系統、git/tea。 +async function setup($, on, opts = {}) { + const writes = {}; + const procs = []; + __vite_ssr_import_0__.mock.store(on); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: "/repo" })); + on("session.cwd", () => ({ value: "/repo" })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); + on("model.complete", (_, e) => { + const t = opts.reply ? opts.reply(String(e.prompt)) : String(e.prompt).startsWith("請撰寫") ? GENERATED : "嗨!"; + return { value: t === undefined ? { + isAnswered: false, + reason: "empty-reply" + } : { + isAnswered: true, + text: t, + usage: {} + } }; + }); + on("process.run", (_, e) => { + procs.push({ argv: [...e.argv] }); + const s = e.argv.join(" "); + if (s.startsWith("git rev-parse")) return { value: { + exitCode: 0, + stdout: "/repo\n", + stderr: "" + } }; + if (s.startsWith("git symbolic-ref")) return { value: { + exitCode: 0, + stdout: "origin/main\n", + stderr: "" + } }; + if (s.startsWith("tea logins")) return { value: { + exitCode: 0, + stdout: "admin\n", + stderr: "" + } }; + if (s.startsWith("tea pulls")) return { value: { + exitCode: 0, + stdout: "https://g/pulls/1\n", + stderr: "" + } }; + return { value: { + exitCode: 0, + stdout: "", + stderr: "" + } }; + }); + on("fs.exists", (_, e) => ({ value: Boolean(opts.existing && String(e.path).endsWith("anima-greet/SKILL.md")) })); + on("fs.read", (_, e) => ({ value: String(e.path).endsWith("plugin.json") ? "{\n \"version\": \"0.3.0\"\n}" : String(e.path).endsWith("README.md") ? "# jsc-anima\n" : "" })); + on("fs.write", (_, e) => { + writes[e.path] = e.text; + return { value: undefined }; + }); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + return { + writes, + procs + }; +} +const run = ($, args) => $.command.run({ + command: "anima-skill", + args +}); +(0,__vite_ssr_import_0__.test)("未啟動角色時工具二被拒絕並提示先啟動", async ($, on) => { + const { procs } = await setup($, on); + const r = await run($, "greet 打招呼"); + (0,__vite_ssr_import_0__.expect)(r.text.includes("請先啟動角色")).toBe(true); + (0,__vite_ssr_import_0__.expect)(procs.length).toBe(0); +}); +(0,__vite_ssr_import_0__.test)("新增技能:寫檔、升 minor、更新 README、建立 PR", async ($, on) => { + const { writes, procs } = await setup($, on); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + const r = await run($, "greet 打招呼"); + const key = (suffix) => Object.keys(writes).find((k) => k.endsWith(suffix)); + (0,__vite_ssr_import_0__.expect)(writes[key("skills/anima-greet/SKILL.md")].includes("name: anima-greet")).toBe(true); + (0,__vite_ssr_import_0__.expect)(writes[key(".claude-plugin/plugin.json")].includes("\"0.4.0\"")).toBe(true); + (0,__vite_ssr_import_0__.expect)(writes[key("/README.md")].includes("目前版本:0.4.0") || Object.values(writes).some((v) => v.includes("目前版本:0.4.0"))).toBe(true); + (0,__vite_ssr_import_0__.expect)(writes[key("skills/jsc-anima/README.md")].includes("/jsc-anima:anima-greet")).toBe(true); + (0,__vite_ssr_import_0__.expect)(procs.some((p) => p.argv.join(" ").startsWith("git commit") && p.argv.join(" ").includes("feat: 新增技能"))).toBe(true); + const pr = procs.find((p) => p.argv[0] === "tea" && p.argv[1] === "pulls"); + (0,__vite_ssr_import_0__.expect)(pr.argv.includes("main")).toBe(true); + (0,__vite_ssr_import_0__.expect)(pr.argv.includes("feat/anima-greet")).toBe(true); + (0,__vite_ssr_import_0__.expect)(r.text.includes("https://g/pulls/1")).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("技能已存在則覆蓋並升 patch", async ($, on) => { + const { writes } = await setup($, on, { existing: true }); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + await run($, "greet 打招呼"); + (0,__vite_ssr_import_0__.expect)(Object.entries(writes).some(([k, v]) => k.endsWith("plugin.json") && v.includes("\"0.3.1\""))).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("驗證失敗或實跑失敗就不建立 PR", async ($, on) => { + const bad = await setup($, on, { reply: () => JSON.stringify({ + skill: "no frontmatter", + example: "x" + }) }); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + const r1 = await run($, "greet 打招呼"); + (0,__vite_ssr_import_0__.expect)(r1.text.includes("驗證失敗")).toBe(true); + (0,__vite_ssr_import_0__.expect)(bad.procs.some((p) => p.argv[0] === "tea")).toBe(false); + (0,__vite_ssr_import_0__.expect)(Object.keys(bad.writes).length).toBe(0); +}); +(0,__vite_ssr_import_0__.test)("實跑無回應就不建立 PR", async ($, on) => { + const s = await setup($, on, { reply: (p) => p.startsWith("請撰寫") ? GENERATED : undefined }); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + const r = await run($, "greet 打招呼"); + (0,__vite_ssr_import_0__.expect)(r.text.includes("實跑失敗")).toBe(true); + (0,__vite_ssr_import_0__.expect)(s.procs.some((p) => p.argv[0] === "tea")).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("技能驗證與版本規則", () => { + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.validateSkill)(SKILL, "greet").length).toBe(0); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.validateSkill)(SKILL, "other").length).toBe(1); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.bumpVersion)("0.3.4", "minor")).toBe("0.4.0"); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.bumpVersion)("0.3.4", "patch")).toBe("0.3.5"); + const list = (0,__vite_ssr_import_1__.upsertEntry)((0,__vite_ssr_import_1__.parseEntries)((0,__vite_ssr_import_1__.renderGuide)([{ + skill: "a", + description: "A" + }])), { + skill: "b", + description: "B" + }); + (0,__vite_ssr_import_0__.expect)(list.length).toBe(2); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.renderGuide)(list).includes("# /jsc-anima:jsc-anima")).toBe(true); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUFDeEUsQ0FBQyIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsic2tpbGx0b29sLnRlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhwZWN0LCBtb2NrLCB0ZXN0IH0gZnJvbSAnY2xhdWRlLWNvZGUvdGVzdGluZydcblxuaW1wb3J0IHsgYnVtcFZlcnNpb24sIHBhcnNlRW50cmllcywgcmVuZGVyR3VpZGUsIHVwc2VydEVudHJ5LCB2YWxpZGF0ZVNraWxsIH0gZnJvbSAnLi9za2lsbGdlbidcblxuY29uc3QgU0tJTEwgPSAnLS0tXFxubmFtZTogYW5pbWEtZ3JlZXRcXG5kZXNjcmlwdGlvbjog5omT5oub5ZG8XFxuLS0tXFxuXFxu55So6KeS6Imy5Y+j5ZC75ZCR5L2/55So6ICF5omT5oub5ZG877yM5Lim57Ch55+t6Kqq5piO5LuK5aSp55qE5b6F6L6m44CCXFxuJ1xuY29uc3QgR0VORVJBVEVEID0gSlNPTi5zdHJpbmdpZnkoeyBza2lsbDogU0tJTEwsIGV4YW1wbGU6ICfml6nlroknIH0pXG5cbnR5cGUgQ2FsbHMgPSB7IGFyZ3Y6IHN0cmluZ1tdIH1bXVxuXG4vLyDllZ/li5Xop5LoibLkuKbmm7/ouqvmiYDmnInlpJbpg6jvvJrmqKHlnovjgIHmqpTmoYjns7vntbHjgIFnaXTvvI90ZWHjgIJcbmFzeW5jIGZ1bmN0aW9uIHNldHVwKCQ6IGFueSwgb246IGFueSwgb3B0czogeyByZXBseT86IChwcm9tcHQ6IHN0cmluZykgPT4gc3RyaW5nIHwgdW5kZWZpbmVkOyBleGlzdGluZz86IGJvb2xlYW4gfSA9IHt9KSB7XG4gIGNvbnN0IHdyaXRlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9XG4gIGNvbnN0IHByb2NzOiBDYWxscyA9IFtdXG4gIG1vY2suc3RvcmUob24pXG4gIG9uKCdjb21tYW5kLnJlZ2lzdGVyJywgKCkgPT4gKHsgdmFsdWU6IHsgbmFtZTogJ3gnIH0gfSkgYXMgbmV2ZXIpXG4gIG9uKCdzZXNzaW9uLnN0YXJ0JywgKCkgPT4gKHsgY3dkOiAnL3JlcG8nIH0pIGFzIG5ldmVyKVxuICBvbignc2Vzc2lvbi5jd2QnLCAoKSA9PiAoeyB2YWx1ZTogJy9yZXBvJyB9KSlcbiAgb24oJ2NvbW1hbmQucnVuJywgKCkgPT4gKHsgdGV4dDogJycgfSkpXG4gIG9uKCdwcm9tcHQuY29tcG9zZScsICgpID0+ICh7IHNlY3Rpb25zOiBbXSB9KSlcbiAgb24oJ21vZGVsLmNvbXBsZXRlJywgKF86IGFueSwgZTogYW55KSA9PiB7XG4gICAgY29uc3QgdCA9IG9wdHMucmVwbHkgPyBvcHRzLnJlcGx5KFN0cmluZyhlLnByb21wdCkpIDogU3RyaW5nKGUucHJvbXB0KS5zdGFydHNXaXRoKCfoq4vmkrDlr6snKSA/IEdFTkVSQVRFRCA6ICfll6jvvIEnXG4gICAgcmV0dXJuIHsgdmFsdWU6IHQgPT09IHVuZGVmaW5lZCA/IHsgaXNBbnN3ZXJlZDogZmFsc2UsIHJlYXNvbjogJ2VtcHR5LXJlcGx5JyB9IDogeyBpc0Fuc3dlcmVkOiB0cnVlLCB0ZXh0OiB0LCB1c2FnZToge30gfSB9XG4gIH0pXG4gIG9uKCdwcm9jZXNzLnJ1bicsIChfOiBhbnksIGU6IGFueSkgPT4ge1xuICAgIHByb2NzLnB1c2goeyBhcmd2OiBbLi4uZS5hcmd2XSB9KVxuICAgIGNvbnN0IHMgPSBlLmFyZ3Yuam9pbignICcpXG4gICAgaWYgKHMuc3RhcnRzV2l0aCgnZ2l0IHJldi1wYXJzZScpKSByZXR1cm4geyB2YWx1ZTogeyBleGl0Q29kZTogMCwgc3Rkb3V0OiAnL3JlcG9cXG4nLCBzdGRlcnI6ICcnIH0gfVxuICAgIGlmIChzLnN0YXJ0c1dpdGgoJ2dpdCBzeW1ib2xpYy1yZWYnKSkgcmV0dXJuIHsgdmFsdWU6IHsgZXhpdENvZGU6IDAsIHN0ZG91dDogJ29yaWdpbi9tYWluXFxuJywgc3RkZXJyOiAnJyB9IH1cbiAgICBpZiAocy5zdGFydHNXaXRoKCd0ZWEgbG9naW5zJykpIHJldHVybiB7IHZhbHVlOiB7IGV4aXRDb2RlOiAwLCBzdGRvdXQ6ICdhZG1pblxcbicsIHN0ZGVycjogJycgfSB9XG4gICAgaWYgKHMuc3RhcnRzV2l0aCgndGVhIHB1bGxzJykpIHJldHVybiB7IHZhbHVlOiB7IGV4aXRDb2RlOiAwLCBzdGRvdXQ6ICdodHRwczovL2cvcHVsbHMvMVxcbicsIHN0ZGVycjogJycgfSB9XG4gICAgcmV0dXJuIHsgdmFsdWU6IHsgZXhpdENvZGU6IDAsIHN0ZG91dDogJycsIHN0ZGVycjogJycgfSB9XG4gIH0pXG4gIG9uKCdmcy5leGlzdHMnLCAoXzogYW55LCBlOiBhbnkpID0+ICh7IHZhbHVlOiBCb29sZWFuKG9wdHMuZXhpc3RpbmcgJiYgU3RyaW5nKGUucGF0aCkuZW5kc1dpdGgoJ2FuaW1hLWdyZWV0L1NLSUxMLm1kJykpIH0pKVxuICBvbignZnMucmVhZCcsIChfOiBhbnksIGU6IGFueSkgPT4gKHtcbiAgICB2YWx1ZTogU3RyaW5nKGUucGF0aCkuZW5kc1dpdGgoJ3BsdWdpbi5qc29uJykgPyAne1xcbiAgXCJ2ZXJzaW9uXCI6IFwiMC4zLjBcIlxcbn0nIDogU3RyaW5nKGUucGF0aCkuZW5kc1dpdGgoJ1JFQURNRS5tZCcpID8gJyMganNjLWFuaW1hXFxuJyA6ICcnLFxuICB9KSlcbiAgb24oJ2ZzLndyaXRlJywgKF86IGFueSwgZTogYW55KSA9PiB7XG4gICAgd3JpdGVzW2UucGF0aF0gPSBlLnRleHRcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkIH1cbiAgfSlcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9yZXBvJyB9IGFzIG5ldmVyKVxuICByZXR1cm4geyB3cml0ZXMsIHByb2NzIH1cbn1cblxuY29uc3QgcnVuID0gKCQ6IGFueSwgYXJnczogc3RyaW5nKSA9PiAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ2FuaW1hLXNraWxsJywgYXJncyB9IGFzIG5ldmVyKVxuXG50ZXN0KCfmnKrllZ/li5Xop5LoibLmmYLlt6Xlhbfkuozooqvmi5LntZXkuKbmj5DnpLrlhYjllZ/li5UnLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgeyBwcm9jcyB9ID0gYXdhaXQgc2V0dXAoJCwgb24pXG4gIGNvbnN0IHIgPSBhd2FpdCBydW4oJCwgJ2dyZWV0IOaJk+aLm+WRvCcpXG4gIGV4cGVjdChyLnRleHQuaW5jbHVkZXMoJ+iri+WFiOWVn+WLleinkuiJsicpKS50b0JlKHRydWUpXG4gIGV4cGVjdChwcm9jcy5sZW5ndGgpLnRvQmUoMClcbn0pXG5cbnRlc3QoJ+aWsOWinuaKgOiDve+8muWvq+aqlOOAgeWNhyBtaW5vcuOAgeabtOaWsCBSRUFETUXjgIHlu7rnq4sgUFInLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgeyB3cml0ZXMsIHByb2NzIH0gPSBhd2FpdCBzZXR1cCgkLCBvbilcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdzYW8tYXN1bmEnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxuICBjb25zdCByID0gYXdhaXQgcnVuKCQsICdncmVldCDmiZPmi5vlkbwnKVxuICBjb25zdCBrZXkgPSAoc3VmZml4OiBzdHJpbmcpID0+IE9iamVjdC5rZXlzKHdyaXRlcykuZmluZChrID0+IGsuZW5kc1dpdGgoc3VmZml4KSkhXG4gIGV4cGVjdCh3cml0ZXNba2V5KCdza2lsbHMvYW5pbWEtZ3JlZXQvU0tJTEwubWQnKV0hLmluY2x1ZGVzKCduYW1lOiBhbmltYS1ncmVldCcpKS50b0JlKHRydWUpXG4gIGV4cGVjdCh3cml0ZXNba2V5KCcuY2xhdWRlLXBsdWdpbi9wbHVnaW4uanNvbicpXSEuaW5jbHVkZXMoJ1wiMC40LjBcIicpKS50b0JlKHRydWUpXG4gIGV4cGVjdCh3cml0ZXNba2V5KCcvUkVBRE1FLm1kJyldIS5pbmNsdWRlcygn55uu5YmN54mI5pys77yaMC40LjAnKSB8fCBPYmplY3QudmFsdWVzKHdyaXRlcykuc29tZSh2ID0+IHYuaW5jbHVkZXMoJ+ebruWJjeeJiOacrO+8mjAuNC4wJykpKS50b0JlKHRydWUpXG4gIGV4cGVjdCh3cml0ZXNba2V5KCdza2lsbHMvanNjLWFuaW1hL1JFQURNRS5tZCcpXSEuaW5jbHVkZXMoJy9qc2MtYW5pbWE6YW5pbWEtZ3JlZXQnKSkudG9CZSh0cnVlKVxuICBleHBlY3QocHJvY3Muc29tZShwID0+IHAuYXJndi5qb2luKCcgJykuc3RhcnRzV2l0aCgnZ2l0IGNvbW1pdCcpICYmIHAuYXJndi5qb2luKCcgJykuaW5jbHVkZXMoJ2ZlYXQ6IOaWsOWinuaKgOiDvScpKSkudG9CZSh0cnVlKVxuICBjb25zdCBwciA9IHByb2NzLmZpbmQocCA9PiBwLmFyZ3ZbMF0gPT09ICd0ZWEnICYmIHAuYXJndlsxXSA9PT0gJ3B1bGxzJykhXG4gIGV4cGVjdChwci5hcmd2LmluY2x1ZGVzKCdtYWluJykpLnRvQmUodHJ1ZSlcbiAgZXhwZWN0KHByLmFyZ3YuaW5jbHVkZXMoJ2ZlYXQvYW5pbWEtZ3JlZXQnKSkudG9CZSh0cnVlKVxuICBleHBlY3Qoci50ZXh0LmluY2x1ZGVzKCdodHRwczovL2cvcHVsbHMvMScpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCfmioDog73lt7LlrZjlnKjliYfopobok4vkuKbljYcgcGF0Y2gnLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgeyB3cml0ZXMgfSA9IGF3YWl0IHNldHVwKCQsIG9uLCB7IGV4aXN0aW5nOiB0cnVlIH0pXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnc2FvLWFzdW5hJywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgYXdhaXQgcnVuKCQsICdncmVldCDmiZPmi5vlkbwnKVxuICBleHBlY3QoT2JqZWN0LmVudHJpZXMod3JpdGVzKS5zb21lKChbaywgdl0pID0+IGsuZW5kc1dpdGgoJ3BsdWdpbi5qc29uJykgJiYgdi5pbmNsdWRlcygnXCIwLjMuMVwiJykpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCfpqZforYnlpLHmlZfmiJblr6bot5HlpLHmlZflsLHkuI3lu7rnq4sgUFInLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgYmFkID0gYXdhaXQgc2V0dXAoJCwgb24sIHsgcmVwbHk6ICgpID0+IEpTT04uc3RyaW5naWZ5KHsgc2tpbGw6ICdubyBmcm9udG1hdHRlcicsIGV4YW1wbGU6ICd4JyB9KSB9KVxuICBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ3Nhby1hc3VuYScsIGFyZ3M6ICcnIH0gYXMgbmV2ZXIpXG4gIGNvbnN0IHIxID0gYXdhaXQgcnVuKCQsICdncmVldCDmiZPmi5vlkbwnKVxuICBleHBlY3QocjEudGV4dC5pbmNsdWRlcygn6amX6K2J5aSx5pWXJykpLnRvQmUodHJ1ZSlcbiAgZXhwZWN0KGJhZC5wcm9jcy5zb21lKHAgPT4gcC5hcmd2WzBdID09PSAndGVhJykpLnRvQmUoZmFsc2UpXG4gIGV4cGVjdChPYmplY3Qua2V5cyhiYWQud3JpdGVzKS5sZW5ndGgpLnRvQmUoMClcbn0pXG5cbnRlc3QoJ+Wvpui3keeEoeWbnuaHieWwseS4jeW7uueriyBQUicsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBzID0gYXdhaXQgc2V0dXAoJCwgb24sIHsgcmVwbHk6IHAgPT4gKHAuc3RhcnRzV2l0aCgn6KuL5pKw5a+rJykgPyBHRU5FUkFURUQgOiB1bmRlZmluZWQpIH0pXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnc2FvLWFzdW5hJywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgY29uc3QgciA9IGF3YWl0IHJ1bigkLCAnZ3JlZXQg5omT5oub5ZG8JylcbiAgZXhwZWN0KHIudGV4dC5pbmNsdWRlcygn5a+m6LeR5aSx5pWXJykpLnRvQmUodHJ1ZSlcbiAgZXhwZWN0KHMucHJvY3Muc29tZShwID0+IHAuYXJndlswXSA9PT0gJ3RlYScpKS50b0JlKGZhbHNlKVxufSlcblxudGVzdCgn5oqA6IO96amX6K2J6IiH54mI5pys6KaP5YmHJywgKCkgPT4ge1xuICBleHBlY3QodmFsaWRhdGVTa2lsbChTS0lMTCwgJ2dyZWV0JykubGVuZ3RoKS50b0JlKDApXG4gIGV4cGVjdCh2YWxpZGF0ZVNraWxsKFNLSUxMLCAnb3RoZXInKS5sZW5ndGgpLnRvQmUoMSlcbiAgZXhwZWN0KGJ1bXBWZXJzaW9uKCcwLjMuNCcsICdtaW5vcicpKS50b0JlKCcwLjQuMCcpXG4gIGV4cGVjdChidW1wVmVyc2lvbignMC4zLjQnLCAncGF0Y2gnKSkudG9CZSgnMC4zLjUnKVxuICBjb25zdCBsaXN0ID0gdXBzZXJ0RW50cnkocGFyc2VFbnRyaWVzKHJlbmRlckd1aWRlKFt7IHNraWxsOiAnYScsIGRlc2NyaXB0aW9uOiAnQScgfV0pKSwgeyBza2lsbDogJ2InLCBkZXNjcmlwdGlvbjogJ0InIH0pXG4gIGV4cGVjdChsaXN0Lmxlbmd0aCkudG9CZSgyKVxuICBleHBlY3QocmVuZGVyR3VpZGUobGlzdCkuaW5jbHVkZXMoJyMgL2pzYy1hbmltYTpqc2MtYW5pbWEnKSkudG9CZSh0cnVlKVxufSlcbiJdLCJmaWxlIjoiL2hvb2tzL3NraWxsdG9vbC50ZXN0LnRzIn0= + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3Mvc2tpbGx0b29sLnRlc3QudHMiLCIvaG9va3Mvc2tpbGx0b29sLnRlc3QudHMiLHsidXJscyI6IjYiLCJpZHMiOiI3In0sWyI4IiwiOSJdLFtdLFsiOCIsIjkiXSx7fSwiY2xhdWRlLWNvZGUvdGVzdGluZyIsIi9ob29rcy9za2lsbGdlbi50cyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/4c2042672310817dab2dc679342b2efbfcc6937b b/node_modules/.vitest-cache/4c2042672310817dab2dc679342b2efbfcc6937b new file mode 100644 index 0000000..0783beb --- /dev/null +++ b/node_modules/.vitest-cache/4c2042672310817dab2dc679342b2efbfcc6937b @@ -0,0 +1,558 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); + +const setup = (on, kv) => { + const ctl = { + complete: () => ({ + isAnswered: false, + reason: "aborted" + }), + usage: { + rateLimits: [], + context: {} + }, + submitted: [] + }; + if (kv) { + // 自備 store 以便檢查寫入內容。 + on("store.get", (_$, e) => ({ value: kv.get(e.key) })); + on("store.set", (_$, e) => (kv.set(e.key, e.value), { value: undefined })); + } else __vite_ssr_import_0__.mock.store(on); + ctl.clock = __vite_ssr_import_0__.mock.clock(on, { now: Date.parse("2026-10-15T08:00:00Z") }); + on("ui.log", () => ({ value: undefined })); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: "/tmp" })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); + on("prompt.submit", (_$, e) => (ctl.submitted.push(e.text), { text: e.text })); + on("model.complete", (_$, e) => ({ value: ctl.complete(e) })); + on("session.usage", () => ({ value: ctl.usage })); + on("turn.step", async function* (_$, e) { + ctl.seen = e; + return { + turnId: e.turnId, + index: 0, + answer: "", + toolUses: [], + stopReason: null, + usage: null + }; + }); + return ctl; +}; +const start = async ($, slug = "sao-asuna") => { + await $.session.start({ + source: "startup", + cwd: "/tmp" + }); + await $.command.run({ + command: slug, + args: "" + }); +}; +const affinity = async ($) => { + const r = await $.command.run({ + command: "anima-affinity", + args: "" + }); + return Number(/好感度 (\d+)/.exec(r.text)?.[1]); +}; +const submit = ($, text) => $.prompt.submit({ text }); +const step = async ($, model) => { + const s = $.turn.step({ + turnId: "t", + index: 0, + model, + messageCount: 1 + }); + for await (const _ of s) void _; +}; +const usage = { + input_tokens: 1, + output_tokens: 1 +}; +const route = (model, tone = "neutral") => ({ + isAnswered: true, + usage, + text: `{"difficulty":9,"model":"${model}","effort":"high","tone":"${tone}","ack":"好,我來看看。"}` +}); +const row = (text) => ({ + message: { + type: "assistant", + role: "assistant", + content: [{ + type: "text", + text + }] + }, + door: "response", + origin: { + kind: "model", + model: "m" + }, + uuid: "u" +}); +(0,__vite_ssr_import_0__.test)("輸入由 Haiku 一次分類,並依分類覆寫 turn.step 的模型與思考程度", async ($, on) => { + const ctl = setup(on); + const asked = []; + ctl.complete = (e) => (asked.push(e.model), route("opus")); + await start($); + await submit($, "請重構整個模組"); + await step($, "sonnet"); + (0,__vite_ssr_import_0__.expect)(asked).toEqual(["haiku"]); + (0,__vite_ssr_import_0__.expect)(ctl.seen.model).toBe("opus"); + (0,__vite_ssr_import_0__.expect)(ctl.seen.effort).toBe("high"); +}); +(0,__vite_ssr_import_0__.test)("額度低於門檻自動降一級", async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("opus"); + ctl.usage = { + rateLimits: [{ + kind: "five_hour", + percentUsed: 95 + }], + context: {} + }; + await start($); + await submit($, "x"); + await step($, "opus"); + (0,__vite_ssr_import_0__.expect)(ctl.seen.model).toBe("sonnet"); +}); +(0,__vite_ssr_import_0__.test)("手動鎖定模型與思考程度", { options: { + lockModel: "haiku", + lockEffort: "low" +} }, async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("opus"); + await start($); + await submit($, "x"); + await step($, "opus"); + (0,__vite_ssr_import_0__.expect)([ctl.seen.model, ctl.seen.effort]).toEqual(["haiku", "low"]); +}); +(0,__vite_ssr_import_0__.test)("回覆改寫:保留程式碼、路徑、URL、數字;前綴只加在開頭一次", async ($, on) => { + const ctl = setup(on); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt).replace("完成了", "做好囉") + }); + await start($); + const src = "完成了,改了 `npm test` 與 /src/a/b.ts,見 https://x.dev/a,共 42 處。"; + const r1 = await $.session.append(row(src)); + (0,__vite_ssr_import_0__.expect)(r1.message.content[0].text).toBe("亞絲娜 > 做好囉,改了 `npm test` 與 /src/a/b.ts,見 https://x.dev/a,共 42 處。"); + const r2 = await $.session.append(row("第二段 7")); + (0,__vite_ssr_import_0__.expect)(r2.message.content[0].text.startsWith("亞絲娜 >")).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("改寫失敗或遺失佔位符時顯示原文", async ($, on) => { + const ctl = setup(on); + await start($); + const r1 = await $.session.append(row("原文 `x` 3")); + (0,__vite_ssr_import_0__.expect)(r1.message.content[0].text).toBe("亞絲娜 > 原文 `x` 3"); + ctl.complete = () => ({ + isAnswered: true, + usage, + text: "丟了佔位符" + }); + const r2 = await $.session.append(row("原文 `y` 5")); + (0,__vite_ssr_import_0__.expect)(r2.message.content[0].text).toBe("原文 `y` 5"); +}); +(0,__vite_ssr_import_0__.test)("改寫模型:長回覆用 Sonnet,一般回覆用 Haiku", async ($, on) => { + const ctl = setup(on); + const asked = []; + ctl.complete = (e) => (asked.push(e.model), { + isAnswered: true, + usage, + text: String(e.prompt) + }); + await start($); + await $.session.append(row("短回覆")); + await $.session.append(row("長".repeat(1300))); + (0,__vite_ssr_import_0__.expect)(asked).toEqual(["haiku", "sonnet"]); +}); +(0,__vite_ssr_import_0__.test)("longReply 可調整長回覆門檻", { options: { longReply: 10 } }, async ($, on) => { + const ctl = setup(on); + const asked = []; + ctl.complete = (e) => (asked.push(e.model), { + isAnswered: true, + usage, + text: String(e.prompt) + }); + await start($); + await $.session.append(row("十一個字的回覆內容喔喔")); + await $.session.append(row("短")); + (0,__vite_ssr_import_0__.expect)(asked).toEqual(["sonnet", "haiku"]); +}); +(0,__vite_ssr_import_0__.test)("改寫逾時、額度不足或拋錯時直接顯示原文", async ($, on) => { + const ctl = setup(on); + await start($); + ctl.complete = () => ({ + isAnswered: false, + reason: "timeout" + }); + const r1 = await $.session.append(row("逾時 1")); + (0,__vite_ssr_import_0__.expect)(r1.message.content[0].text).toBe("亞絲娜 > 逾時 1"); + ctl.complete = () => ({ + isAnswered: false, + reason: "rate_limited" + }); + const r2 = await $.session.append(row("額度 2")); + (0,__vite_ssr_import_0__.expect)(r2.message.content[0].text).toBe("額度 2"); + ctl.complete = () => { + throw new Error("quota"); + }; + const r3 = await $.session.append(row("拋錯 3")); + (0,__vite_ssr_import_0__.expect)(r3.message.content[0].text).toBe("拋錯 3"); +}); +(0,__vite_ssr_import_0__.test)("改寫逾時設定傳給模型呼叫", { options: { rewriteTimeoutSec: 5 } }, async ($, on) => { + const ctl = setup(on); + let timeout = 0; + ctl.complete = (e) => (timeout = e.timeoutMs, { + isAnswered: false, + reason: "timeout" + }); + await start($); + await $.session.append(row("x")); + (0,__vite_ssr_import_0__.expect)(timeout).toBe(5e3); +}); +const rawLog = (kv) => (kv.get("rawlog") ?? []).map((x) => x.raw); +(0,__vite_ssr_import_0__.test)("原文 log 預設寫入,改寫失敗時不寫", async ($, on) => { + const kv = new Map(); + const ctl = setup(on, kv); + await start($); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt) + }); + await $.session.append(row("原文甲")); + ctl.complete = () => ({ + isAnswered: false, + reason: "timeout" + }); + await $.session.append(row("原文乙")); + (0,__vite_ssr_import_0__.expect)(rawLog(kv)).toEqual(["原文甲"]); +}); +(0,__vite_ssr_import_0__.test)("在 /config 關閉原文 log 時不寫入", { options: { rawLog: false } }, async ($, on) => { + const kv = new Map(); + const ctl = setup(on, kv); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt) + }); + await start($); + const r = await $.session.append(row("原文丙")); + (0,__vite_ssr_import_0__.expect)(r.message.content[0].text).toBe("亞絲娜 > 原文丙"); + (0,__vite_ssr_import_0__.expect)(rawLog(kv)).toEqual([]); +}); +(0,__vite_ssr_import_0__.test)("前綴只加在整則回覆開頭一次,多段文字區塊與多次寫入都不重複", async ($, on) => { + const ctl = setup(on); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt) + }); + await start($); + const multi = { + message: { + type: "assistant", + role: "assistant", + content: [ + { + type: "text", + text: "第一段" + }, + { + type: "tool_use", + id: "t", + name: "x", + input: {} + }, + { + type: "text", + text: "第二段" + } + ] + }, + door: "response", + origin: { + kind: "model", + model: "m" + }, + uuid: "u" + }; + const r = await $.session.append(multi); + (0,__vite_ssr_import_0__.expect)(r.message.content[0].text).toBe("亞絲娜 > 第一段"); + (0,__vite_ssr_import_0__.expect)(r.message.content[2].text).toBe("第二段"); + const r2 = await $.session.append(row("同一回覆後續")); + (0,__vite_ssr_import_0__.expect)(r2.message.content[0].text).toBe("同一回覆後續"); +}); +(0,__vite_ssr_import_0__.test)("新的使用者輸入後,下一則回覆重新加前綴", async ($, on) => { + const ctl = setup(on); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt) + }); + await start($); + await $.session.append(row("第一則")); + ctl.complete = () => route("haiku"); + await submit($, "再問一次"); + ctl.complete = (e) => ({ + isAnswered: true, + usage, + text: String(e.prompt) + }); + const r = await $.session.append(row("第二則")); + (0,__vite_ssr_import_0__.expect)(r.message.content[0].text).toBe("亞絲娜 > 第二則"); +}); +(0,__vite_ssr_import_0__.test)("好感度:由 0 開始,每日首次互動加分且有每日上限", async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("haiku", "praise"); + await start($); + (0,__vite_ssr_import_0__.expect)(await affinity($)).toBe(0); + await submit($, "謝謝你,做得很好"); + const n = await affinity($); + (0,__vite_ssr_import_0__.expect)(n > 0 && n <= 5).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("關閉好感度時不記錄", { options: { affinity: false } }, async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("haiku", "praise"); + await start($); + await submit($, "謝謝"); + (0,__vite_ssr_import_0__.expect)(await affinity($)).toBe(0); +}); +const personaText = async ($) => { + const res = await $.prompt.compose({ + model: "m", + promptModel: "m", + surfaces: [], + tools: [], + outputStyle: null, + traits: [] + }); + return res.sections.find((s) => s.id === "jsc-anima:persona")?.text ?? ""; +}; +(0,__vite_ssr_import_0__.test)("好感度被責罵扣分但不跨階段掉落;可手動設定與重置", async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("haiku", "scold"); + await start($); + await $.command.run({ + command: "anima-affinity", + args: "20" + }); + await submit($, "你好笨"); + (0,__vite_ssr_import_0__.expect)(await affinity($) >= 20).toBe(true); + await $.command.run({ + command: "anima-affinity", + args: "reset" + }); + (0,__vite_ssr_import_0__.expect)(await affinity($)).toBe(0); +}); +(0,__vite_ssr_import_0__.test)("好感度階段反映在語氣,且不使用情緒勒索", async ($, on) => { + setup(on); + await start($); + const t0 = await personaText($); + (0,__vite_ssr_import_0__.expect)(t0.includes("生疏")).toBe(true); + (0,__vite_ssr_import_0__.expect)(t0.includes("不使用愧疚感或情緒勒索")).toBe(true); + await $.command.run({ + command: "anima-affinity", + args: "85" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("特別的存在")).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("未成年角色維持友情,即使好感度最高且開啟戀愛式依賴", { options: { romance: true } }, async ($, on) => { + setup(on); + await start($, "sao-suguha"); + await $.command.run({ + command: "anima-affinity", + args: "100" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("關係定位:友情")).toBe(true); +}); +// 以 fs 事件邊界提供角色包(characters/index.json),讓外掛自行載入成年角色。 +const packs = (on, list) => { + const files = new Map(); + files.set("index.json", JSON.stringify({ packs: list.map((p) => ({ + work: "tw", + workName: "測試作品", + slug: p.slug + })) })); + for (const p of list) { + files.set(`tw/${p.slug}.json`, JSON.stringify({ + work: "tw", + slug: p.slug, + name: "成年測試", + persona: { + selfRef: "我", + address: "你", + tone: "平穩", + catchphrase: "好", + values: "可靠", + taboos: "無" + }, + axes: { + gentle: 5, + tsundere: 5, + lively: 5, + formal: 5, + talkative: 5, + humor: 5, + proactive: 5, + expressive: 5 + }, + anime: { + moe: "", + speech: "", + emotions: "", + kaomoji: "", + themeColor: "cyan" + }, + timeline: [{ + chapter: "第1章", + age: 17, + relationships: [] + }, { + chapter: "第2章", + age: 20, + relationships: p.romance ? [{ + with: p.romance, + kind: "romantic" + }] : [] + }] + })); + }; + const key = (path) => path.replace(/^.*\/characters\//, ""); + on("fs.exists", (_$, e) => ({ value: files.has(key(e.path)) })); + on("fs.read", (_$, e) => ({ value: files.get(key(e.path)) ?? "" })); +}; +(0,__vite_ssr_import_0__.test)("成年且原作有戀愛關係:關係移轉給使用者,原戀人退為過去的重要人物", async ($, on) => { + setup(on); + packs(on, [{ + slug: "lover", + romance: "桐人" + }]); + await start($, "tw-lover"); + const t = await personaText($); + (0,__vite_ssr_import_0__.expect)(t.includes("已移轉給使用者")).toBe(true); + (0,__vite_ssr_import_0__.expect)(t.includes("桐人")).toBe(true); + (0,__vite_ssr_import_0__.expect)(t.includes("過去的重要人物")).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("成年但原作無戀愛關係:需最高階段且明確開啟才進入戀愛式依賴", async ($, on) => { + setup(on); + packs(on, [{ slug: "plain" }]); + await start($, "tw-plain"); + await $.command.run({ + command: "anima-affinity", + args: "100" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("戀愛式依賴")).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("成年無戀愛、最高階段但未在 /config 開啟:維持夥伴關係", { options: { romance: false } }, async ($, on) => { + setup(on); + packs(on, [{ slug: "plain" }]); + await start($, "tw-plain"); + await $.command.run({ + command: "anima-affinity", + args: "100" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("夥伴與朋友")).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("成年無戀愛、已開啟但好感度未達最高階段:不進入戀愛式依賴", { options: { romance: true } }, async ($, on) => { + setup(on); + packs(on, [{ slug: "plain" }]); + await start($, "tw-plain"); + await $.command.run({ + command: "anima-affinity", + args: "79" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("戀愛式依賴")).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("成年無戀愛、最高階段且已開啟:進入戀愛式依賴", { options: { romance: true } }, async ($, on) => { + setup(on); + packs(on, [{ slug: "plain" }]); + await start($, "tw-plain"); + await $.command.run({ + command: "anima-affinity", + args: "80" + }); + (0,__vite_ssr_import_0__.expect)((await personaText($)).includes("戀愛式依賴")).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("長期不互動好感度緩慢下降,但不跨階段掉落", async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("haiku"); + await start($); + await submit($, "你好"); + await $.command.run({ + command: "anima-affinity", + args: "45" + }); + await ctl.clock.advance(30 * 864e5); + await submit($, "我回來了"); + const n = await affinity($); + (0,__vite_ssr_import_0__.expect)(n < 45).toBe(true); + (0,__vite_ssr_import_0__.expect)(n >= 40).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("個性軸影響扣分倍率:傲嬌角色掉得比溫柔角色多", async ($, on) => { + const ctl = setup(on); + ctl.complete = () => route("haiku"); + packs(on, [{ slug: "plain" }]); + const run = async (slug) => { + await start($, slug); + await submit($, "你好"); + await $.command.run({ + command: "anima-affinity", + args: "70" + }); + await ctl.clock.advance(8 * 864e5); + await submit($, "我回來了"); + return affinity($); + }; + const proud = await run("tw-plain"); + const calm = await run("sao-suguha"); + (0,__vite_ssr_import_0__.expect)(proud < calm).toBe(true); +}); +const workRoute = (model, work) => ({ + isAnswered: true, + usage, + text: `{"difficulty":8,"model":"${model}","effort":"high","tone":"neutral","ack":"好,我來處理。","work":${work}}` +}); +(0,__vite_ssr_import_0__.test)("需要動手的要求交給背景工作線,對話線改用 Haiku", async ($, on) => { + const ctl = setup(on); + const spawned = []; + on("agent.spawn", (_$, e) => (spawned.push(e), { + model: e.model, + agentId: "a1" + })); + ctl.complete = () => workRoute("opus", true); + await start($); + await submit($, "幫我重構 src 目錄"); + (0,__vite_ssr_import_0__.expect)(spawned.length).toBe(1); + (0,__vite_ssr_import_0__.expect)(spawned[0].model).toBe("opus"); + await step($, "main"); + (0,__vite_ssr_import_0__.expect)(ctl.seen.model).toBe("haiku"); + const sys = await $.prompt.compose({ + model: "m", + promptModel: "m", + surfaces: [], + tools: [], + outputStyle: null, + traits: [] + }); + (0,__vite_ssr_import_0__.expect)(sys.sections.find((s) => s.id === "jsc-anima:persona")?.text).toContain("背景工作線"); +}); +(0,__vite_ssr_import_0__.test)("work 為 false 或關閉背景工作線時不派工", async ($, on) => { + const ctl = setup(on); + let n = 0; + on("agent.spawn", () => (n++, { + model: "m", + agentId: "a" + })); + ctl.complete = () => workRoute("sonnet", false); + await start($); + await submit($, "你好"); + (0,__vite_ssr_import_0__.expect)(n).toBe(0); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUE7O0FBSUEsTUFBTSxTQUFTLElBQVMsT0FBbUM7Q0FDekQsTUFBTSxNQUFXO0VBQUUsaUJBQWlCO0dBQUUsWUFBWTtHQUFPLFFBQVE7RUFBVTtFQUFJLE9BQU87R0FBRSxZQUFZLENBQUM7R0FBRyxTQUFTLENBQUM7RUFBRTtFQUFHLFdBQVcsQ0FBQztDQUFFO0NBQ3JJLElBQUksSUFBSTs7RUFFTixHQUFHLGNBQWMsSUFBUyxPQUFZLEVBQUUsT0FBTyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBVztFQUN4RSxHQUFHLGNBQWMsSUFBUyxPQUFZLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEdBQUcsRUFBRSxPQUFPLFVBQVUsRUFBVztDQUM5RixPQUFPLDJCQUFLLE1BQU0sRUFBRTtDQUNwQixJQUFJLFFBQVEsMkJBQUssTUFBTSxJQUFJLEVBQUUsS0FBSyxLQUFLLE1BQU0sc0JBQXNCLEVBQUUsQ0FBQztDQUN0RSxHQUFHLGlCQUFpQixFQUFFLE9BQU8sVUFBVSxFQUFXO0NBQ2xELEdBQUcsMkJBQTJCLEVBQUUsT0FBTyxFQUFFLE1BQU0sSUFBSSxFQUFFLEVBQVc7Q0FDaEUsR0FBRyx3QkFBd0IsRUFBRSxLQUFLLE9BQU8sRUFBVztDQUNwRCxHQUFHLHNCQUFzQixFQUFFLE1BQU0sR0FBRyxFQUFFO0NBQ3RDLEdBQUcseUJBQXlCLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRTtDQUM3QyxHQUFHLGtCQUFrQixJQUFTLE9BQVksSUFBSSxVQUFVLEtBQUssRUFBRSxJQUFJLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFXO0NBQ2hHLEdBQUcsbUJBQW1CLElBQVMsT0FBWSxFQUFFLE9BQU8sSUFBSSxTQUFTLENBQUMsRUFBRSxFQUFXO0NBQy9FLEdBQUcsd0JBQXdCLEVBQUUsT0FBTyxJQUFJLE1BQU0sRUFBVztDQUN6RCxHQUFHLGFBQWEsaUJBQWlCLElBQVMsR0FBUTtFQUNoRCxJQUFJLE9BQU87RUFDWCxPQUFPO0dBQUUsUUFBUSxFQUFFO0dBQVEsT0FBTztHQUFHLFFBQVE7R0FBSSxVQUFVLENBQUM7R0FBRyxZQUFZO0dBQU0sT0FBTztFQUFLO0NBQy9GLENBQUM7Q0FDRCxPQUFPO0FBQ1Q7QUFFQSxNQUFNLFFBQVEsT0FBTyxHQUFRLE9BQU8sZ0JBQWdCO0NBQ2xELE1BQU0sRUFBRSxRQUFRLE1BQU07RUFBRSxRQUFRO0VBQVcsS0FBSztDQUFPLENBQVU7Q0FDakUsTUFBTSxFQUFFLFFBQVEsSUFBSTtFQUFFLFNBQVM7RUFBTSxNQUFNO0NBQUcsQ0FBVTtBQUMxRDtBQUVBLE1BQU0sV0FBVyxPQUFPLE1BQTRCO0NBQ2xELE1BQU0sSUFBUyxNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQUcsQ0FBVTtDQUNuRixPQUFPLE9BQU8sWUFBWSxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUM3QztBQUVBLE1BQU0sVUFBVSxHQUFRLFNBQWlCLEVBQUUsT0FBTyxPQUFPLEVBQUUsS0FBSyxDQUFVO0FBQzFFLE1BQU0sT0FBTyxPQUFPLEdBQVEsVUFBa0I7Q0FDNUMsTUFBTSxJQUFJLEVBQUUsS0FBSyxLQUFLO0VBQUUsUUFBUTtFQUFLLE9BQU87RUFBRztFQUFPLGNBQWM7Q0FBRSxDQUFVO0NBQ2hGLFdBQVcsTUFBTSxLQUFLLEdBQUcsS0FBSztBQUNoQztBQUNBLE1BQU0sUUFBUTtDQUFFLGNBQWM7Q0FBRyxlQUFlO0FBQUU7QUFDbEQsTUFBTSxTQUFTLE9BQWUsT0FBTyxlQUFlO0NBQUUsWUFBWTtDQUFNO0NBQU8sTUFBTSw0QkFBNEIsTUFBTSw0QkFBNEIsS0FBSztBQUFvQjtBQUM1SyxNQUFNLE9BQU8sVUFBa0I7Q0FBRSxTQUFTO0VBQUUsTUFBTTtFQUFhLE1BQU07RUFBYSxTQUFTLENBQUM7R0FBRSxNQUFNO0dBQVE7RUFBSyxDQUFDO0NBQUU7Q0FBRyxNQUFNO0NBQVksUUFBUTtFQUFFLE1BQU07RUFBUyxPQUFPO0NBQUk7Q0FBRyxNQUFNO0FBQUk7QUFFMUwsK0JBQUssNENBQTRDLE9BQU8sR0FBRyxPQUFPO0NBQ2hFLE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsTUFBTSxRQUFrQixDQUFDO0NBQ3pCLElBQUksWUFBVyxPQUFNLE1BQU0sS0FBSyxFQUFFLEtBQUssR0FBRyxNQUFNLE1BQU07Q0FDdEQsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLE9BQU8sR0FBRyxTQUFTO0NBQ3pCLE1BQU0sS0FBSyxHQUFHLFFBQVE7Q0FDdEIsaUNBQU8sS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztDQUMvQixpQ0FBTyxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsS0FBSyxNQUFNO0NBQ2xDLGlDQUFPLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxLQUFLLE1BQU07QUFDckMsQ0FBQztBQUVELCtCQUFLLGVBQWUsT0FBTyxHQUFHLE9BQU87Q0FDbkMsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLGlCQUFpQixNQUFNLE1BQU07Q0FDakMsSUFBSSxRQUFRO0VBQUUsWUFBWSxDQUFDO0dBQUUsTUFBTTtHQUFhLGFBQWE7RUFBRyxDQUFDO0VBQUcsU0FBUyxDQUFDO0NBQUU7Q0FDaEYsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLE9BQU8sR0FBRyxHQUFHO0NBQ25CLE1BQU0sS0FBSyxHQUFHLE1BQU07Q0FDcEIsaUNBQU8sSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLEtBQUssUUFBUTtBQUN0QyxDQUFDO0FBRUQsK0JBQUssZUFBZSxFQUFFLFNBQVM7Q0FBRSxXQUFXO0NBQVMsWUFBWTtBQUFNLEVBQUUsR0FBRyxPQUFPLEdBQUcsT0FBTztDQUMzRixNQUFNLE1BQU0sTUFBTSxFQUFFO0NBQ3BCLElBQUksaUJBQWlCLE1BQU0sTUFBTTtDQUNqQyxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sT0FBTyxHQUFHLEdBQUc7Q0FDbkIsTUFBTSxLQUFLLEdBQUcsTUFBTTtDQUNwQixpQ0FBTyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEtBQUssQ0FBQztBQUNwRSxDQUFDO0FBRUQsK0JBQUssa0NBQWtDLE9BQU8sR0FBRyxPQUFPO0NBQ3RELE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsSUFBSSxZQUFXLE9BQU07RUFBRSxZQUFZO0VBQU07RUFBTyxNQUFNLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLE9BQU8sS0FBSztDQUFFO0NBQzdGLE1BQU0sTUFBTSxDQUFDO0NBQ2IsTUFBTSxNQUFNO0NBQ1osTUFBTSxLQUFVLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxHQUFHLENBQUM7Q0FDL0MsaUNBQU8sR0FBRyxRQUFRLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssaUVBQWlFO0NBQ3pHLE1BQU0sS0FBVSxNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksT0FBTyxDQUFDO0NBQ25ELGlDQUFPLEdBQUcsUUFBUSxRQUFRLEVBQUUsQ0FBQyxLQUFLLFdBQVcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUs7QUFDbkUsQ0FBQztBQUVELCtCQUFLLG1CQUFtQixPQUFPLEdBQUcsT0FBTztDQUN2QyxNQUFNLE1BQU0sTUFBTSxFQUFFO0NBQ3BCLE1BQU0sTUFBTSxDQUFDO0NBQ2IsTUFBTSxLQUFVLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxVQUFVLENBQUM7Q0FDdEQsaUNBQU8sR0FBRyxRQUFRLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssZ0JBQWdCO0NBQ3hELElBQUksa0JBQWtCO0VBQUUsWUFBWTtFQUFNO0VBQU8sTUFBTTtDQUFRO0NBQy9ELE1BQU0sS0FBVSxNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksVUFBVSxDQUFDO0NBQ3RELGlDQUFPLEdBQUcsUUFBUSxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFVBQVU7QUFDcEQsQ0FBQztBQUVELCtCQUFLLGdDQUFnQyxPQUFPLEdBQUcsT0FBTztDQUNwRCxNQUFNLE1BQU0sTUFBTSxFQUFFO0NBQ3BCLE1BQU0sUUFBa0IsQ0FBQztDQUN6QixJQUFJLFlBQVcsT0FBTSxNQUFNLEtBQUssRUFBRSxLQUFLLEdBQUc7RUFBRSxZQUFZO0VBQU07RUFBTyxNQUFNLE9BQU8sRUFBRSxNQUFNO0NBQUU7Q0FDNUYsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksS0FBSyxDQUFDO0NBQ2pDLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLENBQUM7Q0FDNUMsaUNBQU8sS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsUUFBUSxDQUFDO0FBQzNDLENBQUM7QUFFRCwrQkFBSyxzQkFBc0IsRUFBRSxTQUFTLEVBQUUsV0FBVyxHQUFHLEVBQUUsR0FBRyxPQUFPLEdBQUcsT0FBTztDQUMxRSxNQUFNLE1BQU0sTUFBTSxFQUFFO0NBQ3BCLE1BQU0sUUFBa0IsQ0FBQztDQUN6QixJQUFJLFlBQVcsT0FBTSxNQUFNLEtBQUssRUFBRSxLQUFLLEdBQUc7RUFBRSxZQUFZO0VBQU07RUFBTyxNQUFNLE9BQU8sRUFBRSxNQUFNO0NBQUU7Q0FDNUYsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksYUFBYSxDQUFDO0NBQ3pDLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxHQUFHLENBQUM7Q0FDL0IsaUNBQU8sS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsT0FBTyxDQUFDO0FBQzNDLENBQUM7QUFFRCwrQkFBSyx1QkFBdUIsT0FBTyxHQUFHLE9BQU87Q0FDM0MsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixNQUFNLE1BQU0sQ0FBQztDQUNiLElBQUksa0JBQWtCO0VBQUUsWUFBWTtFQUFPLFFBQVE7Q0FBVTtDQUM3RCxNQUFNLEtBQVUsTUFBTSxFQUFFLFFBQVEsT0FBTyxJQUFJLE1BQU0sQ0FBQztDQUNsRCxpQ0FBTyxHQUFHLFFBQVEsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZO0NBQ3BELElBQUksa0JBQWtCO0VBQUUsWUFBWTtFQUFPLFFBQVE7Q0FBZTtDQUNsRSxNQUFNLEtBQVUsTUFBTSxFQUFFLFFBQVEsT0FBTyxJQUFJLE1BQU0sQ0FBQztDQUNsRCxpQ0FBTyxHQUFHLFFBQVEsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxNQUFNO0NBQzlDLElBQUksaUJBQWlCO0VBQUUsTUFBTSxJQUFJLE1BQU0sT0FBTztDQUFFO0NBQ2hELE1BQU0sS0FBVSxNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksTUFBTSxDQUFDO0NBQ2xELGlDQUFPLEdBQUcsUUFBUSxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLE1BQU07QUFDaEQsQ0FBQztBQUVELCtCQUFLLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxFQUFFLEdBQUcsT0FBTyxHQUFHLE9BQU87Q0FDM0UsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLFVBQVU7Q0FDZCxJQUFJLFlBQVcsT0FBTSxVQUFVLEVBQUUsV0FBVztFQUFFLFlBQVk7RUFBTyxRQUFRO0NBQVU7Q0FDbkYsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksR0FBRyxDQUFDO0NBQy9CLGlDQUFPLE9BQU8sQ0FBQyxDQUFDLEtBQUssR0FBSTtBQUMzQixDQUFDO0FBRUQsTUFBTSxVQUFVLFFBQXlDLEdBQUcsSUFBSSxRQUFRLEtBQXVDLENBQUMsRUFBQyxDQUFFLEtBQUksTUFBSyxFQUFFLEdBQUc7QUFFakksK0JBQUssdUJBQXVCLE9BQU8sR0FBRyxPQUFPO0NBQzNDLE1BQU0sS0FBSyxJQUFJLElBQXFCO0NBQ3BDLE1BQU0sTUFBTSxNQUFNLElBQUksRUFBRTtDQUN4QixNQUFNLE1BQU0sQ0FBQztDQUNiLElBQUksWUFBVyxPQUFNO0VBQUUsWUFBWTtFQUFNO0VBQU8sTUFBTSxPQUFPLEVBQUUsTUFBTTtDQUFFO0NBQ3ZFLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxLQUFLLENBQUM7Q0FDakMsSUFBSSxrQkFBa0I7RUFBRSxZQUFZO0VBQU8sUUFBUTtDQUFVO0NBQzdELE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxLQUFLLENBQUM7Q0FDakMsaUNBQU8sT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7QUFDcEMsQ0FBQztBQUVELCtCQUFLLDJCQUEyQixFQUFFLFNBQVMsRUFBRSxRQUFRLE1BQU0sRUFBRSxHQUFHLE9BQU8sR0FBRyxPQUFPO0NBQy9FLE1BQU0sS0FBSyxJQUFJLElBQXFCO0NBQ3BDLE1BQU0sTUFBTSxNQUFNLElBQUksRUFBRTtDQUN4QixJQUFJLFlBQVcsT0FBTTtFQUFFLFlBQVk7RUFBTTtFQUFPLE1BQU0sT0FBTyxFQUFFLE1BQU07Q0FBRTtDQUN2RSxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sSUFBUyxNQUFNLEVBQUUsUUFBUSxPQUFPLElBQUksS0FBSyxDQUFDO0NBQ2hELGlDQUFPLEVBQUUsUUFBUSxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFdBQVc7Q0FDbEQsaUNBQU8sT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFFRCwrQkFBSyxpQ0FBaUMsT0FBTyxHQUFHLE9BQU87Q0FDckQsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLFlBQVcsT0FBTTtFQUFFLFlBQVk7RUFBTTtFQUFPLE1BQU0sT0FBTyxFQUFFLE1BQU07Q0FBRTtDQUN2RSxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sUUFBUTtFQUFFLFNBQVM7R0FBRSxNQUFNO0dBQWEsTUFBTTtHQUFhLFNBQVM7SUFBQztLQUFFLE1BQU07S0FBUSxNQUFNO0lBQU07SUFBRztLQUFFLE1BQU07S0FBWSxJQUFJO0tBQUssTUFBTTtLQUFLLE9BQU8sQ0FBQztJQUFFO0lBQUc7S0FBRSxNQUFNO0tBQVEsTUFBTTtJQUFNO0dBQUM7RUFBRTtFQUFHLE1BQU07RUFBWSxRQUFRO0dBQUUsTUFBTTtHQUFTLE9BQU87RUFBSTtFQUFHLE1BQU07Q0FBSTtDQUNwUSxNQUFNLElBQVMsTUFBTSxFQUFFLFFBQVEsT0FBTyxLQUFLO0NBQzNDLGlDQUFPLEVBQUUsUUFBUSxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFdBQVc7Q0FDbEQsaUNBQU8sRUFBRSxRQUFRLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSztDQUM1QyxNQUFNLEtBQVUsTUFBTSxFQUFFLFFBQVEsT0FBTyxJQUFJLFFBQVEsQ0FBQztDQUNwRCxpQ0FBTyxHQUFHLFFBQVEsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxRQUFRO0FBQ2xELENBQUM7QUFFRCwrQkFBSyx1QkFBdUIsT0FBTyxHQUFHLE9BQU87Q0FDM0MsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLFlBQVcsT0FBTTtFQUFFLFlBQVk7RUFBTTtFQUFPLE1BQU0sT0FBTyxFQUFFLE1BQU07Q0FBRTtDQUN2RSxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxLQUFLLENBQUM7Q0FDakMsSUFBSSxpQkFBaUIsTUFBTSxPQUFPO0NBQ2xDLE1BQU0sT0FBTyxHQUFHLE1BQU07Q0FDdEIsSUFBSSxZQUFXLE9BQU07RUFBRSxZQUFZO0VBQU07RUFBTyxNQUFNLE9BQU8sRUFBRSxNQUFNO0NBQUU7Q0FDdkUsTUFBTSxJQUFTLE1BQU0sRUFBRSxRQUFRLE9BQU8sSUFBSSxLQUFLLENBQUM7Q0FDaEQsaUNBQU8sRUFBRSxRQUFRLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssV0FBVztBQUNwRCxDQUFDO0FBRUQsK0JBQUssNkJBQTZCLE9BQU8sR0FBRyxPQUFPO0NBQ2pELE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsSUFBSSxpQkFBaUIsTUFBTSxTQUFTLFFBQVE7Q0FDNUMsTUFBTSxNQUFNLENBQUM7Q0FDYixpQ0FBTyxNQUFNLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Q0FDaEMsTUFBTSxPQUFPLEdBQUcsVUFBVTtDQUMxQixNQUFNLElBQUksTUFBTSxTQUFTLENBQUM7Q0FDMUIsaUNBQU8sSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO0FBQ25DLENBQUM7QUFFRCwrQkFBSyxhQUFhLEVBQUUsU0FBUyxFQUFFLFVBQVUsTUFBTSxFQUFFLEdBQUcsT0FBTyxHQUFHLE9BQU87Q0FDbkUsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLGlCQUFpQixNQUFNLFNBQVMsUUFBUTtDQUM1QyxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sT0FBTyxHQUFHLElBQUk7Q0FDcEIsaUNBQU8sTUFBTSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2xDLENBQUM7QUFFRCxNQUFNLGNBQWMsT0FBTyxNQUE0QjtDQUNyRCxNQUFNLE1BQVcsTUFBTSxFQUFFLE9BQU8sUUFBUTtFQUFFLE9BQU87RUFBSyxhQUFhO0VBQUssVUFBVSxDQUFDO0VBQUcsT0FBTyxDQUFDO0VBQUcsYUFBYTtFQUFNLFFBQVEsQ0FBQztDQUFFLENBQVU7Q0FDekksT0FBTyxJQUFJLFNBQVMsTUFBTSxNQUFXLEVBQUUsT0FBTyxtQkFBbUIsQ0FBQyxFQUFFLFFBQVE7QUFDOUU7QUFFQSwrQkFBSyw0QkFBNEIsT0FBTyxHQUFHLE9BQU87Q0FDaEQsTUFBTSxNQUFNLE1BQU0sRUFBRTtDQUNwQixJQUFJLGlCQUFpQixNQUFNLFNBQVMsT0FBTztDQUMzQyxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sRUFBRSxRQUFRLElBQUk7RUFBRSxTQUFTO0VBQWtCLE1BQU07Q0FBSyxDQUFVO0NBQ3RFLE1BQU0sT0FBTyxHQUFHLEtBQUs7Q0FDckIsaUNBQU8sTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUk7Q0FDekMsTUFBTSxFQUFFLFFBQVEsSUFBSTtFQUFFLFNBQVM7RUFBa0IsTUFBTTtDQUFRLENBQVU7Q0FDekUsaUNBQU8sTUFBTSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2xDLENBQUM7QUFFRCwrQkFBSyx1QkFBdUIsT0FBTyxHQUFHLE9BQU87Q0FDM0MsTUFBTSxFQUFFO0NBQ1IsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLEtBQUssTUFBTSxZQUFZLENBQUM7Q0FDOUIsaUNBQU8sR0FBRyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO0NBQ25DLGlDQUFPLEdBQUcsU0FBUyxhQUFhLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtDQUM1QyxNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQUssQ0FBVTtDQUN0RSxrQ0FBUSxNQUFNLFlBQVksQ0FBQyxFQUFDLENBQUUsU0FBUyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUM1RCxDQUFDO0FBRUQsK0JBQUssNkJBQTZCLEVBQUUsU0FBUyxFQUFFLFNBQVMsS0FBSyxFQUFFLEdBQUcsT0FBTyxHQUFHLE9BQU87Q0FDakYsTUFBTSxFQUFFO0NBQ1IsTUFBTSxNQUFNLEdBQUcsWUFBWTtDQUMzQixNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQU0sQ0FBVTtDQUN2RSxrQ0FBUSxNQUFNLFlBQVksQ0FBQyxFQUFDLENBQUUsU0FBUyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUM5RCxDQUFDOztBQUdELE1BQU0sU0FBUyxJQUFTLFNBQStDO0NBQ3JFLE1BQU0sUUFBUSxJQUFJLElBQW9CO0NBQ3RDLE1BQU0sSUFBSSxjQUFjLEtBQUssVUFBVSxFQUFFLE9BQU8sS0FBSyxLQUFJLE9BQU07RUFBRSxNQUFNO0VBQU0sVUFBVTtFQUFRLE1BQU0sRUFBRTtDQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Q0FDbEgsS0FBSyxNQUFNLEtBQUssTUFBTTtFQUNwQixNQUFNLElBQ0osTUFBTSxFQUFFLEtBQUssUUFDYixLQUFLLFVBQVU7R0FDYixNQUFNO0dBQ04sTUFBTSxFQUFFO0dBQ1IsTUFBTTtHQUNOLFNBQVM7SUFBRSxTQUFTO0lBQUssU0FBUztJQUFLLE1BQU07SUFBTSxhQUFhO0lBQUssUUFBUTtJQUFNLFFBQVE7R0FBSTtHQUMvRixNQUFNO0lBQUUsUUFBUTtJQUFHLFVBQVU7SUFBRyxRQUFRO0lBQUcsUUFBUTtJQUFHLFdBQVc7SUFBRyxPQUFPO0lBQUcsV0FBVztJQUFHLFlBQVk7R0FBRTtHQUMxRyxPQUFPO0lBQUUsS0FBSztJQUFJLFFBQVE7SUFBSSxVQUFVO0lBQUksU0FBUztJQUFJLFlBQVk7R0FBTztHQUM1RSxVQUFVLENBQ1I7SUFBRSxTQUFTO0lBQU8sS0FBSztJQUFJLGVBQWUsQ0FBQztHQUFFLEdBQzdDO0lBQUUsU0FBUztJQUFPLEtBQUs7SUFBSSxlQUFlLEVBQUUsVUFBVSxDQUFDO0tBQUUsTUFBTSxFQUFFO0tBQVMsTUFBTTtJQUFXLENBQUMsSUFBSSxDQUFDO0dBQUUsQ0FDckc7RUFDRixDQUFDLENBQ0g7Q0FDRjtDQUNBLE1BQU0sT0FBTyxTQUFpQixLQUFLLFFBQVEscUJBQXFCLEVBQUU7Q0FDbEUsR0FBRyxjQUFjLElBQVMsT0FBWSxFQUFFLE9BQU8sTUFBTSxJQUFJLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFXO0NBQ2pGLEdBQUcsWUFBWSxJQUFTLE9BQVksRUFBRSxPQUFPLE1BQU0sSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFXO0FBQ3ZGO0FBRUEsK0JBQUssb0NBQW9DLE9BQU8sR0FBRyxPQUFPO0NBQ3hELE1BQU0sRUFBRTtDQUNSLE1BQU0sSUFBSSxDQUFDO0VBQUUsTUFBTTtFQUFTLFNBQVM7Q0FBSyxDQUFDLENBQUM7Q0FDNUMsTUFBTSxNQUFNLEdBQUcsVUFBVTtDQUN6QixNQUFNLElBQUksTUFBTSxZQUFZLENBQUM7Q0FDN0IsaUNBQU8sRUFBRSxTQUFTLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO0NBQ3ZDLGlDQUFPLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtDQUNsQyxpQ0FBTyxFQUFFLFNBQVMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUk7QUFDekMsQ0FBQztBQUVELCtCQUFLLGlDQUFpQyxPQUFPLEdBQUcsT0FBTztDQUNyRCxNQUFNLEVBQUU7Q0FDUixNQUFNLElBQUksQ0FBQyxFQUFFLE1BQU0sUUFBUSxDQUFDLENBQUM7Q0FDN0IsTUFBTSxNQUFNLEdBQUcsVUFBVTtDQUN6QixNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQU0sQ0FBVTtDQUN2RSxrQ0FBUSxNQUFNLFlBQVksQ0FBQyxFQUFDLENBQUUsU0FBUyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSztBQUM3RCxDQUFDO0FBRUQsK0JBQUssbUNBQW1DLEVBQUUsU0FBUyxFQUFFLFNBQVMsTUFBTSxFQUFFLEdBQUcsT0FBTyxHQUFHLE9BQU87Q0FDeEYsTUFBTSxFQUFFO0NBQ1IsTUFBTSxJQUFJLENBQUMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxDQUFDO0NBQzdCLE1BQU0sTUFBTSxHQUFHLFVBQVU7Q0FDekIsTUFBTSxFQUFFLFFBQVEsSUFBSTtFQUFFLFNBQVM7RUFBa0IsTUFBTTtDQUFNLENBQVU7Q0FDdkUsa0NBQVEsTUFBTSxZQUFZLENBQUMsRUFBQyxDQUFFLFNBQVMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUk7QUFDNUQsQ0FBQztBQUVELCtCQUFLLGdDQUFnQyxFQUFFLFNBQVMsRUFBRSxTQUFTLEtBQUssRUFBRSxHQUFHLE9BQU8sR0FBRyxPQUFPO0NBQ3BGLE1BQU0sRUFBRTtDQUNSLE1BQU0sSUFBSSxDQUFDLEVBQUUsTUFBTSxRQUFRLENBQUMsQ0FBQztDQUM3QixNQUFNLE1BQU0sR0FBRyxVQUFVO0NBQ3pCLE1BQU0sRUFBRSxRQUFRLElBQUk7RUFBRSxTQUFTO0VBQWtCLE1BQU07Q0FBSyxDQUFVO0NBQ3RFLGtDQUFRLE1BQU0sWUFBWSxDQUFDLEVBQUMsQ0FBRSxTQUFTLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLO0FBQzdELENBQUM7QUFFRCwrQkFBSywwQkFBMEIsRUFBRSxTQUFTLEVBQUUsU0FBUyxLQUFLLEVBQUUsR0FBRyxPQUFPLEdBQUcsT0FBTztDQUM5RSxNQUFNLEVBQUU7Q0FDUixNQUFNLElBQUksQ0FBQyxFQUFFLE1BQU0sUUFBUSxDQUFDLENBQUM7Q0FDN0IsTUFBTSxNQUFNLEdBQUcsVUFBVTtDQUN6QixNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQUssQ0FBVTtDQUN0RSxrQ0FBUSxNQUFNLFlBQVksQ0FBQyxFQUFDLENBQUUsU0FBUyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUM1RCxDQUFDO0FBRUQsK0JBQUssd0JBQXdCLE9BQU8sR0FBRyxPQUFPO0NBQzVDLE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsSUFBSSxpQkFBaUIsTUFBTSxPQUFPO0NBQ2xDLE1BQU0sTUFBTSxDQUFDO0NBQ2IsTUFBTSxPQUFPLEdBQUcsSUFBSTtDQUNwQixNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFrQixNQUFNO0NBQUssQ0FBVTtDQUN0RSxNQUFNLElBQUksTUFBTSxRQUFRLEtBQUssS0FBVTtDQUN2QyxNQUFNLE9BQU8sR0FBRyxNQUFNO0NBQ3RCLE1BQU0sSUFBSSxNQUFNLFNBQVMsQ0FBQztDQUMxQixpQ0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSTtDQUN4QixpQ0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUMzQixDQUFDO0FBRUQsK0JBQUssMEJBQTBCLE9BQU8sR0FBRyxPQUFPO0NBQzlDLE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsSUFBSSxpQkFBaUIsTUFBTSxPQUFPO0NBQ2xDLE1BQU0sSUFBSSxDQUFDLEVBQUUsTUFBTSxRQUFRLENBQUMsQ0FBQztDQUM3QixNQUFNLE1BQU0sT0FBTyxTQUFpQjtFQUNsQyxNQUFNLE1BQU0sR0FBRyxJQUFJO0VBQ25CLE1BQU0sT0FBTyxHQUFHLElBQUk7RUFDcEIsTUFBTSxFQUFFLFFBQVEsSUFBSTtHQUFFLFNBQVM7R0FBa0IsTUFBTTtFQUFLLENBQVU7RUFDdEUsTUFBTSxJQUFJLE1BQU0sUUFBUSxJQUFJLEtBQVU7RUFDdEMsTUFBTSxPQUFPLEdBQUcsTUFBTTtFQUN0QixPQUFPLFNBQVMsQ0FBQztDQUNuQjtDQUNBLE1BQU0sUUFBUSxNQUFNLElBQUksVUFBVTtDQUNsQyxNQUFNLE9BQU8sTUFBTSxJQUFJLFlBQVk7Q0FDbkMsaUNBQU8sUUFBUSxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUk7QUFDaEMsQ0FBQztBQUVELE1BQU0sYUFBYSxPQUFlLFVBQW1CO0NBQUUsWUFBWTtDQUFNO0NBQU8sTUFBTSw0QkFBNEIsTUFBTSw0REFBNEQsS0FBSztBQUFHO0FBRTVMLCtCQUFLLDhCQUE4QixPQUFPLEdBQUcsT0FBTztDQUNsRCxNQUFNLE1BQU0sTUFBTSxFQUFFO0NBQ3BCLE1BQU0sVUFBaUIsQ0FBQztDQUN4QixHQUFHLGdCQUFnQixJQUFTLE9BQVksUUFBUSxLQUFLLENBQUMsR0FBRztFQUFFLE9BQU8sRUFBRTtFQUFPLFNBQVM7Q0FBSyxFQUFXO0NBQ3BHLElBQUksaUJBQWlCLFVBQVUsUUFBUSxJQUFJO0NBQzNDLE1BQU0sTUFBTSxDQUFDO0NBQ2IsTUFBTSxPQUFPLEdBQUcsYUFBYTtDQUM3QixpQ0FBTyxRQUFRLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQztDQUM3QixpQ0FBTyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLE1BQU07Q0FDcEMsTUFBTSxLQUFLLEdBQUcsTUFBTTtDQUNwQixpQ0FBTyxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsS0FBSyxPQUFPO0NBQ25DLE1BQU0sTUFBTSxNQUFNLEVBQUUsT0FBTyxRQUFRO0VBQUUsT0FBTztFQUFLLGFBQWE7RUFBSyxVQUFVLENBQUM7RUFBRyxPQUFPLENBQUM7RUFBRyxhQUFhO0VBQU0sUUFBUSxDQUFDO0NBQUUsQ0FBVTtDQUNwSSxpQ0FBTyxJQUFJLFNBQVMsTUFBTSxNQUFXLEVBQUUsT0FBTyxtQkFBbUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTztBQUM3RixDQUFDO0FBRUQsK0JBQUssNkJBQTZCLE9BQU8sR0FBRyxPQUFPO0NBQ2pELE1BQU0sTUFBTSxNQUFNLEVBQUU7Q0FDcEIsSUFBSSxJQUFJO0NBQ1IsR0FBRyxzQkFBc0IsS0FBSztFQUFFLE9BQU87RUFBSyxTQUFTO0NBQUksRUFBVztDQUNwRSxJQUFJLGlCQUFpQixVQUFVLFVBQVUsS0FBSztDQUM5QyxNQUFNLE1BQU0sQ0FBQztDQUNiLE1BQU0sT0FBTyxHQUFHLElBQUk7Q0FDcEIsaUNBQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2xCLENBQUMiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbInJvdXRpbmcudGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleHBlY3QsIG1vY2ssIHRlc3QgfSBmcm9tICdjbGF1ZGUtY29kZS90ZXN0aW5nJ1xuXG50eXBlIEN0bCA9IHsgY29tcGxldGU6IChlOiBhbnkpID0+IHVua25vd247IHVzYWdlOiB1bmtub3duOyBzZWVuPzogYW55OyBzdWJtaXR0ZWQ6IHN0cmluZ1tdOyBjbG9jaz86IGFueSB9XG5cbmNvbnN0IHNldHVwID0gKG9uOiBhbnksIGt2PzogTWFwPHN0cmluZywgdW5rbm93bj4pOiBDdGwgPT4ge1xuICBjb25zdCBjdGw6IEN0bCA9IHsgY29tcGxldGU6ICgpID0+ICh7IGlzQW5zd2VyZWQ6IGZhbHNlLCByZWFzb246ICdhYm9ydGVkJyB9KSwgdXNhZ2U6IHsgcmF0ZUxpbWl0czogW10sIGNvbnRleHQ6IHt9IH0sIHN1Ym1pdHRlZDogW10gfVxuICBpZiAoa3YpIHtcbiAgICAvLyDoh6rlgpkgc3RvcmUg5Lul5L6/5qqi5p+l5a+r5YWl5YWn5a6544CCXG4gICAgb24oJ3N0b3JlLmdldCcsIChfJDogYW55LCBlOiBhbnkpID0+ICh7IHZhbHVlOiBrdi5nZXQoZS5rZXkpIH0pIGFzIG5ldmVyKVxuICAgIG9uKCdzdG9yZS5zZXQnLCAoXyQ6IGFueSwgZTogYW55KSA9PiAoa3Yuc2V0KGUua2V5LCBlLnZhbHVlKSwgeyB2YWx1ZTogdW5kZWZpbmVkIH0pIGFzIG5ldmVyKVxuICB9IGVsc2UgbW9jay5zdG9yZShvbilcbiAgY3RsLmNsb2NrID0gbW9jay5jbG9jayhvbiwgeyBub3c6IERhdGUucGFyc2UoJzIwMjYtMTAtMTVUMDg6MDA6MDBaJykgfSlcbiAgb24oJ3VpLmxvZycsICgpID0+ICh7IHZhbHVlOiB1bmRlZmluZWQgfSkgYXMgbmV2ZXIpXG4gIG9uKCdjb21tYW5kLnJlZ2lzdGVyJywgKCkgPT4gKHsgdmFsdWU6IHsgbmFtZTogJ3gnIH0gfSkgYXMgbmV2ZXIpXG4gIG9uKCdzZXNzaW9uLnN0YXJ0JywgKCkgPT4gKHsgY3dkOiAnL3RtcCcgfSkgYXMgbmV2ZXIpXG4gIG9uKCdjb21tYW5kLnJ1bicsICgpID0+ICh7IHRleHQ6ICcnIH0pKVxuICBvbigncHJvbXB0LmNvbXBvc2UnLCAoKSA9PiAoeyBzZWN0aW9uczogW10gfSkpXG4gIG9uKCdwcm9tcHQuc3VibWl0JywgKF8kOiBhbnksIGU6IGFueSkgPT4gKGN0bC5zdWJtaXR0ZWQucHVzaChlLnRleHQpLCB7IHRleHQ6IGUudGV4dCB9KSBhcyBuZXZlcilcbiAgb24oJ21vZGVsLmNvbXBsZXRlJywgKF8kOiBhbnksIGU6IGFueSkgPT4gKHsgdmFsdWU6IGN0bC5jb21wbGV0ZShlKSB9KSBhcyBuZXZlcilcbiAgb24oJ3Nlc3Npb24udXNhZ2UnLCAoKSA9PiAoeyB2YWx1ZTogY3RsLnVzYWdlIH0pIGFzIG5ldmVyKVxuICBvbigndHVybi5zdGVwJywgYXN5bmMgZnVuY3Rpb24qIChfJDogYW55LCBlOiBhbnkpIHtcbiAgICBjdGwuc2VlbiA9IGVcbiAgICByZXR1cm4geyB0dXJuSWQ6IGUudHVybklkLCBpbmRleDogMCwgYW5zd2VyOiAnJywgdG9vbFVzZXM6IFtdLCBzdG9wUmVhc29uOiBudWxsLCB1c2FnZTogbnVsbCB9IGFzIG5ldmVyXG4gIH0pXG4gIHJldHVybiBjdGxcbn1cblxuY29uc3Qgc3RhcnQgPSBhc3luYyAoJDogYW55LCBzbHVnID0gJ3Nhby1hc3VuYScpID0+IHtcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy90bXAnIH0gYXMgbmV2ZXIpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiBzbHVnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxufVxuXG5jb25zdCBhZmZpbml0eSA9IGFzeW5jICgkOiBhbnkpOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICBjb25zdCByOiBhbnkgPSBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ2FuaW1hLWFmZmluaXR5JywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgcmV0dXJuIE51bWJlcigv5aW95oSf5bqmIChcXGQrKS8uZXhlYyhyLnRleHQpPy5bMV0pXG59XG5cbmNvbnN0IHN1Ym1pdCA9ICgkOiBhbnksIHRleHQ6IHN0cmluZykgPT4gJC5wcm9tcHQuc3VibWl0KHsgdGV4dCB9IGFzIG5ldmVyKVxuY29uc3Qgc3RlcCA9IGFzeW5jICgkOiBhbnksIG1vZGVsOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgcyA9ICQudHVybi5zdGVwKHsgdHVybklkOiAndCcsIGluZGV4OiAwLCBtb2RlbCwgbWVzc2FnZUNvdW50OiAxIH0gYXMgbmV2ZXIpXG4gIGZvciBhd2FpdCAoY29uc3QgXyBvZiBzKSB2b2lkIF9cbn1cbmNvbnN0IHVzYWdlID0geyBpbnB1dF90b2tlbnM6IDEsIG91dHB1dF90b2tlbnM6IDEgfVxuY29uc3Qgcm91dGUgPSAobW9kZWw6IHN0cmluZywgdG9uZSA9ICduZXV0cmFsJykgPT4gKHsgaXNBbnN3ZXJlZDogdHJ1ZSwgdXNhZ2UsIHRleHQ6IGB7XCJkaWZmaWN1bHR5XCI6OSxcIm1vZGVsXCI6XCIke21vZGVsfVwiLFwiZWZmb3J0XCI6XCJoaWdoXCIsXCJ0b25lXCI6XCIke3RvbmV9XCIsXCJhY2tcIjpcIuWlve+8jOaIkeS+hueci+eci+OAglwifWAgfSlcbmNvbnN0IHJvdyA9ICh0ZXh0OiBzdHJpbmcpID0+ICh7IG1lc3NhZ2U6IHsgdHlwZTogJ2Fzc2lzdGFudCcsIHJvbGU6ICdhc3Npc3RhbnQnLCBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQgfV0gfSwgZG9vcjogJ3Jlc3BvbnNlJywgb3JpZ2luOiB7IGtpbmQ6ICdtb2RlbCcsIG1vZGVsOiAnbScgfSwgdXVpZDogJ3UnIH0pIGFzIG5ldmVyXG5cbnRlc3QoJ+i8uOWFpeeUsSBIYWlrdSDkuIDmrKHliIbpoZ7vvIzkuKbkvp3liIbpoZ7opoblr6sgdHVybi5zdGVwIOeahOaooeWei+iIh+aAneiAg+eoi+W6picsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBjdGwgPSBzZXR1cChvbilcbiAgY29uc3QgYXNrZWQ6IHN0cmluZ1tdID0gW11cbiAgY3RsLmNvbXBsZXRlID0gZSA9PiAoYXNrZWQucHVzaChlLm1vZGVsKSwgcm91dGUoJ29wdXMnKSlcbiAgYXdhaXQgc3RhcnQoJClcbiAgYXdhaXQgc3VibWl0KCQsICfoq4vph43mp4vmlbTlgIvmqKHntYQnKVxuICBhd2FpdCBzdGVwKCQsICdzb25uZXQnKVxuICBleHBlY3QoYXNrZWQpLnRvRXF1YWwoWydoYWlrdSddKVxuICBleHBlY3QoY3RsLnNlZW4ubW9kZWwpLnRvQmUoJ29wdXMnKVxuICBleHBlY3QoY3RsLnNlZW4uZWZmb3J0KS50b0JlKCdoaWdoJylcbn0pXG5cbnRlc3QoJ+mhjeW6puS9juaWvOmWgOaqu+iHquWLlemZjeS4gOe0micsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBjdGwgPSBzZXR1cChvbilcbiAgY3RsLmNvbXBsZXRlID0gKCkgPT4gcm91dGUoJ29wdXMnKVxuICBjdGwudXNhZ2UgPSB7IHJhdGVMaW1pdHM6IFt7IGtpbmQ6ICdmaXZlX2hvdXInLCBwZXJjZW50VXNlZDogOTUgfV0sIGNvbnRleHQ6IHt9IH1cbiAgYXdhaXQgc3RhcnQoJClcbiAgYXdhaXQgc3VibWl0KCQsICd4JylcbiAgYXdhaXQgc3RlcCgkLCAnb3B1cycpXG4gIGV4cGVjdChjdGwuc2Vlbi5tb2RlbCkudG9CZSgnc29ubmV0Jylcbn0pXG5cbnRlc3QoJ+aJi+WLlemOluWumuaooeWei+iIh+aAneiAg+eoi+W6picsIHsgb3B0aW9uczogeyBsb2NrTW9kZWw6ICdoYWlrdScsIGxvY2tFZmZvcnQ6ICdsb3cnIH0gfSwgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBjdGwuY29tcGxldGUgPSAoKSA9PiByb3V0ZSgnb3B1cycpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0IHN1Ym1pdCgkLCAneCcpXG4gIGF3YWl0IHN0ZXAoJCwgJ29wdXMnKVxuICBleHBlY3QoW2N0bC5zZWVuLm1vZGVsLCBjdGwuc2Vlbi5lZmZvcnRdKS50b0VxdWFsKFsnaGFpa3UnLCAnbG93J10pXG59KVxuXG50ZXN0KCflm57opobmlLnlr6vvvJrkv53nlZnnqIvlvI/norzjgIHot6/lvpHjgIFVUkzjgIHmlbjlrZfvvJvliY3ntrTlj6rliqDlnKjplovpoK3kuIDmrKEnLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGN0bC5jb21wbGV0ZSA9IGUgPT4gKHsgaXNBbnN3ZXJlZDogdHJ1ZSwgdXNhZ2UsIHRleHQ6IFN0cmluZyhlLnByb21wdCkucmVwbGFjZSgn5a6M5oiQ5LqGJywgJ+WBmuWlveWbiScpIH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGNvbnN0IHNyYyA9ICflrozmiJDkuobvvIzmlLnkuoYgYG5wbSB0ZXN0YCDoiIcgL3NyYy9hL2IudHPvvIzoposgaHR0cHM6Ly94LmRldi9h77yM5YWxIDQyIOiZleOAgidcbiAgY29uc3QgcjE6IGFueSA9IGF3YWl0ICQuc2Vzc2lvbi5hcHBlbmQocm93KHNyYykpXG4gIGV4cGVjdChyMS5tZXNzYWdlLmNvbnRlbnRbMF0udGV4dCkudG9CZSgn5Lqe57Wy5aicID4g5YGa5aW95ZuJ77yM5pS55LqGIGBucG0gdGVzdGAg6IiHIC9zcmMvYS9iLnRz77yM6KaLIGh0dHBzOi8veC5kZXYvYe+8jOWFsSA0MiDomZXjgIInKVxuICBjb25zdCByMjogYW55ID0gYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+esrOS6jOautSA3JykpXG4gIGV4cGVjdChyMi5tZXNzYWdlLmNvbnRlbnRbMF0udGV4dC5zdGFydHNXaXRoKCfkup7ntbLlqJwgPicpKS50b0JlKGZhbHNlKVxufSlcblxudGVzdCgn5pS55a+r5aSx5pWX5oiW6YG65aSx5L2U5L2N56ym5pmC6aGv56S65Y6f5paHJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBhd2FpdCBzdGFydCgkKVxuICBjb25zdCByMTogYW55ID0gYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+WOn+aWhyBgeGAgMycpKVxuICBleHBlY3QocjEubWVzc2FnZS5jb250ZW50WzBdLnRleHQpLnRvQmUoJ+S6nue1suWonCA+IOWOn+aWhyBgeGAgMycpXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+ICh7IGlzQW5zd2VyZWQ6IHRydWUsIHVzYWdlLCB0ZXh0OiAn5Lif5LqG5L2U5L2N56ymJyB9KVxuICBjb25zdCByMjogYW55ID0gYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+WOn+aWhyBgeWAgNScpKVxuICBleHBlY3QocjIubWVzc2FnZS5jb250ZW50WzBdLnRleHQpLnRvQmUoJ+WOn+aWhyBgeWAgNScpXG59KVxuXG50ZXN0KCfmlLnlr6vmqKHlnovvvJrplbflm57opobnlKggU29ubmV077yM5LiA6Iis5Zue6KaG55SoIEhhaWt1JywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBjb25zdCBhc2tlZDogc3RyaW5nW10gPSBbXVxuICBjdGwuY29tcGxldGUgPSBlID0+IChhc2tlZC5wdXNoKGUubW9kZWwpLCB7IGlzQW5zd2VyZWQ6IHRydWUsIHVzYWdlLCB0ZXh0OiBTdHJpbmcoZS5wcm9tcHQpIH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0ICQuc2Vzc2lvbi5hcHBlbmQocm93KCfnn63lm57opoYnKSlcbiAgYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+mVtycucmVwZWF0KDEzMDApKSlcbiAgZXhwZWN0KGFza2VkKS50b0VxdWFsKFsnaGFpa3UnLCAnc29ubmV0J10pXG59KVxuXG50ZXN0KCdsb25nUmVwbHkg5Y+v6Kq/5pW06ZW35Zue6KaG6ZaA5qq7JywgeyBvcHRpb25zOiB7IGxvbmdSZXBseTogMTAgfSB9LCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGNvbnN0IGFza2VkOiBzdHJpbmdbXSA9IFtdXG4gIGN0bC5jb21wbGV0ZSA9IGUgPT4gKGFza2VkLnB1c2goZS5tb2RlbCksIHsgaXNBbnN3ZXJlZDogdHJ1ZSwgdXNhZ2UsIHRleHQ6IFN0cmluZyhlLnByb21wdCkgfSlcbiAgYXdhaXQgc3RhcnQoJClcbiAgYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+WNgeS4gOWAi+Wtl+eahOWbnuimhuWFp+WuueWWlOWWlCcpKVxuICBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn55+tJykpXG4gIGV4cGVjdChhc2tlZCkudG9FcXVhbChbJ3Nvbm5ldCcsICdoYWlrdSddKVxufSlcblxudGVzdCgn5pS55a+r6YC+5pmC44CB6aGN5bqm5LiN6Laz5oiW5ouL6Yyv5pmC55u05o6l6aGv56S65Y6f5paHJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBhd2FpdCBzdGFydCgkKVxuICBjdGwuY29tcGxldGUgPSAoKSA9PiAoeyBpc0Fuc3dlcmVkOiBmYWxzZSwgcmVhc29uOiAndGltZW91dCcgfSlcbiAgY29uc3QgcjE6IGFueSA9IGF3YWl0ICQuc2Vzc2lvbi5hcHBlbmQocm93KCfpgL7mmYIgMScpKVxuICBleHBlY3QocjEubWVzc2FnZS5jb250ZW50WzBdLnRleHQpLnRvQmUoJ+S6nue1suWonCA+IOmAvuaZgiAxJylcbiAgY3RsLmNvbXBsZXRlID0gKCkgPT4gKHsgaXNBbnN3ZXJlZDogZmFsc2UsIHJlYXNvbjogJ3JhdGVfbGltaXRlZCcgfSlcbiAgY29uc3QgcjI6IGFueSA9IGF3YWl0ICQuc2Vzc2lvbi5hcHBlbmQocm93KCfpoY3luqYgMicpKVxuICBleHBlY3QocjIubWVzc2FnZS5jb250ZW50WzBdLnRleHQpLnRvQmUoJ+mhjeW6piAyJylcbiAgY3RsLmNvbXBsZXRlID0gKCkgPT4geyB0aHJvdyBuZXcgRXJyb3IoJ3F1b3RhJykgfVxuICBjb25zdCByMzogYW55ID0gYXdhaXQgJC5zZXNzaW9uLmFwcGVuZChyb3coJ+aLi+mMryAzJykpXG4gIGV4cGVjdChyMy5tZXNzYWdlLmNvbnRlbnRbMF0udGV4dCkudG9CZSgn5ouL6YyvIDMnKVxufSlcblxudGVzdCgn5pS55a+r6YC+5pmC6Kit5a6a5YKz57Wm5qih5Z6L5ZG85Y+rJywgeyBvcHRpb25zOiB7IHJld3JpdGVUaW1lb3V0U2VjOiA1IH0gfSwgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBsZXQgdGltZW91dCA9IDBcbiAgY3RsLmNvbXBsZXRlID0gZSA9PiAodGltZW91dCA9IGUudGltZW91dE1zLCB7IGlzQW5zd2VyZWQ6IGZhbHNlLCByZWFzb246ICd0aW1lb3V0JyB9KVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygneCcpKVxuICBleHBlY3QodGltZW91dCkudG9CZSg1MDAwKVxufSlcblxuY29uc3QgcmF3TG9nID0gKGt2OiBNYXA8c3RyaW5nLCB1bmtub3duPik6IHN0cmluZ1tdID0+ICgoa3YuZ2V0KCdyYXdsb2cnKSBhcyB7IHJhdzogc3RyaW5nIH1bXSB8IHVuZGVmaW5lZCkgPz8gW10pLm1hcCh4ID0+IHgucmF3KVxuXG50ZXN0KCfljp/mlocgbG9nIOmgkOioreWvq+WFpe+8jOaUueWvq+WkseaVl+aZguS4jeWvqycsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBrdiA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpXG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uLCBrdilcbiAgYXdhaXQgc3RhcnQoJClcbiAgY3RsLmNvbXBsZXRlID0gZSA9PiAoeyBpc0Fuc3dlcmVkOiB0cnVlLCB1c2FnZSwgdGV4dDogU3RyaW5nKGUucHJvbXB0KSB9KVxuICBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn5Y6f5paH55SyJykpXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+ICh7IGlzQW5zd2VyZWQ6IGZhbHNlLCByZWFzb246ICd0aW1lb3V0JyB9KVxuICBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn5Y6f5paH5LmZJykpXG4gIGV4cGVjdChyYXdMb2coa3YpKS50b0VxdWFsKFsn5Y6f5paH55SyJ10pXG59KVxuXG50ZXN0KCflnKggL2NvbmZpZyDpl5zplonljp/mlocgbG9nIOaZguS4jeWvq+WFpScsIHsgb3B0aW9uczogeyByYXdMb2c6IGZhbHNlIH0gfSwgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGt2ID0gbmV3IE1hcDxzdHJpbmcsIHVua25vd24+KClcbiAgY29uc3QgY3RsID0gc2V0dXAob24sIGt2KVxuICBjdGwuY29tcGxldGUgPSBlID0+ICh7IGlzQW5zd2VyZWQ6IHRydWUsIHVzYWdlLCB0ZXh0OiBTdHJpbmcoZS5wcm9tcHQpIH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGNvbnN0IHI6IGFueSA9IGF3YWl0ICQuc2Vzc2lvbi5hcHBlbmQocm93KCfljp/mlofkuJknKSlcbiAgZXhwZWN0KHIubWVzc2FnZS5jb250ZW50WzBdLnRleHQpLnRvQmUoJ+S6nue1suWonCA+IOWOn+aWh+S4mScpXG4gIGV4cGVjdChyYXdMb2coa3YpKS50b0VxdWFsKFtdKVxufSlcblxudGVzdCgn5YmN57a05Y+q5Yqg5Zyo5pW05YmH5Zue6KaG6ZaL6aCt5LiA5qyh77yM5aSa5q615paH5a2X5Y2A5aGK6IiH5aSa5qyh5a+r5YWl6YO95LiN6YeN6KSHJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBjdGwuY29tcGxldGUgPSBlID0+ICh7IGlzQW5zd2VyZWQ6IHRydWUsIHVzYWdlLCB0ZXh0OiBTdHJpbmcoZS5wcm9tcHQpIH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGNvbnN0IG11bHRpID0geyBtZXNzYWdlOiB7IHR5cGU6ICdhc3Npc3RhbnQnLCByb2xlOiAnYXNzaXN0YW50JywgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiAn56ys5LiA5q61JyB9LCB7IHR5cGU6ICd0b29sX3VzZScsIGlkOiAndCcsIG5hbWU6ICd4JywgaW5wdXQ6IHt9IH0sIHsgdHlwZTogJ3RleHQnLCB0ZXh0OiAn56ys5LqM5q61JyB9XSB9LCBkb29yOiAncmVzcG9uc2UnLCBvcmlnaW46IHsga2luZDogJ21vZGVsJywgbW9kZWw6ICdtJyB9LCB1dWlkOiAndScgfSBhcyBuZXZlclxuICBjb25zdCByOiBhbnkgPSBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKG11bHRpKVxuICBleHBlY3Qoci5tZXNzYWdlLmNvbnRlbnRbMF0udGV4dCkudG9CZSgn5Lqe57Wy5aicID4g56ys5LiA5q61JylcbiAgZXhwZWN0KHIubWVzc2FnZS5jb250ZW50WzJdLnRleHQpLnRvQmUoJ+esrOS6jOautScpXG4gIGNvbnN0IHIyOiBhbnkgPSBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn5ZCM5LiA5Zue6KaG5b6M57qMJykpXG4gIGV4cGVjdChyMi5tZXNzYWdlLmNvbnRlbnRbMF0udGV4dCkudG9CZSgn5ZCM5LiA5Zue6KaG5b6M57qMJylcbn0pXG5cbnRlc3QoJ+aWsOeahOS9v+eUqOiAhei8uOWFpeW+jO+8jOS4i+S4gOWJh+WbnuimhumHjeaWsOWKoOWJjee2tCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBjdGwgPSBzZXR1cChvbilcbiAgY3RsLmNvbXBsZXRlID0gZSA9PiAoeyBpc0Fuc3dlcmVkOiB0cnVlLCB1c2FnZSwgdGV4dDogU3RyaW5nKGUucHJvbXB0KSB9KVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn56ys5LiA5YmHJykpXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHJvdXRlKCdoYWlrdScpXG4gIGF3YWl0IHN1Ym1pdCgkLCAn5YaN5ZWP5LiA5qyhJylcbiAgY3RsLmNvbXBsZXRlID0gZSA9PiAoeyBpc0Fuc3dlcmVkOiB0cnVlLCB1c2FnZSwgdGV4dDogU3RyaW5nKGUucHJvbXB0KSB9KVxuICBjb25zdCByOiBhbnkgPSBhd2FpdCAkLnNlc3Npb24uYXBwZW5kKHJvdygn56ys5LqM5YmHJykpXG4gIGV4cGVjdChyLm1lc3NhZ2UuY29udGVudFswXS50ZXh0KS50b0JlKCfkup7ntbLlqJwgPiDnrKzkuozliYcnKVxufSlcblxudGVzdCgn5aW95oSf5bqm77ya55SxIDAg6ZaL5aeL77yM5q+P5pel6aaW5qyh5LqS5YuV5Yqg5YiG5LiU5pyJ5q+P5pel5LiK6ZmQJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBjdGwuY29tcGxldGUgPSAoKSA9PiByb3V0ZSgnaGFpa3UnLCAncHJhaXNlJylcbiAgYXdhaXQgc3RhcnQoJClcbiAgZXhwZWN0KGF3YWl0IGFmZmluaXR5KCQpKS50b0JlKDApXG4gIGF3YWl0IHN1Ym1pdCgkLCAn6Kyd6Kyd5L2g77yM5YGa5b6X5b6I5aW9JylcbiAgY29uc3QgbiA9IGF3YWl0IGFmZmluaXR5KCQpXG4gIGV4cGVjdChuID4gMCAmJiBuIDw9IDUpLnRvQmUodHJ1ZSlcbn0pXG5cbnRlc3QoJ+mXnOmWieWlveaEn+W6puaZguS4jeiomOmMhCcsIHsgb3B0aW9uczogeyBhZmZpbml0eTogZmFsc2UgfSB9LCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHJvdXRlKCdoYWlrdScsICdwcmFpc2UnKVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCBzdWJtaXQoJCwgJ+isneisnScpXG4gIGV4cGVjdChhd2FpdCBhZmZpbml0eSgkKSkudG9CZSgwKVxufSlcblxuY29uc3QgcGVyc29uYVRleHQgPSBhc3luYyAoJDogYW55KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgY29uc3QgcmVzOiBhbnkgPSBhd2FpdCAkLnByb21wdC5jb21wb3NlKHsgbW9kZWw6ICdtJywgcHJvbXB0TW9kZWw6ICdtJywgc3VyZmFjZXM6IFtdLCB0b29sczogW10sIG91dHB1dFN0eWxlOiBudWxsLCB0cmFpdHM6IFtdIH0gYXMgbmV2ZXIpXG4gIHJldHVybiByZXMuc2VjdGlvbnMuZmluZCgoczogYW55KSA9PiBzLmlkID09PSAnanNjLWFuaW1hOnBlcnNvbmEnKT8udGV4dCA/PyAnJ1xufVxuXG50ZXN0KCflpb3mhJ/luqbooqvosqznvbXmiaPliIbkvYbkuI3ot6jpmo7mrrXmjonokL3vvJvlj6/miYvli5XoqK3lrproiIfph43nva4nLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHJvdXRlKCdoYWlrdScsICdzY29sZCcpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtYWZmaW5pdHknLCBhcmdzOiAnMjAnIH0gYXMgbmV2ZXIpXG4gIGF3YWl0IHN1Ym1pdCgkLCAn5L2g5aW956yoJylcbiAgZXhwZWN0KGF3YWl0IGFmZmluaXR5KCQpID49IDIwKS50b0JlKHRydWUpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtYWZmaW5pdHknLCBhcmdzOiAncmVzZXQnIH0gYXMgbmV2ZXIpXG4gIGV4cGVjdChhd2FpdCBhZmZpbml0eSgkKSkudG9CZSgwKVxufSlcblxudGVzdCgn5aW95oSf5bqm6ZqO5q615Y+N5pig5Zyo6Kqe5rCj77yM5LiU5LiN5L2/55So5oOF57eS5YuS57SiJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIHNldHVwKG9uKVxuICBhd2FpdCBzdGFydCgkKVxuICBjb25zdCB0MCA9IGF3YWl0IHBlcnNvbmFUZXh0KCQpXG4gIGV4cGVjdCh0MC5pbmNsdWRlcygn55Sf55aPJykpLnRvQmUodHJ1ZSlcbiAgZXhwZWN0KHQwLmluY2x1ZGVzKCfkuI3kvb/nlKjmhKfnlprmhJ/miJbmg4Xnt5Lli5LntKInKSkudG9CZSh0cnVlKVxuICBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ2FuaW1hLWFmZmluaXR5JywgYXJnczogJzg1JyB9IGFzIG5ldmVyKVxuICBleHBlY3QoKGF3YWl0IHBlcnNvbmFUZXh0KCQpKS5pbmNsdWRlcygn54m55Yil55qE5a2Y5ZyoJykpLnRvQmUodHJ1ZSlcbn0pXG5cbnRlc3QoJ+acquaIkOW5tOinkuiJsue2reaMgeWPi+aDhe+8jOWNs+S9v+WlveaEn+W6puacgOmrmOS4lOmWi+WVn+aIgOaEm+W8j+S+neiztCcsIHsgb3B0aW9uczogeyByb21hbmNlOiB0cnVlIH0gfSwgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIHNldHVwKG9uKVxuICBhd2FpdCBzdGFydCgkLCAnc2FvLXN1Z3VoYScpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtYWZmaW5pdHknLCBhcmdzOiAnMTAwJyB9IGFzIG5ldmVyKVxuICBleHBlY3QoKGF3YWl0IHBlcnNvbmFUZXh0KCQpKS5pbmNsdWRlcygn6Zec5L+C5a6a5L2N77ya5Y+L5oOFJykpLnRvQmUodHJ1ZSlcbn0pXG5cbi8vIOS7pSBmcyDkuovku7bpgornlYzmj5Dkvpvop5LoibLljIXvvIhjaGFyYWN0ZXJzL2luZGV4Lmpzb27vvInvvIzorpPlpJbmjpvoh6rooYzovInlhaXmiJDlubTop5LoibLjgIJcbmNvbnN0IHBhY2tzID0gKG9uOiBhbnksIGxpc3Q6IHsgc2x1Zzogc3RyaW5nOyByb21hbmNlPzogc3RyaW5nIH1bXSkgPT4ge1xuICBjb25zdCBmaWxlcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KClcbiAgZmlsZXMuc2V0KCdpbmRleC5qc29uJywgSlNPTi5zdHJpbmdpZnkoeyBwYWNrczogbGlzdC5tYXAocCA9PiAoeyB3b3JrOiAndHcnLCB3b3JrTmFtZTogJ+a4rOippuS9nOWTgScsIHNsdWc6IHAuc2x1ZyB9KSkgfSkpXG4gIGZvciAoY29uc3QgcCBvZiBsaXN0KSB7XG4gICAgZmlsZXMuc2V0KFxuICAgICAgYHR3LyR7cC5zbHVnfS5qc29uYCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgd29yazogJ3R3JyxcbiAgICAgICAgc2x1ZzogcC5zbHVnLFxuICAgICAgICBuYW1lOiAn5oiQ5bm05ris6KmmJyxcbiAgICAgICAgcGVyc29uYTogeyBzZWxmUmVmOiAn5oiRJywgYWRkcmVzczogJ+S9oCcsIHRvbmU6ICflubPnqaknLCBjYXRjaHBocmFzZTogJ+WlvScsIHZhbHVlczogJ+WPr+mdoCcsIHRhYm9vczogJ+eEoScgfSxcbiAgICAgICAgYXhlczogeyBnZW50bGU6IDUsIHRzdW5kZXJlOiA1LCBsaXZlbHk6IDUsIGZvcm1hbDogNSwgdGFsa2F0aXZlOiA1LCBodW1vcjogNSwgcHJvYWN0aXZlOiA1LCBleHByZXNzaXZlOiA1IH0sXG4gICAgICAgIGFuaW1lOiB7IG1vZTogJycsIHNwZWVjaDogJycsIGVtb3Rpb25zOiAnJywga2FvbW9qaTogJycsIHRoZW1lQ29sb3I6ICdjeWFuJyB9LFxuICAgICAgICB0aW1lbGluZTogW1xuICAgICAgICAgIHsgY2hhcHRlcjogJ+esrDHnq6AnLCBhZ2U6IDE3LCByZWxhdGlvbnNoaXBzOiBbXSB9LFxuICAgICAgICAgIHsgY2hhcHRlcjogJ+esrDLnq6AnLCBhZ2U6IDIwLCByZWxhdGlvbnNoaXBzOiBwLnJvbWFuY2UgPyBbeyB3aXRoOiBwLnJvbWFuY2UsIGtpbmQ6ICdyb21hbnRpYycgfV0gOiBbXSB9LFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKVxuICB9XG4gIGNvbnN0IGtleSA9IChwYXRoOiBzdHJpbmcpID0+IHBhdGgucmVwbGFjZSgvXi4qXFwvY2hhcmFjdGVyc1xcLy8sICcnKVxuICBvbignZnMuZXhpc3RzJywgKF8kOiBhbnksIGU6IGFueSkgPT4gKHsgdmFsdWU6IGZpbGVzLmhhcyhrZXkoZS5wYXRoKSkgfSkgYXMgbmV2ZXIpXG4gIG9uKCdmcy5yZWFkJywgKF8kOiBhbnksIGU6IGFueSkgPT4gKHsgdmFsdWU6IGZpbGVzLmdldChrZXkoZS5wYXRoKSkgPz8gJycgfSkgYXMgbmV2ZXIpXG59XG5cbnRlc3QoJ+aIkOW5tOS4lOWOn+S9nOacieaIgOaEm+mXnOS/gu+8mumXnOS/guenu+i9iee1puS9v+eUqOiAhe+8jOWOn+aIgOS6uumAgOeCuumBjuWOu+eahOmHjeimgeS6uueJqScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbilcbiAgcGFja3Mob24sIFt7IHNsdWc6ICdsb3ZlcicsIHJvbWFuY2U6ICfmoZDkuronIH1dKVxuICBhd2FpdCBzdGFydCgkLCAndHctbG92ZXInKVxuICBjb25zdCB0ID0gYXdhaXQgcGVyc29uYVRleHQoJClcbiAgZXhwZWN0KHQuaW5jbHVkZXMoJ+W3suenu+i9iee1puS9v+eUqOiAhScpKS50b0JlKHRydWUpXG4gIGV4cGVjdCh0LmluY2x1ZGVzKCfmoZDkuronKSkudG9CZSh0cnVlKVxuICBleHBlY3QodC5pbmNsdWRlcygn6YGO5Y6755qE6YeN6KaB5Lq654mpJykpLnRvQmUodHJ1ZSlcbn0pXG5cbnRlc3QoJ+aIkOW5tOS9huWOn+S9nOeEoeaIgOaEm+mXnOS/gu+8mumcgOacgOmrmOmajuauteS4lOaYjueiuumWi+WVn+aJjemAsuWFpeaIgOaEm+W8j+S+neiztCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbilcbiAgcGFja3Mob24sIFt7IHNsdWc6ICdwbGFpbicgfV0pXG4gIGF3YWl0IHN0YXJ0KCQsICd0dy1wbGFpbicpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtYWZmaW5pdHknLCBhcmdzOiAnMTAwJyB9IGFzIG5ldmVyKVxuICBleHBlY3QoKGF3YWl0IHBlcnNvbmFUZXh0KCQpKS5pbmNsdWRlcygn5oiA5oSb5byP5L6d6LO0JykpLnRvQmUoZmFsc2UpXG59KVxuXG50ZXN0KCfmiJDlubTnhKHmiIDmhJvjgIHmnIDpq5jpmo7mrrXkvYbmnKrlnKggL2NvbmZpZyDplovllZ/vvJrntq3mjIHlpKXkvLTpl5zkv4InLCB7IG9wdGlvbnM6IHsgcm9tYW5jZTogZmFsc2UgfSB9LCBhc3luYyAoJCwgb24pID0+IHtcbiAgc2V0dXAob24pXG4gIHBhY2tzKG9uLCBbeyBzbHVnOiAncGxhaW4nIH1dKVxuICBhd2FpdCBzdGFydCgkLCAndHctcGxhaW4nKVxuICBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ2FuaW1hLWFmZmluaXR5JywgYXJnczogJzEwMCcgfSBhcyBuZXZlcilcbiAgZXhwZWN0KChhd2FpdCBwZXJzb25hVGV4dCgkKSkuaW5jbHVkZXMoJ+WkpeS8tOiIh+aci+WPiycpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCfmiJDlubTnhKHmiIDmhJvjgIHlt7LplovllZ/kvYblpb3mhJ/luqbmnKrpgZTmnIDpq5jpmo7mrrXvvJrkuI3pgLLlhaXmiIDmhJvlvI/kvp3os7QnLCB7IG9wdGlvbnM6IHsgcm9tYW5jZTogdHJ1ZSB9IH0sIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbilcbiAgcGFja3Mob24sIFt7IHNsdWc6ICdwbGFpbicgfV0pXG4gIGF3YWl0IHN0YXJ0KCQsICd0dy1wbGFpbicpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtYWZmaW5pdHknLCBhcmdzOiAnNzknIH0gYXMgbmV2ZXIpXG4gIGV4cGVjdCgoYXdhaXQgcGVyc29uYVRleHQoJCkpLmluY2x1ZGVzKCfmiIDmhJvlvI/kvp3os7QnKSkudG9CZShmYWxzZSlcbn0pXG5cbnRlc3QoJ+aIkOW5tOeEoeaIgOaEm+OAgeacgOmrmOmajuauteS4lOW3sumWi+WVn++8mumAsuWFpeaIgOaEm+W8j+S+neiztCcsIHsgb3B0aW9uczogeyByb21hbmNlOiB0cnVlIH0gfSwgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIHNldHVwKG9uKVxuICBwYWNrcyhvbiwgW3sgc2x1ZzogJ3BsYWluJyB9XSlcbiAgYXdhaXQgc3RhcnQoJCwgJ3R3LXBsYWluJylcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdhbmltYS1hZmZpbml0eScsIGFyZ3M6ICc4MCcgfSBhcyBuZXZlcilcbiAgZXhwZWN0KChhd2FpdCBwZXJzb25hVGV4dCgkKSkuaW5jbHVkZXMoJ+aIgOaEm+W8j+S+neiztCcpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCfplbfmnJ/kuI3kupLli5Xlpb3mhJ/luqbnt6nmhaLkuIvpmY3vvIzkvYbkuI3ot6jpmo7mrrXmjonokL0nLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHJvdXRlKCdoYWlrdScpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0IHN1Ym1pdCgkLCAn5L2g5aW9JylcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdhbmltYS1hZmZpbml0eScsIGFyZ3M6ICc0NScgfSBhcyBuZXZlcilcbiAgYXdhaXQgY3RsLmNsb2NrLmFkdmFuY2UoMzAgKiA4Nl80MDBfMDAwKVxuICBhd2FpdCBzdWJtaXQoJCwgJ+aIkeWbnuS+huS6hicpXG4gIGNvbnN0IG4gPSBhd2FpdCBhZmZpbml0eSgkKVxuICBleHBlY3QobiA8IDQ1KS50b0JlKHRydWUpXG4gIGV4cGVjdChuID49IDQwKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCflgIvmgKfou7jlvbHpn7/miaPliIblgI3njofvvJrlgrLlrIzop5LoibLmjonlvpfmr5Tmuqvmn5Top5LoibLlpJonLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgY3RsID0gc2V0dXAob24pXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHJvdXRlKCdoYWlrdScpXG4gIHBhY2tzKG9uLCBbeyBzbHVnOiAncGxhaW4nIH1dKVxuICBjb25zdCBydW4gPSBhc3luYyAoc2x1Zzogc3RyaW5nKSA9PiB7XG4gICAgYXdhaXQgc3RhcnQoJCwgc2x1ZylcbiAgICBhd2FpdCBzdWJtaXQoJCwgJ+S9oOWlvScpXG4gICAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdhbmltYS1hZmZpbml0eScsIGFyZ3M6ICc3MCcgfSBhcyBuZXZlcilcbiAgICBhd2FpdCBjdGwuY2xvY2suYWR2YW5jZSg4ICogODZfNDAwXzAwMClcbiAgICBhd2FpdCBzdWJtaXQoJCwgJ+aIkeWbnuS+huS6hicpXG4gICAgcmV0dXJuIGFmZmluaXR5KCQpXG4gIH1cbiAgY29uc3QgcHJvdWQgPSBhd2FpdCBydW4oJ3R3LXBsYWluJylcbiAgY29uc3QgY2FsbSA9IGF3YWl0IHJ1bignc2FvLXN1Z3VoYScpXG4gIGV4cGVjdChwcm91ZCA8IGNhbG0pLnRvQmUodHJ1ZSlcbn0pXG5cbmNvbnN0IHdvcmtSb3V0ZSA9IChtb2RlbDogc3RyaW5nLCB3b3JrOiBib29sZWFuKSA9PiAoeyBpc0Fuc3dlcmVkOiB0cnVlLCB1c2FnZSwgdGV4dDogYHtcImRpZmZpY3VsdHlcIjo4LFwibW9kZWxcIjpcIiR7bW9kZWx9XCIsXCJlZmZvcnRcIjpcImhpZ2hcIixcInRvbmVcIjpcIm5ldXRyYWxcIixcImFja1wiOlwi5aW977yM5oiR5L6G6JmV55CG44CCXCIsXCJ3b3JrXCI6JHt3b3JrfX1gIH0pXG5cbnRlc3QoJ+mcgOimgeWLleaJi+eahOimgeaxguS6pOe1puiDjOaZr+W3peS9nOe3mu+8jOWwjeipsee3muaUueeUqCBIYWlrdScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBjdGwgPSBzZXR1cChvbilcbiAgY29uc3Qgc3Bhd25lZDogYW55W10gPSBbXVxuICBvbignYWdlbnQuc3Bhd24nLCAoXyQ6IGFueSwgZTogYW55KSA9PiAoc3Bhd25lZC5wdXNoKGUpLCB7IG1vZGVsOiBlLm1vZGVsLCBhZ2VudElkOiAnYTEnIH0pIGFzIG5ldmVyKVxuICBjdGwuY29tcGxldGUgPSAoKSA9PiB3b3JrUm91dGUoJ29wdXMnLCB0cnVlKVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCBzdWJtaXQoJCwgJ+W5q+aIkemHjeaniyBzcmMg55uu6YyEJylcbiAgZXhwZWN0KHNwYXduZWQubGVuZ3RoKS50b0JlKDEpXG4gIGV4cGVjdChzcGF3bmVkWzBdLm1vZGVsKS50b0JlKCdvcHVzJylcbiAgYXdhaXQgc3RlcCgkLCAnbWFpbicpXG4gIGV4cGVjdChjdGwuc2Vlbi5tb2RlbCkudG9CZSgnaGFpa3UnKVxuICBjb25zdCBzeXMgPSBhd2FpdCAkLnByb21wdC5jb21wb3NlKHsgbW9kZWw6ICdtJywgcHJvbXB0TW9kZWw6ICdtJywgc3VyZmFjZXM6IFtdLCB0b29sczogW10sIG91dHB1dFN0eWxlOiBudWxsLCB0cmFpdHM6IFtdIH0gYXMgbmV2ZXIpXG4gIGV4cGVjdChzeXMuc2VjdGlvbnMuZmluZCgoczogYW55KSA9PiBzLmlkID09PSAnanNjLWFuaW1hOnBlcnNvbmEnKT8udGV4dCkudG9Db250YWluKCfog4zmma/lt6XkvZznt5onKVxufSlcblxudGVzdCgnd29yayDngrogZmFsc2Ug5oiW6Zec6ZaJ6IOM5pmv5bel5L2c57ea5pmC5LiN5rS+5belJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGN0bCA9IHNldHVwKG9uKVxuICBsZXQgbiA9IDBcbiAgb24oJ2FnZW50LnNwYXduJywgKCkgPT4gKG4rKywgeyBtb2RlbDogJ20nLCBhZ2VudElkOiAnYScgfSkgYXMgbmV2ZXIpXG4gIGN0bC5jb21wbGV0ZSA9ICgpID0+IHdvcmtSb3V0ZSgnc29ubmV0JywgZmFsc2UpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0IHN1Ym1pdCgkLCAn5L2g5aW9JylcbiAgZXhwZWN0KG4pLnRvQmUoMClcbn0pXG4iXSwiZmlsZSI6Ii9ob29rcy9yb3V0aW5nLnRlc3QudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3Mvcm91dGluZy50ZXN0LnRzIiwiL2hvb2tzL3JvdXRpbmcudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiY2xhdWRlLWNvZGUvdGVzdGluZyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/525834972c06d5ab6bb7d533090f3ffef02c20b5 b/node_modules/.vitest-cache/525834972c06d5ab6bb7d533090f3ffef02c20b5 new file mode 100644 index 0000000..db10a28 --- /dev/null +++ b/node_modules/.vitest-cache/525834972c06d5ab6bb7d533090f3ffef02c20b5 @@ -0,0 +1,303 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); + +const char = (over = {}, tone = "溫柔") => ({ + name: "小葵", + nameEn: "Aoi", + slug: "aoi", + persona: { + selfRef: "我", + address: "你", + tone, + catchphrase: "加油", + values: "誠實", + taboos: "背叛" + }, + axes: { + gentle: 7, + tsundere: 2, + lively: 5, + formal: 4, + talkative: 5, + humor: 3, + proactive: 6, + expressive: 5 + }, + anime: { + moe: "認真", + speech: "柔和", + emotions: "會臉紅", + kaomoji: "(^_^)", + themeColor: "#88c" + }, + state: { + mood: "緊張", + dialogueStyle: "客氣", + monologue: "想變強", + relationships: [{ + with: "阿零", + kind: "friend", + note: "同伴" + }], + age: 16, + place: "學院" + }, + ...over +}); +const reply = (c) => JSON.stringify({ + work: { + name: "測試物語", + nameEn: "Test Story", + slug: "ts", + timeline: [{ + time: "春", + place: "學院" + }], + terms: [{ + term: "魔核", + definition: "力量來源" + }] + }, + characters: [c] +}); +let cloneMissing = false; +let registered = []; +const probed = new Set(); +let sessionCwd = "/repo"; +const setup = (on, answers, files = new Map()) => { + const s = { + files, + cmds: [], + prompts: [] + }; + const o = on; + __vite_ssr_import_0__.mock.store(on); + o("command.register", ((_$, e) => { + registered.push(e.name); + return { value: { name: e.name } }; + })); + o("session.start", () => ({ cwd: "/repo" })); + o("session.cwd", (() => ({ value: sessionCwd }))); + __vite_ssr_import_0__.mock.env(on, { HOME: "/home/u" }); + o("fs.exists", ((_$, e) => (e.path.endsWith("/characters/index.json") && probed.add(e.path), { value: s.files.has(e.path) || e.path === "/home/u/.cache/jsc-anima/repo/.git" && !cloneMissing }))); + o("fs.read", ((_$, e) => ({ value: s.files.get(e.path) ?? "" }))); + o("fs.write", ((_$, e) => { + s.files.set(e.path, e.text); + return { value: undefined }; + })); + o("model.complete", ((_$, e) => { + s.prompts.push(e.prompt); + return { value: { + isAnswered: true, + text: answers.shift() ?? "", + usage: {} + } }; + })); + o("process.run", ((_$, e) => { + s.cmds.push(e.argv); + const j = e.argv.join(" "); + const out = j.includes("--abbrev-ref") ? "issue-4" : j.includes("symbolic-ref") ? "origin/main" : j.includes("get-url") ? "https://gitea.jsc.idv.tw/jiantw83/jsc-anima.git" : j.startsWith("tea logins") ? "admin https://gitea.jsc.idv.tw u" : j.startsWith("tea pulls") ? "PR#1" : ""; + return { value: { + exitCode: 0, + stdout: out, + stderr: "" + } }; + })); + return s; +}; +const run = ($, args) => $.command.run({ + command: "anima-extract", + args +}).then((r) => r.text); +(0,__vite_ssr_import_0__.test)("萃取:先確認代號、再看變更摘要、最後寫檔並建立 PR", async ($, on) => { + const s = setup(on, [reply(char())], new Map([["/repo/ch1.txt", "第一段\n\n第二段"]])); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + const t1 = await run($, "ch1.txt"); + (0,__vite_ssr_import_0__.expect)(t1).toContain("ts"); + (0,__vite_ssr_import_0__.expect)(t1).toContain("aoi"); + (0,__vite_ssr_import_0__.expect)(t1).toContain("尚未建立"); + (0,__vite_ssr_import_0__.expect)(s.files.has("/home/u/.cache/jsc-anima/repo/characters/ts/aoi.json")).toBe(false); + const t2 = await run($, "confirm work=testy aoi=ao"); + (0,__vite_ssr_import_0__.expect)(t2).toContain("變更摘要"); + (0,__vite_ssr_import_0__.expect)(s.files.has("/home/u/.cache/jsc-anima/repo/characters/testy/ao.json")).toBe(false); + const t3 = await run($, "confirm"); + (0,__vite_ssr_import_0__.expect)(t3).toContain("已建立 PR"); + const pack = JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/testy/ao.json")); + (0,__vite_ssr_import_0__.expect)(pack.timeline[0].chapter).toBe("ch1"); + (0,__vite_ssr_import_0__.expect)(pack.timeline[0].age).toBe(16); + (0,__vite_ssr_import_0__.expect)(JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/testy/work.json")).terms[0].term).toBe("魔核"); + const pr = s.cmds.find((c) => c[0] === "tea" && c[1] === "pulls"); + (0,__vite_ssr_import_0__.expect)(pr).toContain("main"); + (0,__vite_ssr_import_0__.expect)(pr).toContain("feat/extract-testy-ch1"); + (0,__vite_ssr_import_0__.expect)(s.cmds.some((c) => c[0] === "git" && c[1] === "commit" && c[3].startsWith("feat: "))).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("同章節重跑覆蓋、新章節追加、基礎設定不同標記待確認", async ($, on) => { + const files = new Map([["/repo/ch1.txt", "a"], ["/repo/ch2.txt", "b"]]); + const s = setup(on, [ + reply(char()), + reply(char()), + reply(char({ state: { + mood: "開心", + dialogueStyle: "", + monologue: "", + relationships: [], + age: 17, + place: "" + } }, "傲嬌")) + ], files); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + const write = async (f) => { + await run($, f); + await run($, "confirm"); + return run($, "confirm"); + }; + await write("ch1.txt"); + await write("ch1.txt"); + (0,__vite_ssr_import_0__.expect)(JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/ts/aoi.json")).timeline.length).toBe(1); + await run($, "ch2.txt"); + const summary = await run($, "confirm"); + (0,__vite_ssr_import_0__.expect)(summary).toContain("追加"); + (0,__vite_ssr_import_0__.expect)(summary).toContain("待確認"); + await run($, "confirm"); + const pack = JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/ts/aoi.json")); + (0,__vite_ssr_import_0__.expect)(pack.timeline.map((t) => t.chapter)).toEqual(["ch1", "ch2"]); + (0,__vite_ssr_import_0__.expect)(pack.persona.tone).toBe("溫柔"); + (0,__vite_ssr_import_0__.expect)(pack.conflicts[0]).toMatchObject({ + field: "persona.tone", + proposed: "傲嬌", + status: "待確認" + }); +}); +(0,__vite_ssr_import_0__.test)("schema 驗證失敗不寫檔、不建 PR;cancel 清除待確認", async ($, on) => { + const bad = char({ axes: { + gentle: 99, + tsundere: 2, + lively: 5, + formal: 4, + talkative: 5, + humor: 3, + proactive: 6, + expressive: 5 + } }); + const s = setup(on, [reply(bad)], new Map([["/repo/ch1.txt", "a"]])); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + await run($, "ch1.txt"); + (0,__vite_ssr_import_0__.expect)(await run($, "confirm")).toContain("schema 驗證失敗"); + (0,__vite_ssr_import_0__.expect)(s.cmds.some((c) => c[0] === "tea")).toBe(false); + (0,__vite_ssr_import_0__.expect)([...s.files.keys()].some((k) => k.includes("characters"))).toBe(false); + (0,__vite_ssr_import_0__.expect)(await run($, "cancel")).toContain("已取消"); +}); +(0,__vite_ssr_import_0__.test)("貼上章節內容:paste <章節名稱> 加下一行起的內容,並寫入語言欄位與 index.json", async ($, on) => { + const s = setup(on, [reply(char({ language: "繁體中文,少量原作口癖" }))]); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + (0,__vite_ssr_import_0__.expect)(await run($, "paste")).toContain("貼上章節的用法"); + const t1 = await run($, "paste 第一章\n這是貼上的章節內容。"); + (0,__vite_ssr_import_0__.expect)(t1).toContain("aoi"); + (0,__vite_ssr_import_0__.expect)(s.prompts[0]).toContain("這是貼上的章節內容。"); + await run($, "confirm"); + await run($, "confirm"); + const pack = JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/ts/aoi.json")); + (0,__vite_ssr_import_0__.expect)(pack.timeline[0].chapter).toBe("第一章"); + (0,__vite_ssr_import_0__.expect)(pack.language).toBe("繁體中文,少量原作口癖"); + (0,__vite_ssr_import_0__.expect)(JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/index.json")).packs[0]).toEqual({ + work: "ts", + workName: "測試物語", + slug: "aoi" + }); +}); +(0,__vite_ssr_import_0__.test)("欄位含長段引號內容視為抄錄原作台詞,不寫檔", async ($, on) => { + const quoted = char({ persona: { + selfRef: "我", + address: "你", + tone: "「這是一段很長很長的原作台詞內容,不應該出現在角色包裡面」", + catchphrase: "加油", + values: "誠實", + taboos: "背叛" + } }); + const s = setup(on, [reply(quoted)], new Map([["/repo/ch1.txt", "a"]])); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + await run($, "ch1.txt"); + (0,__vite_ssr_import_0__.expect)(await run($, "confirm")).toContain("疑似抄錄原作台詞"); + (0,__vite_ssr_import_0__.expect)([...s.files.keys()].some((k) => k.includes("characters"))).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("在非 jsc-anima 目錄執行:git 與 PR 都走 jsc-anima 的快取 clone,不碰 session 目錄", async ($, on) => { + sessionCwd = "/other/proj"; + try { + const s = setup(on, [reply(char())], new Map([["/other/proj/ch1.txt", "第一段"]])); + await $.session.start({ + source: "startup", + cwd: "/other/proj" + }); + await run($, "/other/proj/ch1.txt"); + await run($, "confirm"); + (0,__vite_ssr_import_0__.expect)(await run($, "confirm")).toContain("已建立 PR"); + (0,__vite_ssr_import_0__.expect)(s.cmds.some((c) => c.includes("fetch"))).toBe(true); + const pr = s.cmds.find((c) => c[0] === "tea" && c[1] === "pulls"); + (0,__vite_ssr_import_0__.expect)(pr).toContain("jiantw83/jsc-anima"); + (0,__vite_ssr_import_0__.expect)(s.files.has("/other/proj/characters/index.json")).toBe(false); + (0,__vite_ssr_import_0__.expect)(JSON.parse(s.files.get("/home/u/.cache/jsc-anima/repo/characters/index.json")).packs[0].slug).toBe("aoi"); + } finally { + sessionCwd = "/repo"; + } +}); +(0,__vite_ssr_import_0__.test)("快取 clone 不存在時先 clone jsc-anima", async ($, on) => { + cloneMissing = true; + try { + const s = setup(on, [reply(char())], new Map([["/repo/ch1.txt", "a"]])); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + await run($, "ch1.txt"); + const clone = s.cmds.find((c) => c.includes("clone")); + (0,__vite_ssr_import_0__.expect)(clone).toContain("https://gitea.jsc.idv.tw/jiantw83/jsc-anima.git"); + } finally { + cloneMissing = false; + } +}); +(0,__vite_ssr_import_0__.test)("paste:CRLF 換行也能分出章節名稱與內容", async ($, on) => { + const s = setup(on, [reply(char())]); + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + await run($, "paste 第二章\r\n第一行\r\n第二行"); + (0,__vite_ssr_import_0__.expect)(s.prompts[0]).toContain("第一行"); +}); +(0,__vite_ssr_import_0__.test)("合併並更新外掛後:啟動時從外掛目錄的 index.json 註冊 {作品代號}-{角色代號} 並可啟動", async ($, on) => { + const s = setup(on, [reply(char())], new Map([["/repo/ch1.txt", "a"]])); + registered = []; + await $.session.start({ + source: "startup", + cwd: "/repo" + }); + await run($, "ch1.txt"); + await run($, "confirm"); + await run($, "confirm"); + // 模擬 PR 合併、外掛更新:clone 內的 characters/ 內容出現在外掛目錄。 + const root = ([...probed].find((q) => !q.startsWith("/home/u/")) ?? "").replace("/characters/index.json", ""); + for (const [k, v] of [...s.files]) if (k.startsWith("/home/u/.cache/jsc-anima/repo/characters/")) s.files.set(k.replace("/home/u/.cache/jsc-anima/repo", root), v); + await $.session.start({ + source: "startup", + cwd: "/anywhere" + }); + (0,__vite_ssr_import_0__.expect)(registered).toContain("ts-aoi"); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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RUFBRSxRQUFRLE1BQU07RUFBRSxRQUFRO0VBQVcsS0FBSztDQUFRLENBQVU7Q0FDbEUsTUFBTSxJQUFJLEdBQVkseUJBQXlCO0NBQy9DLGlDQUFPLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUs7QUFDdEMsQ0FBQztBQUVELCtCQUFLLHVEQUF1RCxPQUFPLEdBQUcsT0FBTztDQUMzRSxNQUFNLElBQUksTUFBTSxJQUFhLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7Q0FDL0UsYUFBYSxDQUFDO0NBQ2QsTUFBTSxFQUFFLFFBQVEsTUFBTTtFQUFFLFFBQVE7RUFBVyxLQUFLO0NBQVEsQ0FBVTtDQUNsRSxNQUFNLElBQUksR0FBWSxTQUFTO0NBQy9CLE1BQU0sSUFBSSxHQUFZLFNBQVM7Q0FDL0IsTUFBTSxJQUFJLEdBQVksU0FBUzs7Q0FFL0IsTUFBTSxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxNQUFLLE1BQUssQ0FBQyxFQUFFLFdBQVcsVUFBVSxDQUFDLEtBQUssR0FBRSxDQUFFLFFBQVEsMEJBQTBCLEVBQUU7Q0FDMUcsS0FBSyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxJQUFJLEVBQUUsV0FBVywyQ0FBMkMsR0FBRyxFQUFFLE1BQU0sSUFBSSxFQUFFLFFBQVEsaUNBQWlDLElBQUksR0FBRyxDQUFDO0NBQ2pLLE1BQU0sRUFBRSxRQUFRLE1BQU07RUFBRSxRQUFRO0VBQVcsS0FBSztDQUFZLENBQVU7Q0FDdEUsaUNBQU8sVUFBVSxDQUFDLENBQUMsVUFBVSxRQUFRO0FBQ3ZDLENBQUMiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbImV4dHJhY3QudGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleHBlY3QsIG1vY2ssIHRlc3QgfSBmcm9tICdjbGF1ZGUtY29kZS90ZXN0aW5nJ1xuXG5pbXBvcnQgdHlwZSB7IEV4dHJhY3RlZCB9IGZyb20gJy4vZXh0cmFjdCdcblxuY29uc3QgY2hhciA9IChvdmVyOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9LCB0b25lID0gJ+a6q+aflCcpOiBFeHRyYWN0ZWRbJ2NoYXJhY3RlcnMnXVtudW1iZXJdID0+XG4gICh7XG4gICAgbmFtZTogJ+Wwj+iRtScsIG5hbWVFbjogJ0FvaScsIHNsdWc6ICdhb2knLFxuICAgIHBlcnNvbmE6IHsgc2VsZlJlZjogJ+aIkScsIGFkZHJlc3M6ICfkvaAnLCB0b25lLCBjYXRjaHBocmFzZTogJ+WKoOayuScsIHZhbHVlczogJ+iqoOWvpicsIHRhYm9vczogJ+iDjOWPmycgfSxcbiAgICBheGVzOiB7IGdlbnRsZTogNywgdHN1bmRlcmU6IDIsIGxpdmVseTogNSwgZm9ybWFsOiA0LCB0YWxrYXRpdmU6IDUsIGh1bW9yOiAzLCBwcm9hY3RpdmU6IDYsIGV4cHJlc3NpdmU6IDUgfSxcbiAgICBhbmltZTogeyBtb2U6ICfoqo3nnJ8nLCBzcGVlY2g6ICfmn5TlkownLCBlbW90aW9uczogJ+acg+iHiee0hScsIGthb21vamk6ICcoXl9eKScsIHRoZW1lQ29sb3I6ICcjODhjJyB9LFxuICAgIHN0YXRlOiB7IG1vb2Q6ICfnt4rlvLUnLCBkaWFsb2d1ZVN0eWxlOiAn5a6i5rCjJywgbW9ub2xvZ3VlOiAn5oOz6K6K5by3JywgcmVsYXRpb25zaGlwczogW3sgd2l0aDogJ+mYv+mbticsIGtpbmQ6ICdmcmllbmQnLCBub3RlOiAn5ZCM5Ly0JyB9XSwgYWdlOiAxNiwgcGxhY2U6ICflrbjpmaInIH0sXG4gICAgLi4ub3ZlcixcbiAgfSkgYXMgbmV2ZXJcblxuY29uc3QgcmVwbHkgPSAoYzogRXh0cmFjdGVkWydjaGFyYWN0ZXJzJ11bbnVtYmVyXSkgPT5cbiAgSlNPTi5zdHJpbmdpZnkoeyB3b3JrOiB7IG5hbWU6ICfmuKzoqabnianoqp4nLCBuYW1lRW46ICdUZXN0IFN0b3J5Jywgc2x1ZzogJ3RzJywgdGltZWxpbmU6IFt7IHRpbWU6ICfmmKUnLCBwbGFjZTogJ+WtuOmZoicgfV0sIHRlcm1zOiBbeyB0ZXJtOiAn6a2U5qC4JywgZGVmaW5pdGlvbjogJ+WKm+mHj+S+hua6kCcgfV0gfSwgY2hhcmFjdGVyczogW2NdIH0pXG5cbnR5cGUgU2V0dXAgPSB7IGZpbGVzOiBNYXA8c3RyaW5nLCBzdHJpbmc+OyBjbWRzOiBzdHJpbmdbXVtdOyBwcm9tcHRzOiBzdHJpbmdbXSB9XG5cbmxldCBjbG9uZU1pc3NpbmcgPSBmYWxzZVxubGV0IHJlZ2lzdGVyZWQ6IHN0cmluZ1tdID0gW11cbmNvbnN0IHByb2JlZCA9IG5ldyBTZXQ8c3RyaW5nPigpXG5sZXQgc2Vzc2lvbkN3ZCA9ICcvcmVwbydcbmNvbnN0IHNldHVwID0gKG9uOiBuZXZlciwgYW5zd2Vyczogc3RyaW5nW10sIGZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKSk6IFNldHVwID0+IHtcbiAgY29uc3QgczogU2V0dXAgPSB7IGZpbGVzLCBjbWRzOiBbXSwgcHJvbXB0czogW10gfVxuICBjb25zdCBvID0gb24gYXMgdW5rbm93biBhcyAobjogc3RyaW5nLCBoOiAoLi4uYTogbmV2ZXJbXSkgPT4gdW5rbm93bikgPT4gdm9pZFxuICBtb2NrLnN0b3JlKG9uKVxuICBvKCdjb21tYW5kLnJlZ2lzdGVyJywgKChfJDogdW5rbm93biwgZTogeyBuYW1lOiBzdHJpbmcgfSkgPT4geyByZWdpc3RlcmVkLnB1c2goZS5uYW1lKTsgcmV0dXJuIHsgdmFsdWU6IHsgbmFtZTogZS5uYW1lIH0gfSB9KSBhcyBuZXZlcilcbiAgbygnc2Vzc2lvbi5zdGFydCcsICgpID0+ICh7IGN3ZDogJy9yZXBvJyB9KSlcbiAgbygnc2Vzc2lvbi5jd2QnLCAoKCkgPT4gKHsgdmFsdWU6IHNlc3Npb25Dd2QgfSkpIGFzIG5ldmVyKVxuICBtb2NrLmVudihvbiwgeyBIT01FOiAnL2hvbWUvdScgfSlcbiAgbygnZnMuZXhpc3RzJywgKChfJDogdW5rbm93biwgZTogeyBwYXRoOiBzdHJpbmcgfSkgPT4gKGUucGF0aC5lbmRzV2l0aCgnL2NoYXJhY3RlcnMvaW5kZXguanNvbicpICYmIHByb2JlZC5hZGQoZS5wYXRoKSwgeyB2YWx1ZTogcy5maWxlcy5oYXMoZS5wYXRoKSB8fCAoZS5wYXRoID09PSAnL2hvbWUvdS8uY2FjaGUvanNjLWFuaW1hL3JlcG8vLmdpdCcgJiYgIWNsb25lTWlzc2luZykgfSkpIGFzIG5ldmVyKVxuICBvKCdmcy5yZWFkJywgKChfJDogdW5rbm93biwgZTogeyBwYXRoOiBzdHJpbmcgfSkgPT4gKHsgdmFsdWU6IHMuZmlsZXMuZ2V0KGUucGF0aCkgPz8gJycgfSkpIGFzIG5ldmVyKVxuICBvKCdmcy53cml0ZScsICgoXyQ6IHVua25vd24sIGU6IHsgcGF0aDogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfSkgPT4geyBzLmZpbGVzLnNldChlLnBhdGgsIGUudGV4dCk7IHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQgfSB9KSBhcyBuZXZlcilcbiAgbygnbW9kZWwuY29tcGxldGUnLCAoKF8kOiB1bmtub3duLCBlOiB7IHByb21wdDogc3RyaW5nIH0pID0+IHtcbiAgICBzLnByb21wdHMucHVzaChlLnByb21wdClcbiAgICByZXR1cm4geyB2YWx1ZTogeyBpc0Fuc3dlcmVkOiB0cnVlLCB0ZXh0OiBhbnN3ZXJzLnNoaWZ0KCkgPz8gJycsIHVzYWdlOiB7fSB9IH1cbiAgfSkgYXMgbmV2ZXIpXG4gIG8oJ3Byb2Nlc3MucnVuJywgKChfJDogdW5rbm93biwgZTogeyBhcmd2OiBzdHJpbmdbXTsgfSkgPT4ge1xuICAgIHMuY21kcy5wdXNoKGUuYXJndilcbiAgICBjb25zdCBqID0gZS5hcmd2LmpvaW4oJyAnKVxuICAgIGNvbnN0IG91dCA9IGouaW5jbHVkZXMoJy0tYWJicmV2LXJlZicpID8gJ2lzc3VlLTQnIDogai5pbmNsdWRlcygnc3ltYm9saWMtcmVmJykgPyAnb3JpZ2luL21haW4nIDogai5pbmNsdWRlcygnZ2V0LXVybCcpID8gJ2h0dHBzOi8vZ2l0ZWEuanNjLmlkdi50dy9qaWFudHc4My9qc2MtYW5pbWEuZ2l0JyA6IGouc3RhcnRzV2l0aCgndGVhIGxvZ2lucycpID8gJ2FkbWluIGh0dHBzOi8vZ2l0ZWEuanNjLmlkdi50dyB1JyA6IGouc3RhcnRzV2l0aCgndGVhIHB1bGxzJykgPyAnUFIjMScgOiAnJ1xuICAgIHJldHVybiB7IHZhbHVlOiB7IGV4aXRDb2RlOiAwLCBzdGRvdXQ6IG91dCwgc3RkZXJyOiAnJyB9IH1cbiAgfSkgYXMgbmV2ZXIpXG4gIHJldHVybiBzXG59XG5cbmNvbnN0IHJ1biA9ICgkOiBuZXZlciwgYXJnczogc3RyaW5nKSA9PiAoJCBhcyBhbnkpLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ2FuaW1hLWV4dHJhY3QnLCBhcmdzIH0pLnRoZW4oKHI6IHsgdGV4dDogc3RyaW5nIH0pID0+IHIudGV4dClcblxudGVzdCgn6JCD5Y+W77ya5YWI56K66KqN5Luj6Jmf44CB5YaN55yL6K6K5pu05pGY6KaB44CB5pyA5b6M5a+r5qqU5Lim5bu656uLIFBSJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHMgPSBzZXR1cChvbiBhcyBuZXZlciwgW3JlcGx5KGNoYXIoKSldLCBuZXcgTWFwKFtbJy9yZXBvL2NoMS50eHQnLCAn56ys5LiA5q61XFxuXFxu56ys5LqM5q61J11dKSlcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9yZXBvJyB9IGFzIG5ldmVyKVxuICBjb25zdCB0MSA9IGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAnY2gxLnR4dCcpXG4gIGV4cGVjdCh0MSkudG9Db250YWluKCd0cycpXG4gIGV4cGVjdCh0MSkudG9Db250YWluKCdhb2knKVxuICBleHBlY3QodDEpLnRvQ29udGFpbign5bCa5pyq5bu656uLJylcbiAgZXhwZWN0KHMuZmlsZXMuaGFzKCcvaG9tZS91Ly5jYWNoZS9qc2MtYW5pbWEvcmVwby9jaGFyYWN0ZXJzL3RzL2FvaS5qc29uJykpLnRvQmUoZmFsc2UpXG5cbiAgY29uc3QgdDIgPSBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0gd29yaz10ZXN0eSBhb2k9YW8nKVxuICBleHBlY3QodDIpLnRvQ29udGFpbign6K6K5pu05pGY6KaBJylcbiAgZXhwZWN0KHMuZmlsZXMuaGFzKCcvaG9tZS91Ly5jYWNoZS9qc2MtYW5pbWEvcmVwby9jaGFyYWN0ZXJzL3Rlc3R5L2FvLmpzb24nKSkudG9CZShmYWxzZSlcblxuICBjb25zdCB0MyA9IGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAnY29uZmlybScpXG4gIGV4cGVjdCh0MykudG9Db250YWluKCflt7Llu7rnq4sgUFInKVxuICBjb25zdCBwYWNrID0gSlNPTi5wYXJzZShzLmZpbGVzLmdldCgnL2hvbWUvdS8uY2FjaGUvanNjLWFuaW1hL3JlcG8vY2hhcmFjdGVycy90ZXN0eS9hby5qc29uJykhKVxuICBleHBlY3QocGFjay50aW1lbGluZVswXS5jaGFwdGVyKS50b0JlKCdjaDEnKVxuICBleHBlY3QocGFjay50aW1lbGluZVswXS5hZ2UpLnRvQmUoMTYpXG4gIGV4cGVjdChKU09OLnBhcnNlKHMuZmlsZXMuZ2V0KCcvaG9tZS91Ly5jYWNoZS9qc2MtYW5pbWEvcmVwby9jaGFyYWN0ZXJzL3Rlc3R5L3dvcmsuanNvbicpISkudGVybXNbMF0udGVybSkudG9CZSgn6a2U5qC4JylcbiAgY29uc3QgcHIgPSBzLmNtZHMuZmluZChjID0+IGNbMF0gPT09ICd0ZWEnICYmIGNbMV0gPT09ICdwdWxscycpIVxuICBleHBlY3QocHIpLnRvQ29udGFpbignbWFpbicpXG4gIGV4cGVjdChwcikudG9Db250YWluKCdmZWF0L2V4dHJhY3QtdGVzdHktY2gxJylcbiAgZXhwZWN0KHMuY21kcy5zb21lKGMgPT4gY1swXSA9PT0gJ2dpdCcgJiYgY1sxXSA9PT0gJ2NvbW1pdCcgJiYgY1szXSEuc3RhcnRzV2l0aCgnZmVhdDogJykpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCflkIznq6Dnr4Dph43ot5Hopobok4vjgIHmlrDnq6Dnr4Dov73liqDjgIHln7rnpI7oqK3lrprkuI3lkIzmqJnoqJjlvoXnorroqo0nLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgZmlsZXMgPSBuZXcgTWFwKFtbJy9yZXBvL2NoMS50eHQnLCAnYSddLCBbJy9yZXBvL2NoMi50eHQnLCAnYiddXSlcbiAgY29uc3QgcyA9IHNldHVwKG9uIGFzIG5ldmVyLCBbcmVwbHkoY2hhcigpKSwgcmVwbHkoY2hhcigpKSwgcmVwbHkoY2hhcih7IHN0YXRlOiB7IG1vb2Q6ICfplovlv4MnLCBkaWFsb2d1ZVN0eWxlOiAnJywgbW9ub2xvZ3VlOiAnJywgcmVsYXRpb25zaGlwczogW10sIGFnZTogMTcsIHBsYWNlOiAnJyB9IH0sICflgrLlrIwnKSldLCBmaWxlcylcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9yZXBvJyB9IGFzIG5ldmVyKVxuICBjb25zdCB3cml0ZSA9IGFzeW5jIChmOiBzdHJpbmcpID0+IHtcbiAgICBhd2FpdCBydW4oJCBhcyBuZXZlciwgZilcbiAgICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKVxuICAgIHJldHVybiBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKVxuICB9XG4gIGF3YWl0IHdyaXRlKCdjaDEudHh0JylcbiAgYXdhaXQgd3JpdGUoJ2NoMS50eHQnKVxuICBleHBlY3QoSlNPTi5wYXJzZShzLmZpbGVzLmdldCgnL2hvbWUvdS8uY2FjaGUvanNjLWFuaW1hL3JlcG8vY2hhcmFjdGVycy90cy9hb2kuanNvbicpISkudGltZWxpbmUubGVuZ3RoKS50b0JlKDEpXG5cbiAgYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICdjaDIudHh0JylcbiAgY29uc3Qgc3VtbWFyeSA9IGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAnY29uZmlybScpXG4gIGV4cGVjdChzdW1tYXJ5KS50b0NvbnRhaW4oJ+i/veWKoCcpXG4gIGV4cGVjdChzdW1tYXJ5KS50b0NvbnRhaW4oJ+W+heeiuuiqjScpXG4gIGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAnY29uZmlybScpXG4gIGNvbnN0IHBhY2sgPSBKU09OLnBhcnNlKHMuZmlsZXMuZ2V0KCcvaG9tZS91Ly5jYWNoZS9qc2MtYW5pbWEvcmVwby9jaGFyYWN0ZXJzL3RzL2FvaS5qc29uJykhKVxuICBleHBlY3QocGFjay50aW1lbGluZS5tYXAoKHQ6IHsgY2hhcHRlcjogc3RyaW5nIH0pID0+IHQuY2hhcHRlcikpLnRvRXF1YWwoWydjaDEnLCAnY2gyJ10pXG4gIGV4cGVjdChwYWNrLnBlcnNvbmEudG9uZSkudG9CZSgn5rqr5p+UJylcbiAgZXhwZWN0KHBhY2suY29uZmxpY3RzWzBdKS50b01hdGNoT2JqZWN0KHsgZmllbGQ6ICdwZXJzb25hLnRvbmUnLCBwcm9wb3NlZDogJ+WCsuWsjCcsIHN0YXR1czogJ+W+heeiuuiqjScgfSlcbn0pXG5cbnRlc3QoJ3NjaGVtYSDpqZforYnlpLHmlZfkuI3lr6vmqpTjgIHkuI3lu7ogUFLvvJtjYW5jZWwg5riF6Zmk5b6F56K66KqNJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IGJhZCA9IGNoYXIoeyBheGVzOiB7IGdlbnRsZTogOTksIHRzdW5kZXJlOiAyLCBsaXZlbHk6IDUsIGZvcm1hbDogNCwgdGFsa2F0aXZlOiA1LCBodW1vcjogMywgcHJvYWN0aXZlOiA2LCBleHByZXNzaXZlOiA1IH0gfSlcbiAgY29uc3QgcyA9IHNldHVwKG9uIGFzIG5ldmVyLCBbcmVwbHkoYmFkKV0sIG5ldyBNYXAoW1snL3JlcG8vY2gxLnR4dCcsICdhJ11dKSlcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9yZXBvJyB9IGFzIG5ldmVyKVxuICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NoMS50eHQnKVxuICBleHBlY3QoYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICdjb25maXJtJykpLnRvQ29udGFpbignc2NoZW1hIOmpl+itieWkseaVlycpXG4gIGV4cGVjdChzLmNtZHMuc29tZShjID0+IGNbMF0gPT09ICd0ZWEnKSkudG9CZShmYWxzZSlcbiAgZXhwZWN0KFsuLi5zLmZpbGVzLmtleXMoKV0uc29tZShrID0+IGsuaW5jbHVkZXMoJ2NoYXJhY3RlcnMnKSkpLnRvQmUoZmFsc2UpXG4gIGV4cGVjdChhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NhbmNlbCcpKS50b0NvbnRhaW4oJ+W3suWPlua2iCcpXG59KVxuXG50ZXN0KCfosrzkuIrnq6Dnr4DlhaflrrnvvJpwYXN0ZSA856ug56+A5ZCN56ixPiDliqDkuIvkuIDooYzotbfnmoTlhaflrrnvvIzkuKblr6vlhaXoqp7oqIDmrITkvY3oiIcgaW5kZXguanNvbicsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBzID0gc2V0dXAob24gYXMgbmV2ZXIsIFtyZXBseShjaGFyKHsgbGFuZ3VhZ2U6ICfnuYHpq5TkuK3mlofvvIzlsJHph4/ljp/kvZzlj6PnmZYnIH0pKV0pXG4gIGF3YWl0ICQuc2Vzc2lvbi5zdGFydCh7IHNvdXJjZTogJ3N0YXJ0dXAnLCBjd2Q6ICcvcmVwbycgfSBhcyBuZXZlcilcbiAgZXhwZWN0KGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAncGFzdGUnKSkudG9Db250YWluKCfosrzkuIrnq6Dnr4DnmoTnlKjms5UnKVxuICBjb25zdCB0MSA9IGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAncGFzdGUg56ys5LiA56ugXFxu6YCZ5piv6LK85LiK55qE56ug56+A5YWn5a6544CCJylcbiAgZXhwZWN0KHQxKS50b0NvbnRhaW4oJ2FvaScpXG4gIGV4cGVjdChzLnByb21wdHNbMF0pLnRvQ29udGFpbign6YCZ5piv6LK85LiK55qE56ug56+A5YWn5a6544CCJylcbiAgYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICdjb25maXJtJylcbiAgYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICdjb25maXJtJylcbiAgY29uc3QgcGFjayA9IEpTT04ucGFyc2Uocy5maWxlcy5nZXQoJy9ob21lL3UvLmNhY2hlL2pzYy1hbmltYS9yZXBvL2NoYXJhY3RlcnMvdHMvYW9pLmpzb24nKSEpXG4gIGV4cGVjdChwYWNrLnRpbWVsaW5lWzBdLmNoYXB0ZXIpLnRvQmUoJ+esrOS4gOeroCcpXG4gIGV4cGVjdChwYWNrLmxhbmd1YWdlKS50b0JlKCfnuYHpq5TkuK3mlofvvIzlsJHph4/ljp/kvZzlj6PnmZYnKVxuICBleHBlY3QoSlNPTi5wYXJzZShzLmZpbGVzLmdldCgnL2hvbWUvdS8uY2FjaGUvanNjLWFuaW1hL3JlcG8vY2hhcmFjdGVycy9pbmRleC5qc29uJykhKS5wYWNrc1swXSkudG9FcXVhbCh7IHdvcms6ICd0cycsIHdvcmtOYW1lOiAn5ris6Kmm54mp6KqeJywgc2x1ZzogJ2FvaScgfSlcbn0pXG5cbnRlc3QoJ+ashOS9jeWQq+mVt+auteW8leiZn+WFp+WuueimlueCuuaKhOmMhOWOn+S9nOWPsOipnu+8jOS4jeWvq+aqlCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBxdW90ZWQgPSBjaGFyKHsgcGVyc29uYTogeyBzZWxmUmVmOiAn5oiRJywgYWRkcmVzczogJ+S9oCcsIHRvbmU6ICfjgIzpgJnmmK/kuIDmrrXlvojplbflvojplbfnmoTljp/kvZzlj7DoqZ7lhaflrrnvvIzkuI3mh4noqbLlh7rnj77lnKjop5LoibLljIXoo6HpnaLjgI0nLCBjYXRjaHBocmFzZTogJ+WKoOayuScsIHZhbHVlczogJ+iqoOWvpicsIHRhYm9vczogJ+iDjOWPmycgfSB9KVxuICBjb25zdCBzID0gc2V0dXAob24gYXMgbmV2ZXIsIFtyZXBseShxdW90ZWQpXSwgbmV3IE1hcChbWycvcmVwby9jaDEudHh0JywgJ2EnXV0pKVxuICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3JlcG8nIH0gYXMgbmV2ZXIpXG4gIGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAnY2gxLnR4dCcpXG4gIGV4cGVjdChhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKSkudG9Db250YWluKCfnlpHkvLzmioTpjITljp/kvZzlj7DoqZ4nKVxuICBleHBlY3QoWy4uLnMuZmlsZXMua2V5cygpXS5zb21lKGsgPT4gay5pbmNsdWRlcygnY2hhcmFjdGVycycpKSkudG9CZShmYWxzZSlcbn0pXG5cbnRlc3QoJ+WcqOmdniBqc2MtYW5pbWEg55uu6YyE5Z+36KGM77yaZ2l0IOiIhyBQUiDpg73otbAganNjLWFuaW1hIOeahOW/q+WPliBjbG9uZe+8jOS4jeeisCBzZXNzaW9uIOebrumMhCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXNzaW9uQ3dkID0gJy9vdGhlci9wcm9qJ1xuICB0cnkge1xuICAgIGNvbnN0IHMgPSBzZXR1cChvbiBhcyBuZXZlciwgW3JlcGx5KGNoYXIoKSldLCBuZXcgTWFwKFtbJy9vdGhlci9wcm9qL2NoMS50eHQnLCAn56ys5LiA5q61J11dKSlcbiAgICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL290aGVyL3Byb2onIH0gYXMgbmV2ZXIpXG4gICAgYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICcvb3RoZXIvcHJvai9jaDEudHh0JylcbiAgICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKVxuICAgIGV4cGVjdChhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKSkudG9Db250YWluKCflt7Llu7rnq4sgUFInKVxuICAgIGV4cGVjdChzLmNtZHMuc29tZShjID0+IGMuaW5jbHVkZXMoJ2ZldGNoJykpKS50b0JlKHRydWUpXG4gICAgY29uc3QgcHIgPSBzLmNtZHMuZmluZChjID0+IGNbMF0gPT09ICd0ZWEnICYmIGNbMV0gPT09ICdwdWxscycpIVxuICAgIGV4cGVjdChwcikudG9Db250YWluKCdqaWFudHc4My9qc2MtYW5pbWEnKVxuICAgIGV4cGVjdChzLmZpbGVzLmhhcygnL290aGVyL3Byb2ovY2hhcmFjdGVycy9pbmRleC5qc29uJykpLnRvQmUoZmFsc2UpXG4gICAgZXhwZWN0KEpTT04ucGFyc2Uocy5maWxlcy5nZXQoJy9ob21lL3UvLmNhY2hlL2pzYy1hbmltYS9yZXBvL2NoYXJhY3RlcnMvaW5kZXguanNvbicpISkucGFja3NbMF0uc2x1ZykudG9CZSgnYW9pJylcbiAgfSBmaW5hbGx5IHtcbiAgICBzZXNzaW9uQ3dkID0gJy9yZXBvJ1xuICB9XG59KVxuXG50ZXN0KCflv6vlj5YgY2xvbmUg5LiN5a2Y5Zyo5pmC5YWIIGNsb25lIGpzYy1hbmltYScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjbG9uZU1pc3NpbmcgPSB0cnVlXG4gIHRyeSB7XG4gICAgY29uc3QgcyA9IHNldHVwKG9uIGFzIG5ldmVyLCBbcmVwbHkoY2hhcigpKV0sIG5ldyBNYXAoW1snL3JlcG8vY2gxLnR4dCcsICdhJ11dKSlcbiAgICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3JlcG8nIH0gYXMgbmV2ZXIpXG4gICAgYXdhaXQgcnVuKCQgYXMgbmV2ZXIsICdjaDEudHh0JylcbiAgICBjb25zdCBjbG9uZSA9IHMuY21kcy5maW5kKGMgPT4gYy5pbmNsdWRlcygnY2xvbmUnKSkhXG4gICAgZXhwZWN0KGNsb25lKS50b0NvbnRhaW4oJ2h0dHBzOi8vZ2l0ZWEuanNjLmlkdi50dy9qaWFudHc4My9qc2MtYW5pbWEuZ2l0JylcbiAgfSBmaW5hbGx5IHtcbiAgICBjbG9uZU1pc3NpbmcgPSBmYWxzZVxuICB9XG59KVxuXG50ZXN0KCdwYXN0Ze+8mkNSTEYg5o+b6KGM5Lmf6IO95YiG5Ye656ug56+A5ZCN56ix6IiH5YWn5a65JywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHMgPSBzZXR1cChvbiBhcyBuZXZlciwgW3JlcGx5KGNoYXIoKSldKVxuICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3JlcG8nIH0gYXMgbmV2ZXIpXG4gIGF3YWl0IHJ1bigkIGFzIG5ldmVyLCAncGFzdGUg56ys5LqM56ugXFxyXFxu56ys5LiA6KGMXFxyXFxu56ys5LqM6KGMJylcbiAgZXhwZWN0KHMucHJvbXB0c1swXSkudG9Db250YWluKCfnrKzkuIDooYwnKVxufSlcblxudGVzdCgn5ZCI5L215Lim5pu05paw5aSW5o6b5b6M77ya5ZWf5YuV5pmC5b6e5aSW5o6b55uu6YyE55qEIGluZGV4Lmpzb24g6Ki75YaKIHvkvZzlk4Hku6PomZ99LXvop5LoibLku6PomZ99IOS4puWPr+WVn+WLlScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCBzID0gc2V0dXAob24gYXMgbmV2ZXIsIFtyZXBseShjaGFyKCkpXSwgbmV3IE1hcChbWycvcmVwby9jaDEudHh0JywgJ2EnXV0pKVxuICByZWdpc3RlcmVkID0gW11cbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9yZXBvJyB9IGFzIG5ldmVyKVxuICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NoMS50eHQnKVxuICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKVxuICBhd2FpdCBydW4oJCBhcyBuZXZlciwgJ2NvbmZpcm0nKVxuICAvLyDmqKHmk6wgUFIg5ZCI5L2144CB5aSW5o6b5pu05paw77yaY2xvbmUg5YWn55qEIGNoYXJhY3RlcnMvIOWFp+WuueWHuuePvuWcqOWkluaOm+ebrumMhOOAglxuICBjb25zdCByb290ID0gKFsuLi5wcm9iZWRdLmZpbmQocSA9PiAhcS5zdGFydHNXaXRoKCcvaG9tZS91LycpKSA/PyAnJykucmVwbGFjZSgnL2NoYXJhY3RlcnMvaW5kZXguanNvbicsICcnKVxuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBbLi4ucy5maWxlc10pIGlmIChrLnN0YXJ0c1dpdGgoJy9ob21lL3UvLmNhY2hlL2pzYy1hbmltYS9yZXBvL2NoYXJhY3RlcnMvJykpIHMuZmlsZXMuc2V0KGsucmVwbGFjZSgnL2hvbWUvdS8uY2FjaGUvanNjLWFuaW1hL3JlcG8nLCByb290KSwgdilcbiAgYXdhaXQgJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy9hbnl3aGVyZScgfSBhcyBuZXZlcilcbiAgZXhwZWN0KHJlZ2lzdGVyZWQpLnRvQ29udGFpbigndHMtYW9pJylcbn0pXG4iXSwiZmlsZSI6Ii9ob29rcy9leHRyYWN0LnRlc3QudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3MvZXh0cmFjdC50ZXN0LnRzIiwiL2hvb2tzL2V4dHJhY3QudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiY2xhdWRlLWNvZGUvdGVzdGluZyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/62b7c79e321aca8bdc9ee9230d8f4b803bd74b84 b/node_modules/.vitest-cache/62b7c79e321aca8bdc9ee9230d8f4b803bd74b84 new file mode 100644 index 0000000..22d36b0 --- /dev/null +++ b/node_modules/.vitest-cache/62b7c79e321aca8bdc9ee9230d8f4b803bd74b84 @@ -0,0 +1,203 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); +const __vite_ssr_import_1__ = await __vite_ssr_import__("/hooks/statusline.ts", {"importedNames":["HIDE_ORDER","bar","layout","remainColor","usedColor"]}); +const __vite_ssr_import_2__ = await __vite_ssr_import__("/hooks/characters.ts", {"importedNames":["CHARACTERS","packToCharacter","personaSection","registerCharacters","themeColor"]}); + + + +const seg = (id, text) => ({ + id, + parts: [{ text }] +}); +(0,__vite_ssr_import_0__.test)("啟動角色後 persona 注入系統提示", async ($, on) => { + __vite_ssr_import_0__.mock.store(on); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: "/tmp" })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); + await $.session.start({ + source: "startup", + cwd: "/tmp" + }); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + const res = await $.prompt.compose({ + model: "m", + promptModel: "m", + surfaces: [], + tools: [], + outputStyle: null, + traits: [] + }); + (0,__vite_ssr_import_0__.expect)(res.sections.some((s) => s.id === "jsc-anima:persona" && s.text.includes("亞絲娜"))).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("切換角色與離開", async ($, on) => { + __vite_ssr_import_0__.mock.store(on); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: "/tmp" })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); + await $.session.start({ + source: "startup", + cwd: "/tmp" + }); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + await $.command.run({ + command: "sao-suguha", + args: "" + }); + const compose = () => $.prompt.compose({ + model: "m", + promptModel: "m", + surfaces: [], + tools: [], + outputStyle: null, + traits: [] + }); + (0,__vite_ssr_import_0__.expect)((await compose()).sections.find((s) => s.id === "jsc-anima:persona")?.text).toContain("直葉"); + await $.command.run({ + command: "anima-off", + args: "" + }); + (0,__vite_ssr_import_0__.expect)((await compose()).sections.some((s) => s.id === "jsc-anima:persona")).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("狀態列:窄時依序整欄隱藏,不截斷", () => { + const all = [ + seg("character", "AB"), + seg("model", "CD"), + seg("dir", "EF"), + seg("branch", "GH"), + seg("5h", "IJ"), + seg("7d", "KL"), + seg("ctx", "MN"), + seg("sys", "OP") + ]; + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.layout)(all, 999).length).toBe(8); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.layout)(all, 26).map((s) => s.id)).not.toContain("sys"); + const narrow = (0,__vite_ssr_import_1__.layout)(all, 14).map((s) => s.id); + (0,__vite_ssr_import_0__.expect)(narrow).toEqual([ + "character", + "model", + "5h", + "ctx" + ]); + (0,__vite_ssr_import_0__.expect)([...__vite_ssr_import_1__.HIDE_ORDER]).toEqual([ + "sys", + "7d", + "dir", + "branch" + ]); +}); +(0,__vite_ssr_import_0__.test)("量表固定長度,剩餘越少越紅", () => { + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.bar)(0).length).toBe((0,__vite_ssr_import_1__.bar)(100).length); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.remainColor)(10, 60, 85)).toBe("red"); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.remainColor)(90, 60, 85)).toBe("green"); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_1__.usedColor)(70, 60, 85)).toBe("yellow"); +}); +(0,__vite_ssr_import_0__.test)("persona 含動漫層與口頭禪,主題色可用於狀態列", () => { + const c = __vite_ssr_import_2__.CHARACTERS[0]; + const text = (0,__vite_ssr_import_2__.personaSection)(c, c.axes); + (0,__vite_ssr_import_0__.expect)(text).toContain("動漫刻畫"); + (0,__vite_ssr_import_0__.expect)(text).toContain("口頭禪"); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_2__.themeColor)(c)).toBe("red"); +}); +(0,__vite_ssr_import_0__.test)("角色包轉成可啟動角色:代號、年齡與原作戀人", () => { + const pack = { + slug: "rin", + name: "凜", + work: "demo", + persona: { + selfRef: "我", + address: "你", + tone: "冷靜", + catchphrase: "嗯", + values: "誠實", + taboos: "不說謊" + }, + axes: __vite_ssr_import_2__.CHARACTERS[0].axes, + anime: { + moe: "m", + speech: "s", + emotions: "e", + kaomoji: "k", + themeColor: "blue" + }, + timeline: [{ + chapter: "第2章", + age: 19, + relationships: [{ + with: "蓮", + kind: "romantic" + }] + }] + }; + const c = (0,__vite_ssr_import_2__.packToCharacter)(pack, "示範"); + (0,__vite_ssr_import_0__.expect)(c.slug).toBe("demo-rin"); + (0,__vite_ssr_import_0__.expect)(c.timeline).toEqual([{ + chapter: 2, + age: 19, + romance: "蓮" + }]); + (0,__vite_ssr_import_0__.expect)((0,__vite_ssr_import_2__.themeColor)(c)).toBe("cyan"); + (0,__vite_ssr_import_2__.registerCharacters)([c, c]); + (0,__vite_ssr_import_0__.expect)(__vite_ssr_import_2__.CHARACTERS.filter((x) => x.slug === "demo-rin").length).toBe(1); +}); +(0,__vite_ssr_import_0__.test)("角色包:最新章節狀態、作品用語與語言設定進入 persona", () => { + const pack = { + slug: "mio", + name: "澪", + work: "demo2", + persona: { + selfRef: "我", + address: "你", + tone: "冷靜", + catchphrase: "嗯", + values: "誠實", + taboos: "不說謊" + }, + axes: __vite_ssr_import_2__.CHARACTERS[0].axes, + anime: { + moe: "m", + speech: "s", + emotions: "e", + kaomoji: "k", + themeColor: "red" + }, + language: "繁體中文,不使用口癖", + timeline: [{ + chapter: "第1章", + mood: "緊張", + dialogueStyle: "客氣", + monologue: "想變強", + place: "學院", + age: 16, + relationships: [] + }, { + chapter: "第2章", + mood: "安心", + dialogueStyle: "放鬆", + monologue: "想守護", + place: "街上", + age: 16, + relationships: [] + }] + }; + const c = (0,__vite_ssr_import_2__.packToCharacter)(pack, "示範二", [{ + term: "魔核", + definition: "力量來源" + }]); + const text = (0,__vite_ssr_import_2__.personaSection)(c, c.axes); + (0,__vite_ssr_import_0__.expect)(text).toContain("最新章節(第2章)"); + (0,__vite_ssr_import_0__.expect)(text).toContain("安心"); + (0,__vite_ssr_import_0__.expect)(text).not.toContain("緊張"); + (0,__vite_ssr_import_0__.expect)(text).toContain("魔核=力量來源"); + (0,__vite_ssr_import_0__.expect)(text).toContain("不使用口癖"); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUE7QUFFQTtBQUVBOzs7O0FBR0EsTUFBTSxPQUFPLElBQVksVUFBMkI7Q0FBRTtDQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssQ0FBQztBQUFFO0FBRTVFLCtCQUFLLHdCQUF3QixPQUFPLEdBQUcsT0FBTztDQUM1QywyQkFBSyxNQUFNLEVBQUU7Q0FDYixHQUFHLDJCQUEyQixFQUFFLE9BQU8sRUFBRSxNQUFNLElBQUksRUFBRSxFQUFXO0NBQ2hFLEdBQUcsd0JBQXdCLEVBQUUsS0FBSyxPQUFPLEVBQVc7Q0FDcEQsR0FBRyxzQkFBc0IsRUFBRSxNQUFNLEdBQUcsRUFBRTtDQUN0QyxHQUFHLHlCQUF5QixFQUFFLFVBQVUsQ0FBQyxFQUFFLEVBQUU7Q0FDN0MsTUFBTSxFQUFFLFFBQVEsTUFBTTtFQUFFLFFBQVE7RUFBVyxLQUFLO0NBQU8sQ0FBVTtDQUNqRSxNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFhLE1BQU07Q0FBRyxDQUFVO0NBQy9ELE1BQU0sTUFBTSxNQUFNLEVBQUUsT0FBTyxRQUFRO0VBQUUsT0FBTztFQUFLLGFBQWE7RUFBSyxVQUFVLENBQUM7RUFBRyxPQUFPLENBQUM7RUFBRyxhQUFhO0VBQU0sUUFBUSxDQUFDO0NBQUUsQ0FBVTtDQUNwSSxpQ0FBTyxJQUFJLFNBQVMsTUFBSyxNQUFLLEVBQUUsT0FBTyx1QkFBdUIsRUFBRSxLQUFLLFNBQVMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUNsRyxDQUFDO0FBRUQsK0JBQUssV0FBVyxPQUFPLEdBQUcsT0FBTztDQUMvQiwyQkFBSyxNQUFNLEVBQUU7Q0FDYixHQUFHLDJCQUEyQixFQUFFLE9BQU8sRUFBRSxNQUFNLElBQUksRUFBRSxFQUFXO0NBQ2hFLEdBQUcsd0JBQXdCLEVBQUUsS0FBSyxPQUFPLEVBQVc7Q0FDcEQsR0FBRyxzQkFBc0IsRUFBRSxNQUFNLEdBQUcsRUFBRTtDQUN0QyxHQUFHLHlCQUF5QixFQUFFLFVBQVUsQ0FBQyxFQUFFLEVBQUU7Q0FDN0MsTUFBTSxFQUFFLFFBQVEsTUFBTTtFQUFFLFFBQVE7RUFBVyxLQUFLO0NBQU8sQ0FBVTtDQUNqRSxNQUFNLEVBQUUsUUFBUSxJQUFJO0VBQUUsU0FBUztFQUFhLE1BQU07Q0FBRyxDQUFVO0NBQy9ELE1BQU0sRUFBRSxRQUFRLElBQUk7RUFBRSxTQUFTO0VBQWMsTUFBTTtDQUFHLENBQVU7Q0FDaEUsTUFBTSxnQkFBZ0IsRUFBRSxPQUFPLFFBQVE7RUFBRSxPQUFPO0VBQUssYUFBYTtFQUFLLFVBQVUsQ0FBQztFQUFHLE9BQU8sQ0FBQztFQUFHLGFBQWE7RUFBTSxRQUFRLENBQUM7Q0FBRSxDQUFVO0NBQ3hJLGtDQUFRLE1BQU0sUUFBUSxFQUFDLENBQUUsU0FBUyxNQUFLLE1BQUssRUFBRSxPQUFPLG1CQUFtQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsVUFBVSxJQUFJO0NBQy9GLE1BQU0sRUFBRSxRQUFRLElBQUk7RUFBRSxTQUFTO0VBQWEsTUFBTTtDQUFHLENBQVU7Q0FDL0Qsa0NBQVEsTUFBTSxRQUFRLEVBQUMsQ0FBRSxTQUFTLE1BQUssTUFBSyxFQUFFLE9BQU8sbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSztBQUN2RixDQUFDO0FBRUQsK0JBQUssMEJBQTBCO0NBQzdCLE1BQU0sTUFBTTtFQUFDLElBQUksYUFBYSxJQUFJO0VBQUcsSUFBSSxTQUFTLElBQUk7RUFBRyxJQUFJLE9BQU8sSUFBSTtFQUFHLElBQUksVUFBVSxJQUFJO0VBQUcsSUFBSSxNQUFNLElBQUk7RUFBRyxJQUFJLE1BQU0sSUFBSTtFQUFHLElBQUksT0FBTyxJQUFJO0VBQUcsSUFBSSxPQUFPLElBQUk7Q0FBQztDQUNwSyxpQ0FBTyxpQ0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQztDQUN0QyxpQ0FBTyxpQ0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUksTUFBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxVQUFVLEtBQUs7Q0FDMUQsTUFBTSxTQUFTLGlDQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSSxNQUFLLEVBQUUsRUFBRTtDQUM1QyxpQ0FBTyxNQUFNLENBQUMsQ0FBQyxRQUFRO0VBQUM7RUFBYTtFQUFTO0VBQU07Q0FBSyxDQUFDO0NBQzFELGlDQUFPLENBQUMsR0FBRyxnQ0FBVSxDQUFDLENBQUMsQ0FBQyxRQUFRO0VBQUM7RUFBTztFQUFNO0VBQU87Q0FBUSxDQUFDO0FBQ2hFLENBQUM7QUFFRCwrQkFBSyx1QkFBdUI7Q0FDMUIsaUNBQU8sOEJBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyw4QkFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNO0NBQzFDLGlDQUFPLHNDQUFZLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSztDQUMxQyxpQ0FBTyxzQ0FBWSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLE9BQU87Q0FDNUMsaUNBQU8sb0NBQVUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRO0FBQzdDLENBQUM7QUFFRCwrQkFBSyxvQ0FBb0M7Q0FDdkMsTUFBTSxJQUFJLGlDQUFXO0NBQ3JCLE1BQU0sT0FBTyx5Q0FBZSxHQUFHLEVBQUUsSUFBSTtDQUNyQyxpQ0FBTyxJQUFJLENBQUMsQ0FBQyxVQUFVLE1BQU07Q0FDN0IsaUNBQU8sSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLO0NBQzVCLGlDQUFPLHFDQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLO0FBQ2xDLENBQUM7QUFFRCwrQkFBSywrQkFBK0I7Q0FDbEMsTUFBTSxPQUFpQjtFQUNyQixNQUFNO0VBQU8sTUFBTTtFQUFLLE1BQU07RUFDOUIsU0FBUztHQUFFLFNBQVM7R0FBSyxTQUFTO0dBQUssTUFBTTtHQUFNLGFBQWE7R0FBSyxRQUFRO0dBQU0sUUFBUTtFQUFNO0VBQ2pHLE1BQU0saUNBQVcsRUFBRSxDQUFFO0VBQ3JCLE9BQU87R0FBRSxLQUFLO0dBQUssUUFBUTtHQUFLLFVBQVU7R0FBSyxTQUFTO0dBQUssWUFBWTtFQUFPO0VBQ2hGLFVBQVUsQ0FBQztHQUFFLFNBQVM7R0FBTyxLQUFLO0dBQUksZUFBZSxDQUFDO0lBQUUsTUFBTTtJQUFLLE1BQU07R0FBVyxDQUFDO0VBQUUsQ0FBQztDQUMxRjtDQUNBLE1BQU0sSUFBSSwwQ0FBZ0IsTUFBTSxJQUFJO0NBQ3BDLGlDQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxVQUFVO0NBQzlCLGlDQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDO0VBQUUsU0FBUztFQUFHLEtBQUs7RUFBSSxTQUFTO0NBQUksQ0FBQyxDQUFDO0NBQ2xFLGlDQUFPLHFDQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNO0NBQ2pDLDZDQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0NBQ3pCLGlDQUFPLGlDQUFXLFFBQU8sTUFBSyxFQUFFLFNBQVMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3JFLENBQUM7QUFFRCwrQkFBSyx3Q0FBd0M7Q0FDM0MsTUFBTSxPQUFpQjtFQUNyQixNQUFNO0VBQU8sTUFBTTtFQUFLLE1BQU07RUFDOUIsU0FBUztHQUFFLFNBQVM7R0FBSyxTQUFTO0dBQUssTUFBTTtHQUFNLGFBQWE7R0FBSyxRQUFRO0dBQU0sUUFBUTtFQUFNO0VBQ2pHLE1BQU0saUNBQVcsRUFBRSxDQUFFO0VBQ3JCLE9BQU87R0FBRSxLQUFLO0dBQUssUUFBUTtHQUFLLFVBQVU7R0FBSyxTQUFTO0dBQUssWUFBWTtFQUFNO0VBQy9FLFVBQVU7RUFDVixVQUFVLENBQ1I7R0FBRSxTQUFTO0dBQU8sTUFBTTtHQUFNLGVBQWU7R0FBTSxXQUFXO0dBQU8sT0FBTztHQUFNLEtBQUs7R0FBSSxlQUFlLENBQUM7RUFBRSxHQUM3RztHQUFFLFNBQVM7R0FBTyxNQUFNO0dBQU0sZUFBZTtHQUFNLFdBQVc7R0FBTyxPQUFPO0dBQU0sS0FBSztHQUFJLGVBQWUsQ0FBQztFQUFFLENBQy9HO0NBQ0Y7Q0FDQSxNQUFNLElBQUksMENBQWdCLE1BQU0sT0FBTyxDQUFDO0VBQUUsTUFBTTtFQUFNLFlBQVk7Q0FBTyxDQUFDLENBQUM7Q0FDM0UsTUFBTSxPQUFPLHlDQUFlLEdBQUcsRUFBRSxJQUFJO0NBQ3JDLGlDQUFPLElBQUksQ0FBQyxDQUFDLFVBQVUsV0FBVztDQUNsQyxpQ0FBTyxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUk7Q0FDM0IsaUNBQU8sSUFBSSxDQUFDLENBQUMsSUFBSSxVQUFVLElBQUk7Q0FDL0IsaUNBQU8sSUFBSSxDQUFDLENBQUMsVUFBVSxTQUFTO0NBQ2hDLGlDQUFPLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTztBQUNoQyxDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJhbmltYS50ZXN0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4cGVjdCwgbW9jaywgdGVzdCB9IGZyb20gJ2NsYXVkZS1jb2RlL3Rlc3RpbmcnXG5cbmltcG9ydCB7IEhJREVfT1JERVIsIGJhciwgbGF5b3V0LCByZW1haW5Db2xvciwgdXNlZENvbG9yIH0gZnJvbSAnLi9zdGF0dXNsaW5lJ1xuaW1wb3J0IHR5cGUgeyBTZWdtZW50IH0gZnJvbSAnLi9zdGF0dXNsaW5lJ1xuaW1wb3J0IHsgQ0hBUkFDVEVSUywgcGFja1RvQ2hhcmFjdGVyLCBwZXJzb25hU2VjdGlvbiwgcmVnaXN0ZXJDaGFyYWN0ZXJzLCB0aGVtZUNvbG9yIH0gZnJvbSAnLi9jaGFyYWN0ZXJzJ1xuaW1wb3J0IHR5cGUgeyBQYWNrTGlrZSB9IGZyb20gJy4vY2hhcmFjdGVycydcblxuY29uc3Qgc2VnID0gKGlkOiBzdHJpbmcsIHRleHQ6IHN0cmluZyk6IFNlZ21lbnQgPT4gKHsgaWQsIHBhcnRzOiBbeyB0ZXh0IH1dIH0pXG5cbnRlc3QoJ+WVn+WLleinkuiJsuW+jCBwZXJzb25hIOazqOWFpeezu+e1seaPkOekuicsIGFzeW5jICgkLCBvbikgPT4ge1xuICBtb2NrLnN0b3JlKG9uKVxuICBvbignY29tbWFuZC5yZWdpc3RlcicsICgpID0+ICh7IHZhbHVlOiB7IG5hbWU6ICd4JyB9IH0pIGFzIG5ldmVyKVxuICBvbignc2Vzc2lvbi5zdGFydCcsICgpID0+ICh7IGN3ZDogJy90bXAnIH0pIGFzIG5ldmVyKVxuICBvbignY29tbWFuZC5ydW4nLCAoKSA9PiAoeyB0ZXh0OiAnJyB9KSlcbiAgb24oJ3Byb21wdC5jb21wb3NlJywgKCkgPT4gKHsgc2VjdGlvbnM6IFtdIH0pKVxuICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3RtcCcgfSBhcyBuZXZlcilcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdzYW8tYXN1bmEnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxuICBjb25zdCByZXMgPSBhd2FpdCAkLnByb21wdC5jb21wb3NlKHsgbW9kZWw6ICdtJywgcHJvbXB0TW9kZWw6ICdtJywgc3VyZmFjZXM6IFtdLCB0b29sczogW10sIG91dHB1dFN0eWxlOiBudWxsLCB0cmFpdHM6IFtdIH0gYXMgbmV2ZXIpXG4gIGV4cGVjdChyZXMuc2VjdGlvbnMuc29tZShzID0+IHMuaWQgPT09ICdqc2MtYW5pbWE6cGVyc29uYScgJiYgcy50ZXh0LmluY2x1ZGVzKCfkup7ntbLlqJwnKSkpLnRvQmUodHJ1ZSlcbn0pXG5cbnRlc3QoJ+WIh+aPm+inkuiJsuiIh+mboumWiycsIGFzeW5jICgkLCBvbikgPT4ge1xuICBtb2NrLnN0b3JlKG9uKVxuICBvbignY29tbWFuZC5yZWdpc3RlcicsICgpID0+ICh7IHZhbHVlOiB7IG5hbWU6ICd4JyB9IH0pIGFzIG5ldmVyKVxuICBvbignc2Vzc2lvbi5zdGFydCcsICgpID0+ICh7IGN3ZDogJy90bXAnIH0pIGFzIG5ldmVyKVxuICBvbignY29tbWFuZC5ydW4nLCAoKSA9PiAoeyB0ZXh0OiAnJyB9KSlcbiAgb24oJ3Byb21wdC5jb21wb3NlJywgKCkgPT4gKHsgc2VjdGlvbnM6IFtdIH0pKVxuICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3RtcCcgfSBhcyBuZXZlcilcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdzYW8tYXN1bmEnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxuICBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ3Nhby1zdWd1aGEnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxuICBjb25zdCBjb21wb3NlID0gKCkgPT4gJC5wcm9tcHQuY29tcG9zZSh7IG1vZGVsOiAnbScsIHByb21wdE1vZGVsOiAnbScsIHN1cmZhY2VzOiBbXSwgdG9vbHM6IFtdLCBvdXRwdXRTdHlsZTogbnVsbCwgdHJhaXRzOiBbXSB9IGFzIG5ldmVyKVxuICBleHBlY3QoKGF3YWl0IGNvbXBvc2UoKSkuc2VjdGlvbnMuZmluZChzID0+IHMuaWQgPT09ICdqc2MtYW5pbWE6cGVyc29uYScpPy50ZXh0KS50b0NvbnRhaW4oJ+ebtOiRiScpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtb2ZmJywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgZXhwZWN0KChhd2FpdCBjb21wb3NlKCkpLnNlY3Rpb25zLnNvbWUocyA9PiBzLmlkID09PSAnanNjLWFuaW1hOnBlcnNvbmEnKSkudG9CZShmYWxzZSlcbn0pXG5cbnRlc3QoJ+eLgOaFi+WIl++8mueqhOaZguS+neW6j+aVtOashOmaseiXj++8jOS4jeaIquaWtycsICgpID0+IHtcbiAgY29uc3QgYWxsID0gW3NlZygnY2hhcmFjdGVyJywgJ0FCJyksIHNlZygnbW9kZWwnLCAnQ0QnKSwgc2VnKCdkaXInLCAnRUYnKSwgc2VnKCdicmFuY2gnLCAnR0gnKSwgc2VnKCc1aCcsICdJSicpLCBzZWcoJzdkJywgJ0tMJyksIHNlZygnY3R4JywgJ01OJyksIHNlZygnc3lzJywgJ09QJyldXG4gIGV4cGVjdChsYXlvdXQoYWxsLCA5OTkpLmxlbmd0aCkudG9CZSg4KVxuICBleHBlY3QobGF5b3V0KGFsbCwgMjYpLm1hcChzID0+IHMuaWQpKS5ub3QudG9Db250YWluKCdzeXMnKVxuICBjb25zdCBuYXJyb3cgPSBsYXlvdXQoYWxsLCAxNCkubWFwKHMgPT4gcy5pZClcbiAgZXhwZWN0KG5hcnJvdykudG9FcXVhbChbJ2NoYXJhY3RlcicsICdtb2RlbCcsICc1aCcsICdjdHgnXSlcbiAgZXhwZWN0KFsuLi5ISURFX09SREVSXSkudG9FcXVhbChbJ3N5cycsICc3ZCcsICdkaXInLCAnYnJhbmNoJ10pXG59KVxuXG50ZXN0KCfph4/ooajlm7rlrprplbfluqbvvIzlianppJjotorlsJHotorntIUnLCAoKSA9PiB7XG4gIGV4cGVjdChiYXIoMCkubGVuZ3RoKS50b0JlKGJhcigxMDApLmxlbmd0aClcbiAgZXhwZWN0KHJlbWFpbkNvbG9yKDEwLCA2MCwgODUpKS50b0JlKCdyZWQnKVxuICBleHBlY3QocmVtYWluQ29sb3IoOTAsIDYwLCA4NSkpLnRvQmUoJ2dyZWVuJylcbiAgZXhwZWN0KHVzZWRDb2xvcig3MCwgNjAsIDg1KSkudG9CZSgneWVsbG93Jylcbn0pXG5cbnRlc3QoJ3BlcnNvbmEg5ZCr5YuV5ryr5bGk6IiH5Y+j6aCt56aq77yM5Li76aGM6Imy5Y+v55So5pa854uA5oWL5YiXJywgKCkgPT4ge1xuICBjb25zdCBjID0gQ0hBUkFDVEVSU1swXSFcbiAgY29uc3QgdGV4dCA9IHBlcnNvbmFTZWN0aW9uKGMsIGMuYXhlcylcbiAgZXhwZWN0KHRleHQpLnRvQ29udGFpbign5YuV5ryr5Yi755WrJylcbiAgZXhwZWN0KHRleHQpLnRvQ29udGFpbign5Y+j6aCt56aqJylcbiAgZXhwZWN0KHRoZW1lQ29sb3IoYykpLnRvQmUoJ3JlZCcpXG59KVxuXG50ZXN0KCfop5LoibLljIXovYnmiJDlj6/llZ/li5Xop5LoibLvvJrku6PomZ/jgIHlubTpvaHoiIfljp/kvZzmiIDkuronLCAoKSA9PiB7XG4gIGNvbnN0IHBhY2s6IFBhY2tMaWtlID0ge1xuICAgIHNsdWc6ICdyaW4nLCBuYW1lOiAn5YecJywgd29yazogJ2RlbW8nLFxuICAgIHBlcnNvbmE6IHsgc2VsZlJlZjogJ+aIkScsIGFkZHJlc3M6ICfkvaAnLCB0b25lOiAn5Ya36Z2cJywgY2F0Y2hwaHJhc2U6ICfll68nLCB2YWx1ZXM6ICfoqqDlr6YnLCB0YWJvb3M6ICfkuI3oqqrorIonIH0sXG4gICAgYXhlczogQ0hBUkFDVEVSU1swXSEuYXhlcyxcbiAgICBhbmltZTogeyBtb2U6ICdtJywgc3BlZWNoOiAncycsIGVtb3Rpb25zOiAnZScsIGthb21vamk6ICdrJywgdGhlbWVDb2xvcjogJ2JsdWUnIH0sXG4gICAgdGltZWxpbmU6IFt7IGNoYXB0ZXI6ICfnrKwy56ugJywgYWdlOiAxOSwgcmVsYXRpb25zaGlwczogW3sgd2l0aDogJ+iTricsIGtpbmQ6ICdyb21hbnRpYycgfV0gfV0sXG4gIH1cbiAgY29uc3QgYyA9IHBhY2tUb0NoYXJhY3RlcihwYWNrLCAn56S656+EJylcbiAgZXhwZWN0KGMuc2x1ZykudG9CZSgnZGVtby1yaW4nKVxuICBleHBlY3QoYy50aW1lbGluZSkudG9FcXVhbChbeyBjaGFwdGVyOiAyLCBhZ2U6IDE5LCByb21hbmNlOiAn6JOuJyB9XSlcbiAgZXhwZWN0KHRoZW1lQ29sb3IoYykpLnRvQmUoJ2N5YW4nKVxuICByZWdpc3RlckNoYXJhY3RlcnMoW2MsIGNdKVxuICBleHBlY3QoQ0hBUkFDVEVSUy5maWx0ZXIoeCA9PiB4LnNsdWcgPT09ICdkZW1vLXJpbicpLmxlbmd0aCkudG9CZSgxKVxufSlcblxudGVzdCgn6KeS6Imy5YyF77ya5pyA5paw56ug56+A54uA5oWL44CB5L2c5ZOB55So6Kqe6IiH6Kqe6KiA6Kit5a6a6YCy5YWlIHBlcnNvbmEnLCAoKSA9PiB7XG4gIGNvbnN0IHBhY2s6IFBhY2tMaWtlID0ge1xuICAgIHNsdWc6ICdtaW8nLCBuYW1lOiAn5r6qJywgd29yazogJ2RlbW8yJyxcbiAgICBwZXJzb25hOiB7IHNlbGZSZWY6ICfmiJEnLCBhZGRyZXNzOiAn5L2gJywgdG9uZTogJ+WGt+mdnCcsIGNhdGNocGhyYXNlOiAn5ZevJywgdmFsdWVzOiAn6Kqg5a+mJywgdGFib29zOiAn5LiN6Kqq6KyKJyB9LFxuICAgIGF4ZXM6IENIQVJBQ1RFUlNbMF0hLmF4ZXMsXG4gICAgYW5pbWU6IHsgbW9lOiAnbScsIHNwZWVjaDogJ3MnLCBlbW90aW9uczogJ2UnLCBrYW9tb2ppOiAnaycsIHRoZW1lQ29sb3I6ICdyZWQnIH0sXG4gICAgbGFuZ3VhZ2U6ICfnuYHpq5TkuK3mlofvvIzkuI3kvb/nlKjlj6PnmZYnLFxuICAgIHRpbWVsaW5lOiBbXG4gICAgICB7IGNoYXB0ZXI6ICfnrKwx56ugJywgbW9vZDogJ+e3iuW8tScsIGRpYWxvZ3VlU3R5bGU6ICflrqLmsKMnLCBtb25vbG9ndWU6ICfmg7PororlvLcnLCBwbGFjZTogJ+WtuOmZoicsIGFnZTogMTYsIHJlbGF0aW9uc2hpcHM6IFtdIH0sXG4gICAgICB7IGNoYXB0ZXI6ICfnrKwy56ugJywgbW9vZDogJ+WuieW/gycsIGRpYWxvZ3VlU3R5bGU6ICfmlL7prIYnLCBtb25vbG9ndWU6ICfmg7PlrojorbcnLCBwbGFjZTogJ+ihl+S4iicsIGFnZTogMTYsIHJlbGF0aW9uc2hpcHM6IFtdIH0sXG4gICAgXSxcbiAgfVxuICBjb25zdCBjID0gcGFja1RvQ2hhcmFjdGVyKHBhY2ssICfnpLrnr4TkuownLCBbeyB0ZXJtOiAn6a2U5qC4JywgZGVmaW5pdGlvbjogJ+WKm+mHj+S+hua6kCcgfV0pXG4gIGNvbnN0IHRleHQgPSBwZXJzb25hU2VjdGlvbihjLCBjLmF4ZXMpXG4gIGV4cGVjdCh0ZXh0KS50b0NvbnRhaW4oJ+acgOaWsOeroOevgO+8iOesrDLnq6DvvIknKVxuICBleHBlY3QodGV4dCkudG9Db250YWluKCflronlv4MnKVxuICBleHBlY3QodGV4dCkubm90LnRvQ29udGFpbign57eK5by1JylcbiAgZXhwZWN0KHRleHQpLnRvQ29udGFpbign6a2U5qC477yd5Yqb6YeP5L6G5rqQJylcbiAgZXhwZWN0KHRleHQpLnRvQ29udGFpbign5LiN5L2/55So5Y+j55mWJylcbn0pXG4iXSwiZmlsZSI6Ii9ob29rcy9hbmltYS50ZXN0LnRzIn0= + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3MvYW5pbWEudGVzdC50cyIsIi9ob29rcy9hbmltYS50ZXN0LnRzIix7InVybHMiOiI2IiwiaWRzIjoiNyJ9LFsiOCIsIjkiLCIxMCJdLFtdLFsiOCIsIjkiLCIxMCJdLHt9LCJjbGF1ZGUtY29kZS90ZXN0aW5nIiwiL2hvb2tzL3N0YXR1c2xpbmUudHMiLCIvaG9va3MvY2hhcmFjdGVycy50cyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/CACHEDIR.TAG b/node_modules/.vitest-cache/CACHEDIR.TAG new file mode 100644 index 0000000..8c1ef4c --- /dev/null +++ b/node_modules/.vitest-cache/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by Vitest. +# For information about cache directory tags see https://bford.info/cachedir/ diff --git a/node_modules/.vitest-cache/_metadata.json b/node_modules/.vitest-cache/_metadata.json new file mode 100644 index 0000000..9ee9061 --- /dev/null +++ b/node_modules/.vitest-cache/_metadata.json @@ -0,0 +1,3 @@ +{ + "lockfileHash": "e3b0c442" +} \ No newline at end of file diff --git a/node_modules/.vitest-cache/c2d7f99331c6f1eaefe80824423496e97f064d35 b/node_modules/.vitest-cache/c2d7f99331c6f1eaefe80824423496e97f064d35 new file mode 100644 index 0000000..e11a8a2 --- /dev/null +++ b/node_modules/.vitest-cache/c2d7f99331c6f1eaefe80824423496e97f064d35 @@ -0,0 +1,190 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); + +const OPTS = { options: { wikiCacheDir: "/cache/wiki" } }; +// 記憶體內的假 wiki:以 process.run/fs.* 事件邊界替代 git 與檔案系統。 +const setup = (on, opts = {}) => { + const files = new Map(Object.entries(opts.seed ?? {})); + const calls = []; + const state = { + online: opts.online ?? true, + pushOk: opts.pushOk ?? true, + commits: [] + }; + const D = "/cache/wiki"; + __vite_ssr_import_0__.mock.store(on); + __vite_ssr_import_0__.mock.env(on, { + HOME: "/home/u", + GITEA_TOKEN: "secret-token" + }); + const clock = __vite_ssr_import_0__.mock.clock(on, { now: 1e6 }); + on("command.register", (_$, e) => { + opts.registered?.push(e.name); + return { value: { name: e.name } }; + }); + on("session.start", () => ({ cwd: "/proj" })); + on("command.run", () => ({ text: "" })); + on("fs.exists", (_$, e) => ({ value: files.has(e.path.replace(`${D}/`, "")) || e.path === `${D}/.git` && files.has(".git") })); + on("fs.read", (_$, e) => { + const k = e.path.replace(`${D}/`, ""); + if (!files.has(k)) return { deny: "ENOENT" }; + return { value: files.get(k) }; + }); + on("fs.write", (_$, e) => { + files.set(e.path.replace(`${D}/`, ""), e.text); + return { value: undefined }; + }); + on("process.run", (_$, e) => { + const argv = [...e.argv]; + calls.push(argv); + const sub = argv.find((a) => [ + "clone", + "pull", + "add", + "commit", + "push", + "reset", + "get-url" + ].includes(a)); + const out = (exitCode = 0, stdout = "") => ({ value: { + exitCode, + stdout, + stderr: "" + } }); + if (sub === "get-url") return out(0, "https://gitea.example/o/r.git\n"); + if (sub === "clone") { + if (!state.online) return out(128); + files.set(".git", "1"); + return out(); + }; + if (sub === "pull") return state.online ? out() : out(128); + if (sub === "commit") { + state.commits.push(argv[argv.indexOf("-m") + 1]); + return out(); + }; + if (sub === "push") return state.pushOk ? out() : out(1); + return out(); + }); + return { + files, + calls, + state, + clock + }; +}; +const start = async ($) => { + await $.session.start({ + source: "startup", + cwd: "/proj" + }); +}; +const run = ($, command, args = "") => $.command.run({ + command, + args +}); +(0,__vite_ssr_import_0__.test)("未啟動角色時拒絕寫入與讀取", OPTS, async ($, on) => { + const w = setup(on, { seed: { + ".git": "1", + "Home.md": "## tools\n\n- [git](tools-git)\n", + "tools-git.md": "內容" + } }); + await start($); + // 工具指令尚未註冊,也未啟動:直接當作一般指令放行(由 harness 底層回空字串)。 + const res = await run($, "anima-wiki", "tools git\n內容"); + (0,__vite_ssr_import_0__.expect)(res.text).toBe(""); + (0,__vite_ssr_import_0__.expect)(w.state.commits.length).toBe(0); +}); +(0,__vite_ssr_import_0__.test)("啟動後才註冊工具,並依 wiki 目錄動態註冊", OPTS, async ($, on) => { + const registered = []; + setup(on, { + registered, + seed: { + ".git": "1", + "Home.md": "## tools\n\n- [git](tools-git)\n" + } + }); + await start($); + (0,__vite_ssr_import_0__.expect)(registered).not.toContain("anima-wiki"); + (0,__vite_ssr_import_0__.expect)(registered).not.toContain("tools-git"); + await run($, "sao-asuna"); + (0,__vite_ssr_import_0__.expect)(registered).toContain("anima-wiki"); + (0,__vite_ssr_import_0__.expect)(registered).toContain("tools-git"); +}); +(0,__vite_ssr_import_0__.test)("寫入:一個中文 commit、更新 Home 與 _Sidebar、推送,並註冊新指令", OPTS, async ($, on) => { + const w = setup(on, { seed: { ".git": "1" } }); + await start($); + await run($, "sao-asuna"); + const res = await run($, "anima-wiki", "tools git https://git-scm.com\n用 rebase 整理歷史。"); + (0,__vite_ssr_import_0__.expect)(res.text).toContain("已新增"); + (0,__vite_ssr_import_0__.expect)(w.state.commits).toEqual(["feat: 新增知識「tools/git」"]); + (0,__vite_ssr_import_0__.expect)(w.files.get("Home.md")).toContain("## tools"); + (0,__vite_ssr_import_0__.expect)(w.files.get("Home.md")).toContain("- [git](tools-git)"); + (0,__vite_ssr_import_0__.expect)(w.files.get("_Sidebar.md")).toContain("[git](tools-git)"); + (0,__vite_ssr_import_0__.expect)(w.files.get("tools-git.md")).toContain("出處:https://git-scm.com"); + (0,__vite_ssr_import_0__.expect)(w.calls.some((c) => c.includes("push"))).toBe(true); + // 讀回 + const read = await run($, "tools-git"); + (0,__vite_ssr_import_0__.expect)(read.text).toContain("用 rebase 整理歷史。"); +}); +(0,__vite_ssr_import_0__.test)("覆蓋既有主題用「更新」訊息;來源預設為使用者提供", OPTS, async ($, on) => { + const w = setup(on, { seed: { ".git": "1" } }); + await start($); + await run($, "sao-asuna"); + await run($, "anima-wiki", "tools git\n第一版"); + await run($, "anima-wiki", "tools git\n第二版"); + (0,__vite_ssr_import_0__.expect)(w.state.commits).toEqual(["feat: 新增知識「tools/git」", "feat: 更新知識「tools/git」"]); + (0,__vite_ssr_import_0__.expect)(w.files.get("tools-git.md")).toContain("出處:使用者提供"); + (0,__vite_ssr_import_0__.expect)(w.files.get("Home.md").match(/\[git\]/g).length).toBe(1); +}); +(0,__vite_ssr_import_0__.test)("10 分鐘內讀取用快取,逾時才重新 pull;離線沿用快取", OPTS, async ($, on) => { + const w = setup(on, { seed: { + ".git": "1", + "Home.md": "## tools\n\n- [git](tools-git)\n", + "tools-git.md": "舊內容" + } }); + await start($); + await run($, "sao-asuna"); + const pulls = () => w.calls.filter((c) => c.includes("pull")).length; + await run($, "tools-git"); + const base = pulls(); + await w.clock.advance(5 * 60 * 1e3); + await run($, "tools-git"); + (0,__vite_ssr_import_0__.expect)(pulls()).toBe(base); + await w.clock.advance(6 * 60 * 1e3); + w.state.online = false; + const res = await run($, "tools-git"); + (0,__vite_ssr_import_0__.expect)(pulls()).toBe(base + 1); + (0,__vite_ssr_import_0__.expect)(res.text).toContain("舊內容"); +}); +(0,__vite_ssr_import_0__.test)("推送失敗時還原並回報,不註冊指令", OPTS, async ($, on) => { + const w = setup(on, { + seed: { ".git": "1" }, + pushOk: false + }); + await start($); + await run($, "sao-asuna"); + const res = await run($, "anima-wiki", "tools git\n內容"); + (0,__vite_ssr_import_0__.expect)(res.text).toContain("失敗"); + (0,__vite_ssr_import_0__.expect)(w.calls.some((c) => c.includes("reset"))).toBe(true); +}); +(0,__vite_ssr_import_0__.test)("token 只放在指令參數,不寫入任何檔案", OPTS, async ($, on) => { + const w = setup(on, { seed: { ".git": "1" } }); + await start($); + await run($, "sao-asuna"); + await run($, "anima-wiki", "tools git\n內容"); + const pushCall = w.calls.find((c) => c.includes("push")); + (0,__vite_ssr_import_0__.expect)(pushCall.join(" ")).toContain("Authorization: token secret-token"); + (0,__vite_ssr_import_0__.expect)([...w.files.values()].some((v) => v.includes("secret-token"))).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("離開角色後工具被拒絕並提示先啟動", OPTS, async ($, on) => { + const w = setup(on, { seed: { ".git": "1" } }); + await start($); + await run($, "sao-asuna"); + await run($, "anima-off"); + const res = await run($, "anima-wiki", "tools git\n內容"); + (0,__vite_ssr_import_0__.expect)(res.text).toContain("請先啟動角色"); + (0,__vite_ssr_import_0__.expect)(w.state.commits.length).toBe(0); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUssTUFBSyxFQUFFLFNBQVMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUMxRCxDQUFDO0FBRUQsK0JBQUsseUJBQXlCLE1BQU0sT0FBTyxHQUFHLE9BQU87Q0FDbkQsTUFBTSxJQUFJLE1BQU0sSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDO0NBQzdDLE1BQU0sTUFBTSxDQUFDO0NBQ2IsTUFBTSxJQUFJLEdBQUcsV0FBVztDQUN4QixNQUFNLElBQUksR0FBRyxjQUFjLGVBQWU7Q0FDMUMsTUFBTSxXQUFXLEVBQUUsTUFBTSxNQUFLLE1BQUssRUFBRSxTQUFTLE1BQU0sQ0FBQztDQUNyRCxpQ0FBTyxTQUFTLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLG1DQUFtQztDQUN4RSxpQ0FBTyxDQUFDLEdBQUcsRUFBRSxNQUFNLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBSyxNQUFLLEVBQUUsU0FBUyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLO0FBQ2hGLENBQUM7QUFFRCwrQkFBSyxvQkFBb0IsTUFBTSxPQUFPLEdBQUcsT0FBTztDQUM5QyxNQUFNLElBQUksTUFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsSUFBSSxFQUFFLENBQUM7Q0FDN0MsTUFBTSxNQUFNLENBQUM7Q0FDYixNQUFNLElBQUksR0FBRyxXQUFXO0NBQ3hCLE1BQU0sSUFBSSxHQUFHLFdBQVc7Q0FDeEIsTUFBTSxNQUFNLE1BQU0sSUFBSSxHQUFHLGNBQWMsZUFBZTtDQUN0RCxpQ0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLFVBQVUsUUFBUTtDQUNuQyxpQ0FBTyxFQUFFLE1BQU0sUUFBUSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDdkMsQ0FBQyIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsid2lraS50ZXN0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4cGVjdCwgbW9jaywgdGVzdCB9IGZyb20gJ2NsYXVkZS1jb2RlL3Rlc3RpbmcnXG5cbmNvbnN0IE9QVFMgPSB7IG9wdGlvbnM6IHsgd2lraUNhY2hlRGlyOiAnL2NhY2hlL3dpa2knIH0gfVxuXG4vLyDoqJjmhrbpq5TlhafnmoTlgYcgd2lrae+8muS7pSBwcm9jZXNzLnJ1bu+8j2ZzLiog5LqL5Lu26YKK55WM5pu/5LujIGdpdCDoiIfmqpTmoYjns7vntbHjgIJcbmNvbnN0IHNldHVwID0gKG9uOiBhbnksIG9wdHM6IHsgcmVnaXN0ZXJlZD86IHN0cmluZ1tdOyBvbmxpbmU/OiBib29sZWFuOyBzZWVkPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjsgcHVzaE9rPzogYm9vbGVhbiB9ID0ge30pID0+IHtcbiAgY29uc3QgZmlsZXMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPihPYmplY3QuZW50cmllcyhvcHRzLnNlZWQgPz8ge30pKVxuICBjb25zdCBjYWxsczogc3RyaW5nW11bXSA9IFtdXG4gIGNvbnN0IHN0YXRlID0geyBvbmxpbmU6IG9wdHMub25saW5lID8/IHRydWUsIHB1c2hPazogb3B0cy5wdXNoT2sgPz8gdHJ1ZSwgY29tbWl0czogW10gYXMgc3RyaW5nW10gfVxuICBjb25zdCBEID0gJy9jYWNoZS93aWtpJ1xuICBtb2NrLnN0b3JlKG9uKVxuICBtb2NrLmVudihvbiwgeyBIT01FOiAnL2hvbWUvdScsIEdJVEVBX1RPS0VOOiAnc2VjcmV0LXRva2VuJyB9KVxuICBjb25zdCBjbG9jayA9IG1vY2suY2xvY2sob24sIHsgbm93OiAxXzAwMF8wMDAgfSlcbiAgb24oJ2NvbW1hbmQucmVnaXN0ZXInLCAoXyQ6IGFueSwgZTogYW55KSA9PiB7XG4gICAgb3B0cy5yZWdpc3RlcmVkPy5wdXNoKGUubmFtZSlcbiAgICByZXR1cm4geyB2YWx1ZTogeyBuYW1lOiBlLm5hbWUgfSB9IGFzIG5ldmVyXG4gIH0pXG4gIG9uKCdzZXNzaW9uLnN0YXJ0JywgKCkgPT4gKHsgY3dkOiAnL3Byb2onIH0pIGFzIG5ldmVyKVxuICBvbignY29tbWFuZC5ydW4nLCAoKSA9PiAoeyB0ZXh0OiAnJyB9KSlcbiAgb24oJ2ZzLmV4aXN0cycsIChfJDogYW55LCBlOiBhbnkpID0+ICh7IHZhbHVlOiBmaWxlcy5oYXMoZS5wYXRoLnJlcGxhY2UoYCR7RH0vYCwgJycpKSB8fCBlLnBhdGggPT09IGAke0R9Ly5naXRgICYmIGZpbGVzLmhhcygnLmdpdCcpIH0pIGFzIG5ldmVyKVxuICBvbignZnMucmVhZCcsIChfJDogYW55LCBlOiBhbnkpID0+IHtcbiAgICBjb25zdCBrID0gZS5wYXRoLnJlcGxhY2UoYCR7RH0vYCwgJycpXG4gICAgaWYgKCFmaWxlcy5oYXMoaykpIHJldHVybiB7IGRlbnk6ICdFTk9FTlQnIH0gYXMgbmV2ZXJcbiAgICByZXR1cm4geyB2YWx1ZTogZmlsZXMuZ2V0KGspISB9IGFzIG5ldmVyXG4gIH0pXG4gIG9uKCdmcy53cml0ZScsIChfJDogYW55LCBlOiBhbnkpID0+IHtcbiAgICBmaWxlcy5zZXQoZS5wYXRoLnJlcGxhY2UoYCR7RH0vYCwgJycpLCBlLnRleHQpXG4gICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCB9IGFzIG5ldmVyXG4gIH0pXG4gIG9uKCdwcm9jZXNzLnJ1bicsIChfJDogYW55LCBlOiBhbnkpID0+IHtcbiAgICBjb25zdCBhcmd2ID0gWy4uLmUuYXJndl1cbiAgICBjYWxscy5wdXNoKGFyZ3YpXG4gICAgY29uc3Qgc3ViID0gYXJndi5maW5kKGEgPT4gWydjbG9uZScsICdwdWxsJywgJ2FkZCcsICdjb21taXQnLCAncHVzaCcsICdyZXNldCcsICdnZXQtdXJsJ10uaW5jbHVkZXMoYSkpXG4gICAgY29uc3Qgb3V0ID0gKGV4aXRDb2RlID0gMCwgc3Rkb3V0ID0gJycpID0+ICh7IHZhbHVlOiB7IGV4aXRDb2RlLCBzdGRvdXQsIHN0ZGVycjogJycgfSB9KSBhcyBuZXZlclxuICAgIGlmIChzdWIgPT09ICdnZXQtdXJsJykgcmV0dXJuIG91dCgwLCAnaHR0cHM6Ly9naXRlYS5leGFtcGxlL28vci5naXRcXG4nKVxuICAgIGlmIChzdWIgPT09ICdjbG9uZScpIHtcbiAgICAgIGlmICghc3RhdGUub25saW5lKSByZXR1cm4gb3V0KDEyOClcbiAgICAgIGZpbGVzLnNldCgnLmdpdCcsICcxJylcbiAgICAgIHJldHVybiBvdXQoKVxuICAgIH1cbiAgICBpZiAoc3ViID09PSAncHVsbCcpIHJldHVybiBzdGF0ZS5vbmxpbmUgPyBvdXQoKSA6IG91dCgxMjgpXG4gICAgaWYgKHN1YiA9PT0gJ2NvbW1pdCcpIHtcbiAgICAgIHN0YXRlLmNvbW1pdHMucHVzaChhcmd2W2FyZ3YuaW5kZXhPZignLW0nKSArIDFdISlcbiAgICAgIHJldHVybiBvdXQoKVxuICAgIH1cbiAgICBpZiAoc3ViID09PSAncHVzaCcpIHJldHVybiBzdGF0ZS5wdXNoT2sgPyBvdXQoKSA6IG91dCgxKVxuICAgIHJldHVybiBvdXQoKVxuICB9KVxuICByZXR1cm4geyBmaWxlcywgY2FsbHMsIHN0YXRlLCBjbG9jayB9XG59XG5cbmNvbnN0IHN0YXJ0ID0gYXN5bmMgKCQ6IGFueSkgPT4ge1xuICBhd2FpdCAkLnNlc3Npb24uc3RhcnQoeyBzb3VyY2U6ICdzdGFydHVwJywgY3dkOiAnL3Byb2onIH0gYXMgbmV2ZXIpXG59XG5jb25zdCBydW4gPSAoJDogYW55LCBjb21tYW5kOiBzdHJpbmcsIGFyZ3MgPSAnJykgPT4gJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQsIGFyZ3MgfSBhcyBuZXZlcilcblxudGVzdCgn5pyq5ZWf5YuV6KeS6Imy5pmC5ouS57WV5a+r5YWl6IiH6K6A5Y+WJywgT1BUUywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHcgPSBzZXR1cChvbiwgeyBzZWVkOiB7ICcuZ2l0JzogJzEnLCAnSG9tZS5tZCc6ICcjIyB0b29sc1xcblxcbi0gW2dpdF0odG9vbHMtZ2l0KVxcbicsICd0b29scy1naXQubWQnOiAn5YWn5a65JyB9IH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIC8vIOW3peWFt+aMh+S7pOWwmuacquiou+WGiu+8jOS5n+acquWVn+WLle+8muebtOaOpeeVtuS9nOS4gOiIrOaMh+S7pOaUvuihjO+8iOeUsSBoYXJuZXNzIOW6leWxpOWbnuepuuWtl+S4su+8ieOAglxuICBjb25zdCByZXMgPSBhd2FpdCBydW4oJCwgJ2FuaW1hLXdpa2knLCAndG9vbHMgZ2l0XFxu5YWn5a65JylcbiAgZXhwZWN0KHJlcy50ZXh0KS50b0JlKCcnKVxuICBleHBlY3Qody5zdGF0ZS5jb21taXRzLmxlbmd0aCkudG9CZSgwKVxufSlcblxudGVzdCgn5ZWf5YuV5b6M5omN6Ki75YaK5bel5YW377yM5Lim5L6dIHdpa2kg55uu6YyE5YuV5oWL6Ki75YaKJywgT1BUUywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHJlZ2lzdGVyZWQ6IHN0cmluZ1tdID0gW11cbiAgc2V0dXAob24sIHsgcmVnaXN0ZXJlZCwgc2VlZDogeyAnLmdpdCc6ICcxJywgJ0hvbWUubWQnOiAnIyMgdG9vbHNcXG5cXG4tIFtnaXRdKHRvb2xzLWdpdClcXG4nIH0gfSlcbiAgYXdhaXQgc3RhcnQoJClcbiAgZXhwZWN0KHJlZ2lzdGVyZWQpLm5vdC50b0NvbnRhaW4oJ2FuaW1hLXdpa2knKVxuICBleHBlY3QocmVnaXN0ZXJlZCkubm90LnRvQ29udGFpbigndG9vbHMtZ2l0JylcbiAgYXdhaXQgcnVuKCQsICdzYW8tYXN1bmEnKVxuICBleHBlY3QocmVnaXN0ZXJlZCkudG9Db250YWluKCdhbmltYS13aWtpJylcbiAgZXhwZWN0KHJlZ2lzdGVyZWQpLnRvQ29udGFpbigndG9vbHMtZ2l0Jylcbn0pXG5cbnRlc3QoJ+Wvq+WFpe+8muS4gOWAi+S4reaWhyBjb21taXTjgIHmm7TmlrAgSG9tZSDoiIcgX1NpZGViYXLjgIHmjqjpgIHvvIzkuKboqLvlhormlrDmjIfku6QnLCBPUFRTLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgdyA9IHNldHVwKG9uLCB7IHNlZWQ6IHsgJy5naXQnOiAnMScgfSB9KVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCBydW4oJCwgJ3Nhby1hc3VuYScpXG4gIGNvbnN0IHJlcyA9IGF3YWl0IHJ1bigkLCAnYW5pbWEtd2lraScsICd0b29scyBnaXQgaHR0cHM6Ly9naXQtc2NtLmNvbVxcbueUqCByZWJhc2Ug5pW055CG5q235Y+y44CCJylcbiAgZXhwZWN0KHJlcy50ZXh0KS50b0NvbnRhaW4oJ+W3suaWsOWinicpXG4gIGV4cGVjdCh3LnN0YXRlLmNvbW1pdHMpLnRvRXF1YWwoWydmZWF0OiDmlrDlop7nn6XorZjjgIx0b29sc++8j2dpdOOAjSddKVxuICBleHBlY3Qody5maWxlcy5nZXQoJ0hvbWUubWQnKSkudG9Db250YWluKCcjIyB0b29scycpXG4gIGV4cGVjdCh3LmZpbGVzLmdldCgnSG9tZS5tZCcpKS50b0NvbnRhaW4oJy0gW2dpdF0odG9vbHMtZ2l0KScpXG4gIGV4cGVjdCh3LmZpbGVzLmdldCgnX1NpZGViYXIubWQnKSkudG9Db250YWluKCdbZ2l0XSh0b29scy1naXQpJylcbiAgZXhwZWN0KHcuZmlsZXMuZ2V0KCd0b29scy1naXQubWQnKSkudG9Db250YWluKCflh7romZXvvJpodHRwczovL2dpdC1zY20uY29tJylcbiAgZXhwZWN0KHcuY2FsbHMuc29tZShjID0+IGMuaW5jbHVkZXMoJ3B1c2gnKSkpLnRvQmUodHJ1ZSlcbiAgLy8g6K6A5ZueXG4gIGNvbnN0IHJlYWQgPSBhd2FpdCBydW4oJCwgJ3Rvb2xzLWdpdCcpXG4gIGV4cGVjdChyZWFkLnRleHQpLnRvQ29udGFpbign55SoIHJlYmFzZSDmlbTnkIbmrbflj7LjgIInKVxufSlcblxudGVzdCgn6KaG6JOL5pei5pyJ5Li76aGM55So44CM5pu05paw44CN6KiK5oGv77yb5L6G5rqQ6aCQ6Kit54K65L2/55So6ICF5o+Q5L6bJywgT1BUUywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHcgPSBzZXR1cChvbiwgeyBzZWVkOiB7ICcuZ2l0JzogJzEnIH0gfSlcbiAgYXdhaXQgc3RhcnQoJClcbiAgYXdhaXQgcnVuKCQsICdzYW8tYXN1bmEnKVxuICBhd2FpdCBydW4oJCwgJ2FuaW1hLXdpa2knLCAndG9vbHMgZ2l0XFxu56ys5LiA54mIJylcbiAgYXdhaXQgcnVuKCQsICdhbmltYS13aWtpJywgJ3Rvb2xzIGdpdFxcbuesrOS6jOeJiCcpXG4gIGV4cGVjdCh3LnN0YXRlLmNvbW1pdHMpLnRvRXF1YWwoWydmZWF0OiDmlrDlop7nn6XorZjjgIx0b29sc++8j2dpdOOAjScsICdmZWF0OiDmm7TmlrDnn6XorZjjgIx0b29sc++8j2dpdOOAjSddKVxuICBleHBlY3Qody5maWxlcy5nZXQoJ3Rvb2xzLWdpdC5tZCcpKS50b0NvbnRhaW4oJ+WHuuiZle+8muS9v+eUqOiAheaPkOS+mycpXG4gIGV4cGVjdCh3LmZpbGVzLmdldCgnSG9tZS5tZCcpIS5tYXRjaCgvXFxbZ2l0XFxdL2cpIS5sZW5ndGgpLnRvQmUoMSlcbn0pXG5cbnRlc3QoJzEwIOWIhumQmOWFp+iugOWPlueUqOW/q+WPlu+8jOmAvuaZguaJjemHjeaWsCBwdWxs77yb6Zui57ea5rK/55So5b+r5Y+WJywgT1BUUywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHcgPSBzZXR1cChvbiwgeyBzZWVkOiB7ICcuZ2l0JzogJzEnLCAnSG9tZS5tZCc6ICcjIyB0b29sc1xcblxcbi0gW2dpdF0odG9vbHMtZ2l0KVxcbicsICd0b29scy1naXQubWQnOiAn6IiK5YWn5a65JyB9IH0pXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGF3YWl0IHJ1bigkLCAnc2FvLWFzdW5hJylcbiAgY29uc3QgcHVsbHMgPSAoKSA9PiB3LmNhbGxzLmZpbHRlcihjID0+IGMuaW5jbHVkZXMoJ3B1bGwnKSkubGVuZ3RoXG4gIGF3YWl0IHJ1bigkLCAndG9vbHMtZ2l0JylcbiAgY29uc3QgYmFzZSA9IHB1bGxzKClcbiAgYXdhaXQgdy5jbG9jay5hZHZhbmNlKDUgKiA2MCAqIDEwMDApXG4gIGF3YWl0IHJ1bigkLCAndG9vbHMtZ2l0JylcbiAgZXhwZWN0KHB1bGxzKCkpLnRvQmUoYmFzZSlcbiAgYXdhaXQgdy5jbG9jay5hZHZhbmNlKDYgKiA2MCAqIDEwMDApXG4gIHcuc3RhdGUub25saW5lID0gZmFsc2VcbiAgY29uc3QgcmVzID0gYXdhaXQgcnVuKCQsICd0b29scy1naXQnKVxuICBleHBlY3QocHVsbHMoKSkudG9CZShiYXNlICsgMSlcbiAgZXhwZWN0KHJlcy50ZXh0KS50b0NvbnRhaW4oJ+iIiuWFp+WuuScpXG59KVxuXG50ZXN0KCfmjqjpgIHlpLHmlZfmmYLpgoTljp/kuKblm57loLHvvIzkuI3oqLvlhormjIfku6QnLCBPUFRTLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgdyA9IHNldHVwKG9uLCB7IHNlZWQ6IHsgJy5naXQnOiAnMScgfSwgcHVzaE9rOiBmYWxzZSB9KVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCBydW4oJCwgJ3Nhby1hc3VuYScpXG4gIGNvbnN0IHJlcyA9IGF3YWl0IHJ1bigkLCAnYW5pbWEtd2lraScsICd0b29scyBnaXRcXG7lhaflrrknKVxuICBleHBlY3QocmVzLnRleHQpLnRvQ29udGFpbign5aSx5pWXJylcbiAgZXhwZWN0KHcuY2FsbHMuc29tZShjID0+IGMuaW5jbHVkZXMoJ3Jlc2V0JykpKS50b0JlKHRydWUpXG59KVxuXG50ZXN0KCd0b2tlbiDlj6rmlL7lnKjmjIfku6Tlj4PmlbjvvIzkuI3lr6vlhaXku7vkvZXmqpTmoYgnLCBPUFRTLCBhc3luYyAoJCwgb24pID0+IHtcbiAgY29uc3QgdyA9IHNldHVwKG9uLCB7IHNlZWQ6IHsgJy5naXQnOiAnMScgfSB9KVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCBydW4oJCwgJ3Nhby1hc3VuYScpXG4gIGF3YWl0IHJ1bigkLCAnYW5pbWEtd2lraScsICd0b29scyBnaXRcXG7lhaflrrknKVxuICBjb25zdCBwdXNoQ2FsbCA9IHcuY2FsbHMuZmluZChjID0+IGMuaW5jbHVkZXMoJ3B1c2gnKSkhXG4gIGV4cGVjdChwdXNoQ2FsbC5qb2luKCcgJykpLnRvQ29udGFpbignQXV0aG9yaXphdGlvbjogdG9rZW4gc2VjcmV0LXRva2VuJylcbiAgZXhwZWN0KFsuLi53LmZpbGVzLnZhbHVlcygpXS5zb21lKHYgPT4gdi5pbmNsdWRlcygnc2VjcmV0LXRva2VuJykpKS50b0JlKGZhbHNlKVxufSlcblxudGVzdCgn6Zui6ZaL6KeS6Imy5b6M5bel5YW36KKr5ouS57WV5Lim5o+Q56S65YWI5ZWf5YuVJywgT1BUUywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHcgPSBzZXR1cChvbiwgeyBzZWVkOiB7ICcuZ2l0JzogJzEnIH0gfSlcbiAgYXdhaXQgc3RhcnQoJClcbiAgYXdhaXQgcnVuKCQsICdzYW8tYXN1bmEnKVxuICBhd2FpdCBydW4oJCwgJ2FuaW1hLW9mZicpXG4gIGNvbnN0IHJlcyA9IGF3YWl0IHJ1bigkLCAnYW5pbWEtd2lraScsICd0b29scyBnaXRcXG7lhaflrrknKVxuICBleHBlY3QocmVzLnRleHQpLnRvQ29udGFpbign6KuL5YWI5ZWf5YuV6KeS6ImyJylcbiAgZXhwZWN0KHcuc3RhdGUuY29tbWl0cy5sZW5ndGgpLnRvQmUoMClcbn0pXG4iXSwiZmlsZSI6Ii9ob29rcy93aWtpLnRlc3QudHMifQ== + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3Mvd2lraS50ZXN0LnRzIiwiL2hvb2tzL3dpa2kudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiY2xhdWRlLWNvZGUvdGVzdGluZyJd \ No newline at end of file diff --git a/node_modules/.vitest-cache/e1806f12dd53b604a37aca3018dcd26b7d00ba5f b/node_modules/.vitest-cache/e1806f12dd53b604a37aca3018dcd26b7d00ba5f new file mode 100644 index 0000000..50de525 --- /dev/null +++ b/node_modules/.vitest-cache/e1806f12dd53b604a37aca3018dcd26b7d00ba5f @@ -0,0 +1,104 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); +const __vite_ssr_import_1__ = await __vite_ssr_import__("/hooks/characters.ts", {"importedNames":["CHARACTERS"]}); + + +const setup = (on, active) => { + __vite_ssr_import_0__.mock.store(on, active ? { active } : undefined); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: "/tmp" })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); +}; +const compose = ($) => $.prompt.compose({ + model: "m", + promptModel: "m", + surfaces: [], + tools: [], + outputStyle: null, + traits: [] +}); +const persona = async ($) => (await compose($)).sections.find((s) => s.id === "jsc-anima:persona")?.text; +const start = ($) => $.session.start({ + source: "startup", + cwd: "/tmp" +}); +(0,__vite_ssr_import_0__.test)("啟動狀態跨 session 保留:下次開啟自動恢復", async ($, on) => { + setup(on, "sao-suguha"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toContain("直葉"); +}); +(0,__vite_ssr_import_0__.test)("啟動角色後寫入儲存,新 session 恢復;離開後不再恢復", async ($, on) => { + setup(on); + await start($); + await $.command.run({ + command: "sao-asuna", + args: "" + }); + await $.command.run({ + command: "anima-off", + args: "" + }); + await $.command.run({ + command: "sao-suguha", + args: "" + }); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toContain("直葉"); + await $.command.run({ + command: "anima-off", + args: "" + }); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toBeUndefined(); +}); +(0,__vite_ssr_import_0__.test)("在 /config 關閉 persist 後不恢復", { options: { persist: false } }, async ($, on) => { + setup(on, "sao-asuna"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toBeUndefined(); +}); +(0,__vite_ssr_import_0__.test)("儲存的角色不存在時不恢復", async ($, on) => { + setup(on, "no-such-character"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toBeUndefined(); +}); +(0,__vite_ssr_import_0__.test)("微調數值軸:反映在 persona,其餘維持角色包預設,且不改動角色包", { options: { + axisGentle: 2, + axisHumor: 9 +} }, async ($, on) => { + setup(on, "sao-asuna"); + const before = { ...__vite_ssr_import_1__.CHARACTERS.find((c) => c.slug === "sao-asuna").axes }; + await start($); + const text = await persona($); + (0,__vite_ssr_import_0__.expect)(text).toContain("溫柔 2"); + (0,__vite_ssr_import_0__.expect)(text).toContain("幽默 9"); + (0,__vite_ssr_import_0__.expect)(text).toContain(`傲嬌 ${before.tsundere}`); + (0,__vite_ssr_import_0__.expect)(__vite_ssr_import_1__.CHARACTERS.find((c) => c.slug === "sao-asuna").axes).toEqual(before); +}); +(0,__vite_ssr_import_0__.test)("未微調(-1)沿用角色包預設", { options: { axisGentle: -1 } }, async ($, on) => { + setup(on, "sao-asuna"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toContain(`溫柔 ${__vite_ssr_import_1__.CHARACTERS.find((c) => c.slug === "sao-asuna").axes.gentle}`); +}); +(0,__vite_ssr_import_0__.test)("8 個數值軸都可微調", { options: { + axisGentle: 1, + axisTsundere: 2, + axisLively: 3, + axisFormal: 4, + axisTalkative: 5, + axisHumor: 6, + axisProactive: 7, + axisExpressive: 8 +} }, async ($, on) => { + setup(on, "sao-asuna"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toContain("溫柔 1、傲嬌 2、活潑 3、正式 4、話量 5、幽默 6、主動 7、情緒外顯 8"); +}); +(0,__vite_ssr_import_0__.test)("超出 0-10 的覆蓋值被忽略", { options: { axisGentle: 11 } }, async ($, on) => { + setup(on, "sao-asuna"); + await start($); + (0,__vite_ssr_import_0__.expect)(await persona($)).toContain(`溫柔 ${__vite_ssr_import_1__.CHARACTERS.find((c) => c.slug === "sao-asuna").axes.gentle}`); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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QUFPLGlDQUFXLE1BQUssTUFBSyxFQUFFLFNBQVMsV0FBVyxDQUFDLENBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxNQUFNO0FBQzNFLENBQUM7QUFFRCwrQkFBSyxrQkFBa0IsRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLEVBQUUsRUFBRSxHQUFHLE9BQU8sR0FBRyxPQUFPO0NBQ3ZFLE1BQU0sSUFBSSxXQUFXO0NBQ3JCLE1BQU0sTUFBTSxDQUFDO0NBQ2IsaUNBQU8sTUFBTSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxNQUFNLGlDQUFXLE1BQUssTUFBSyxFQUFFLFNBQVMsV0FBVyxDQUFDLENBQUUsS0FBSyxRQUFRO0FBQ3RHLENBQUM7QUFFRCwrQkFBSyxjQUFjLEVBQ2pCLFNBQVM7Q0FBRSxZQUFZO0NBQUcsY0FBYztDQUFHLFlBQVk7Q0FBRyxZQUFZO0NBQUcsZUFBZTtDQUFHLFdBQVc7Q0FBRyxlQUFlO0NBQUcsZ0JBQWdCO0FBQUUsRUFDL0ksR0FBRyxPQUFPLEdBQUcsT0FBTztDQUNsQixNQUFNLElBQUksV0FBVztDQUNyQixNQUFNLE1BQU0sQ0FBQztDQUNiLGlDQUFPLE1BQU0sUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsMkNBQTJDO0FBQ2hGLENBQUM7QUFFRCwrQkFBSyxtQkFBbUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxHQUFHLEVBQUUsR0FBRyxPQUFPLEdBQUcsT0FBTztDQUN4RSxNQUFNLElBQUksV0FBVztDQUNyQixNQUFNLE1BQU0sQ0FBQztDQUNiLGlDQUFPLE1BQU0sUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsTUFBTSxpQ0FBVyxNQUFLLE1BQUssRUFBRSxTQUFTLFdBQVcsQ0FBQyxDQUFFLEtBQUssUUFBUTtBQUN0RyxDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJwZXJzaXN0LnRlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhwZWN0LCBtb2NrLCB0ZXN0IH0gZnJvbSAnY2xhdWRlLWNvZGUvdGVzdGluZydcblxuaW1wb3J0IHsgQ0hBUkFDVEVSUyB9IGZyb20gJy4vY2hhcmFjdGVycydcblxuY29uc3Qgc2V0dXAgPSAob246IGFueSwgYWN0aXZlPzogc3RyaW5nKSA9PiB7XG4gIG1vY2suc3RvcmUob24sIGFjdGl2ZSA/IHsgYWN0aXZlIH0gOiB1bmRlZmluZWQpXG4gIG9uKCdjb21tYW5kLnJlZ2lzdGVyJywgKCkgPT4gKHsgdmFsdWU6IHsgbmFtZTogJ3gnIH0gfSkgYXMgbmV2ZXIpXG4gIG9uKCdzZXNzaW9uLnN0YXJ0JywgKCkgPT4gKHsgY3dkOiAnL3RtcCcgfSkgYXMgbmV2ZXIpXG4gIG9uKCdjb21tYW5kLnJ1bicsICgpID0+ICh7IHRleHQ6ICcnIH0pKVxuICBvbigncHJvbXB0LmNvbXBvc2UnLCAoKSA9PiAoeyBzZWN0aW9uczogW10gfSkpXG59XG5jb25zdCBjb21wb3NlID0gKCQ6IGFueSkgPT4gJC5wcm9tcHQuY29tcG9zZSh7IG1vZGVsOiAnbScsIHByb21wdE1vZGVsOiAnbScsIHN1cmZhY2VzOiBbXSwgdG9vbHM6IFtdLCBvdXRwdXRTdHlsZTogbnVsbCwgdHJhaXRzOiBbXSB9IGFzIG5ldmVyKVxuY29uc3QgcGVyc29uYSA9IGFzeW5jICgkOiBhbnkpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4gPT4gKGF3YWl0IGNvbXBvc2UoJCkpLnNlY3Rpb25zLmZpbmQoKHM6IGFueSkgPT4gcy5pZCA9PT0gJ2pzYy1hbmltYTpwZXJzb25hJyk/LnRleHRcbmNvbnN0IHN0YXJ0ID0gKCQ6IGFueSkgPT4gJC5zZXNzaW9uLnN0YXJ0KHsgc291cmNlOiAnc3RhcnR1cCcsIGN3ZDogJy90bXAnIH0gYXMgbmV2ZXIpXG5cbnRlc3QoJ+WVn+WLleeLgOaFi+i3qCBzZXNzaW9uIOS/neeVme+8muS4i+asoemWi+WVn+iHquWLleaBouW+qScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbiwgJ3Nhby1zdWd1aGEnKVxuICBhd2FpdCBzdGFydCgkKVxuICBleHBlY3QoYXdhaXQgcGVyc29uYSgkKSkudG9Db250YWluKCfnm7TokYknKVxufSlcblxudGVzdCgn5ZWf5YuV6KeS6Imy5b6M5a+r5YWl5YSy5a2Y77yM5pawIHNlc3Npb24g5oGi5b6p77yb6Zui6ZaL5b6M5LiN5YaN5oGi5b6pJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIHNldHVwKG9uKVxuICBhd2FpdCBzdGFydCgkKVxuICBhd2FpdCAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ3Nhby1hc3VuYScsIGFyZ3M6ICcnIH0gYXMgbmV2ZXIpXG4gIGF3YWl0ICQuY29tbWFuZC5ydW4oeyBjb21tYW5kOiAnYW5pbWEtb2ZmJywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdzYW8tc3VndWhhJywgYXJnczogJycgfSBhcyBuZXZlcilcbiAgYXdhaXQgc3RhcnQoJClcbiAgZXhwZWN0KGF3YWl0IHBlcnNvbmEoJCkpLnRvQ29udGFpbign55u06JGJJylcbiAgYXdhaXQgJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdhbmltYS1vZmYnLCBhcmdzOiAnJyB9IGFzIG5ldmVyKVxuICBhd2FpdCBzdGFydCgkKVxuICBleHBlY3QoYXdhaXQgcGVyc29uYSgkKSkudG9CZVVuZGVmaW5lZCgpXG59KVxuXG50ZXN0KCflnKggL2NvbmZpZyDpl5zplokgcGVyc2lzdCDlvozkuI3mgaLlvqknLCB7IG9wdGlvbnM6IHsgcGVyc2lzdDogZmFsc2UgfSB9LCBhc3luYyAoJCwgb24pID0+IHtcbiAgc2V0dXAob24sICdzYW8tYXN1bmEnKVxuICBhd2FpdCBzdGFydCgkKVxuICBleHBlY3QoYXdhaXQgcGVyc29uYSgkKSkudG9CZVVuZGVmaW5lZCgpXG59KVxuXG50ZXN0KCflhLLlrZjnmoTop5LoibLkuI3lrZjlnKjmmYLkuI3mgaLlvqknLCBhc3luYyAoJCwgb24pID0+IHtcbiAgc2V0dXAob24sICduby1zdWNoLWNoYXJhY3RlcicpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGV4cGVjdChhd2FpdCBwZXJzb25hKCQpKS50b0JlVW5kZWZpbmVkKClcbn0pXG5cbnRlc3QoJ+W+ruiqv+aVuOWAvOi7uO+8muWPjeaYoOWcqCBwZXJzb25h77yM5YW26aSY57at5oyB6KeS6Imy5YyF6aCQ6Kit77yM5LiU5LiN5pS55YuV6KeS6Imy5YyFJywgeyBvcHRpb25zOiB7IGF4aXNHZW50bGU6IDIsIGF4aXNIdW1vcjogOSB9IH0sIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbiwgJ3Nhby1hc3VuYScpXG4gIGNvbnN0IGJlZm9yZSA9IHsgLi4uQ0hBUkFDVEVSUy5maW5kKGMgPT4gYy5zbHVnID09PSAnc2FvLWFzdW5hJykhLmF4ZXMgfVxuICBhd2FpdCBzdGFydCgkKVxuICBjb25zdCB0ZXh0ID0gKGF3YWl0IHBlcnNvbmEoJCkpIVxuICBleHBlY3QodGV4dCkudG9Db250YWluKCfmuqvmn5QgMicpXG4gIGV4cGVjdCh0ZXh0KS50b0NvbnRhaW4oJ+W5vem7mCA5JylcbiAgZXhwZWN0KHRleHQpLnRvQ29udGFpbihg5YKy5ayMICR7YmVmb3JlLnRzdW5kZXJlfWApXG4gIGV4cGVjdChDSEFSQUNURVJTLmZpbmQoYyA9PiBjLnNsdWcgPT09ICdzYW8tYXN1bmEnKSEuYXhlcykudG9FcXVhbChiZWZvcmUpXG59KVxuXG50ZXN0KCfmnKrlvq7oqr/vvIgtMe+8ieayv+eUqOinkuiJsuWMhemgkOiorScsIHsgb3B0aW9uczogeyBheGlzR2VudGxlOiAtMSB9IH0sIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbiwgJ3Nhby1hc3VuYScpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGV4cGVjdChhd2FpdCBwZXJzb25hKCQpKS50b0NvbnRhaW4oYOa6q+aflCAke0NIQVJBQ1RFUlMuZmluZChjID0+IGMuc2x1ZyA9PT0gJ3Nhby1hc3VuYScpIS5heGVzLmdlbnRsZX1gKVxufSlcblxudGVzdCgnOCDlgIvmlbjlgLzou7jpg73lj6/lvq7oqr8nLCB7XG4gIG9wdGlvbnM6IHsgYXhpc0dlbnRsZTogMSwgYXhpc1RzdW5kZXJlOiAyLCBheGlzTGl2ZWx5OiAzLCBheGlzRm9ybWFsOiA0LCBheGlzVGFsa2F0aXZlOiA1LCBheGlzSHVtb3I6IDYsIGF4aXNQcm9hY3RpdmU6IDcsIGF4aXNFeHByZXNzaXZlOiA4IH0sXG59LCBhc3luYyAoJCwgb24pID0+IHtcbiAgc2V0dXAob24sICdzYW8tYXN1bmEnKVxuICBhd2FpdCBzdGFydCgkKVxuICBleHBlY3QoYXdhaXQgcGVyc29uYSgkKSkudG9Db250YWluKCfmuqvmn5QgMeOAgeWCsuWsjCAy44CB5rS75r2RIDPjgIHmraPlvI8gNOOAgeipsemHjyA144CB5bm96buYIDbjgIHkuLvli5UgN+OAgeaDhee3kuWklumhryA4Jylcbn0pXG5cbnRlc3QoJ+i2heWHuiAwLTEwIOeahOimhuiTi+WAvOiiq+W/veeVpScsIHsgb3B0aW9uczogeyBheGlzR2VudGxlOiAxMSB9IH0sIGFzeW5jICgkLCBvbikgPT4ge1xuICBzZXR1cChvbiwgJ3Nhby1hc3VuYScpXG4gIGF3YWl0IHN0YXJ0KCQpXG4gIGV4cGVjdChhd2FpdCBwZXJzb25hKCQpKS50b0NvbnRhaW4oYOa6q+aflCAke0NIQVJBQ1RFUlMuZmluZChjID0+IGMuc2x1ZyA9PT0gJ3Nhby1hc3VuYScpIS5heGVzLmdlbnRsZX1gKVxufSlcbiJdLCJmaWxlIjoiL2hvb2tzL3BlcnNpc3QudGVzdC50cyJ9 + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3MvcGVyc2lzdC50ZXN0LnRzIiwiL2hvb2tzL3BlcnNpc3QudGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5Il0sW10sWyI4IiwiOSJdLHt9LCJjbGF1ZGUtY29kZS90ZXN0aW5nIiwiL2hvb2tzL2NoYXJhY3RlcnMudHMiXQ== \ No newline at end of file diff --git a/node_modules/.vitest-cache/eed085b873787578cf2924a0270929bf794c74a5 b/node_modules/.vitest-cache/eed085b873787578cf2924a0270929bf794c74a5 new file mode 100644 index 0000000..6ac8746 --- /dev/null +++ b/node_modules/.vitest-cache/eed085b873787578cf2924a0270929bf794c74a5 @@ -0,0 +1,150 @@ +const __vite_ssr_import_0__ = await __vite_ssr_import__("claude-code/testing", {"importedNames":["expect","mock","test"]}); + +const NOW = new Date(2026, 9, 15, 10, 0).getTime(); +async function setup($, on, opts = {}) { + const cwd = { value: opts.cwd ?? "/proj-a" }; + const logs = []; + const prompts = []; + __vite_ssr_import_0__.mock.store(on); + const clock = __vite_ssr_import_0__.mock.clock(on, { now: NOW }); + on("command.register", () => ({ value: { name: "x" } })); + on("session.start", () => ({ cwd: opts.cwd ?? "/proj-a" })); + on("session.cwd", () => ({ value: cwd.value })); + on("command.run", () => ({ text: "" })); + on("prompt.compose", () => ({ sections: [] })); + on("prompt.submit", (_, e) => e); + on("ui.log", (_, e) => { + logs.push(String(e.text ?? e.message ?? JSON.stringify(e))); + return { value: undefined }; + }); + on("model.complete", (_, e) => { + prompts.push(String(e.prompt)); + return { value: opts.reply === undefined ? { + isAnswered: true, + text: "已經處理好了", + usage: {} + } : { + isAnswered: opts.reply !== "", + text: opts.reply, + usage: {} + } }; + }); + await $.session.start({ + source: "startup", + cwd: opts.cwd ?? "/proj-a" + }); + return { + logs, + prompts, + clock, + cwd + }; +} +const todo = ($, args) => $.command.run({ + command: "anima-todo", + args +}); +const activate = ($) => $.command.run({ + command: "sao-asuna", + args: "" +}); +(0,__vite_ssr_import_0__.test)("未啟動角色時待辦被拒絕並提示先啟動", async ($, on) => { + await setup($, on); + const r = await todo($, "list"); + (0,__vite_ssr_import_0__.expect)(r.text).toContain("請先啟動角色"); +}); +(0,__vite_ssr_import_0__.test)("啟動後建立、更新與列出待辦,記錄所屬專案", async ($, on) => { + await setup($, on); + await activate($); + (0,__vite_ssr_import_0__.expect)((await todo($, "add 開發 2026-10-16 09:30 重構路由")).text).toContain("#1"); + (0,__vite_ssr_import_0__.expect)((await todo($, "add 提醒 2026-10-15 11:00 喝水")).text).toContain("#2"); + (0,__vite_ssr_import_0__.expect)((await todo($, "update 1 研究 2026-10-17 08:00 讀文件")).text).toContain("已更新"); + const list = (await todo($, "list")).text; + (0,__vite_ssr_import_0__.expect)(list).toContain("#1 [研究] 2026-10-17 08:00 讀文件"); + (0,__vite_ssr_import_0__.expect)(list).toContain("專案:/proj-a"); + (0,__vite_ssr_import_0__.expect)(list.indexOf("#2")).toBeLessThan(list.indexOf("#1")); +}); +(0,__vite_ssr_import_0__.test)("類型預設四種且可自訂,未知類型被拒絕", async ($, on) => { + await setup($, on); + await activate($); + for (const t of [ + "提醒", + "開發", + "研究", + "維護" + ]) { + (0,__vite_ssr_import_0__.expect)((await todo($, `add ${t} 2026-10-16 09:00 x`)).text).toContain("已建立"); + }; + (0,__vite_ssr_import_0__.expect)((await todo($, "add 運動 2026-10-16 09:00 跑步")).text).toContain("沒有「運動」"); + (0,__vite_ssr_import_0__.expect)((await todo($, "type 運動")).text).toContain("已新增"); + (0,__vite_ssr_import_0__.expect)((await todo($, "add 運動 2026-10-16 09:00 跑步")).text).toContain("已建立"); +}); +(0,__vite_ssr_import_0__.test)("參數格式錯誤時顯示用法", async ($, on) => { + await setup($, on); + await activate($); + (0,__vite_ssr_import_0__.expect)((await todo($, "add 開發 明天 重構")).text).toContain("用法"); + (0,__vite_ssr_import_0__.expect)((await todo($, "add 開發 2026-02-31 09:00 x")).text).toContain("用法"); +}); +(0,__vite_ssr_import_0__.test)("到點時由角色提醒一次,確認前不執行", async ($, on) => { + const { logs, prompts } = await setup($, on); + await activate($); + await todo($, "add 維護 2026-10-15 09:00 清理暫存"); + await $.prompt.submit({ + text: "嗨", + command: undefined, + isMeta: false + }); + (0,__vite_ssr_import_0__.expect)(logs.length).toBe(1); + (0,__vite_ssr_import_0__.expect)(logs[0]).toContain("亞絲娜 >"); + (0,__vite_ssr_import_0__.expect)(logs[0]).toContain("清理暫存"); + (0,__vite_ssr_import_0__.expect)(logs[0]).toContain("run 1"); + await $.prompt.submit({ + text: "再一次", + command: undefined, + isMeta: false + }); + (0,__vite_ssr_import_0__.expect)(logs.length).toBe(1); + (0,__vite_ssr_import_0__.expect)(prompts.some((p) => p.includes("清理暫存"))).toBe(false); +}); +(0,__vite_ssr_import_0__.test)("未到點不提醒", async ($, on) => { + const { logs } = await setup($, on); + await activate($); + await todo($, "add 提醒 2026-10-16 09:00 明天的事"); + await $.prompt.submit({ + text: "嗨", + command: undefined, + isMeta: false + }); + (0,__vite_ssr_import_0__.expect)(logs.length).toBe(0); +}); +(0,__vite_ssr_import_0__.test)("確認後執行,並由角色告知結果", async ($, on) => { + const { prompts } = await setup($, on, { reply: "清好了三個暫存目錄" }); + await activate($); + await todo($, "add 維護 2026-10-15 09:00 清理暫存"); + const r = await todo($, "run 1"); + (0,__vite_ssr_import_0__.expect)(prompts.some((p) => p.includes("清理暫存"))).toBe(true); + (0,__vite_ssr_import_0__.expect)(r.text).toBe("亞絲娜 > 清好了三個暫存目錄"); + (0,__vite_ssr_import_0__.expect)((await todo($, "list")).text).toContain("完成"); + (0,__vite_ssr_import_0__.expect)((await todo($, "run 1")).text).toContain("已經完成"); +}); +(0,__vite_ssr_import_0__.test)("執行失敗時保留為待辦", async ($, on) => { + await setup($, on, { reply: "" }); + await activate($); + await todo($, "add 開發 2026-10-15 09:00 重構"); + (0,__vite_ssr_import_0__.expect)((await todo($, "run 1")).text).toContain("執行失敗"); + (0,__vite_ssr_import_0__.expect)((await todo($, "list")).text).not.toContain("完成"); +}); +(0,__vite_ssr_import_0__.test)("待辦全域一份:換專案仍看得到", async ($, on) => { + const { cwd } = await setup($, on, { cwd: "/proj-a" }); + await activate($); + await todo($, "add 研究 2026-10-16 09:00 讀論文"); + cwd.value = "/proj-b"; + await todo($, "add 研究 2026-10-16 10:00 另一專案的事"); + const list = (await todo($, "list")).text; + (0,__vite_ssr_import_0__.expect)(list).toContain("專案:/proj-a"); + (0,__vite_ssr_import_0__.expect)(list).toContain("專案:/proj-b"); +}); +//# sourceMappingSource=vite-generated +//# sourceMappingURL=data:application/json;base64,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LEtBQUssR0FBRyxPQUFPLEVBQUMsQ0FBRSxJQUFJLENBQUMsQ0FBQyxVQUFVLE1BQU07QUFDeEQsQ0FBQztBQUVELCtCQUFLLGNBQWMsT0FBTyxHQUFHLE9BQU87Q0FDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxFQUFFLE9BQU8sR0FBRyxDQUFDO0NBQ2hDLE1BQU0sU0FBUyxDQUFDO0NBQ2hCLE1BQU0sS0FBSyxHQUFHLDRCQUE0QjtDQUMxQyxrQ0FBUSxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUMsQ0FBRSxJQUFJLENBQUMsQ0FBQyxVQUFVLE1BQU07Q0FDdEQsa0NBQVEsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFDLENBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxVQUFVLElBQUk7QUFDekQsQ0FBQztBQUVELCtCQUFLLGtCQUFrQixPQUFPLEdBQUcsT0FBTztDQUN0QyxNQUFNLEVBQUUsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLEVBQUUsS0FBSyxVQUFVLENBQUM7Q0FDckQsTUFBTSxTQUFTLENBQUM7Q0FDaEIsTUFBTSxLQUFLLEdBQUcsNkJBQTZCO0NBQzNDLElBQUksUUFBUTtDQUNaLE1BQU0sS0FBSyxHQUFHLGdDQUFnQztDQUM5QyxNQUFNLFFBQVEsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFDLENBQUU7Q0FDckMsaUNBQU8sSUFBSSxDQUFDLENBQUMsVUFBVSxZQUFZO0NBQ25DLGlDQUFPLElBQUksQ0FBQyxDQUFDLFVBQVUsWUFBWTtBQUNyQyxDQUFDIiwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJ0b2RvLnRlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhwZWN0LCBtb2NrLCB0ZXN0IH0gZnJvbSAnY2xhdWRlLWNvZGUvdGVzdGluZydcblxuY29uc3QgTk9XID0gbmV3IERhdGUoMjAyNiwgOSwgMTUsIDEwLCAwKS5nZXRUaW1lKClcblxuYXN5bmMgZnVuY3Rpb24gc2V0dXAoJDogYW55LCBvbjogYW55LCBvcHRzOiB7IHJlcGx5Pzogc3RyaW5nOyBjd2Q/OiBzdHJpbmcgfSA9IHt9KSB7XG4gIGNvbnN0IGN3ZCA9IHsgdmFsdWU6IG9wdHMuY3dkID8/ICcvcHJvai1hJyB9XG4gIGNvbnN0IGxvZ3M6IHN0cmluZ1tdID0gW11cbiAgY29uc3QgcHJvbXB0czogc3RyaW5nW10gPSBbXVxuICBtb2NrLnN0b3JlKG9uKVxuICBjb25zdCBjbG9jayA9IG1vY2suY2xvY2sob24sIHsgbm93OiBOT1cgfSlcbiAgb24oJ2NvbW1hbmQucmVnaXN0ZXInLCAoKSA9PiAoeyB2YWx1ZTogeyBuYW1lOiAneCcgfSB9KSBhcyBuZXZlcilcbiAgb24oJ3Nlc3Npb24uc3RhcnQnLCAoKSA9PiAoeyBjd2Q6IG9wdHMuY3dkID8/ICcvcHJvai1hJyB9KSBhcyBuZXZlcilcbiAgb24oJ3Nlc3Npb24uY3dkJywgKCkgPT4gKHsgdmFsdWU6IGN3ZC52YWx1ZSB9KSlcbiAgb24oJ2NvbW1hbmQucnVuJywgKCkgPT4gKHsgdGV4dDogJycgfSkpXG4gIG9uKCdwcm9tcHQuY29tcG9zZScsICgpID0+ICh7IHNlY3Rpb25zOiBbXSB9KSlcbiAgb24oJ3Byb21wdC5zdWJtaXQnLCAoXzogYW55LCBlOiBhbnkpID0+IGUgYXMgbmV2ZXIpXG4gIG9uKCd1aS5sb2cnLCAoXzogYW55LCBlOiBhbnkpID0+IHtcbiAgICBsb2dzLnB1c2goU3RyaW5nKGUudGV4dCA/PyBlLm1lc3NhZ2UgPz8gSlNPTi5zdHJpbmdpZnkoZSkpKVxuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQgfSBhcyBuZXZlclxuICB9KVxuICBvbignbW9kZWwuY29tcGxldGUnLCAoXzogYW55LCBlOiBhbnkpID0+IHtcbiAgICBwcm9tcHRzLnB1c2goU3RyaW5nKGUucHJvbXB0KSlcbiAgICByZXR1cm4geyB2YWx1ZTogb3B0cy5yZXBseSA9PT0gdW5kZWZpbmVkID8geyBpc0Fuc3dlcmVkOiB0cnVlLCB0ZXh0OiAn5bey57aT6JmV55CG5aW95LqGJywgdXNhZ2U6IHt9IH0gOiB7IGlzQW5zd2VyZWQ6IG9wdHMucmVwbHkgIT09ICcnLCB0ZXh0OiBvcHRzLnJlcGx5LCB1c2FnZToge30gfSB9IGFzIG5ldmVyXG4gIH0pXG4gIGF3YWl0ICQuc2Vzc2lvbi5zdGFydCh7IHNvdXJjZTogJ3N0YXJ0dXAnLCBjd2Q6IG9wdHMuY3dkID8/ICcvcHJvai1hJyB9IGFzIG5ldmVyKVxuICByZXR1cm4geyBsb2dzLCBwcm9tcHRzLCBjbG9jaywgY3dkIH1cbn1cblxuY29uc3QgdG9kbyA9ICgkOiBhbnksIGFyZ3M6IHN0cmluZykgPT4gJC5jb21tYW5kLnJ1bih7IGNvbW1hbmQ6ICdhbmltYS10b2RvJywgYXJncyB9IGFzIG5ldmVyKVxuY29uc3QgYWN0aXZhdGUgPSAoJDogYW55KSA9PiAkLmNvbW1hbmQucnVuKHsgY29tbWFuZDogJ3Nhby1hc3VuYScsIGFyZ3M6ICcnIH0gYXMgbmV2ZXIpXG5cbnRlc3QoJ+acquWVn+WLleinkuiJsuaZguW+hei+puiiq+aLkue1leS4puaPkOekuuWFiOWVn+WLlScsIGFzeW5jICgkLCBvbikgPT4ge1xuICBhd2FpdCBzZXR1cCgkLCBvbilcbiAgY29uc3QgciA9IGF3YWl0IHRvZG8oJCwgJ2xpc3QnKVxuICBleHBlY3Qoci50ZXh0KS50b0NvbnRhaW4oJ+iri+WFiOWVn+WLleinkuiJsicpXG59KVxuXG50ZXN0KCfllZ/li5Xlvozlu7rnq4vjgIHmm7TmlrDoiIfliJflh7rlvoXovqbvvIzoqJjpjITmiYDlsazlsIjmoYgnLCBhc3luYyAoJCwgb24pID0+IHtcbiAgYXdhaXQgc2V0dXAoJCwgb24pXG4gIGF3YWl0IGFjdGl2YXRlKCQpXG4gIGV4cGVjdCgoYXdhaXQgdG9kbygkLCAnYWRkIOmWi+eZvCAyMDI2LTEwLTE2IDA5OjMwIOmHjeani+i3r+eUsScpKS50ZXh0KS50b0NvbnRhaW4oJyMxJylcbiAgZXhwZWN0KChhd2FpdCB0b2RvKCQsICdhZGQg5o+Q6YaSIDIwMjYtMTAtMTUgMTE6MDAg5Zad5rC0JykpLnRleHQpLnRvQ29udGFpbignIzInKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ3VwZGF0ZSAxIOeglOeptiAyMDI2LTEwLTE3IDA4OjAwIOiugOaWh+S7ticpKS50ZXh0KS50b0NvbnRhaW4oJ+W3suabtOaWsCcpXG4gIGNvbnN0IGxpc3QgPSAoYXdhaXQgdG9kbygkLCAnbGlzdCcpKS50ZXh0XG4gIGV4cGVjdChsaXN0KS50b0NvbnRhaW4oJyMxIFvnoJTnqbZdIDIwMjYtMTAtMTcgMDg6MDAg6K6A5paH5Lu2JylcbiAgZXhwZWN0KGxpc3QpLnRvQ29udGFpbign5bCI5qGI77yaL3Byb2otYScpXG4gIGV4cGVjdChsaXN0LmluZGV4T2YoJyMyJykpLnRvQmVMZXNzVGhhbihsaXN0LmluZGV4T2YoJyMxJykpXG59KVxuXG50ZXN0KCfpoZ7lnovpoJDoqK3lm5vnqK7kuJTlj6/oh6roqILvvIzmnKrnn6XpoZ7lnovooqvmi5LntZUnLCBhc3luYyAoJCwgb24pID0+IHtcbiAgYXdhaXQgc2V0dXAoJCwgb24pXG4gIGF3YWl0IGFjdGl2YXRlKCQpXG4gIGZvciAoY29uc3QgdCBvZiBbJ+aPkOmGkicsICfplovnmbwnLCAn56CU56m2JywgJ+e2reittyddKSB7XG4gICAgZXhwZWN0KChhd2FpdCB0b2RvKCQsIGBhZGQgJHt0fSAyMDI2LTEwLTE2IDA5OjAwIHhgKSkudGV4dCkudG9Db250YWluKCflt7Llu7rnq4snKVxuICB9XG4gIGV4cGVjdCgoYXdhaXQgdG9kbygkLCAnYWRkIOmBi+WLlSAyMDI2LTEwLTE2IDA5OjAwIOi3keatpScpKS50ZXh0KS50b0NvbnRhaW4oJ+aykuacieOAjOmBi+WLleOAjScpXG4gIGV4cGVjdCgoYXdhaXQgdG9kbygkLCAndHlwZSDpgYvli5UnKSkudGV4dCkudG9Db250YWluKCflt7LmlrDlop4nKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ2FkZCDpgYvli5UgMjAyNi0xMC0xNiAwOTowMCDot5HmraUnKSkudGV4dCkudG9Db250YWluKCflt7Llu7rnq4snKVxufSlcblxudGVzdCgn5Y+D5pW45qC85byP6Yyv6Kqk5pmC6aGv56S655So5rOVJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGF3YWl0IHNldHVwKCQsIG9uKVxuICBhd2FpdCBhY3RpdmF0ZSgkKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ2FkZCDplovnmbwg5piO5aSpIOmHjeaniycpKS50ZXh0KS50b0NvbnRhaW4oJ+eUqOazlScpXG4gIGV4cGVjdCgoYXdhaXQgdG9kbygkLCAnYWRkIOmWi+eZvCAyMDI2LTAyLTMxIDA5OjAwIHgnKSkudGV4dCkudG9Db250YWluKCfnlKjms5UnKVxufSlcblxudGVzdCgn5Yiw6bue5pmC55Sx6KeS6Imy5o+Q6YaS5LiA5qyh77yM56K66KqN5YmN5LiN5Z+36KGMJywgYXN5bmMgKCQsIG9uKSA9PiB7XG4gIGNvbnN0IHsgbG9ncywgcHJvbXB0cyB9ID0gYXdhaXQgc2V0dXAoJCwgb24pXG4gIGF3YWl0IGFjdGl2YXRlKCQpXG4gIGF3YWl0IHRvZG8oJCwgJ2FkZCDntq3orbcgMjAyNi0xMC0xNSAwOTowMCDmuIXnkIbmmqvlrZgnKVxuICBhd2FpdCAkLnByb21wdC5zdWJtaXQoeyB0ZXh0OiAn5ZeoJywgY29tbWFuZDogdW5kZWZpbmVkLCBpc01ldGE6IGZhbHNlIH0gYXMgbmV2ZXIpXG4gIGV4cGVjdChsb2dzLmxlbmd0aCkudG9CZSgxKVxuICBleHBlY3QobG9nc1swXSkudG9Db250YWluKCfkup7ntbLlqJwgPicpXG4gIGV4cGVjdChsb2dzWzBdKS50b0NvbnRhaW4oJ+a4heeQhuaaq+WtmCcpXG4gIGV4cGVjdChsb2dzWzBdKS50b0NvbnRhaW4oJ3J1biAxJylcbiAgYXdhaXQgJC5wcm9tcHQuc3VibWl0KHsgdGV4dDogJ+WGjeS4gOasoScsIGNvbW1hbmQ6IHVuZGVmaW5lZCwgaXNNZXRhOiBmYWxzZSB9IGFzIG5ldmVyKVxuICBleHBlY3QobG9ncy5sZW5ndGgpLnRvQmUoMSlcbiAgZXhwZWN0KHByb21wdHMuc29tZShwID0+IHAuaW5jbHVkZXMoJ+a4heeQhuaaq+WtmCcpKSkudG9CZShmYWxzZSlcbn0pXG5cbnRlc3QoJ+acquWIsOm7nuS4jeaPkOmGkicsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCB7IGxvZ3MgfSA9IGF3YWl0IHNldHVwKCQsIG9uKVxuICBhd2FpdCBhY3RpdmF0ZSgkKVxuICBhd2FpdCB0b2RvKCQsICdhZGQg5o+Q6YaSIDIwMjYtMTAtMTYgMDk6MDAg5piO5aSp55qE5LqLJylcbiAgYXdhaXQgJC5wcm9tcHQuc3VibWl0KHsgdGV4dDogJ+WXqCcsIGNvbW1hbmQ6IHVuZGVmaW5lZCwgaXNNZXRhOiBmYWxzZSB9IGFzIG5ldmVyKVxuICBleHBlY3QobG9ncy5sZW5ndGgpLnRvQmUoMClcbn0pXG5cbnRlc3QoJ+eiuuiqjeW+jOWft+ihjO+8jOS4pueUseinkuiJsuWRiuefpee1kOaenCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCB7IHByb21wdHMgfSA9IGF3YWl0IHNldHVwKCQsIG9uLCB7IHJlcGx5OiAn5riF5aW95LqG5LiJ5YCL5pqr5a2Y55uu6YyEJyB9KVxuICBhd2FpdCBhY3RpdmF0ZSgkKVxuICBhd2FpdCB0b2RvKCQsICdhZGQg57at6K23IDIwMjYtMTAtMTUgMDk6MDAg5riF55CG5pqr5a2YJylcbiAgY29uc3QgciA9IGF3YWl0IHRvZG8oJCwgJ3J1biAxJylcbiAgZXhwZWN0KHByb21wdHMuc29tZShwID0+IHAuaW5jbHVkZXMoJ+a4heeQhuaaq+WtmCcpKSkudG9CZSh0cnVlKVxuICBleHBlY3Qoci50ZXh0KS50b0JlKCfkup7ntbLlqJwgPiDmuIXlpb3kuobkuInlgIvmmqvlrZjnm67pjIQnKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ2xpc3QnKSkudGV4dCkudG9Db250YWluKCflrozmiJAnKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ3J1biAxJykpLnRleHQpLnRvQ29udGFpbign5bey57aT5a6M5oiQJylcbn0pXG5cbnRlc3QoJ+Wft+ihjOWkseaVl+aZguS/neeVmeeCuuW+hei+picsIGFzeW5jICgkLCBvbikgPT4ge1xuICBhd2FpdCBzZXR1cCgkLCBvbiwgeyByZXBseTogJycgfSlcbiAgYXdhaXQgYWN0aXZhdGUoJClcbiAgYXdhaXQgdG9kbygkLCAnYWRkIOmWi+eZvCAyMDI2LTEwLTE1IDA5OjAwIOmHjeaniycpXG4gIGV4cGVjdCgoYXdhaXQgdG9kbygkLCAncnVuIDEnKSkudGV4dCkudG9Db250YWluKCfln7fooYzlpLHmlZcnKVxuICBleHBlY3QoKGF3YWl0IHRvZG8oJCwgJ2xpc3QnKSkudGV4dCkubm90LnRvQ29udGFpbign5a6M5oiQJylcbn0pXG5cbnRlc3QoJ+W+hei+puWFqOWfn+S4gOS7ve+8muaPm+WwiOahiOS7jeeci+W+l+WIsCcsIGFzeW5jICgkLCBvbikgPT4ge1xuICBjb25zdCB7IGN3ZCB9ID0gYXdhaXQgc2V0dXAoJCwgb24sIHsgY3dkOiAnL3Byb2otYScgfSlcbiAgYXdhaXQgYWN0aXZhdGUoJClcbiAgYXdhaXQgdG9kbygkLCAnYWRkIOeglOeptiAyMDI2LTEwLTE2IDA5OjAwIOiugOirluaWhycpXG4gIGN3ZC52YWx1ZSA9ICcvcHJvai1iJ1xuICBhd2FpdCB0b2RvKCQsICdhZGQg56CU56m2IDIwMjYtMTAtMTYgMTA6MDAg5Y+m5LiA5bCI5qGI55qE5LqLJylcbiAgY29uc3QgbGlzdCA9IChhd2FpdCB0b2RvKCQsICdsaXN0JykpLnRleHRcbiAgZXhwZWN0KGxpc3QpLnRvQ29udGFpbign5bCI5qGI77yaL3Byb2otYScpXG4gIGV4cGVjdChsaXN0KS50b0NvbnRhaW4oJ+WwiOahiO+8mi9wcm9qLWInKVxufSlcbiJdLCJmaWxlIjoiL2hvb2tzL3RvZG8udGVzdC50cyJ9 + +//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvcm9vdC9qc2MtYW5pbWEvaG9va3MvdG9kby50ZXN0LnRzIiwiL2hvb2tzL3RvZG8udGVzdC50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiXSxbXSxbIjgiXSx7fSwiY2xhdWRlLWNvZGUvdGVzdGluZyJd \ No newline at end of file -- 2.53.0