@actalk/inkos-core 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/agents/architect.d.ts +3 -3
- package/dist/agents/architect.d.ts.map +1 -1
- package/dist/agents/architect.js +91 -16
- package/dist/agents/architect.js.map +1 -1
- package/dist/agents/continuity.d.ts +1 -1
- package/dist/agents/continuity.d.ts.map +1 -1
- package/dist/agents/continuity.js +88 -17
- package/dist/agents/continuity.js.map +1 -1
- package/dist/agents/radar-source.d.ts +38 -0
- package/dist/agents/radar-source.d.ts.map +1 -0
- package/dist/agents/radar-source.js +92 -0
- package/dist/agents/radar-source.js.map +1 -0
- package/dist/agents/radar.d.ts +4 -1
- package/dist/agents/radar.d.ts.map +1 -1
- package/dist/agents/radar.js +35 -10
- package/dist/agents/radar.js.map +1 -1
- package/dist/agents/reviser.d.ts +2 -1
- package/dist/agents/reviser.d.ts.map +1 -1
- package/dist/agents/reviser.js +40 -18
- package/dist/agents/reviser.js.map +1 -1
- package/dist/agents/rules-reader.d.ts +26 -0
- package/dist/agents/rules-reader.d.ts.map +1 -0
- package/dist/agents/rules-reader.js +86 -0
- package/dist/agents/rules-reader.js.map +1 -0
- package/dist/agents/writer-prompts.d.ts +5 -0
- package/dist/agents/writer-prompts.d.ts.map +1 -0
- package/dist/agents/writer-prompts.js +289 -0
- package/dist/agents/writer-prompts.js.map +1 -0
- package/dist/agents/writer.d.ts +2 -2
- package/dist/agents/writer.d.ts.map +1 -1
- package/dist/agents/writer.js +31 -165
- package/dist/agents/writer.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/models/book-rules.d.ts +112 -0
- package/dist/models/book-rules.d.ts.map +1 -0
- package/dist/models/book-rules.js +45 -0
- package/dist/models/book-rules.js.map +1 -0
- package/dist/models/genre-profile.d.ts +42 -0
- package/dist/models/genre-profile.d.ts.map +1 -0
- package/dist/models/genre-profile.js +25 -0
- package/dist/models/genre-profile.js.map +1 -0
- package/dist/pipeline/agent.d.ts +14 -0
- package/dist/pipeline/agent.d.ts.map +1 -0
- package/dist/pipeline/agent.js +345 -0
- package/dist/pipeline/agent.js.map +1 -0
- package/dist/pipeline/runner.d.ts +49 -0
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +221 -11
- package/dist/pipeline/runner.js.map +1 -1
- package/genres/horror.md +51 -0
- package/genres/other.md +24 -0
- package/genres/urban.md +53 -0
- package/genres/xianxia.md +46 -0
- package/genres/xuanhuan.md +64 -0
- package/package.json +14 -9
package/dist/agents/radar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radar.js","sourceRoot":"","sources":["../../src/agents/radar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"radar.js","sourceRoot":"","sources":["../../src/agents/radar.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/reviser.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseAgent } from "./base.js";
|
|
2
2
|
import type { AuditIssue } from "./continuity.js";
|
|
3
|
+
export type ReviseMode = "polish" | "rewrite" | "rework";
|
|
3
4
|
export interface ReviseOutput {
|
|
4
5
|
readonly revisedContent: string;
|
|
5
6
|
readonly wordCount: number;
|
|
@@ -10,7 +11,7 @@ export interface ReviseOutput {
|
|
|
10
11
|
}
|
|
11
12
|
export declare class ReviserAgent extends BaseAgent {
|
|
12
13
|
get name(): string;
|
|
13
|
-
reviseChapter(bookDir: string, chapterContent: string, chapterNumber: number, issues: ReadonlyArray<AuditIssue
|
|
14
|
+
reviseChapter(bookDir: string, chapterContent: string, chapterNumber: number, issues: ReadonlyArray<AuditIssue>, mode?: ReviseMode, genre?: string): Promise<ReviseOutput>;
|
|
14
15
|
private parseOutput;
|
|
15
16
|
private readFileSafe;
|
|
16
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviser.d.ts","sourceRoot":"","sources":["../../src/agents/reviser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"reviser.d.ts","sourceRoot":"","sources":["../../src/agents/reviser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKlD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAQD,qBAAa,YAAa,SAAQ,SAAS;IACzC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EACjC,IAAI,GAAE,UAAsB,EAC5B,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC;IAyFxB,OAAO,CAAC,WAAW;YA2BL,YAAY;CAO3B"}
|
package/dist/agents/reviser.js
CHANGED
|
@@ -1,30 +1,53 @@
|
|
|
1
1
|
import { BaseAgent } from "./base.js";
|
|
2
|
+
import { readGenreProfile, readBookRules } from "./rules-reader.js";
|
|
2
3
|
import { readFile } from "node:fs/promises";
|
|
3
4
|
import { join } from "node:path";
|
|
5
|
+
const MODE_DESCRIPTIONS = {
|
|
6
|
+
polish: "润色:只改表达、节奏、段落呼吸,不改事实与剧情结论",
|
|
7
|
+
rewrite: "改写:可改叙述顺序、画面、力度,但保留核心事实与人物动机",
|
|
8
|
+
rework: "重写:可重构场景推进和冲突组织,但不改主设定和大事件结果",
|
|
9
|
+
};
|
|
4
10
|
export class ReviserAgent extends BaseAgent {
|
|
5
11
|
get name() {
|
|
6
12
|
return "reviser";
|
|
7
13
|
}
|
|
8
|
-
async reviseChapter(bookDir, chapterContent, chapterNumber, issues) {
|
|
9
|
-
const [currentState, ledger, hooks,
|
|
14
|
+
async reviseChapter(bookDir, chapterContent, chapterNumber, issues, mode = "rewrite", genre) {
|
|
15
|
+
const [currentState, ledger, hooks, styleGuideRaw] = await Promise.all([
|
|
10
16
|
this.readFileSafe(join(bookDir, "story/current_state.md")),
|
|
11
17
|
this.readFileSafe(join(bookDir, "story/particle_ledger.md")),
|
|
12
18
|
this.readFileSafe(join(bookDir, "story/pending_hooks.md")),
|
|
13
19
|
this.readFileSafe(join(bookDir, "story/style_guide.md")),
|
|
14
20
|
]);
|
|
21
|
+
// Load genre profile and book rules
|
|
22
|
+
const genreId = genre ?? "other";
|
|
23
|
+
const { profile: gp } = await readGenreProfile(this.ctx.projectRoot, genreId);
|
|
24
|
+
const parsedRules = await readBookRules(bookDir);
|
|
25
|
+
const bookRules = parsedRules?.rules ?? null;
|
|
26
|
+
// Fallback: use book_rules body when style_guide.md doesn't exist
|
|
27
|
+
const styleGuide = styleGuideRaw !== "(文件不存在)"
|
|
28
|
+
? styleGuideRaw
|
|
29
|
+
: (parsedRules?.body ?? "(无文风指南)");
|
|
15
30
|
const issueList = issues
|
|
16
31
|
.map((i) => `- [${i.severity}] ${i.category}: ${i.description}\n 建议: ${i.suggestion}`)
|
|
17
32
|
.join("\n");
|
|
18
|
-
const
|
|
33
|
+
const modeDesc = MODE_DESCRIPTIONS[mode];
|
|
34
|
+
const numericalRule = gp.numericalSystem
|
|
35
|
+
? "\n3. 数值错误必须精确修正,前后对账"
|
|
36
|
+
: "";
|
|
37
|
+
const protagonistBlock = bookRules?.protagonist
|
|
38
|
+
? `\n\n主角人设锁定:${bookRules.protagonist.name},${bookRules.protagonist.personalityLock.join("、")}。修改不得违反人设。`
|
|
39
|
+
: "";
|
|
40
|
+
const systemPrompt = `你是一位专业的${gp.name}网络小说修稿编辑。你的任务是根据审稿意见对章节进行修正。${protagonistBlock}
|
|
41
|
+
|
|
42
|
+
修稿模式:${modeDesc}
|
|
19
43
|
|
|
20
44
|
修稿原则:
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3. 数值错误必须精确修正,前后对账
|
|
45
|
+
1. 按模式控制修改幅度
|
|
46
|
+
2. 修根因,不做表面润色${numericalRule}
|
|
24
47
|
4. 伏笔状态必须与伏笔池同步
|
|
25
48
|
5. 不改变剧情走向和核心冲突
|
|
26
49
|
6. 保持原文的语言风格和节奏
|
|
27
|
-
7.
|
|
50
|
+
7. 修改后同步更新状态卡${gp.numericalSystem ? "、账本" : ""}、伏笔池
|
|
28
51
|
|
|
29
52
|
输出格式:
|
|
30
53
|
|
|
@@ -36,12 +59,12 @@ export class ReviserAgent extends BaseAgent {
|
|
|
36
59
|
|
|
37
60
|
=== UPDATED_STATE ===
|
|
38
61
|
(更新后的完整状态卡)
|
|
39
|
-
|
|
40
|
-
=== UPDATED_LEDGER ===
|
|
41
|
-
(更新后的完整资源账本)
|
|
42
|
-
|
|
62
|
+
${gp.numericalSystem ? "\n=== UPDATED_LEDGER ===\n(更新后的完整资源账本)" : ""}
|
|
43
63
|
=== UPDATED_HOOKS ===
|
|
44
64
|
(更新后的完整伏笔池)`;
|
|
65
|
+
const ledgerBlock = gp.numericalSystem
|
|
66
|
+
? `\n## 资源账本\n${ledger}`
|
|
67
|
+
: "";
|
|
45
68
|
const userPrompt = `请修正第${chapterNumber}章。
|
|
46
69
|
|
|
47
70
|
## 审稿问题
|
|
@@ -49,10 +72,7 @@ ${issueList}
|
|
|
49
72
|
|
|
50
73
|
## 当前状态卡
|
|
51
74
|
${currentState}
|
|
52
|
-
|
|
53
|
-
## 资源账本
|
|
54
|
-
${ledger}
|
|
55
|
-
|
|
75
|
+
${ledgerBlock}
|
|
56
76
|
## 伏笔池
|
|
57
77
|
${hooks}
|
|
58
78
|
|
|
@@ -65,9 +85,9 @@ ${chapterContent}`;
|
|
|
65
85
|
{ role: "system", content: systemPrompt },
|
|
66
86
|
{ role: "user", content: userPrompt },
|
|
67
87
|
], { temperature: 0.3, maxTokens: 16384 });
|
|
68
|
-
return this.parseOutput(response.content);
|
|
88
|
+
return this.parseOutput(response.content, gp);
|
|
69
89
|
}
|
|
70
|
-
parseOutput(content) {
|
|
90
|
+
parseOutput(content, gp) {
|
|
71
91
|
const extract = (tag) => {
|
|
72
92
|
const regex = new RegExp(`=== ${tag} ===\\s*([\\s\\S]*?)(?==== [A-Z_]+ ===|$)`);
|
|
73
93
|
const match = content.match(regex);
|
|
@@ -83,7 +103,9 @@ ${chapterContent}`;
|
|
|
83
103
|
.map((l) => l.trim())
|
|
84
104
|
.filter((l) => l.length > 0),
|
|
85
105
|
updatedState: extract("UPDATED_STATE") || "(状态卡未更新)",
|
|
86
|
-
updatedLedger:
|
|
106
|
+
updatedLedger: gp.numericalSystem
|
|
107
|
+
? (extract("UPDATED_LEDGER") || "(账本未更新)")
|
|
108
|
+
: "",
|
|
87
109
|
updatedHooks: extract("UPDATED_HOOKS") || "(伏笔池未更新)",
|
|
88
110
|
};
|
|
89
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviser.js","sourceRoot":"","sources":["../../src/agents/reviser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"reviser.js","sourceRoot":"","sources":["../../src/agents/reviser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ParsedGenreProfile } from "../models/genre-profile.js";
|
|
2
|
+
import { type ParsedBookRules } from "../models/book-rules.js";
|
|
3
|
+
/**
|
|
4
|
+
* Load genre profile. Lookup order:
|
|
5
|
+
* 1. Project-level: {projectRoot}/genres/{genreId}.md
|
|
6
|
+
* 2. Built-in: packages/core/genres/{genreId}.md
|
|
7
|
+
* 3. Fallback: built-in other.md
|
|
8
|
+
*/
|
|
9
|
+
export declare function readGenreProfile(projectRoot: string, genreId: string): Promise<ParsedGenreProfile>;
|
|
10
|
+
/**
|
|
11
|
+
* List all available genre profiles (project-level + built-in, deduped).
|
|
12
|
+
* Returns array of { id, name, source }.
|
|
13
|
+
*/
|
|
14
|
+
export declare function listAvailableGenres(projectRoot: string): Promise<ReadonlyArray<{
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly source: "project" | "builtin";
|
|
18
|
+
}>>;
|
|
19
|
+
/** Return the path to the built-in genres directory. */
|
|
20
|
+
export declare function getBuiltinGenresDir(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Load book_rules.md from the book's story directory.
|
|
23
|
+
* Returns null if the file doesn't exist.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readBookRules(bookDir: string): Promise<ParsedBookRules | null>;
|
|
26
|
+
//# sourceMappingURL=rules-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-reader.d.ts","sourceRoot":"","sources":["../../src/agents/rules-reader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAY/E;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,kBAAkB,CAAC,CAe7B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAAC,CAAC,CA+BhH;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAIpF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { parseGenreProfile } from "../models/genre-profile.js";
|
|
5
|
+
import { parseBookRules } from "../models/book-rules.js";
|
|
6
|
+
const BUILTIN_GENRES_DIR = join(dirname(fileURLToPath(import.meta.url)), "../../genres");
|
|
7
|
+
async function tryReadFile(path) {
|
|
8
|
+
try {
|
|
9
|
+
return await readFile(path, "utf-8");
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Load genre profile. Lookup order:
|
|
17
|
+
* 1. Project-level: {projectRoot}/genres/{genreId}.md
|
|
18
|
+
* 2. Built-in: packages/core/genres/{genreId}.md
|
|
19
|
+
* 3. Fallback: built-in other.md
|
|
20
|
+
*/
|
|
21
|
+
export async function readGenreProfile(projectRoot, genreId) {
|
|
22
|
+
const projectPath = join(projectRoot, "genres", `${genreId}.md`);
|
|
23
|
+
const builtinPath = join(BUILTIN_GENRES_DIR, `${genreId}.md`);
|
|
24
|
+
const fallbackPath = join(BUILTIN_GENRES_DIR, "other.md");
|
|
25
|
+
const raw = (await tryReadFile(projectPath)) ??
|
|
26
|
+
(await tryReadFile(builtinPath)) ??
|
|
27
|
+
(await tryReadFile(fallbackPath));
|
|
28
|
+
if (!raw) {
|
|
29
|
+
throw new Error(`Genre profile not found for "${genreId}" and fallback "other.md" is missing`);
|
|
30
|
+
}
|
|
31
|
+
return parseGenreProfile(raw);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* List all available genre profiles (project-level + built-in, deduped).
|
|
35
|
+
* Returns array of { id, name, source }.
|
|
36
|
+
*/
|
|
37
|
+
export async function listAvailableGenres(projectRoot) {
|
|
38
|
+
const results = new Map();
|
|
39
|
+
// Built-in genres first
|
|
40
|
+
try {
|
|
41
|
+
const builtinFiles = await readdir(BUILTIN_GENRES_DIR);
|
|
42
|
+
for (const file of builtinFiles) {
|
|
43
|
+
if (!file.endsWith(".md"))
|
|
44
|
+
continue;
|
|
45
|
+
const id = file.replace(/\.md$/, "");
|
|
46
|
+
const raw = await tryReadFile(join(BUILTIN_GENRES_DIR, file));
|
|
47
|
+
if (!raw)
|
|
48
|
+
continue;
|
|
49
|
+
const parsed = parseGenreProfile(raw);
|
|
50
|
+
results.set(id, { id, name: parsed.profile.name, source: "builtin" });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch { /* no builtin dir */ }
|
|
54
|
+
// Project-level genres override
|
|
55
|
+
const projectDir = join(projectRoot, "genres");
|
|
56
|
+
try {
|
|
57
|
+
const projectFiles = await readdir(projectDir);
|
|
58
|
+
for (const file of projectFiles) {
|
|
59
|
+
if (!file.endsWith(".md"))
|
|
60
|
+
continue;
|
|
61
|
+
const id = file.replace(/\.md$/, "");
|
|
62
|
+
const raw = await tryReadFile(join(projectDir, file));
|
|
63
|
+
if (!raw)
|
|
64
|
+
continue;
|
|
65
|
+
const parsed = parseGenreProfile(raw);
|
|
66
|
+
results.set(id, { id, name: parsed.profile.name, source: "project" });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch { /* no project genres dir */ }
|
|
70
|
+
return [...results.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
71
|
+
}
|
|
72
|
+
/** Return the path to the built-in genres directory. */
|
|
73
|
+
export function getBuiltinGenresDir() {
|
|
74
|
+
return BUILTIN_GENRES_DIR;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Load book_rules.md from the book's story directory.
|
|
78
|
+
* Returns null if the file doesn't exist.
|
|
79
|
+
*/
|
|
80
|
+
export async function readBookRules(bookDir) {
|
|
81
|
+
const raw = await tryReadFile(join(bookDir, "story/book_rules.md"));
|
|
82
|
+
if (!raw)
|
|
83
|
+
return null;
|
|
84
|
+
return parseBookRules(raw);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=rules-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-reader.js","sourceRoot":"","sources":["../../src/agents/rules-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BookConfig } from "../models/book.js";
|
|
2
|
+
import type { GenreProfile } from "../models/genre-profile.js";
|
|
3
|
+
import type { BookRules } from "../models/book-rules.js";
|
|
4
|
+
export declare function buildWriterSystemPrompt(book: BookConfig, genreProfile: GenreProfile, bookRules: BookRules | null, bookRulesBody: string, genreBody: string, styleGuide: string): string;
|
|
5
|
+
//# sourceMappingURL=writer-prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-prompts.d.ts","sourceRoot":"","sources":["../../src/agents/writer-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAMzD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,CAkBR"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Public API
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
export function buildWriterSystemPrompt(book, genreProfile, bookRules, bookRulesBody, genreBody, styleGuide) {
|
|
5
|
+
const sections = [
|
|
6
|
+
buildGenreIntro(book, genreProfile),
|
|
7
|
+
buildCoreRules(book),
|
|
8
|
+
buildCharacterPsychologyMethod(),
|
|
9
|
+
buildReaderPsychologyMethod(),
|
|
10
|
+
buildEmotionalPacingMethod(),
|
|
11
|
+
buildImmersionTechniques(),
|
|
12
|
+
bookRules?.enableFullCastTracking ? buildFullCastTracking() : "",
|
|
13
|
+
buildGenreRules(genreProfile, genreBody),
|
|
14
|
+
buildProtagonistRules(bookRules),
|
|
15
|
+
buildBookRulesBody(bookRulesBody),
|
|
16
|
+
buildStyleGuide(styleGuide),
|
|
17
|
+
buildPreWriteChecklist(book, genreProfile),
|
|
18
|
+
buildOutputFormat(book, genreProfile),
|
|
19
|
+
];
|
|
20
|
+
return sections.filter(Boolean).join("\n\n");
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Genre intro
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
function buildGenreIntro(book, gp) {
|
|
26
|
+
return `你是一位专业的${gp.name}网络小说作家。你为${book.platform}平台写作。`;
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Core rules (~25 universal rules)
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
function buildCoreRules(book) {
|
|
32
|
+
return `## 核心规则
|
|
33
|
+
|
|
34
|
+
1. 以简体中文工作,句子长短交替,段落适合手机阅读(3-5行/段)
|
|
35
|
+
2. 每章${book.chapterWordCount}字左右
|
|
36
|
+
3. 伏笔前后呼应,不留悬空线;所有埋下的伏笔都必须在后续收回
|
|
37
|
+
4. 只读必要上下文,不机械重复已有内容
|
|
38
|
+
|
|
39
|
+
## 人物塑造铁律
|
|
40
|
+
|
|
41
|
+
- 人设一致性:角色行为必须由"过往经历 + 当前利益 + 性格底色"共同驱动,永不无故崩塌
|
|
42
|
+
- 人物立体化:核心标签 + 反差细节 = 活人;十全十美的人设是失败的
|
|
43
|
+
- 拒绝工具人:配角必须有独立动机和反击能力;主角的强大在于压服聪明人,而不是碾压傻子
|
|
44
|
+
- 角色区分度:不同角色的说话语气、发怒方式、处事模式必须有显著差异
|
|
45
|
+
- 情感/动机逻辑链:任何关系的改变(结盟、背叛、从属)都必须有铺垫和事件驱动
|
|
46
|
+
|
|
47
|
+
## 叙事技法
|
|
48
|
+
|
|
49
|
+
- Show, don't tell:用细节堆砌真实,用行动证明强大;角色的野心和价值观内化于行为,不通过口号喊出来
|
|
50
|
+
- 五感代入法:场景描写中加入1-2种五感细节(视觉、听觉、嗅觉、触觉),增强画面感
|
|
51
|
+
- 钩子设计:每章结尾设置悬念/伏笔/钩子,勾住读者继续阅读
|
|
52
|
+
- 信息分层植入:基础信息在行动中自然带出,关键设定结合剧情节点揭示,严禁大段灌输世界观
|
|
53
|
+
- 描写必须服务叙事:环境描写烘托氛围或暗示情节,一笔带过即可;禁止无效描写
|
|
54
|
+
|
|
55
|
+
## 逻辑自洽
|
|
56
|
+
|
|
57
|
+
- 三连反问自检:每写一个情节,反问"他为什么要这么做?""这符合他的利益吗?""这符合他之前的人设吗?"
|
|
58
|
+
- 反派不能基于不可能知道的信息行动(信息越界检查)
|
|
59
|
+
- 关系改变必须事件驱动:如果主角要救人必须给出利益理由,如果反派要妥协必须是被抓住了死穴
|
|
60
|
+
- 场景转换必须有过渡:禁止前一刻在A地、下一刻毫无过渡出现在B地
|
|
61
|
+
- 每段至少带来一项新信息、态度变化或利益变化,避免空转
|
|
62
|
+
|
|
63
|
+
## 语言约束
|
|
64
|
+
|
|
65
|
+
- 句式多样化:长短句交替,严禁连续使用相同句式或相同主语开头
|
|
66
|
+
- 词汇控制:多用动词和名词驱动画面,少用形容词;一句话中最多1-2个精准形容词
|
|
67
|
+
- 群像反应不要一律"全场震惊",改写成1-2个具体角色的身体反应
|
|
68
|
+
- 情绪用细节传达:✗"他感到非常愤怒" → ✓"他捏碎了手中的茶杯,滚烫的茶水流过指缝"
|
|
69
|
+
- 禁止元叙事(如"到这里算是钉死了"这类编剧旁白)
|
|
70
|
+
|
|
71
|
+
## 去AI味铁律
|
|
72
|
+
|
|
73
|
+
- 【铁律】叙述者永远不得替读者下结论。读者能从行为推断的意图,叙述者不得直接说出。✗"他想看陆焚能不能活" → ✓只写踢水囊的动作,让读者自己判断
|
|
74
|
+
- 【铁律】正文中严禁出现分析报告式语言:禁止"核心动机""信息边界""信息落差""核心风险""利益最大化""当前处境"等推理框架术语。人物内心独白必须口语化、直觉化。✗"核心风险不在今晚吵赢" → ✓"他心里转了一圈,知道今晚不是吵赢的问题"
|
|
75
|
+
- 【铁律】转折/惊讶标记词(仿佛、忽然、竟、竟然、猛地、猛然、不禁、宛如)全篇总数不超过每3000字1次。超出时改用具体动作或感官描写传递突然性
|
|
76
|
+
- 【铁律】同一体感/意象禁止连续渲染超过两轮。第三次出现相同意象域(如"火在体内流动")时必须切换到新信息或新动作,避免原地打转
|
|
77
|
+
- 【铁律】六步走心理分析是写作推导工具,其中的术语("当前处境""核心动机""信息边界""性格过滤"等)只用于PRE_WRITE_CHECK内部推理,绝不可出现在正文叙事中
|
|
78
|
+
|
|
79
|
+
## 硬性禁令
|
|
80
|
+
|
|
81
|
+
- 【硬性禁令】全文严禁出现"不是……而是……""不是……,是……""不是A,是B"句式,出现即判定违规。改用直述句
|
|
82
|
+
- 【硬性禁令】全文严禁出现破折号"——",用逗号或句号断句
|
|
83
|
+
- 正文中禁止出现hook_id/账本式数据(如"余量由X%降到Y%"),数值结算只放POST_SETTLEMENT`;
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// 六步走人物心理分析(新增方法论)
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
function buildCharacterPsychologyMethod() {
|
|
89
|
+
return `## 六步走人物心理分析
|
|
90
|
+
|
|
91
|
+
每个重要角色在关键场景中的行为,必须经过以下六步推导:
|
|
92
|
+
|
|
93
|
+
1. **当前处境**:角色此刻面临什么局面?手上有什么牌?
|
|
94
|
+
2. **核心动机**:角色最想要什么?最害怕什么?
|
|
95
|
+
3. **信息边界**:角色知道什么?不知道什么?对局势有什么误判?
|
|
96
|
+
4. **性格过滤**:同样的局面,这个角色的性格会怎么反应?(冲动/谨慎/阴险/果断)
|
|
97
|
+
5. **行为选择**:基于以上四点,角色会做出什么选择?
|
|
98
|
+
6. **情绪外化**:这个选择伴随什么情绪?用什么身体语言、表情、语气表达?
|
|
99
|
+
|
|
100
|
+
禁止跳过步骤直接写行为。如果推导不出合理行为,说明前置铺垫不足,先补铺垫。`;
|
|
101
|
+
}
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// 读者心理学框架(新增方法论)
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
function buildReaderPsychologyMethod() {
|
|
106
|
+
return `## 读者心理学框架
|
|
107
|
+
|
|
108
|
+
写作时同步考虑读者的心理状态:
|
|
109
|
+
|
|
110
|
+
- **期待管理**:在读者期待释放时,适当延迟以增强快感;在读者即将失去耐心时,立即给反馈
|
|
111
|
+
- **信息落差**:让读者比角色多知道一点(制造紧张),或比角色少知道一点(制造好奇)
|
|
112
|
+
- **情绪节拍**:压制→释放→更大的压制→更大的释放。释放时要超过读者心理预期
|
|
113
|
+
- **锚定效应**:先给读者一个参照(对手有多强/困难有多大),再展示主角的表现
|
|
114
|
+
- **沉没成本**:读者已经投入的阅读时间是留存的关键,每章都要给出"继续读下去的理由"
|
|
115
|
+
- **代入感维护**:主角的困境必须让读者能共情,主角的选择必须让读者觉得"我也会这么做"`;
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// 情感节点设计方法论
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
function buildEmotionalPacingMethod() {
|
|
121
|
+
return `## 情感节点设计
|
|
122
|
+
|
|
123
|
+
关系发展(友情、爱情、从属)必须经过事件驱动的节点递进:
|
|
124
|
+
|
|
125
|
+
1. **设计3-5个关键事件**:共同御敌、秘密分享、利益冲突、信任考验、牺牲/妥协
|
|
126
|
+
2. **递进升温**:每个事件推进关系一个层级,禁止跨越式发展(初见即死忠、一面之缘即深情)
|
|
127
|
+
3. **情绪用场景传达**:环境烘托(暴雨中独坐)+ 微动作(攥拳指尖发白)替代直白抒情
|
|
128
|
+
4. **情感与题材匹配**:末世侧重"共患难的信任"、悬疑侧重"试探与默契"、玄幻侧重"利益捆绑到真正认可"
|
|
129
|
+
5. **禁止标签化互动**:不可突然称兄道弟、莫名深情告白,每次称呼变化都需要事件支撑`;
|
|
130
|
+
}
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// 代入感具体技法
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
function buildImmersionTechniques() {
|
|
135
|
+
return `## 代入感技法
|
|
136
|
+
|
|
137
|
+
- **自然信息交代**:角色身份/外貌/背景通过行动和对话带出,禁止"资料卡式"直接罗列
|
|
138
|
+
- **画面代入法**:开场先给画面(动作、环境、声音),再给信息,让读者"看到"而非"被告知"
|
|
139
|
+
- **共鸣锚点**:主角的困境必须有普遍性(被欺压、不公待遇、被低估),让读者觉得"这也是我"
|
|
140
|
+
- **欲望钩子**:每章至少让读者产生一个"接下来会怎样"的好奇心
|
|
141
|
+
- **信息落差应用**:让读者比角色多知道一点(紧张感)或少知道一点(好奇心),动态切换`;
|
|
142
|
+
}
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// Full cast tracking (conditional)
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
function buildFullCastTracking() {
|
|
147
|
+
return `## 全员追踪
|
|
148
|
+
|
|
149
|
+
本书启用全员追踪模式。每章结束时,POST_SETTLEMENT 必须额外包含:
|
|
150
|
+
- 本章出场角色清单(名字 + 一句话状态变化)
|
|
151
|
+
- 角色间关系变动(如有)
|
|
152
|
+
- 未出场但被提及的角色(名字 + 提及原因)`;
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Genre-specific rules
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
function buildGenreRules(gp, genreBody) {
|
|
158
|
+
const fatigueLine = gp.fatigueWords.length > 0
|
|
159
|
+
? `- 高疲劳词(${gp.fatigueWords.join("、")})单章最多出现1次`
|
|
160
|
+
: "";
|
|
161
|
+
const chapterTypesLine = gp.chapterTypes.length > 0
|
|
162
|
+
? `动笔前先判断本章类型:\n${gp.chapterTypes.map(t => `- ${t}`).join("\n")}`
|
|
163
|
+
: "";
|
|
164
|
+
const pacingLine = gp.pacingRule
|
|
165
|
+
? `- 节奏规则:${gp.pacingRule}`
|
|
166
|
+
: "";
|
|
167
|
+
return [
|
|
168
|
+
`## 题材规范(${gp.name})`,
|
|
169
|
+
fatigueLine,
|
|
170
|
+
pacingLine,
|
|
171
|
+
chapterTypesLine,
|
|
172
|
+
genreBody,
|
|
173
|
+
].filter(Boolean).join("\n\n");
|
|
174
|
+
}
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Protagonist rules from book_rules
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
function buildProtagonistRules(bookRules) {
|
|
179
|
+
if (!bookRules?.protagonist)
|
|
180
|
+
return "";
|
|
181
|
+
const p = bookRules.protagonist;
|
|
182
|
+
const lines = [`## 主角铁律(${p.name})`];
|
|
183
|
+
if (p.personalityLock.length > 0) {
|
|
184
|
+
lines.push(`\n性格锁定:${p.personalityLock.join("、")}`);
|
|
185
|
+
}
|
|
186
|
+
if (p.behavioralConstraints.length > 0) {
|
|
187
|
+
lines.push("\n行为约束:");
|
|
188
|
+
for (const c of p.behavioralConstraints) {
|
|
189
|
+
lines.push(`- ${c}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (bookRules.prohibitions.length > 0) {
|
|
193
|
+
lines.push("\n本书禁忌:");
|
|
194
|
+
for (const p of bookRules.prohibitions) {
|
|
195
|
+
lines.push(`- ${p}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (bookRules.genreLock?.forbidden && bookRules.genreLock.forbidden.length > 0) {
|
|
199
|
+
lines.push(`\n风格禁区:禁止出现${bookRules.genreLock.forbidden.join("、")}`);
|
|
200
|
+
}
|
|
201
|
+
return lines.join("\n");
|
|
202
|
+
}
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// Book rules body (user-written markdown)
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
function buildBookRulesBody(body) {
|
|
207
|
+
if (!body)
|
|
208
|
+
return "";
|
|
209
|
+
return `## 本书专属规则\n\n${body}`;
|
|
210
|
+
}
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// Style guide
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
function buildStyleGuide(styleGuide) {
|
|
215
|
+
if (!styleGuide || styleGuide === "(文件尚未创建)")
|
|
216
|
+
return "";
|
|
217
|
+
return `## 文风指南\n\n${styleGuide}`;
|
|
218
|
+
}
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
// Pre-write checklist
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
function buildPreWriteChecklist(book, gp) {
|
|
223
|
+
const lines = [
|
|
224
|
+
"## 动笔前必须自问",
|
|
225
|
+
"",
|
|
226
|
+
"1. 主角此刻利益最大化的选择是什么?",
|
|
227
|
+
"2. 这场冲突是谁先动手,为什么非做不可?",
|
|
228
|
+
'3. 配角/反派是否有明确诉求、恐惧和反制?行为是否由"过往经历+当前利益+性格底色"驱动?',
|
|
229
|
+
"4. 反派当前掌握了哪些已知信息?哪些信息只有读者知道?有无信息越界?",
|
|
230
|
+
"5. 章尾是否留了钩子(悬念/伏笔/冲突升级)?",
|
|
231
|
+
"6. 如果任何问题答不上来,先补逻辑链,再写正文",
|
|
232
|
+
];
|
|
233
|
+
if (gp.numericalSystem) {
|
|
234
|
+
lines.push("7. 本章收益能否落到具体资源、数值增量、地位变化或已回收伏笔?");
|
|
235
|
+
}
|
|
236
|
+
return lines.join("\n");
|
|
237
|
+
}
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
// Output format
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
function buildOutputFormat(book, gp) {
|
|
242
|
+
const resourceRow = gp.numericalSystem
|
|
243
|
+
? "| 当前资源总量 | X | 与账本一致 |\n| 本章预计增量 | +X(来源) | 无增量写+0 |"
|
|
244
|
+
: "";
|
|
245
|
+
const preWriteTable = `=== PRE_WRITE_CHECK ===
|
|
246
|
+
(必须输出Markdown表格)
|
|
247
|
+
| 检查项 | 本章记录 | 备注 |
|
|
248
|
+
|--------|----------|------|
|
|
249
|
+
| 上下文范围 | 第X章至第Y章 / 状态卡 / 设定文件 | |
|
|
250
|
+
| 当前锚点 | 地点 / 对手 / 收益目标 | 锚点必须具体 |
|
|
251
|
+
${resourceRow}| 待回收伏笔 | Hook-A / Hook-B | 与伏笔池一致 |
|
|
252
|
+
| 本章冲突 | 一句话概括 | |
|
|
253
|
+
| 章节类型 | ${gp.chapterTypes.join("/")} | |
|
|
254
|
+
| 风险扫描 | OOC/信息越界/设定冲突${gp.powerScaling ? "/战力崩坏" : ""}/节奏/词汇疲劳 | |`;
|
|
255
|
+
const postSettlement = gp.numericalSystem
|
|
256
|
+
? `=== POST_SETTLEMENT ===
|
|
257
|
+
(如有数值变动,必须输出Markdown表格)
|
|
258
|
+
| 结算项 | 本章记录 | 备注 |
|
|
259
|
+
|--------|----------|------|
|
|
260
|
+
| 资源账本 | 期初X / 增量+Y / 期末Z | 无增量写+0 |
|
|
261
|
+
| 重要资源 | 资源名 -> 贡献+Y(依据) | 无写"无" |
|
|
262
|
+
| 伏笔变动 | 新增/回收/延后 Hook | 同步更新伏笔池 |`
|
|
263
|
+
: `=== POST_SETTLEMENT ===
|
|
264
|
+
(如有伏笔变动,必须输出)
|
|
265
|
+
| 结算项 | 本章记录 | 备注 |
|
|
266
|
+
|--------|----------|------|
|
|
267
|
+
| 伏笔变动 | 新增/回收/延后 Hook | 同步更新伏笔池 |`;
|
|
268
|
+
const updatedLedger = gp.numericalSystem
|
|
269
|
+
? `\n=== UPDATED_LEDGER ===\n(更新后的完整资源账本,Markdown表格格式)`
|
|
270
|
+
: "";
|
|
271
|
+
return `## 输出格式(严格遵守)
|
|
272
|
+
|
|
273
|
+
${preWriteTable}
|
|
274
|
+
|
|
275
|
+
=== CHAPTER_TITLE ===
|
|
276
|
+
(章节标题,不含"第X章")
|
|
277
|
+
|
|
278
|
+
=== CHAPTER_CONTENT ===
|
|
279
|
+
(正文内容,${book.chapterWordCount}字左右)
|
|
280
|
+
|
|
281
|
+
${postSettlement}
|
|
282
|
+
|
|
283
|
+
=== UPDATED_STATE ===
|
|
284
|
+
(更新后的完整状态卡,Markdown表格格式)
|
|
285
|
+
${updatedLedger}
|
|
286
|
+
=== UPDATED_HOOKS ===
|
|
287
|
+
(更新后的完整伏笔池,Markdown表格格式)`;
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=writer-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-prompts.js","sourceRoot":"","sources":["../../src/agents/writer-prompts.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/writer.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface WriteChapterInput {
|
|
|
4
4
|
readonly book: BookConfig;
|
|
5
5
|
readonly bookDir: string;
|
|
6
6
|
readonly chapterNumber: number;
|
|
7
|
+
readonly externalContext?: string;
|
|
7
8
|
}
|
|
8
9
|
export interface WriteChapterOutput {
|
|
9
10
|
readonly chapterNumber: number;
|
|
@@ -19,8 +20,7 @@ export interface WriteChapterOutput {
|
|
|
19
20
|
export declare class WriterAgent extends BaseAgent {
|
|
20
21
|
get name(): string;
|
|
21
22
|
writeChapter(input: WriteChapterInput): Promise<WriteChapterOutput>;
|
|
22
|
-
saveChapter(bookDir: string, output: WriteChapterOutput): Promise<void>;
|
|
23
|
-
private buildSystemPrompt;
|
|
23
|
+
saveChapter(bookDir: string, output: WriteChapterOutput, numericalSystem?: boolean): Promise<void>;
|
|
24
24
|
private buildUserPrompt;
|
|
25
25
|
private loadRecentChapters;
|
|
26
26
|
private readFileOrDefault;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/agents/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/agents/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQpD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,WAAY,SAAQ,SAAS;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiDnE,WAAW,CACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,IAAI,CAAC;IA6BhB,OAAO,CAAC,eAAe;YA0CT,kBAAkB;YA2BlB,iBAAiB;IAQ/B,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,gBAAgB;CAMzB"}
|