mcp-user-system 2.0.3 → 2.0.5
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/dist/env.js +3 -1
- package/dist/env.js.map +1 -1
- package/dist/tools/auth.d.ts +3 -1
- package/dist/tools/auth.js +26 -10
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/client.d.ts +3 -0
- package/dist/tools/client.js +56 -13
- package/dist/tools/client.js.map +1 -1
- package/dist/tools/crypto.d.ts +1 -0
- package/dist/tools/crypto.js +18 -0
- package/dist/tools/crypto.js.map +1 -0
- package/package.json +1 -1
package/dist/env.js
CHANGED
|
@@ -18,8 +18,10 @@ export function loadConfig() {
|
|
|
18
18
|
if (!accessToken && (!username || !password)) {
|
|
19
19
|
throw new Error("Authentication required: provide TUS_ACCESS_TOKEN, or both TUS_USERNAME and TUS_PASSWORD");
|
|
20
20
|
}
|
|
21
|
+
// 默认 http://localhost:7081,防止环境变量未正确传入时 baseUrl 为 "null"
|
|
22
|
+
const baseUrl = process.env["TUS_BASE_URL"] || "https://models.ipsunion.com/prod-api";
|
|
21
23
|
return {
|
|
22
|
-
baseUrl
|
|
24
|
+
baseUrl,
|
|
23
25
|
accessToken,
|
|
24
26
|
username,
|
|
25
27
|
password,
|
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAE7C,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAE7C,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,yDAAyD;IACzD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,sCAAsC,CAAC;IAEtF,OAAO;QACL,OAAO;QACP,WAAW;QACX,QAAQ;QACR,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
package/dist/tools/auth.d.ts
CHANGED
|
@@ -30,7 +30,9 @@ export declare const tools: ({
|
|
|
30
30
|
export declare function handle(name: string, args: Record<string, string>): Promise<unknown>;
|
|
31
31
|
/**
|
|
32
32
|
* 执行密码登录
|
|
33
|
-
* POST /console/user/login
|
|
33
|
+
* POST /console/user/login
|
|
34
|
+
* 前端 request 拦截器会将整个 JSON body AES 加密后以 { data: "<base64>" } 发送,
|
|
35
|
+
* 后端有对应的解密过滤器还原原始 body。MCP 需模拟相同行为。
|
|
34
36
|
* 响应格式: { code: 200, msg: "操作成功", token: "eyJ..." }
|
|
35
37
|
*/
|
|
36
38
|
export declare function doLogin(username: string, password: string): Promise<unknown>;
|
package/dist/tools/auth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { apiPostRaw, setToken, getToken } from "./client.js";
|
|
2
2
|
import { loadConfig } from "../env.js";
|
|
3
|
+
import { aesEncrypt } from "./crypto.js";
|
|
3
4
|
// ---- 工具定义 ----
|
|
4
5
|
export const tools = [
|
|
5
6
|
{
|
|
@@ -39,21 +40,36 @@ export async function handle(name, args) {
|
|
|
39
40
|
// ---- 内部函数 ----
|
|
40
41
|
/**
|
|
41
42
|
* 执行密码登录
|
|
42
|
-
* POST /console/user/login
|
|
43
|
+
* POST /console/user/login
|
|
44
|
+
* 前端 request 拦截器会将整个 JSON body AES 加密后以 { data: "<base64>" } 发送,
|
|
45
|
+
* 后端有对应的解密过滤器还原原始 body。MCP 需模拟相同行为。
|
|
43
46
|
* 响应格式: { code: 200, msg: "操作成功", token: "eyJ..." }
|
|
44
47
|
*/
|
|
45
48
|
export async function doLogin(username, password) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
// 构造原始请求体(与前端登录组件一致)
|
|
50
|
+
const plainBody = { username, password, loginSms: false };
|
|
51
|
+
// AES-128-CBC 加密整个 JSON body → Base64
|
|
52
|
+
const encryptedData = aesEncrypt(JSON.stringify(plainBody));
|
|
53
|
+
// 以 { data: "<encrypted>" } 格式发送(与前端 request.js 拦截器行为一致)
|
|
54
|
+
const response = await apiPostRaw("/console/user/login", { data: encryptedData });
|
|
55
|
+
// Debug: 打印完整后端响应
|
|
56
|
+
if (process.env.TUS_DEBUG) {
|
|
57
|
+
console.error("[MCP-DEBUG] login 响应:", JSON.stringify(response).slice(0, 1000));
|
|
53
58
|
}
|
|
54
|
-
|
|
59
|
+
// 兼容多种响应格式:
|
|
60
|
+
// 格式1: { code: 200, msg: "操作成功", token: "eyJ..." } (AjaxResult.put)
|
|
61
|
+
// 格式2: { code: 200, msg: "操作成功", data: { token: "eyJ..." } }
|
|
62
|
+
// 格式3: { code: 200, data: "eyJ..." } (token 直接作为 data)
|
|
63
|
+
const code = response.code;
|
|
64
|
+
if (code !== undefined && code !== 200) {
|
|
65
|
+
throw new Error(`登录失败 (${code}): ${response.msg}`);
|
|
66
|
+
}
|
|
67
|
+
// 从多个位置尝试获取 token
|
|
68
|
+
const token = response.token ?? response.data?.token ?? (typeof response.data === "string" ? response.data : undefined);
|
|
55
69
|
if (!token) {
|
|
56
|
-
|
|
70
|
+
// 打印完整响应帮助调试
|
|
71
|
+
const keys = Object.keys(response);
|
|
72
|
+
throw new Error(`登录成功但未返回 token,响应字段: [${keys.join(", ")}],完整响应: ${JSON.stringify(response).slice(0, 500)}`);
|
|
57
73
|
}
|
|
58
74
|
setToken(token);
|
|
59
75
|
return {
|
package/dist/tools/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/client.d.ts
CHANGED
|
@@ -8,14 +8,17 @@ export declare function getToken(): string | undefined;
|
|
|
8
8
|
export declare function setToken(token: string): void;
|
|
9
9
|
/**
|
|
10
10
|
* 发起 GET 请求
|
|
11
|
+
* 与前端 request.js 一致:params 加密后作为 ?data=<encrypted> 发送
|
|
11
12
|
*/
|
|
12
13
|
export declare function apiGet<T = unknown>(path: string, params?: Record<string, string | undefined>): Promise<T>;
|
|
13
14
|
/**
|
|
14
15
|
* 发起 GET 请求,返回分页数据(TableDataInfo 格式)
|
|
16
|
+
* 与前端 request.js 一致:params 加密后作为 ?data=<encrypted> 发送
|
|
15
17
|
*/
|
|
16
18
|
export declare function apiGetPage<T = unknown>(path: string, params?: Record<string, string | undefined>): Promise<TableDataInfo<T>>;
|
|
17
19
|
/**
|
|
18
20
|
* 发起 POST 请求(携带 Authorization 头)
|
|
21
|
+
* 与前端 request.js 一致:body 加密后以 { data: "<encrypted>" } 发送
|
|
19
22
|
*/
|
|
20
23
|
export declare function apiPost<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
21
24
|
/**
|
package/dist/tools/client.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { loadConfig } from "../env.js";
|
|
2
2
|
import { tryRelogin } from "./auth.js";
|
|
3
|
+
import { aesEncrypt } from "./crypto.js";
|
|
4
|
+
// ── Debug logging ──
|
|
5
|
+
function debugLog(label, ...args) {
|
|
6
|
+
if (process.env.TUS_DEBUG) {
|
|
7
|
+
console.error(`[MCP-DEBUG] ${label}`, ...args);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
3
10
|
// ── Token management ──
|
|
4
11
|
let currentToken = loadConfig().accessToken;
|
|
5
12
|
export function getToken() {
|
|
@@ -11,16 +18,25 @@ export function setToken(token) {
|
|
|
11
18
|
// ── Helpers ──
|
|
12
19
|
function getBaseUrl() {
|
|
13
20
|
const config = loadConfig();
|
|
14
|
-
|
|
21
|
+
// 后端所有接口均在 /api 路径下
|
|
22
|
+
return config.baseUrl.replace(/\/+$/, "") + "/api";
|
|
15
23
|
}
|
|
24
|
+
// ── 标准请求头(与前端 request.js 拦截器一致) ──
|
|
25
|
+
const COMMON_HEADERS = {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"Crypto-Version": "1.0.0",
|
|
28
|
+
"accountType": "S_",
|
|
29
|
+
"platformType": "WEB_",
|
|
30
|
+
"DeviceType": "browser",
|
|
31
|
+
};
|
|
16
32
|
function getAuthHeaders() {
|
|
17
33
|
const token = currentToken ?? loadConfig().accessToken;
|
|
18
34
|
if (!token) {
|
|
19
35
|
throw new Error("未登录,请先使用 login 工具登录,或在环境变量中配置 TUS_ACCESS_TOKEN");
|
|
20
36
|
}
|
|
21
37
|
return {
|
|
38
|
+
...COMMON_HEADERS,
|
|
22
39
|
"Authorization": `Bearer ${token}`,
|
|
23
|
-
"Content-Type": "application/json",
|
|
24
40
|
};
|
|
25
41
|
}
|
|
26
42
|
/**
|
|
@@ -60,19 +76,26 @@ async function withAutoRetry(requestFn) {
|
|
|
60
76
|
}
|
|
61
77
|
/**
|
|
62
78
|
* 发起 GET 请求
|
|
79
|
+
* 与前端 request.js 一致:params 加密后作为 ?data=<encrypted> 发送
|
|
63
80
|
*/
|
|
64
81
|
export async function apiGet(path, params) {
|
|
65
82
|
return withAutoRetry(async () => {
|
|
66
|
-
|
|
83
|
+
// 构建参数对象(过滤空值)
|
|
84
|
+
const cleanParams = {};
|
|
67
85
|
if (params) {
|
|
68
86
|
for (const [key, value] of Object.entries(params)) {
|
|
69
87
|
if (value !== undefined && value !== "") {
|
|
70
|
-
|
|
88
|
+
cleanParams[key] = value;
|
|
71
89
|
}
|
|
72
90
|
}
|
|
73
91
|
}
|
|
74
|
-
|
|
75
|
-
|
|
92
|
+
// 加密参数:JSON → AES → Base64 → ?data=<encrypted>
|
|
93
|
+
// 注意:与前端一致,不做 encodeURIComponent,后端用 replace(" ","+") 补偿
|
|
94
|
+
const hasParams = Object.keys(cleanParams).length > 0;
|
|
95
|
+
const url = hasParams
|
|
96
|
+
? `${getBaseUrl()}${path}?data=${aesEncrypt(JSON.stringify(cleanParams))}`
|
|
97
|
+
: `${getBaseUrl()}${path}`;
|
|
98
|
+
debugLog(`GET ${url}`);
|
|
76
99
|
const controller = new AbortController();
|
|
77
100
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
78
101
|
try {
|
|
@@ -82,6 +105,7 @@ export async function apiGet(path, params) {
|
|
|
82
105
|
signal: controller.signal,
|
|
83
106
|
});
|
|
84
107
|
const text = await res.text();
|
|
108
|
+
debugLog(`GET ${path} → ${res.status}`, text.slice(0, 500));
|
|
85
109
|
if (!res.ok) {
|
|
86
110
|
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
87
111
|
}
|
|
@@ -102,19 +126,26 @@ export async function apiGet(path, params) {
|
|
|
102
126
|
}
|
|
103
127
|
/**
|
|
104
128
|
* 发起 GET 请求,返回分页数据(TableDataInfo 格式)
|
|
129
|
+
* 与前端 request.js 一致:params 加密后作为 ?data=<encrypted> 发送
|
|
105
130
|
*/
|
|
106
131
|
export async function apiGetPage(path, params) {
|
|
107
132
|
return withAutoRetry(async () => {
|
|
108
|
-
|
|
133
|
+
// 构建参数对象(过滤空值)
|
|
134
|
+
const cleanParams = {};
|
|
109
135
|
if (params) {
|
|
110
136
|
for (const [key, value] of Object.entries(params)) {
|
|
111
137
|
if (value !== undefined && value !== "") {
|
|
112
|
-
|
|
138
|
+
cleanParams[key] = value;
|
|
113
139
|
}
|
|
114
140
|
}
|
|
115
141
|
}
|
|
116
|
-
|
|
117
|
-
|
|
142
|
+
// 加密参数:JSON → AES → Base64 → ?data=<encrypted>
|
|
143
|
+
// 注意:与前端一致,不做 encodeURIComponent,后端用 replace(" ","+") 补偿
|
|
144
|
+
const hasParams = Object.keys(cleanParams).length > 0;
|
|
145
|
+
const url = hasParams
|
|
146
|
+
? `${getBaseUrl()}${path}?data=${aesEncrypt(JSON.stringify(cleanParams))}`
|
|
147
|
+
: `${getBaseUrl()}${path}`;
|
|
148
|
+
debugLog(`GET(page) ${url}`);
|
|
118
149
|
const controller = new AbortController();
|
|
119
150
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
120
151
|
try {
|
|
@@ -124,6 +155,7 @@ export async function apiGetPage(path, params) {
|
|
|
124
155
|
signal: controller.signal,
|
|
125
156
|
});
|
|
126
157
|
const text = await res.text();
|
|
158
|
+
debugLog(`GET(page) ${path} → ${res.status}`, text.slice(0, 500));
|
|
127
159
|
if (!res.ok) {
|
|
128
160
|
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
129
161
|
}
|
|
@@ -140,20 +172,28 @@ export async function apiGetPage(path, params) {
|
|
|
140
172
|
}
|
|
141
173
|
/**
|
|
142
174
|
* 发起 POST 请求(携带 Authorization 头)
|
|
175
|
+
* 与前端 request.js 一致:body 加密后以 { data: "<encrypted>" } 发送
|
|
143
176
|
*/
|
|
144
177
|
export async function apiPost(path, body) {
|
|
145
178
|
return withAutoRetry(async () => {
|
|
146
179
|
const url = `${getBaseUrl()}${path}`;
|
|
180
|
+
// 加密 body:JSON → AES → Base64 → { data: "<encrypted>" }
|
|
181
|
+
const encryptedBody = body
|
|
182
|
+
? { data: aesEncrypt(JSON.stringify(body)) }
|
|
183
|
+
: undefined;
|
|
184
|
+
const bodyStr = encryptedBody ? JSON.stringify(encryptedBody) : undefined;
|
|
185
|
+
debugLog(`POST ${url}`, body ? `原始: ${JSON.stringify(body).slice(0, 300)}` : "(无body)");
|
|
147
186
|
const controller = new AbortController();
|
|
148
187
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
149
188
|
try {
|
|
150
189
|
const res = await fetch(url, {
|
|
151
190
|
method: "POST",
|
|
152
191
|
headers: getAuthHeaders(),
|
|
153
|
-
body:
|
|
192
|
+
body: bodyStr,
|
|
154
193
|
signal: controller.signal,
|
|
155
194
|
});
|
|
156
195
|
const text = await res.text();
|
|
196
|
+
debugLog(`POST ${path} → ${res.status}`, text.slice(0, 500));
|
|
157
197
|
if (!res.ok) {
|
|
158
198
|
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
159
199
|
}
|
|
@@ -174,16 +214,19 @@ export async function apiPost(path, body) {
|
|
|
174
214
|
*/
|
|
175
215
|
export async function apiPostRaw(path, body) {
|
|
176
216
|
const url = `${getBaseUrl()}${path}`;
|
|
217
|
+
const bodyStr = body ? JSON.stringify(body) : undefined;
|
|
218
|
+
debugLog(`POST(raw) ${url}`, bodyStr?.slice(0, 500));
|
|
177
219
|
const controller = new AbortController();
|
|
178
220
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
179
221
|
try {
|
|
180
222
|
const res = await fetch(url, {
|
|
181
223
|
method: "POST",
|
|
182
|
-
headers:
|
|
183
|
-
body:
|
|
224
|
+
headers: COMMON_HEADERS,
|
|
225
|
+
body: bodyStr,
|
|
184
226
|
signal: controller.signal,
|
|
185
227
|
});
|
|
186
228
|
const text = await res.text();
|
|
229
|
+
debugLog(`POST(raw) ${path} → ${res.status}`, text.slice(0, 500));
|
|
187
230
|
if (!res.ok) {
|
|
188
231
|
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
189
232
|
}
|
package/dist/tools/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/tools/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/tools/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function aesEncrypt(data: string): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-128-CBC 加密工具(与前端 crypto-js 保持一致)
|
|
3
|
+
*
|
|
4
|
+
* Key: 'Kvz4P00D79JiXdM8' (16 字节)
|
|
5
|
+
* IV: 同 Key
|
|
6
|
+
* Padding: PKCS7
|
|
7
|
+
* 输出: Base64
|
|
8
|
+
*/
|
|
9
|
+
import { createCipheriv } from "crypto";
|
|
10
|
+
const AES_KEY = "Kvz4P00D79JiXdM8";
|
|
11
|
+
export function aesEncrypt(data) {
|
|
12
|
+
const key = Buffer.from(AES_KEY, "latin1");
|
|
13
|
+
const iv = key; // 前端 iv = key
|
|
14
|
+
const cipher = createCipheriv("aes-128-cbc", key, iv);
|
|
15
|
+
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
16
|
+
return encrypted.toString("base64");
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/tools/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,OAAO,GAAG,kBAAkB,CAAC;AAEnC,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,cAAc;IAC9B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/E,OAAO,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
|