dsh-codegraph-visualizer 0.1.1 → 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/README.md +391 -226
- package/assets/icon-180.png +0 -0
- package/assets/icon.svg +30 -0
- package/cordis.patch.yml +22 -17
- package/dist/CodeGraphAdapter-C8JvcS7m.js +10 -0
- package/dist/CodeGraphAdapter-eyrhs0K0.js +422 -0
- package/dist/CodeGraphAdapter-eyrhs0K0.js.map +1 -0
- package/dist/FileSystemAdapter-CgasSGbB.js +524 -0
- package/dist/FileSystemAdapter-CgasSGbB.js.map +1 -0
- package/dist/LensAdapter-C9Saf_i_.js +89 -0
- package/dist/LensAdapter-C9Saf_i_.js.map +1 -0
- package/dist/Logger-DUIJSeNu.js +80 -0
- package/dist/Logger-DUIJSeNu.js.map +1 -0
- package/dist/TreeSitterAdapter-C-EWy8br.js +631 -0
- package/dist/TreeSitterAdapter-C-EWy8br.js.map +1 -0
- package/dist/TreeSitterAdapter-C6FcO2_s.js +8 -0
- package/dist/client/index.css +8900 -1777
- package/dist/client/index.css.map +1 -0
- package/dist/client/index.d.ts +634 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.esm.js +57219 -20978
- package/dist/client/index.js.map +1 -0
- package/dist/client/{index.js → worker/layoutWorker.js} +7657 -8787
- package/dist/client.js +90067 -0
- package/dist/codeGraphDb-BT9nZCEO.js +357 -0
- package/dist/codeGraphDb-BT9nZCEO.js.map +1 -0
- package/dist/codeGraphDb-Bg7bWud2.js +9 -0
- package/dist/codeGraphRows-BhZX34uB.js +6 -0
- package/dist/codeGraphRows-C7hqu35E.js +246 -0
- package/dist/codeGraphRows-C7hqu35E.js.map +1 -0
- package/dist/constants-CQq93l3e.js +399 -0
- package/dist/constants-CQq93l3e.js.map +1 -0
- package/dist/graphFingerprint-CeARo7jG.js +4 -0
- package/dist/graphFingerprint-PuxORZUF.js +277 -0
- package/dist/graphFingerprint-PuxORZUF.js.map +1 -0
- package/dist/graphMetrics-C0F30730.js +555 -0
- package/dist/graphMetrics-C0F30730.js.map +1 -0
- package/dist/index.d.ts +572 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14734 -2003
- package/dist/index.js.map +1 -1
- package/dist/inheritanceEnhancer-Bi3UoYJS.js +291 -0
- package/dist/inheritanceEnhancer-Bi3UoYJS.js.map +1 -0
- package/dist/layerUtils-DDm-EsaD.js +72 -0
- package/dist/layerUtils-DDm-EsaD.js.map +1 -0
- package/dist/nativeIndex-Cx7RLXUp.js +5 -0
- package/dist/nativeIndex-DlSpD611.js +347 -0
- package/dist/nativeIndex-DlSpD611.js.map +1 -0
- package/dist/treeSitterExtractors-B1ybKNrC.js +394 -0
- package/dist/treeSitterExtractors-B1ybKNrC.js.map +1 -0
- package/dist/types-BUDxI_00.js +23 -0
- package/dist/types-BUDxI_00.js.map +1 -0
- package/locale/en.json +6 -0
- package/locale/zh-CN.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +100 -20
- package/dist/client-cjs/index.cjs +0 -44283
- package/dist/client-cjs/index.css +0 -2404
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { EdgeId, NodeId } from "./types-BUDxI_00.js";
|
|
2
|
+
import "./constants-CQq93l3e.js";
|
|
3
|
+
import { scoped } from "./Logger-DUIJSeNu.js";
|
|
4
|
+
import { inferLayerFromPath } from "./layerUtils-DDm-EsaD.js";
|
|
5
|
+
|
|
6
|
+
//#region src/adapters/LensAdapter.ts
|
|
7
|
+
const log = scoped("lens-adapter");
|
|
8
|
+
var LensAdapter = class {
|
|
9
|
+
source = "lens";
|
|
10
|
+
async fetchData(repoId, invoke) {
|
|
11
|
+
try {
|
|
12
|
+
const raw = await invoke("lens_analyze", { repoId });
|
|
13
|
+
if (!raw) return {
|
|
14
|
+
nodes: [],
|
|
15
|
+
edges: [],
|
|
16
|
+
source: this.source,
|
|
17
|
+
timestamp: Date.now()
|
|
18
|
+
};
|
|
19
|
+
const symbols = Array.isArray(raw.symbols) ? raw.symbols : [];
|
|
20
|
+
const references = Array.isArray(raw.references) ? raw.references : [];
|
|
21
|
+
const fileNodeMap = new Map();
|
|
22
|
+
for (const s of symbols) if (s.category === "module" || s.category === "file") fileNodeMap.set(s.file, s.id);
|
|
23
|
+
const nodes = symbols.map((s) => {
|
|
24
|
+
const parentId = s.category !== "module" && s.category !== "file" ? fileNodeMap.get(s.file) : void 0;
|
|
25
|
+
return {
|
|
26
|
+
id: NodeId(s.id),
|
|
27
|
+
label: s.name,
|
|
28
|
+
type: this.mapCategory(s.category),
|
|
29
|
+
filePath: s.file,
|
|
30
|
+
lineNumber: s.line,
|
|
31
|
+
properties: { scope: s.scope },
|
|
32
|
+
...parentId ? { parentId: NodeId(parentId) } : {},
|
|
33
|
+
layer: inferLayerFromPath(s.file)
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const edges = references.map((r) => {
|
|
37
|
+
const edgeType = this.mapRelation(r.relation);
|
|
38
|
+
return {
|
|
39
|
+
id: EdgeId(`${r.from}->${r.to}:${edgeType}`),
|
|
40
|
+
source: NodeId(r.from),
|
|
41
|
+
target: NodeId(r.to),
|
|
42
|
+
type: edgeType,
|
|
43
|
+
properties: {}
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
nodes,
|
|
48
|
+
edges,
|
|
49
|
+
source: this.source,
|
|
50
|
+
timestamp: Date.now()
|
|
51
|
+
};
|
|
52
|
+
} catch (e) {
|
|
53
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
54
|
+
log.warn("Lens fetchData failed — lens is optional, returning empty", e);
|
|
55
|
+
return {
|
|
56
|
+
nodes: [],
|
|
57
|
+
edges: [],
|
|
58
|
+
source: this.source,
|
|
59
|
+
timestamp: Date.now(),
|
|
60
|
+
error: errorMsg
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
mapCategory(cat) {
|
|
65
|
+
const map = {
|
|
66
|
+
function: "function",
|
|
67
|
+
class: "class",
|
|
68
|
+
variable: "variable",
|
|
69
|
+
module: "module",
|
|
70
|
+
interface: "interface",
|
|
71
|
+
type: "type"
|
|
72
|
+
};
|
|
73
|
+
return map[cat] ?? "module";
|
|
74
|
+
}
|
|
75
|
+
mapRelation(rel) {
|
|
76
|
+
const map = {
|
|
77
|
+
call: "call",
|
|
78
|
+
reference: "dependency",
|
|
79
|
+
import: "import",
|
|
80
|
+
extend: "extend",
|
|
81
|
+
implement: "implement"
|
|
82
|
+
};
|
|
83
|
+
return map[rel] ?? "dependency";
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
export { LensAdapter };
|
|
89
|
+
//# sourceMappingURL=LensAdapter-C9Saf_i_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LensAdapter-C9Saf_i_.js","names":["repoId: string","invoke: UpstreamInvoker","nodes: GraphNode[]","edges: GraphEdge[]","cat: string","map: Record<string, GraphNode['type']>","rel: string","map: Record<string, GraphEdge['type']>"],"sources":["../src/adapters/LensAdapter.ts"],"sourcesContent":["// LensAdapter - adapter for the optional dsh-tool-lens data source.\r\nimport type { GraphNode, GraphEdge, AdapterResult, DataSourceType } from '../types/index.ts';\r\nimport { NodeId, EdgeId } from '../types/index.ts';\r\nimport type { IDataAdapter, UpstreamInvoker } from './IAdapter.ts';\r\nimport { scoped } from '../shared/Logger.ts';\r\nimport { inferLayerFromPath } from '../shared/layerUtils.ts';\r\n\r\nconst log = scoped('lens-adapter');\r\n\r\ninterface LensToolResult {\r\n symbols: Array<{\r\n id: string;\r\n name: string;\r\n scope: string;\r\n file: string;\r\n line: number;\r\n category: string;\r\n }>;\r\n references: Array<{\r\n from: string;\r\n to: string;\r\n relation: string;\r\n }>;\r\n}\r\n\r\n\r\nexport class LensAdapter implements IDataAdapter {\r\n readonly source: DataSourceType = 'lens';\r\n\r\n async fetchData(repoId: string, invoke: UpstreamInvoker): Promise<AdapterResult> {\r\n try {\r\n const raw = (await invoke('lens_analyze', { repoId })) as LensToolResult | null;\r\n if (!raw) return { nodes: [], edges: [], source: this.source, timestamp: Date.now() };\r\n\r\n const symbols = Array.isArray(raw.symbols) ? raw.symbols : [];\r\n const references = Array.isArray(raw.references) ? raw.references : [];\r\n\r\n const fileNodeMap = new Map<string, string>();\r\n for (const s of symbols) {\r\n if (s.category === 'module' || s.category === 'file') {\r\n fileNodeMap.set(s.file, s.id);\r\n }\r\n }\r\n\r\n const nodes: GraphNode[] = symbols.map((s) => {\r\n const parentId = (s.category !== 'module' && s.category !== 'file')\r\n ? fileNodeMap.get(s.file)\r\n : undefined;\r\n return {\r\n id: NodeId(s.id),\r\n label: s.name,\r\n type: this.mapCategory(s.category),\r\n filePath: s.file,\r\n lineNumber: s.line,\r\n properties: { scope: s.scope },\r\n ...(parentId ? { parentId: NodeId(parentId) } : {}),\r\n layer: inferLayerFromPath(s.file),\r\n };\r\n });\r\n\r\n const edges: GraphEdge[] = references.map((r) => {\r\n const edgeType = this.mapRelation(r.relation);\r\n return {\r\n id: EdgeId(`${r.from}->${r.to}:${edgeType}`),\r\n source: NodeId(r.from),\r\n target: NodeId(r.to),\r\n type: edgeType,\r\n properties: {},\r\n };\r\n });\r\n\r\n return { nodes, edges, source: this.source, timestamp: Date.now() };\r\n } catch (e) {\r\n const errorMsg = e instanceof Error ? e.message : String(e);\r\n log.warn('Lens fetchData failed — lens is optional, returning empty', e);\r\n return { nodes: [], edges: [], source: this.source, timestamp: Date.now(), error: errorMsg };\r\n }\r\n }\r\n\r\n private mapCategory(cat: string): GraphNode['type'] {\r\n const map: Record<string, GraphNode['type']> = {\r\n function: 'function',\r\n class: 'class',\r\n variable: 'variable',\r\n module: 'module',\r\n interface: 'interface',\r\n type: 'type',\r\n };\r\n return map[cat] ?? 'module';\r\n }\r\n\r\n private mapRelation(rel: string): GraphEdge['type'] {\r\n const map: Record<string, GraphEdge['type']> = {\r\n call: 'call',\r\n reference: 'dependency',\r\n import: 'import',\r\n extend: 'extend',\r\n implement: 'implement',\r\n };\r\n return map[rel] ?? 'dependency';\r\n }\r\n}"],"mappings":";;;;;;AAOA,MAAM,MAAM,OAAO,eAAe;AAmBlC,IAAa,cAAb,MAAiD;CAC/C,AAAS,SAAyB;CAElC,MAAM,UAAUA,QAAgBC,QAAiD;AAC/E,MAAI;GACF,MAAM,MAAO,MAAM,OAAO,gBAAgB,EAAE,OAAQ,EAAC;AACrD,QAAK,IAAK,QAAO;IAAE,OAAO,CAAE;IAAE,OAAO,CAAE;IAAE,QAAQ,KAAK;IAAQ,WAAW,KAAK,KAAK;GAAE;GAErF,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,GAAG,IAAI,UAAU,CAAE;GAC7D,MAAM,aAAa,MAAM,QAAQ,IAAI,WAAW,GAAG,IAAI,aAAa,CAAE;GAEtE,MAAM,cAAc,IAAI;AACxB,QAAK,MAAM,KAAK,QACd,KAAI,EAAE,aAAa,YAAY,EAAE,aAAa,OAC5C,aAAY,IAAI,EAAE,MAAM,EAAE,GAAG;GAIjC,MAAMC,QAAqB,QAAQ,IAAI,CAAC,MAAM;IAC5C,MAAM,WAAY,EAAE,aAAa,YAAY,EAAE,aAAa,SACxD,YAAY,IAAI,EAAE,KAAK;AAE3B,WAAO;KACL,IAAI,OAAO,EAAE,GAAG;KAChB,OAAO,EAAE;KACT,MAAM,KAAK,YAAY,EAAE,SAAS;KAClC,UAAU,EAAE;KACZ,YAAY,EAAE;KACd,YAAY,EAAE,OAAO,EAAE,MAAO;KAC9B,GAAI,WAAW,EAAE,UAAU,OAAO,SAAS,CAAE,IAAG,CAAE;KAClD,OAAO,mBAAmB,EAAE,KAAK;IAClC;GACF,EAAC;GAEF,MAAMC,QAAqB,WAAW,IAAI,CAAC,MAAM;IAC/C,MAAM,WAAW,KAAK,YAAY,EAAE,SAAS;AAC7C,WAAO;KACL,IAAI,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,SAAS,EAAE;KAC5C,QAAQ,OAAO,EAAE,KAAK;KACtB,QAAQ,OAAO,EAAE,GAAG;KACpB,MAAM;KACN,YAAY,CAAE;IACf;GACF,EAAC;AAEF,UAAO;IAAE;IAAO;IAAO,QAAQ,KAAK;IAAQ,WAAW,KAAK,KAAK;GAAE;EACpE,SAAQ,GAAG;GACV,MAAM,WAAW,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AAC3D,OAAI,KAAK,6DAA6D,EAAE;AACxE,UAAO;IAAE,OAAO,CAAE;IAAE,OAAO,CAAE;IAAE,QAAQ,KAAK;IAAQ,WAAW,KAAK,KAAK;IAAE,OAAO;GAAU;EAC7F;CACF;CAED,AAAQ,YAAYC,KAAgC;EAClD,MAAMC,MAAyC;GAC7C,UAAU;GACV,OAAO;GACP,UAAU;GACV,QAAQ;GACR,WAAW;GACX,MAAM;EACP;AACD,SAAO,IAAI,QAAQ;CACpB;CAED,AAAQ,YAAYC,KAAgC;EAClD,MAAMC,MAAyC;GAC7C,MAAM;GACN,WAAW;GACX,QAAQ;GACR,QAAQ;GACR,WAAW;EACZ;AACD,SAAO,IAAI,QAAQ;CACpB;AACF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LOGGER } from "./constants-CQq93l3e.js";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/Logger.ts
|
|
4
|
+
const LEVEL_ORDER = {
|
|
5
|
+
debug: 0,
|
|
6
|
+
info: 1,
|
|
7
|
+
warn: 2,
|
|
8
|
+
error: 3
|
|
9
|
+
};
|
|
10
|
+
var LoggerImpl = class {
|
|
11
|
+
buffer = [];
|
|
12
|
+
listeners = new Set();
|
|
13
|
+
minLevel = typeof globalThis !== "undefined" && globalThis.__CG_DEBUG ? "debug" : "info";
|
|
14
|
+
log(level, scope, message, data) {
|
|
15
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[this.minLevel]) return;
|
|
16
|
+
const entry = {
|
|
17
|
+
ts: Date.now(),
|
|
18
|
+
level,
|
|
19
|
+
scope,
|
|
20
|
+
message,
|
|
21
|
+
data
|
|
22
|
+
};
|
|
23
|
+
this.buffer.push(entry);
|
|
24
|
+
if (this.buffer.length > LOGGER.RING_SIZE) this.buffer.splice(0, this.buffer.length - LOGGER.RING_SIZE);
|
|
25
|
+
this.emit();
|
|
26
|
+
const fn = level === "error" ? console.error : level === "warn" ? console.warn : console.log;
|
|
27
|
+
try {
|
|
28
|
+
if (typeof fn === "function") fn(`[codegraph:${scope}] ${message}`, data ?? "");
|
|
29
|
+
} catch {}
|
|
30
|
+
}
|
|
31
|
+
debug(scope, message, data) {
|
|
32
|
+
this.log("debug", scope, message, data);
|
|
33
|
+
}
|
|
34
|
+
info(scope, message, data) {
|
|
35
|
+
this.log("info", scope, message, data);
|
|
36
|
+
}
|
|
37
|
+
warn(scope, message, data) {
|
|
38
|
+
this.log("warn", scope, message, data);
|
|
39
|
+
}
|
|
40
|
+
error(scope, message, data) {
|
|
41
|
+
this.log("error", scope, message, data);
|
|
42
|
+
}
|
|
43
|
+
entries() {
|
|
44
|
+
return this.buffer.slice();
|
|
45
|
+
}
|
|
46
|
+
clear() {
|
|
47
|
+
this.buffer = [];
|
|
48
|
+
this.emit();
|
|
49
|
+
}
|
|
50
|
+
subscribe(fn) {
|
|
51
|
+
this.listeners.add(fn);
|
|
52
|
+
fn(this.entries());
|
|
53
|
+
return () => {
|
|
54
|
+
this.listeners.delete(fn);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
clearListeners() {
|
|
58
|
+
this.listeners.clear();
|
|
59
|
+
}
|
|
60
|
+
emit() {
|
|
61
|
+
if (this.listeners.size === 0) return;
|
|
62
|
+
const snapshot = this.entries();
|
|
63
|
+
for (const fn of this.listeners) try {
|
|
64
|
+
fn(snapshot);
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const logger = new LoggerImpl();
|
|
69
|
+
function scoped(scope) {
|
|
70
|
+
return {
|
|
71
|
+
debug: (m, d) => logger.debug(scope, m, d),
|
|
72
|
+
info: (m, d) => logger.info(scope, m, d),
|
|
73
|
+
warn: (m, d) => logger.warn(scope, m, d),
|
|
74
|
+
error: (m, d) => logger.error(scope, m, d)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { scoped };
|
|
80
|
+
//# sourceMappingURL=Logger-DUIJSeNu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger-DUIJSeNu.js","names":["LEVEL_ORDER: Record<LogLevel, number>","level: LogLevel","scope: string","message: string","data?: unknown","entry: LogEntry","fn: (entries: LogEntry[]) => void","m: string","d?: unknown"],"sources":["../src/shared/Logger.ts"],"sourcesContent":["// Lightweight structured logger with an in-memory ring buffer for UI surfacing.\r\n// Ponytail: no deps, ~60 lines. Levels respect host console when available.\r\n/* eslint-disable no-console */\r\n\r\nimport { LOGGER } from './constants.ts';\r\n\r\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\nexport interface LogEntry {\r\n ts: number;\r\n level: LogLevel;\r\n scope: string;\r\n message: string;\r\n data?: unknown;\r\n}\r\n\r\nconst LEVEL_ORDER: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\r\n\r\n\r\nclass LoggerImpl {\r\n private buffer: LogEntry[] = [];\r\n private listeners = new Set<(entries: LogEntry[]) => void>();\r\n minLevel: LogLevel = (typeof globalThis !== 'undefined' &&\r\n (globalThis as unknown as { __CG_DEBUG?: boolean }).__CG_DEBUG) ? 'debug' : 'info';\r\n\r\n log(level: LogLevel, scope: string, message: string, data?: unknown): void {\r\n if (LEVEL_ORDER[level] < LEVEL_ORDER[this.minLevel]) return;\r\n const entry: LogEntry = { ts: Date.now(), level, scope, message, data };\r\n this.buffer.push(entry);\r\n if (this.buffer.length > LOGGER.RING_SIZE) this.buffer.splice(0, this.buffer.length - LOGGER.RING_SIZE);\r\n this.emit();\r\n const fn = level === 'error' ? console.error : level === 'warn' ? console.warn : console.log;\r\n try { if (typeof fn === 'function') fn(`[codegraph:${scope}] ${message}`, data ?? ''); } catch { /* console unavailable */ }\r\n }\r\n\r\n debug(scope: string, message: string, data?: unknown): void { this.log('debug', scope, message, data); }\r\n info(scope: string, message: string, data?: unknown): void { this.log('info', scope, message, data); }\r\n warn(scope: string, message: string, data?: unknown): void { this.log('warn', scope, message, data); }\r\n error(scope: string, message: string, data?: unknown): void { this.log('error', scope, message, data); }\r\n\r\n entries(): LogEntry[] { return this.buffer.slice(); }\r\n clear(): void { this.buffer = []; this.emit(); }\r\n\r\n subscribe(fn: (entries: LogEntry[]) => void): () => void {\r\n this.listeners.add(fn);\r\n fn(this.entries());\r\n return () => { this.listeners.delete(fn); };\r\n }\r\n\r\n clearListeners(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n private emit(): void {\r\n if (this.listeners.size === 0) return;\r\n const snapshot = this.entries();\r\n for (const fn of this.listeners) { try { fn(snapshot); } catch { /* listener fault */ } }\r\n }\r\n}\r\n\r\nexport const logger = new LoggerImpl();\r\n\r\n// Convenience scoped logger factory.\r\nexport function scoped(scope: string) {\r\n return {\r\n debug: (m: string, d?: unknown) => logger.debug(scope, m, d),\r\n info: (m: string, d?: unknown) => logger.info(scope, m, d),\r\n warn: (m: string, d?: unknown) => logger.warn(scope, m, d),\r\n error: (m: string, d?: unknown) => logger.error(scope, m, d),\r\n };\r\n}\r\nexport function resetLoggerListeners(): void {\r\n logger.clearListeners();\r\n}"],"mappings":";;;AAgBA,MAAMA,cAAwC;CAAE,OAAO;CAAG,MAAM;CAAG,MAAM;CAAG,OAAO;AAAG;AAGtF,IAAM,aAAN,MAAiB;CACf,AAAQ,SAAqB,CAAE;CAC/B,AAAQ,YAAY,IAAI;CACxB,kBAA6B,eAAe,eACzC,WAAmD,aAAc,UAAU;CAE9E,IAAIC,OAAiBC,OAAeC,SAAiBC,MAAsB;AACzE,MAAI,YAAY,SAAS,YAAY,KAAK,UAAW;EACrD,MAAMC,QAAkB;GAAE,IAAI,KAAK,KAAK;GAAE;GAAO;GAAO;GAAS;EAAM;AACvE,OAAK,OAAO,KAAK,MAAM;AACvB,MAAI,KAAK,OAAO,SAAS,OAAO,UAAW,MAAK,OAAO,OAAO,GAAG,KAAK,OAAO,SAAS,OAAO,UAAU;AACvG,OAAK,MAAM;EACX,MAAM,KAAK,UAAU,UAAU,QAAQ,QAAQ,UAAU,SAAS,QAAQ,OAAO,QAAQ;AACzF,MAAI;AAAE,cAAW,OAAO,WAAY,KAAI,aAAa,MAAM,IAAI,QAAQ,GAAG,QAAQ,GAAG;EAAG,QAAO,CAA6B;CAC7H;CAED,MAAMH,OAAeC,SAAiBC,MAAsB;AAAE,OAAK,IAAI,SAAS,OAAO,SAAS,KAAK;CAAG;CACxG,KAAKF,OAAeC,SAAiBC,MAAsB;AAAE,OAAK,IAAI,QAAQ,OAAO,SAAS,KAAK;CAAG;CACtG,KAAKF,OAAeC,SAAiBC,MAAsB;AAAE,OAAK,IAAI,QAAQ,OAAO,SAAS,KAAK;CAAG;CACtG,MAAMF,OAAeC,SAAiBC,MAAsB;AAAE,OAAK,IAAI,SAAS,OAAO,SAAS,KAAK;CAAG;CAExG,UAAsB;AAAE,SAAO,KAAK,OAAO,OAAO;CAAG;CACrD,QAAc;AAAE,OAAK,SAAS,CAAE;AAAE,OAAK,MAAM;CAAG;CAEhD,UAAUE,IAA+C;AACvD,OAAK,UAAU,IAAI,GAAG;AACtB,KAAG,KAAK,SAAS,CAAC;AAClB,SAAO,MAAM;AAAE,QAAK,UAAU,OAAO,GAAG;EAAG;CAC5C;CAED,iBAAuB;AACrB,OAAK,UAAU,OAAO;CACvB;CAED,AAAQ,OAAa;AACnB,MAAI,KAAK,UAAU,SAAS,EAAG;EAC/B,MAAM,WAAW,KAAK,SAAS;AAC/B,OAAK,MAAM,MAAM,KAAK,UAAa,KAAI;AAAE,MAAG,SAAS;EAAG,QAAO,CAAwB;CACxF;AACF;AAED,MAAa,SAAS,IAAI;AAG1B,SAAgB,OAAOJ,OAAe;AACpC,QAAO;EACL,OAAO,CAACK,GAAWC,MAAgB,OAAO,MAAM,OAAO,GAAG,EAAE;EAC5D,MAAM,CAACD,GAAWC,MAAgB,OAAO,KAAK,OAAO,GAAG,EAAE;EAC1D,MAAM,CAACD,GAAWC,MAAgB,OAAO,KAAK,OAAO,GAAG,EAAE;EAC1D,OAAO,CAACD,GAAWC,MAAgB,OAAO,MAAM,OAAO,GAAG,EAAE;CAC7D;AACF"}
|