@chantezy/mcp-product-design 0.1.7 → 0.1.8
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/index.js +58 -3
- package/dist/index.js.map +1 -1
- package/dist/skill-loader.d.ts +13 -0
- package/dist/skill-loader.js +198 -8
- package/dist/skill-loader.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { listSkills, getSkill, getReference } from "./skill-loader.js";
|
|
5
|
+
import { listSkills, getSkill, getReference, routeIntent } from "./skill-loader.js";
|
|
6
6
|
import { readFileSync } from "fs";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
8
|
import { dirname, join } from "path";
|
|
@@ -12,7 +12,62 @@ const server = new McpServer({
|
|
|
12
12
|
name: "mcp-product-design",
|
|
13
13
|
version: pkg.version,
|
|
14
14
|
});
|
|
15
|
-
|
|
15
|
+
// ----- Tool: route_intent (Intent Router) -----
|
|
16
|
+
// Fast skill matching based on trigger + description. Does NOT load full skill content.
|
|
17
|
+
// Returns: best match (high confidence), top-3 candidates (medium confidence), or all skills (fallback).
|
|
18
|
+
server.tool("route_intent", "意图路由器:根据用户输入快速匹配最合适的产品设计技能。仅基于 trigger + description 做轻量级关键词匹配,不加载完整 Skill 内容。匹配策略:高置信度直接返回最佳技能,中置信度返回 top-3 候选,无法匹配时返回所有技能列表让用户选择。优先调用此工具做快速匹配,匹配后再调用 get_skill 获取完整内容。", {
|
|
19
|
+
user_intent: z
|
|
20
|
+
.string()
|
|
21
|
+
.describe("用户的原始意图描述或问题文本,例如 '我想写一份PRD'、'帮我做交互评估'"),
|
|
22
|
+
}, async ({ user_intent }) => {
|
|
23
|
+
const result = routeIntent(user_intent);
|
|
24
|
+
if (result.matched && result.best) {
|
|
25
|
+
// High confidence match
|
|
26
|
+
const best = result.best;
|
|
27
|
+
const text = `# 意图匹配结果:高置信度 ✅\n\n` +
|
|
28
|
+
`**输入意图:** ${user_intent}\n\n` +
|
|
29
|
+
`**推荐技能:** \`${best.name}\`\n\n` +
|
|
30
|
+
`**触发场景:** ${best.trigger || "(未设置)"}\n\n` +
|
|
31
|
+
`**描述:** ${best.description}\n\n` +
|
|
32
|
+
`---\n` +
|
|
33
|
+
`匹配分数:${result.scores?.[0]?.score ?? "N/A"},命中关键词:${result.scores?.[0]?.matchedKeywords.join("、") || "无"}\n\n` +
|
|
34
|
+
`**下一步:** 调用 \`get_skill\` 工具,参数 name="${best.name}" 获取完整工作流指令。`;
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: "text", text }],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (!result.fallback && result.candidates.length > 0) {
|
|
40
|
+
// Medium confidence: top-3 candidates
|
|
41
|
+
const lines = result.candidates.map((s, i) => {
|
|
42
|
+
const score = result.scores?.[i];
|
|
43
|
+
return (`### ${i + 1}. \`${s.name}\`\n` +
|
|
44
|
+
`- **触发场景:** ${s.trigger || "(未设置)"}\n` +
|
|
45
|
+
`- **描述:** ${s.description}\n` +
|
|
46
|
+
`- **匹配分数:** ${score?.score ?? "N/A"},命中:${score?.matchedKeywords.join("、") || "无"}`);
|
|
47
|
+
});
|
|
48
|
+
const text = `# 意图匹配结果:中置信度 ⚠️\n\n` +
|
|
49
|
+
`**输入意图:** ${user_intent}\n\n` +
|
|
50
|
+
`找到 ${result.candidates.length} 个候选技能,请根据具体需求选择:\n\n` +
|
|
51
|
+
lines.join("\n\n") +
|
|
52
|
+
`\n\n---\n**下一步:** 调用 \`get_skill\` 工具,参数 name="<选中的技能名>" 获取完整工作流指令。`;
|
|
53
|
+
return {
|
|
54
|
+
content: [{ type: "text", text }],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Fallback: no match, return all skills
|
|
58
|
+
const lines = result.candidates.map((s) => {
|
|
59
|
+
return `- **${s.name}** — ${s.trigger || s.description}`;
|
|
60
|
+
});
|
|
61
|
+
const text = `# 意图匹配结果:未找到匹配(兜底策略)\n\n` +
|
|
62
|
+
`**输入意图:** ${user_intent}\n\n` +
|
|
63
|
+
`无法明确匹配到具体技能,以下是全部 ${result.total} 个可用技能,请选择最合适的一个:\n\n` +
|
|
64
|
+
lines.join("\n") +
|
|
65
|
+
`\n\n---\n**下一步:** 调用 \`get_skill\` 工具,参数 name="<选中的技能名>" 获取完整工作流指令。`;
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: "text", text }],
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
server.tool("list_skills", "列出所有可用的产品设计技能及其触发条件。使用策略:1. 优先调用 route_intent 做意图匹配。2. 当用户明确指定技能时,直接调用 get_skill。3. 仅当需要浏览全部技能时才调用此工具。", {}, async () => {
|
|
16
71
|
const skills = listSkills();
|
|
17
72
|
if (skills.length === 0) {
|
|
18
73
|
return {
|
|
@@ -28,7 +83,7 @@ server.tool("list_skills", "列出所有可用的产品设计技能及其触发
|
|
|
28
83
|
const text = `# 可用产品设计技能 (${skills.length})\n\n` +
|
|
29
84
|
`请根据用户意图,选择最匹配的 skill 调用 \`get_skill\`:\n\n` +
|
|
30
85
|
lines.join("\n") +
|
|
31
|
-
`\n\n---\n使用 \`get_skill\`
|
|
86
|
+
`\n\n---\n使用 \`get_skill\` 工具并提供技能名称来获取完整的工作流程指令。\n使用 \`route_intent\` 工具传入用户意图,可自动匹配最合适的技能。`;
|
|
32
87
|
return {
|
|
33
88
|
content: [{ type: "text", text }],
|
|
34
89
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/skill-loader.d.ts
CHANGED
|
@@ -9,6 +9,19 @@ export interface SkillDetail extends SkillMeta {
|
|
|
9
9
|
body: string;
|
|
10
10
|
references: string[];
|
|
11
11
|
}
|
|
12
|
+
export interface RouteResult {
|
|
13
|
+
matched: boolean;
|
|
14
|
+
best?: SkillMeta;
|
|
15
|
+
candidates: SkillMeta[];
|
|
16
|
+
fallback: boolean;
|
|
17
|
+
total: number;
|
|
18
|
+
scores?: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
score: number;
|
|
21
|
+
matchedKeywords: string[];
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
12
24
|
export declare function listSkills(): SkillMeta[];
|
|
25
|
+
export declare function routeIntent(userIntent: string): RouteResult;
|
|
13
26
|
export declare function getSkill(name: string): SkillDetail | null;
|
|
14
27
|
export declare function getReference(name: string, ref: string): string | null;
|
package/dist/skill-loader.js
CHANGED
|
@@ -4,6 +4,40 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import * as yaml from "js-yaml";
|
|
5
5
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
6
|
const SKILLS_DIR = path.join(__dirname, "..", "skills");
|
|
7
|
+
// ----- LRU Cache for full skill details -----
|
|
8
|
+
// MCP Server 是常驻进程,缓存让重复 getSkill 调用跳过磁盘 IO。
|
|
9
|
+
const SKILL_CACHE_MAX = 32;
|
|
10
|
+
const skillDetailCache = new Map();
|
|
11
|
+
const skillDetailOrder = [];
|
|
12
|
+
function cachePut(key, value) {
|
|
13
|
+
if (skillDetailCache.has(key)) {
|
|
14
|
+
skillDetailCache.delete(key);
|
|
15
|
+
skillDetailCache.set(key, value);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (skillDetailCache.size >= SKILL_CACHE_MAX) {
|
|
19
|
+
const oldest = skillDetailOrder.shift();
|
|
20
|
+
if (oldest !== undefined) {
|
|
21
|
+
skillDetailCache.delete(oldest);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
skillDetailCache.set(key, value);
|
|
25
|
+
skillDetailOrder.push(key);
|
|
26
|
+
}
|
|
27
|
+
function cacheGet(key) {
|
|
28
|
+
const value = skillDetailCache.get(key);
|
|
29
|
+
if (value) {
|
|
30
|
+
// refresh recency
|
|
31
|
+
skillDetailCache.delete(key);
|
|
32
|
+
skillDetailCache.set(key, value);
|
|
33
|
+
const idx = skillDetailOrder.indexOf(key);
|
|
34
|
+
if (idx >= 0) {
|
|
35
|
+
skillDetailOrder.splice(idx, 1);
|
|
36
|
+
skillDetailOrder.push(key);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
7
41
|
function parseFrontmatter(content) {
|
|
8
42
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
9
43
|
if (!match) {
|
|
@@ -38,22 +72,33 @@ function sanitizeRef(ref) {
|
|
|
38
72
|
const sanitized = ref.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
39
73
|
return sanitized || null;
|
|
40
74
|
}
|
|
41
|
-
|
|
75
|
+
// ----- Lightweight metadata index (no full content) -----
|
|
76
|
+
// Built once on first access, cached for process lifetime.
|
|
77
|
+
let skillIndexCache = null;
|
|
78
|
+
function buildSkillIndex() {
|
|
79
|
+
if (skillIndexCache)
|
|
80
|
+
return skillIndexCache;
|
|
81
|
+
const skills = [];
|
|
42
82
|
if (!fs.existsSync(SKILLS_DIR)) {
|
|
43
|
-
|
|
83
|
+
skillIndexCache = skills;
|
|
84
|
+
return skills;
|
|
44
85
|
}
|
|
45
|
-
const skills = [];
|
|
46
86
|
const entries = fs.readdirSync(SKILLS_DIR);
|
|
47
87
|
for (const entry of entries) {
|
|
48
88
|
const entryPath = path.join(SKILLS_DIR, entry);
|
|
49
89
|
const skillMdPath = path.join(entryPath, "SKILL.md");
|
|
50
90
|
if (fs.statSync(entryPath).isDirectory() && fs.existsSync(skillMdPath)) {
|
|
51
|
-
|
|
52
|
-
const
|
|
91
|
+
// Only read frontmatter head (first ~1KB) to avoid loading entire file
|
|
92
|
+
const fd = fs.openSync(skillMdPath, "r");
|
|
93
|
+
const buf = Buffer.alloc(1024);
|
|
94
|
+
const bytesRead = fs.readSync(fd, buf, 0, 1024, 0);
|
|
95
|
+
fs.closeSync(fd);
|
|
96
|
+
const head = buf.subarray(0, bytesRead).toString("utf-8");
|
|
97
|
+
const { fm } = parseFrontmatter(head);
|
|
53
98
|
let trigger = fm.trigger || "";
|
|
54
99
|
// Auto-extract trigger from description if not explicitly set
|
|
55
100
|
if (!trigger && fm.description) {
|
|
56
|
-
const triggerMatch = fm.description.match(/当[
|
|
101
|
+
const triggerMatch = fm.description.match(/当[^触发]*?(?:时|触发)/);
|
|
57
102
|
if (triggerMatch) {
|
|
58
103
|
trigger = triggerMatch[0];
|
|
59
104
|
}
|
|
@@ -66,11 +111,154 @@ export function listSkills() {
|
|
|
66
111
|
});
|
|
67
112
|
}
|
|
68
113
|
}
|
|
114
|
+
skillIndexCache = skills;
|
|
69
115
|
return skills;
|
|
70
116
|
}
|
|
71
|
-
export function
|
|
117
|
+
export function listSkills() {
|
|
118
|
+
return buildSkillIndex();
|
|
119
|
+
}
|
|
120
|
+
// ----- Intent Router: keyword-based fast matching on trigger + description -----
|
|
121
|
+
// Tokenization for CJK + latin: split by non-word chars but keep CJK chars as singles.
|
|
122
|
+
function tokenize(text) {
|
|
123
|
+
if (!text)
|
|
124
|
+
return [];
|
|
125
|
+
const lower = text.toLowerCase();
|
|
126
|
+
// Extract CJK runs and latin words separately
|
|
127
|
+
const tokens = [];
|
|
128
|
+
const cjkRe = /[\u4e00-\u9fff]+/g;
|
|
129
|
+
const latinRe = /[a-z][a-z0-9_-]{1,}/g;
|
|
130
|
+
let m;
|
|
131
|
+
while ((m = cjkRe.exec(lower)) !== null) {
|
|
132
|
+
// For CJK runs, split into single chars AND bigrams for better recall
|
|
133
|
+
const run = m[0];
|
|
134
|
+
for (const ch of run)
|
|
135
|
+
tokens.push(ch);
|
|
136
|
+
for (let i = 0; i < run.length - 1; i++) {
|
|
137
|
+
tokens.push(run.substring(i, i + 2));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
while ((m = latinRe.exec(lower)) !== null) {
|
|
141
|
+
tokens.push(m[0]);
|
|
142
|
+
}
|
|
143
|
+
return tokens;
|
|
144
|
+
}
|
|
145
|
+
// Common Chinese stopwords (single char) to reduce noise
|
|
146
|
+
const STOPWORDS = new Set([
|
|
147
|
+
"的", "了", "是", "在", "和", "或", "与", "时", "当", "需", "要",
|
|
148
|
+
"一", "个", "些", "等", "中",
|
|
149
|
+
]);
|
|
150
|
+
function scoreSkill(skill, queryTokens) {
|
|
151
|
+
const nameTokens = tokenize(skill.name);
|
|
152
|
+
const triggerTokens = tokenize(skill.trigger + " " + skill.description);
|
|
153
|
+
const nameSet = new Set(nameTokens);
|
|
154
|
+
const triggerSet = new Set(triggerTokens);
|
|
155
|
+
let score = 0;
|
|
156
|
+
const matched = [];
|
|
157
|
+
const seenTokens = new Set();
|
|
158
|
+
for (const tok of queryTokens) {
|
|
159
|
+
if (tok.length < 2 && STOPWORDS.has(tok))
|
|
160
|
+
continue;
|
|
161
|
+
if (seenTokens.has(tok))
|
|
162
|
+
continue;
|
|
163
|
+
seenTokens.add(tok);
|
|
164
|
+
// Name match: high weight (5)
|
|
165
|
+
if (nameSet.has(tok)) {
|
|
166
|
+
score += 5;
|
|
167
|
+
matched.push(tok);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// Trigger/description match: medium weight (2)
|
|
171
|
+
if (triggerSet.has(tok)) {
|
|
172
|
+
score += 2;
|
|
173
|
+
matched.push(tok);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Partial substring match in trigger (CJK single char fallback): weight 1
|
|
177
|
+
if (tok.length >= 2 && (skill.trigger.includes(tok) || skill.description.includes(tok))) {
|
|
178
|
+
score += 1;
|
|
179
|
+
if (!matched.includes(tok))
|
|
180
|
+
matched.push(tok);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return { score, matchedKeywords: matched };
|
|
184
|
+
}
|
|
185
|
+
export function routeIntent(userIntent) {
|
|
72
186
|
const skills = listSkills();
|
|
187
|
+
if (skills.length === 0) {
|
|
188
|
+
return { matched: false, candidates: [], fallback: true, total: 0 };
|
|
189
|
+
}
|
|
190
|
+
const queryTokens = tokenize(userIntent);
|
|
191
|
+
// Empty query or very short → fallback to full list
|
|
192
|
+
if (queryTokens.length === 0) {
|
|
193
|
+
return {
|
|
194
|
+
matched: false,
|
|
195
|
+
candidates: skills,
|
|
196
|
+
fallback: true,
|
|
197
|
+
total: skills.length,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const scored = skills.map((s) => ({
|
|
201
|
+
skill: s,
|
|
202
|
+
...scoreSkill(s, queryTokens),
|
|
203
|
+
}));
|
|
204
|
+
scored.sort((a, b) => b.score - a.score);
|
|
205
|
+
const top = scored[0];
|
|
206
|
+
const second = scored[1];
|
|
207
|
+
// Score thresholds for confident match:
|
|
208
|
+
// - top score >= 4 (i.e. one name hit OR two trigger hits OR strong overlap)
|
|
209
|
+
// - and top strictly greater than second
|
|
210
|
+
const HIGH_CONFIDENCE = 4;
|
|
211
|
+
const isHighConfidence = top.score >= HIGH_CONFIDENCE &&
|
|
212
|
+
(second.score === 0 || top.score - second.score >= 2);
|
|
213
|
+
if (isHighConfidence) {
|
|
214
|
+
return {
|
|
215
|
+
matched: true,
|
|
216
|
+
best: top.skill,
|
|
217
|
+
candidates: [top.skill, ...(second.score > 0 ? [second.skill] : [])],
|
|
218
|
+
fallback: false,
|
|
219
|
+
total: skills.length,
|
|
220
|
+
scores: scored.slice(0, 5).map((s) => ({
|
|
221
|
+
name: s.skill.name,
|
|
222
|
+
score: s.score,
|
|
223
|
+
matchedKeywords: s.matchedKeywords,
|
|
224
|
+
})),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// Medium confidence: return top 3 candidates for the LLM/user to choose
|
|
228
|
+
const top3 = scored.filter((s) => s.score > 0).slice(0, 3);
|
|
229
|
+
if (top3.length > 0) {
|
|
230
|
+
return {
|
|
231
|
+
matched: false,
|
|
232
|
+
candidates: top3.map((s) => s.skill),
|
|
233
|
+
fallback: false,
|
|
234
|
+
total: skills.length,
|
|
235
|
+
scores: scored.slice(0, 5).map((s) => ({
|
|
236
|
+
name: s.skill.name,
|
|
237
|
+
score: s.score,
|
|
238
|
+
matchedKeywords: s.matchedKeywords,
|
|
239
|
+
})),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// No match at all → return ALL skills for user selection (fallback strategy)
|
|
243
|
+
return {
|
|
244
|
+
matched: false,
|
|
245
|
+
candidates: skills,
|
|
246
|
+
fallback: true,
|
|
247
|
+
total: skills.length,
|
|
248
|
+
scores: scored.slice(0, 5).map((s) => ({
|
|
249
|
+
name: s.skill.name,
|
|
250
|
+
score: s.score,
|
|
251
|
+
matchedKeywords: s.matchedKeywords,
|
|
252
|
+
})),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
export function getSkill(name) {
|
|
73
256
|
const normalized = name.toLowerCase().replace(/\s+/g, "-");
|
|
257
|
+
// Try cache first (by normalized key)
|
|
258
|
+
const cached = cacheGet(normalized);
|
|
259
|
+
if (cached)
|
|
260
|
+
return cached;
|
|
261
|
+
const skills = listSkills();
|
|
74
262
|
const skill = skills.find((s) => s.name === name ||
|
|
75
263
|
s.name === normalized ||
|
|
76
264
|
s.directory === name ||
|
|
@@ -90,7 +278,7 @@ export function getSkill(name) {
|
|
|
90
278
|
}
|
|
91
279
|
}
|
|
92
280
|
}
|
|
93
|
-
|
|
281
|
+
const detail = {
|
|
94
282
|
name: fm.name || skill.name,
|
|
95
283
|
description: fm.description || skill.description,
|
|
96
284
|
trigger: fm.trigger || skill.trigger || "",
|
|
@@ -99,6 +287,8 @@ export function getSkill(name) {
|
|
|
99
287
|
body,
|
|
100
288
|
references,
|
|
101
289
|
};
|
|
290
|
+
cachePut(normalized, detail);
|
|
291
|
+
return detail;
|
|
102
292
|
}
|
|
103
293
|
export function getReference(name, ref) {
|
|
104
294
|
const safeRef = sanitizeRef(ref);
|
package/dist/skill-loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../src/skill-loader.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../src/skill-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAExD,+CAA+C;AAC/C,6CAA6C;AAC7C,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;AACxD,MAAM,gBAAgB,GAAa,EAAE,CAAC;AAEtC,SAAS,QAAQ,CAAC,GAAW,EAAE,KAAkB;IAC/C,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IACD,IAAI,gBAAgB,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,kBAAkB;QAClB,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAChC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAqBD,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,EAAE,GAAgB,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,EAAE,GAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAiB,IAAI,EAAE,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC1D,IAAI,SAAS;YAAE,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,SAAS;YAAE,EAAE,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAChF,IAAI,YAAY;YAAE,EAAE,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,SAAS,IAAI,IAAI,CAAC;AAC3B,CAAC;AAWD,2DAA2D;AAC3D,2DAA2D;AAC3D,IAAI,eAAe,GAAuB,IAAI,CAAC;AAE/C,SAAS,eAAe;IACtB,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAE5C,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,eAAe,GAAG,MAAM,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACvE,uEAAuE;YACvE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACnD,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACjB,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,EAAE,EAAE,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,OAAO,GAAG,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;YAC/B,8DAA8D;YAC9D,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC/B,MAAM,YAAY,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAC9D,IAAI,YAAY,EAAE,CAAC;oBACjB,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,iBAAiB,CAAC,KAAK,CAAC;gBACzC,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE;gBACjC,OAAO;gBACP,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,eAAe,GAAG,MAAM,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,kFAAkF;AAClF,uFAAuF;AACvF,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,8CAA8C;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,mBAAmB,CAAC;IAClC,MAAM,OAAO,GAAG,sBAAsB,CAAC;IACvC,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,sEAAsE;QACtE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjB,KAAK,MAAM,EAAE,IAAI,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,yDAAyD;AACzD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IACrD,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACxB,CAAC,CAAC;AAEH,SAAS,UAAU,CACjB,KAAgB,EAChB,WAAqB;IAErB,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACnD,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAClC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,8BAA8B;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,+CAA+C;QAC/C,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,0EAA0E;QAC1E,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxF,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzC,oDAAoD;IACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,MAAM,CAAC,MAAM;SACrB,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChC,KAAK,EAAE,CAAC;QACR,GAAG,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC;KAC9B,CAAC,CAAC,CAAC;IACJ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAEzC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACzB,wCAAwC;IACxC,6EAA6E;IAC7E,yCAAyC;IACzC,MAAM,eAAe,GAAG,CAAC,CAAC;IAC1B,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,IAAI,eAAe;QACnD,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAExD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,GAAG,CAAC,KAAK;YACf,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpE,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;gBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,eAAe,EAAE,CAAC,CAAC,eAAe;aACnC,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACpC,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;gBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,eAAe,EAAE,CAAC,CAAC,eAAe;aACnC,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,OAAO;QACL,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,MAAM;QAClB,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;YAClB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,eAAe,EAAE,CAAC,CAAC,eAAe;SACnC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3D,sCAAsC;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,KAAK,IAAI;QACf,CAAC,CAAC,IAAI,KAAK,UAAU;QACrB,CAAC,CAAC,SAAS,KAAK,IAAI;QACpB,CAAC,CAAC,SAAS,KAAK,UAAU,CAC7B,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAgB;QAC1B,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;QAC3B,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW;QAChD,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE;QAC1C,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO;QACP,IAAI;QACJ,UAAU;KACX,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,GAAW;IACpD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,KAAK,IAAI;QACf,CAAC,CAAC,IAAI,KAAK,UAAU;QACrB,CAAC,CAAC,SAAS,KAAK,IAAI;QACpB,CAAC,CAAC,SAAS,KAAK,UAAU,CAC7B,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,UAAU,EACV,KAAK,CAAC,SAAS,EACf,YAAY,EACZ,GAAG,OAAO,KAAK,CAChB,CAAC;IACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,UAAU,EACV,KAAK,CAAC,SAAS,EACf,YAAY,EACZ,OAAO,CACR,CAAC;QACF,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
|