@whispering233/ai-editor-server 0.0.21 → 0.0.29
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/client-dist/assets/index-0zEqGbv5.css +1 -0
- package/client-dist/assets/index-DMtHdMMq.js +521 -0
- package/client-dist/index.html +3 -3
- package/dist/backup.d.ts +78 -78
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +138 -139
- package/dist/backup.js.map +1 -1
- package/dist/consistency.d.ts +3 -3
- package/dist/consistency.d.ts.map +1 -1
- package/dist/consistency.js +4 -4
- package/dist/consistency.js.map +1 -1
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +7 -7
- package/dist/debug.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -37
- package/dist/index.js.map +1 -1
- package/dist/middleware/error.d.ts +4 -4
- package/dist/middleware/error.d.ts.map +1 -1
- package/dist/middleware/error.js +7 -9
- package/dist/middleware/error.js.map +1 -1
- package/dist/middleware/project.d.ts +9 -9
- package/dist/middleware/project.d.ts.map +1 -1
- package/dist/middleware/project.js +23 -23
- package/dist/middleware/project.js.map +1 -1
- package/dist/reference-files.d.ts +12 -12
- package/dist/reference-files.d.ts.map +1 -1
- package/dist/reference-files.js +20 -21
- package/dist/reference-files.js.map +1 -1
- package/dist/routes/chat.d.ts +18 -18
- package/dist/routes/chat.d.ts.map +1 -1
- package/dist/routes/chat.js +70 -83
- package/dist/routes/chat.js.map +1 -1
- package/dist/routes/delta.d.ts.map +1 -1
- package/dist/routes/delta.js +27 -28
- package/dist/routes/delta.js.map +1 -1
- package/dist/routes/entity.d.ts.map +1 -1
- package/dist/routes/entity.js +44 -45
- package/dist/routes/entity.js.map +1 -1
- package/dist/routes/names.d.ts.map +1 -1
- package/dist/routes/names.js +8 -9
- package/dist/routes/names.js.map +1 -1
- package/dist/routes/outline.d.ts +1 -1
- package/dist/routes/outline.d.ts.map +1 -1
- package/dist/routes/outline.js +23 -24
- package/dist/routes/outline.js.map +1 -1
- package/dist/routes/project.d.ts +6 -6
- package/dist/routes/project.d.ts.map +1 -1
- package/dist/routes/project.js +91 -95
- package/dist/routes/project.js.map +1 -1
- package/dist/routes/proposal.d.ts.map +1 -1
- package/dist/routes/proposal.js +40 -42
- package/dist/routes/proposal.js.map +1 -1
- package/dist/routes/reference.d.ts.map +1 -1
- package/dist/routes/reference.js +1 -2
- package/dist/routes/reference.js.map +1 -1
- package/dist/routes/relation.d.ts.map +1 -1
- package/dist/routes/relation.js +14 -15
- package/dist/routes/relation.js.map +1 -1
- package/dist/routes/settings.d.ts +35 -17
- package/dist/routes/settings.d.ts.map +1 -1
- package/dist/routes/settings.js +157 -52
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/trash.d.ts.map +1 -1
- package/dist/routes/trash.js +15 -16
- package/dist/routes/trash.js.map +1 -1
- package/package.json +7 -7
- package/client-dist/assets/index-B51Kcb1K.css +0 -1
- package/client-dist/assets/index-zgl3whdc.js +0 -104
package/dist/middleware/error.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
// 统一错误处理(T6.1 + S1.2)
|
|
2
2
|
//
|
|
3
|
-
// 契约来源:doc/api/endpoints.md「通用约定」——
|
|
4
|
-
// 成功响应 { success: true, data: T };错误响应 { success: false, error: { code, message } }。
|
|
5
3
|
// ErrorCode 单一来源为 @whispering233/ai-editor-shared(types/api.ts);本文件补充服务端侧错误码
|
|
6
4
|
// (不在 shared 枚举内,与 client 的 CLIENT_NETWORK_ERROR 同类做法):
|
|
7
|
-
//
|
|
8
|
-
//
|
|
5
|
+
// INTERNAL_ERROR(未处理异常 500)、FORBIDDEN(来源校验拒绝 403)、NOT_FOUND(未知端点 404)、
|
|
6
|
+
// NO_PROJECT_OPEN(S1.2:无当前项目时业务操作 409)、PROJECT_ALREADY_EXISTS(S1.2:create 目录已是项目 409)
|
|
9
7
|
// 记录:错误码分散(shared 枚举 + 服务端补充 + client 补充)为已知技术债,MVP 不收敛
|
|
10
8
|
import { ZodError } from "zod";
|
|
11
9
|
/** 服务端补充错误码(不在 shared ErrorCode 枚举内) */
|
|
@@ -15,13 +13,13 @@ export const SERVER_ERROR_CODES = [
|
|
|
15
13
|
"NOT_FOUND",
|
|
16
14
|
"NO_PROJECT_OPEN",
|
|
17
15
|
"PROJECT_ALREADY_EXISTS",
|
|
18
|
-
"LLM_API_KEY_MISSING", // S7.6:POST /chat 未配置 DeepSeek key
|
|
16
|
+
"LLM_API_KEY_MISSING", // S7.6:POST /chat 未配置 DeepSeek key——400
|
|
19
17
|
];
|
|
20
|
-
/**
|
|
18
|
+
/** 成功响应包裹() */
|
|
21
19
|
export function ok(data) {
|
|
22
20
|
return { success: true, data };
|
|
23
21
|
}
|
|
24
|
-
/**
|
|
22
|
+
/** 错误响应包裹();fields 仅 VALIDATION_ERROR 附带(校验失败字段路径) */
|
|
25
23
|
export function fail(code, message, fields) {
|
|
26
24
|
return { success: false, error: { code, message, ...(fields ? { fields } : {}) } };
|
|
27
25
|
}
|
|
@@ -44,8 +42,8 @@ export class HttpError extends Error {
|
|
|
44
42
|
* HttpError → 按 status/code 透传;ZodError(路由内 schema.parse 抛出)→ 400 VALIDATION_ERROR(含 fields);
|
|
45
43
|
* 未处理异常 → 500 包裹。
|
|
46
44
|
* 说明:Hono 4 的 compose 在 dispatch 内部捕获路由错误并直接调用 onError,
|
|
47
|
-
*
|
|
48
|
-
*
|
|
45
|
+
* 错误不会沿 next 链传播——middleware 内的 try/catch 捕获不到下游错误
|
|
46
|
+
* (实测 hono@4.12 compose.js),因此本处理器以 ErrorHandler 形式导出。
|
|
49
47
|
*/
|
|
50
48
|
export function errorHandler() {
|
|
51
49
|
return (err, c) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,EAAE;AACF,6EAA6E;AAC7E,wDAAwD;AACxD,uEAAuE;AACvE,sFAAsF;AACtF,wDAAwD;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAK/B,wCAAwC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,iBAAiB;IACjB,wBAAwB;IACxB,qBAAqB,EAAE,wCAAwC;CACvD,CAAC;AAKX,eAAe;AACf,MAAM,UAAU,EAAE,CAAI,IAAO;IAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,IAAI,CAClB,IAAkB,EAClB,OAAe,EACf,MAAiB;IAEjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AACrF,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,MAAM,CAAuB;IAC7B,IAAI,CAAe;IAC5B,YAAY,MAA4B,EAAE,IAAkB,EAAE,OAAe;QAC3E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QAChB,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YACjC,4EAA4E;YACvE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,OAAO,CAAC,CAAC,IAAI,CACX,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,CAAC,EACpE,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7F,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Context, MiddlewareHandler } from "hono";
|
|
2
2
|
import type { ProjectFileConfig } from "@whispering233/ai-editor-shared";
|
|
3
3
|
import { type Db } from "@whispering233/ai-editor-db";
|
|
4
|
-
/** data.db
|
|
4
|
+
/** data.db 文件名(项目根目录) */
|
|
5
5
|
export declare const DATA_DB_FILE_NAME = "data.db";
|
|
6
|
-
/** 项目上下文:内存中单一 currentProject
|
|
6
|
+
/** 项目上下文:内存中单一 currentProject(,所有 API 共享) */
|
|
7
7
|
export interface ProjectContext {
|
|
8
8
|
root: string;
|
|
9
9
|
config: ProjectFileConfig;
|
|
@@ -19,7 +19,7 @@ export declare function getProject(c: Context<{
|
|
|
19
19
|
}>): ProjectContext;
|
|
20
20
|
/**
|
|
21
21
|
* 设置当前项目(create/open 成功后调用;传 null 清空——close 时)。
|
|
22
|
-
* B2.2
|
|
22
|
+
* B2.2:自动备份定时器跟随当前项目生命周期——设置非空 → 启动调度
|
|
23
23
|
* (open/切换/启动即打开),清空 → 停止(close)。频率变化(restore 等)由
|
|
24
24
|
* 调度器 tick 内重读 config 自行跟随。
|
|
25
25
|
*/
|
|
@@ -32,7 +32,7 @@ export declare function getCurrentProject(): ProjectContext | null;
|
|
|
32
32
|
*/
|
|
33
33
|
export declare function requireCurrentProject(): ProjectContext;
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* 检测并打开项目( 启动流程 ④ 修订——设计缺陷修复):
|
|
36
36
|
* project.json 存在 → openDatabase 打开,返回项目上下文(打开语义,部署场景「启动即用」);
|
|
37
37
|
* project.json 不存在 → **返回 null(待命)**——不初始化、不建任何文件(含目录),
|
|
38
38
|
* 由前端 Dashboard 引导走 POST /project/create 或 /project/open(S1.4 开/建页;
|
|
@@ -43,23 +43,23 @@ export declare function requireCurrentProject(): ProjectContext;
|
|
|
43
43
|
*/
|
|
44
44
|
export declare function detectProject(root: string): ProjectContext | null;
|
|
45
45
|
/**
|
|
46
|
-
* 显式初始化新项目(S1.2 create
|
|
46
|
+
* 显式初始化新项目(S1.2 create 路由专用,「首次初始化三文件」语义):
|
|
47
47
|
* 建目录(mkdir recursive,含嵌套不存在的父目录)→ 写 project.json(id=proj- 前缀 nanoid、
|
|
48
48
|
* name 默认取目录名、language 默认 zh、schema_version=SCHEMA_VERSION,created_at/updated_at
|
|
49
49
|
* 应用层写当前 ISO 时间)→ 写 outline.json 最小空树 → openDatabase 建 data.db(自动建表)
|
|
50
50
|
* → setUserVersion(SCHEMA_VERSION)(S1.1 审核建议:brand-new 库立即写版本号,
|
|
51
51
|
* 避免后续 open 时 ensureSchemaCompatible 触发无意义重建并留空库 data.db.v0.bak)。
|
|
52
|
-
* 注:`prompt`
|
|
52
|
+
* 注:`prompt` 已废弃——新项目不再写入该字段(项目规则改由 承载)。
|
|
53
53
|
*
|
|
54
54
|
* @param configOverride 可选覆盖 {name?, language?}(create 请求的 config 字段);
|
|
55
|
-
*
|
|
55
|
+
* 传入时 updated_at 一并刷新
|
|
56
56
|
* @returns 已打开的项目上下文(调用方负责 closeProject;create 路由创建后即关闭)
|
|
57
57
|
*/
|
|
58
58
|
export declare function initProject(root: string, configOverride?: Partial<Pick<ProjectFileConfig, "name" | "language">>): ProjectContext;
|
|
59
|
-
/**
|
|
59
|
+
/** 关闭项目:释放数据库连接(;WAL + synchronous=FULL 已即时落盘) */
|
|
60
60
|
export declare function closeProject(project: ProjectContext): void;
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
62
|
+
* 来源校验中间件:
|
|
63
63
|
* Origin 头存在 → 校验其 host;Origin 缺失(地址栏直接导航)→ 退化为校验 Host 头 host。
|
|
64
64
|
* 两者皆拒 → 403(防 CSRF / DNS rebinding;DNS rebinding 下读操作同样是敏感操作)。
|
|
65
65
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/middleware/project.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,EAA+C,KAAK,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAQnG,
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/middleware/project.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,EAA+C,KAAK,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAQnG,yBAAyB;AACzB,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAK3C,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,EAAE,EAAE,EAAE,CAAC;CACR;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,8BAA8B;AAC9B,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC;IAAE,SAAS,EAAE,gBAAgB,CAAA;CAAE,CAAC,GAAG,cAAc,CAEtF;AAWD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAOtE;AAED,uBAAuB;AACvB,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAKtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAUjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,GACrE,cAAc,CAoBhB;AAED,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAE1D;AAYD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,iBAAiB,CASzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,CAQrD"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// 项目上下文中间件(T6.1 + S1.2)
|
|
2
2
|
//
|
|
3
|
-
// 职责(
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
3
|
+
// 职责( 第 121-122 行 middleware/project.ts「项目路径注入」):
|
|
4
|
+
// 1. detectProject:检测 project.json——存在则打开(部署场景「启动即用」);不存在返回
|
|
5
|
+
// null 待命(不初始化、不建文件,由前端 Dashboard 引导 create/open;S1.4 开/建页依赖)
|
|
6
|
+
// initProject:显式初始化三文件(S1.2 create 路由专用,含建目录 + user_version)
|
|
7
|
+
// 2. currentProject 内存单例(S1.2,):create/open 切换、close 清空,
|
|
8
|
+
// 模块级可变状态由路由(routes/project.ts)读写,projectMiddleware 从状态注入 Hono 上下文
|
|
9
|
+
// 3. 来源校验:全部请求校验 Origin(缺失时退化为 Host)的 host
|
|
10
|
+
// ∈ {127.0.0.1, localhost, ::1},不匹配拒绝 403;**不校验端口**
|
|
11
|
+
// (端口 +1 可变;dev 态 Vite proxy 转发后端口为 5173,校验端口会误杀开发请求)
|
|
12
12
|
import { basename, join } from "node:path";
|
|
13
13
|
import { mkdirSync } from "node:fs";
|
|
14
14
|
import { generateProjectId, DEFAULT_BACKUP_FREQUENCY_MINUTES } from "@whispering233/ai-editor-shared";
|
|
@@ -19,9 +19,9 @@ import { SCHEMA_VERSION } from "@whispering233/ai-editor-db";
|
|
|
19
19
|
import { nowIso } from "@whispering233/ai-editor-db";
|
|
20
20
|
import { HttpError, fail } from "./error.js";
|
|
21
21
|
import { migratePromptToAgents, startAutoBackup, stopAutoBackup } from "../backup.js";
|
|
22
|
-
/** data.db
|
|
22
|
+
/** data.db 文件名(项目根目录) */
|
|
23
23
|
export const DATA_DB_FILE_NAME = "data.db";
|
|
24
|
-
/** 来源白名单 host
|
|
24
|
+
/** 来源白名单 host(仅允许本机访问;IPv6 ::1 去括号后比对) */
|
|
25
25
|
const ALLOWED_HOSTS = ["127.0.0.1", "localhost", "::1"];
|
|
26
26
|
/** 从 Hono 上下文取项目上下文(路由内使用) */
|
|
27
27
|
export function getProject(c) {
|
|
@@ -29,14 +29,14 @@ export function getProject(c) {
|
|
|
29
29
|
}
|
|
30
30
|
// ============ currentProject 内存单例(S1.2) ============
|
|
31
31
|
//
|
|
32
|
-
//
|
|
32
|
+
// 语义():单进程内存中只有一个 currentProject,所有 API 调用共享;
|
|
33
33
|
// create/open 切换它、close 清空它。多项目并发打开不在 MVP 范围(backlog)。
|
|
34
34
|
// 模块级可变状态 + 显式读写函数:路由层可读可写,中间件只读注入。
|
|
35
35
|
/** 当前打开的项目(null = 无) */
|
|
36
36
|
let currentProject = null;
|
|
37
37
|
/**
|
|
38
38
|
* 设置当前项目(create/open 成功后调用;传 null 清空——close 时)。
|
|
39
|
-
* B2.2
|
|
39
|
+
* B2.2:自动备份定时器跟随当前项目生命周期——设置非空 → 启动调度
|
|
40
40
|
* (open/切换/启动即打开),清空 → 停止(close)。频率变化(restore 等)由
|
|
41
41
|
* 调度器 tick 内重读 config 自行跟随。
|
|
42
42
|
*/
|
|
@@ -64,7 +64,7 @@ export function requireCurrentProject() {
|
|
|
64
64
|
return currentProject;
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* 检测并打开项目( 启动流程 ④ 修订——设计缺陷修复):
|
|
68
68
|
* project.json 存在 → openDatabase 打开,返回项目上下文(打开语义,部署场景「启动即用」);
|
|
69
69
|
* project.json 不存在 → **返回 null(待命)**——不初始化、不建任何文件(含目录),
|
|
70
70
|
* 由前端 Dashboard 引导走 POST /project/create 或 /project/open(S1.4 开/建页;
|
|
@@ -79,34 +79,34 @@ export function detectProject(root) {
|
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
81
81
|
const project = { root, config: existing, db: openDatabase(join(root, DATA_DB_FILE_NAME)) };
|
|
82
|
-
//
|
|
82
|
+
// 自动迁移:project.json 有非空 prompt 且无 → 迁移写入(原样,一次性)
|
|
83
83
|
//(实现位于 backup.ts——backup 模块不依赖 middleware,middleware 侧经 ../backup.js 复用)
|
|
84
84
|
migratePromptToAgents(project);
|
|
85
85
|
return project;
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* 显式初始化新项目(S1.2 create
|
|
88
|
+
* 显式初始化新项目(S1.2 create 路由专用,「首次初始化三文件」语义):
|
|
89
89
|
* 建目录(mkdir recursive,含嵌套不存在的父目录)→ 写 project.json(id=proj- 前缀 nanoid、
|
|
90
90
|
* name 默认取目录名、language 默认 zh、schema_version=SCHEMA_VERSION,created_at/updated_at
|
|
91
91
|
* 应用层写当前 ISO 时间)→ 写 outline.json 最小空树 → openDatabase 建 data.db(自动建表)
|
|
92
92
|
* → setUserVersion(SCHEMA_VERSION)(S1.1 审核建议:brand-new 库立即写版本号,
|
|
93
93
|
* 避免后续 open 时 ensureSchemaCompatible 触发无意义重建并留空库 data.db.v0.bak)。
|
|
94
|
-
* 注:`prompt`
|
|
94
|
+
* 注:`prompt` 已废弃——新项目不再写入该字段(项目规则改由 承载)。
|
|
95
95
|
*
|
|
96
96
|
* @param configOverride 可选覆盖 {name?, language?}(create 请求的 config 字段);
|
|
97
|
-
*
|
|
97
|
+
* 传入时 updated_at 一并刷新
|
|
98
98
|
* @returns 已打开的项目上下文(调用方负责 closeProject;create 路由创建后即关闭)
|
|
99
99
|
*/
|
|
100
100
|
export function initProject(root, configOverride) {
|
|
101
101
|
mkdirSync(root, { recursive: true });
|
|
102
102
|
const now = nowIso();
|
|
103
103
|
const config = {
|
|
104
|
-
id: generateProjectId(), // proj- 前缀(
|
|
104
|
+
id: generateProjectId(), // proj- 前缀( id 约定)
|
|
105
105
|
name: basename(root),
|
|
106
106
|
language: "zh",
|
|
107
107
|
schema_version: SCHEMA_VERSION,
|
|
108
108
|
current_position: null,
|
|
109
|
-
//
|
|
109
|
+
// 新项目默认开启自动备份(显式写入缺省 10,跟随书籍)
|
|
110
110
|
backup_frequency_minutes: DEFAULT_BACKUP_FREQUENCY_MINUTES,
|
|
111
111
|
created_at: now,
|
|
112
112
|
updated_at: now,
|
|
@@ -115,10 +115,10 @@ export function initProject(root, configOverride) {
|
|
|
115
115
|
writeProjectFile(root, config);
|
|
116
116
|
writeOutlineFile(root, { id: "root", type: "root", schema_version: SCHEMA_VERSION, children: [] });
|
|
117
117
|
const db = openDatabase(join(root, DATA_DB_FILE_NAME)); // 文件不存在则创建 + 自动建表
|
|
118
|
-
setUserVersion(db, SCHEMA_VERSION); // 与 project.json/outline.json 的 schema_version
|
|
118
|
+
setUserVersion(db, SCHEMA_VERSION); // 与 project.json/outline.json 的 schema_version 同步
|
|
119
119
|
return { root, config, db };
|
|
120
120
|
}
|
|
121
|
-
/**
|
|
121
|
+
/** 关闭项目:释放数据库连接(;WAL + synchronous=FULL 已即时落盘) */
|
|
122
122
|
export function closeProject(project) {
|
|
123
123
|
closeDatabase(project.db);
|
|
124
124
|
}
|
|
@@ -133,7 +133,7 @@ function extractHostname(value) {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
136
|
+
* 来源校验中间件:
|
|
137
137
|
* Origin 头存在 → 校验其 host;Origin 缺失(地址栏直接导航)→ 退化为校验 Host 头 host。
|
|
138
138
|
* 两者皆拒 → 403(防 CSRF / DNS rebinding;DNS rebinding 下读操作同样是敏感操作)。
|
|
139
139
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/middleware/project.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/middleware/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { type Db } from "@whispering233/ai-editor-db";
|
|
2
2
|
import type { EntityRow } from "@whispering233/ai-editor-shared";
|
|
3
|
-
/**
|
|
3
|
+
/** 参考资料目录(项目根下,书籍项目文件夹自包含参考资料) */
|
|
4
4
|
export declare const REFERENCE_DIR = "references";
|
|
5
|
-
/** 软删回收目录(references/.trash
|
|
5
|
+
/** 软删回收目录(references/.trash/,软删文件移入,restore 移回、purge 物理删) */
|
|
6
6
|
export declare const REFERENCE_TRASH_DIR = ".trash";
|
|
7
7
|
/** 文件 mtime 比对容差(毫秒):**仅防御 ISO 毫秒截断 roundtrip**(mtimeMs 浮点 → toISOString
|
|
8
8
|
* 毫秒截断 → getTime 可能差亚毫秒)。与备份体系 1s 容差语义相反——备份容差防「mtime 未刷新
|
|
9
9
|
* 误判有变更」,scan 容差过大会**漏检真实外部修改**(1s 内的改动检测不到),故取最小值。
|
|
10
10
|
* 应用内写入:writeFileAtomic 后 stat 与 scan 读取的 mtime 必然一致(同一文件),严格相等即可。 */
|
|
11
11
|
export declare const REFERENCE_MTIME_TOLERANCE_MS = 2;
|
|
12
|
-
/**
|
|
12
|
+
/** 原子写( 同款:临时文件 + fsync + rename;参考资料 md 文件同样禁止直接覆盖) */
|
|
13
13
|
export declare function writeFileAtomic(filePath: string, data: string): void;
|
|
14
14
|
/** 确保 references/ 与 references/.trash/ 存在(幂等) */
|
|
15
15
|
export declare function ensureReferenceDirs(root: string): void;
|
|
@@ -49,7 +49,7 @@ export declare function restoreReferenceFromTrash(root: string, fileName: string
|
|
|
49
49
|
export declare function removeReferenceFile(root: string, fileName: string): void;
|
|
50
50
|
/** references/ 顶层 md 文件列表(排除 .trash/;不含子目录——YAGNI) */
|
|
51
51
|
export declare function listReferenceFiles(root: string): string[];
|
|
52
|
-
/**
|
|
52
|
+
/** 扫描结果统计(幂等全量比对) */
|
|
53
53
|
export interface ScanReferenceResult {
|
|
54
54
|
added: number;
|
|
55
55
|
updated: number;
|
|
@@ -62,14 +62,14 @@ export interface ScanReferenceResult {
|
|
|
62
62
|
* 列表页打开项目提示条用,不触发索引写入/软删) */
|
|
63
63
|
export declare function countUnsyncedReferenceFiles(root: string, db: Db): number;
|
|
64
64
|
/**
|
|
65
|
-
* 扫描重建参考资料索引(POST /api/v1/reference/scan
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
65
|
+
* 扫描重建参考资料索引(POST /api/v1/reference/scan,)。
|
|
66
|
+
* 规则( + 2026-08 修订:软删文件归 .trash/,references/ 下缺失即视为外部删除):
|
|
67
|
+
* 1. 遍历 references/ 顶层 *.md(排除 .trash/):
|
|
68
|
+
* - 非软删索引匹配(kind='file' 且 file_name === 文件名)→ mtime 一致(容差内)跳过;
|
|
69
|
+
* 不一致 → 以文件为准更新(title/category/tags/content/file_mtime/updated_at)
|
|
70
|
+
* - 软删索引匹配 → 还原(deleted_at=NULL,文件留 references/ 原地)+ 更新数据
|
|
71
|
+
* - 无匹配 → 新建(title=frontmatter title ?? 文件名去扩展名、category ?? material)
|
|
72
|
+
* 2. 反向:非软删 file 类索引,references/ 下对应文件缺失 → 索引同步软删(进回收站可还原)
|
|
73
73
|
* 幂等:重复执行无副作用;只处理顶层文件。
|
|
74
74
|
*/
|
|
75
75
|
export declare function scanReferences(root: string, db: Db): ScanReferenceResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-files.d.ts","sourceRoot":"","sources":["../src/reference-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reference-files.d.ts","sourceRoot":"","sources":["../src/reference-files.ts"],"names":[],"mappings":"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"}
|
package/dist/reference-files.js
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
|
-
//
|
|
1
|
+
// 参考资料文件服务(批次十一)
|
|
2
2
|
//
|
|
3
|
-
// 单一事实来源:doc/design/decisions.md 决策 43、doc/ui/pages/references.md。
|
|
4
3
|
// 职责:references/ 目录(项目文件夹内自包含)的读写/原子写/移动(软删 .trash/)/物理删,
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
4
|
+
// + 扫描重建索引(文件 = 真相源,DB 索引 = 派生镜像,mtime 快照比对)。
|
|
5
|
+
// 同步方案(与用户确认):
|
|
6
|
+
// - 应用内编辑:先原子写文件再更新 DB(文件写失败 → 操作报错 DB 不动;DB 失败 → 文件已写,
|
|
7
|
+
// scan 以文件为准自愈——文件可重建 DB 而 DB 不可重建文件)
|
|
8
|
+
// - 外部编辑/新增/删除:scan 幂等全量比对——「已索引跳过」= 索引存在 且 文件 mtime === 索引
|
|
9
|
+
// file_mtime;mtime 不一致 → 以文件为准重新解析 frontmatter + 正文更新索引
|
|
10
|
+
// - 软删:文件移 references/.trash/ + 索引 deleted_at;restore 移回;purge 物理删
|
|
12
11
|
// 依赖方向:本模块只依赖 shared 纯函数与 db 包实体查询(getEntity/updateEntity/softDeleteEntity/
|
|
13
|
-
//
|
|
12
|
+
// restoreEntity——scan 用),不依赖 route/middleware(避免循环依赖)。
|
|
14
13
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, openSync, fsyncSync, closeSync } from "node:fs";
|
|
15
14
|
import { join } from "node:path";
|
|
16
15
|
import { parseReferenceFrontmatter, serializeReferenceFile, } from "@whispering233/ai-editor-shared";
|
|
17
16
|
import { createEntity, getEntity, nowIso, restoreEntity, softDeleteEntity, updateEntity, } from "@whispering233/ai-editor-db";
|
|
18
|
-
/**
|
|
17
|
+
/** 参考资料目录(项目根下,书籍项目文件夹自包含参考资料) */
|
|
19
18
|
export const REFERENCE_DIR = "references";
|
|
20
|
-
/** 软删回收目录(references/.trash
|
|
19
|
+
/** 软删回收目录(references/.trash/,软删文件移入,restore 移回、purge 物理删) */
|
|
21
20
|
export const REFERENCE_TRASH_DIR = ".trash";
|
|
22
21
|
/** 文件 mtime 比对容差(毫秒):**仅防御 ISO 毫秒截断 roundtrip**(mtimeMs 浮点 → toISOString
|
|
23
22
|
* 毫秒截断 → getTime 可能差亚毫秒)。与备份体系 1s 容差语义相反——备份容差防「mtime 未刷新
|
|
24
23
|
* 误判有变更」,scan 容差过大会**漏检真实外部修改**(1s 内的改动检测不到),故取最小值。
|
|
25
24
|
* 应用内写入:writeFileAtomic 后 stat 与 scan 读取的 mtime 必然一致(同一文件),严格相等即可。 */
|
|
26
25
|
export const REFERENCE_MTIME_TOLERANCE_MS = 2;
|
|
27
|
-
/**
|
|
26
|
+
/** 原子写( 同款:临时文件 + fsync + rename;参考资料 md 文件同样禁止直接覆盖) */
|
|
28
27
|
export function writeFileAtomic(filePath, data) {
|
|
29
28
|
const tmp = `${filePath}.tmp`;
|
|
30
29
|
const fd = openSync(tmp, "w");
|
|
@@ -166,14 +165,14 @@ export function countUnsyncedReferenceFiles(root, db) {
|
|
|
166
165
|
return unsynced;
|
|
167
166
|
}
|
|
168
167
|
/**
|
|
169
|
-
* 扫描重建参考资料索引(POST /api/v1/reference/scan
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
168
|
+
* 扫描重建参考资料索引(POST /api/v1/reference/scan,)。
|
|
169
|
+
* 规则( + 2026-08 修订:软删文件归 .trash/,references/ 下缺失即视为外部删除):
|
|
170
|
+
* 1. 遍历 references/ 顶层 *.md(排除 .trash/):
|
|
171
|
+
* - 非软删索引匹配(kind='file' 且 file_name === 文件名)→ mtime 一致(容差内)跳过;
|
|
172
|
+
* 不一致 → 以文件为准更新(title/category/tags/content/file_mtime/updated_at)
|
|
173
|
+
* - 软删索引匹配 → 还原(deleted_at=NULL,文件留 references/ 原地)+ 更新数据
|
|
174
|
+
* - 无匹配 → 新建(title=frontmatter title ?? 文件名去扩展名、category ?? material)
|
|
175
|
+
* 2. 反向:非软删 file 类索引,references/ 下对应文件缺失 → 索引同步软删(进回收站可还原)
|
|
177
176
|
* 幂等:重复执行无副作用;只处理顶层文件。
|
|
178
177
|
*/
|
|
179
178
|
export function scanReferences(root, db) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-files.js","sourceRoot":"","sources":["../src/reference-files.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"reference-files.js","sourceRoot":"","sources":["../src/reference-files.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/chat.d.ts
CHANGED
|
@@ -3,20 +3,20 @@ import { type z } from "zod";
|
|
|
3
3
|
import { type AgentEvent, type ProposalStore, type RunAgentDeps, type ToolDispatcher } from "@whispering233/ai-editor-agent";
|
|
4
4
|
import type { LLMToolDefinition } from "@whispering233/ai-editor-llm";
|
|
5
5
|
import { type ToolDefinition } from "@whispering233/ai-editor-tools";
|
|
6
|
-
/**
|
|
6
|
+
/** 心跳间隔(15-30s 随机;测试经 deps.heartbeat 覆盖为毫秒级) */
|
|
7
7
|
export declare const DEFAULT_HEARTBEAT_MS: {
|
|
8
8
|
readonly minMs: 15000;
|
|
9
9
|
readonly maxMs: 30000;
|
|
10
10
|
};
|
|
11
|
-
/**
|
|
11
|
+
/** 续聊历史重建的条数上限(超限按尾部保留—— 的 token 裁剪由 S7.2 buildContext
|
|
12
12
|
* 按预算二次兜底,此处仅防御病态超长会话的加载开销) */
|
|
13
13
|
export declare const SESSION_HISTORY_MAX_MESSAGES = 2000;
|
|
14
14
|
/**
|
|
15
15
|
* 单个工具 argsSchema(zod)→ OpenAI 兼容 JSON Schema(LLMToolDefinition.parameters)。
|
|
16
16
|
* 方案:**zod 4 内置 toJSONSchema**(`import { toJSONSchema } from "zod"`,v4.4+ 自带,
|
|
17
17
|
* 无新增依赖)——33 个工具参数均为简单对象 + string/enum/array/record/literal/union 字段,
|
|
18
|
-
* 内置转换全覆盖且输出 draft 2020-12 合法 schema(`.strict
|
|
19
|
-
* `.refine
|
|
18
|
+
* 内置转换全覆盖且输出 draft 2020-12 合法 schema(`.strict` → additionalProperties:false、
|
|
19
|
+
* `.refine` 仅影响校验不改变类型 schema、`z.record` → propertyNames 形态)。
|
|
20
20
|
* 仅剥离顶层 `$schema` 关键字——OpenAI 兼容端点(含 DeepSeek)对 parameters 内未知关键字
|
|
21
21
|
* 存在严格模式拒绝风险,剥离后零风险(其余关键字为标准 JSON Schema 内容,兼容)。
|
|
22
22
|
*/
|
|
@@ -31,16 +31,16 @@ export declare function toLLMToolDefinitions(defs: readonly ToolDefinition[]): L
|
|
|
31
31
|
* [llm] 请求调试日志装饰器:给 produce 包一层(真实路径经
|
|
32
32
|
* `createLLMRequestLogger(createRealProduce(...), { model, tools })` 组装),对应类别开启时:
|
|
33
33
|
* - **request 日志**(类别 request):模型名 + 请求参数 + **完整 messages JSON(不截断——
|
|
34
|
-
*
|
|
34
|
+
* 用户核心诉求「最终组装的 prompt」)** + 工具名列表;每轮每次 attempt 各打一次(含重试)
|
|
35
35
|
* - **usage 日志**(类别 usage):onEvent 转发处捕获 finish 事件,打真实 token 数
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* (需求 3,流内真实 usage)——与 request **分开判定**(categories: ["request","usage"]
|
|
37
|
+
* 时只显示请求与 tokens 统计)
|
|
38
38
|
* - **敏感红线**:只打印请求体(messages 本身无 key——key 走 fetch header),
|
|
39
|
-
*
|
|
39
|
+
* 绝不打印 apiKey / headers
|
|
40
40
|
* - 两类别全关(request + usage 均未开启)时**零开销直通**:不包装 onEvent、不拼接字符串
|
|
41
41
|
* 独立成装饰器而非塞进 createRealProduce:测试可用 mock produce 直测日志层,
|
|
42
42
|
* 不经真实 DeepSeek 网络调用(与 createChatEventLogger 的「工厂 + 组合」同款模式)。
|
|
43
|
-
* 注:produce
|
|
43
|
+
* 注:produce (run.ts)不含 maxTokens/temperature(当前无对应配置),如实标注 <未设置>。
|
|
44
44
|
*/
|
|
45
45
|
export declare function createLLMRequestLogger(produce: RunAgentDeps["produce"], ctx: {
|
|
46
46
|
model: string;
|
|
@@ -54,7 +54,7 @@ export interface ChatRouteDeps {
|
|
|
54
54
|
dispatcher?: ToolDispatcher;
|
|
55
55
|
/** 提案仓(缺省 defaultProposalStore 单例——与 S7.5 confirm/reject 同仓;测试注入独立实例隔离) */
|
|
56
56
|
store?: ProposalStore;
|
|
57
|
-
/** 心跳间隔覆盖 ms(缺省 15-30s
|
|
57
|
+
/** 心跳间隔覆盖 ms(缺省 15-30s 随机,;测试注入毫秒级) */
|
|
58
58
|
heartbeat?: {
|
|
59
59
|
minMs: number;
|
|
60
60
|
maxMs: number;
|
|
@@ -63,7 +63,7 @@ export interface ChatRouteDeps {
|
|
|
63
63
|
now?: () => string;
|
|
64
64
|
/** 模型名覆盖(缺省设置页模型或 DEFAULT_MODEL) */
|
|
65
65
|
model?: string;
|
|
66
|
-
/** apiKey 覆盖(缺省 effectiveApiKey() 环境变量 >
|
|
66
|
+
/** apiKey 覆盖(缺省 effectiveApiKey() 环境变量 > 用户级配置) */
|
|
67
67
|
apiKey?: string;
|
|
68
68
|
/** 已转换工具定义覆盖(缺省 listTools → toLLMToolDefinitions) */
|
|
69
69
|
tools?: LLMToolDefinition[];
|
|
@@ -73,19 +73,19 @@ export interface ChatRouteDeps {
|
|
|
73
73
|
/**
|
|
74
74
|
* 创建 [chat] 事件调试日志器(对话链路调试,打到服务端终端 stdout/stderr;类别 chat):
|
|
75
75
|
* - 类别未开启(配置文件未列 chat 且 env 关)时零开销早退——不做任何字符串拼接
|
|
76
|
-
*
|
|
76
|
+
* (onEvent 高频路径无条件调用)
|
|
77
77
|
* - turn_start → 轮次;tool_call → 工具名 + 参数 JSON 摘要(截断);tool_result → 工具名 + 结果
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* - 注:AgentEvent.tool_result
|
|
81
|
-
*
|
|
78
|
+
* 摘要(截断);proposal → proposal_id + type;text → **只打 delta 长度**(流式高频防刷屏);
|
|
79
|
+
* done → sessionId + 轮次;error → code + message
|
|
80
|
+
* - 注:AgentEvent.tool_result (run.ts)不含 ok/isError 字段——工具成败已编码进 result
|
|
81
|
+
* 文本(失败为错误说明),日志只摘要该文本
|
|
82
82
|
*/
|
|
83
83
|
export declare function createChatEventLogger(): (event: AgentEvent) => void;
|
|
84
84
|
/**
|
|
85
85
|
* POST /chat 处理器工厂(测试经 createChatRoutes 注入 deps)。
|
|
86
86
|
* 流程:项目/请求校验(JSON 错误,不开流)→ 会话解析(历史重建或新建 sess_)→ 用户消息落库
|
|
87
|
-
*
|
|
88
|
-
* onEvent 转 SSE 帧、onMessages 落库)→
|
|
87
|
+
* → 三路断开检测挂接 → SSE 流内:心跳协程 + runAgent(produce/dispatcher 组装、
|
|
88
|
+
* onEvent 转 SSE 帧、onMessages 落库)→ 取消作废提案(B2 取舍见下)→ 关流。
|
|
89
89
|
*/
|
|
90
90
|
export declare function chatSendHandler(deps?: ChatRouteDeps): (c: Context) => Promise<Response>;
|
|
91
91
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAgB,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EAGjB,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAA+C,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACnH,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAsBhF,gDAAgD;AAChD,eAAO,MAAM,oBAAoB;;;CAA4C,CAAC;AAE9E;+BAC+B;AAC/B,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAIjD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIjF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,GAAG,iBAAiB,EAAE,CAQzF;AA0BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,iBAAiB,EAAE,CAAA;CAAE,GACjD,YAAY,CAAC,SAAS,CAAC,CA4BzB;AAID,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC7B,2DAA2D;IAC1D,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACnC,kFAAkF;IACjF,UAAU,CAAC,EAAE,cAAc,CAAC;IAC7B,2EAA2E;IAC1E,KAAK,CAAC,EAAE,aAAa,CAAC;IACvB,uCAAuC;IACtC,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,2CAA2C;IAC1C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACpB,oCAAoC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACpD,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,wDAAwD;IACvD,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAwED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CA6BnE;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,aAAkB,GAAG,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAwO3F;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,aAAkB,GAAG,IAAI,CAc/D;AAED,0CAA0C;AAC1C,eAAO,MAAM,UAAU,4EAAqB,CAAC"}
|