@aetherwing/fcp-drawio 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/dist/adapter.d.ts +38 -0
- package/dist/adapter.js +259 -0
- package/dist/adapter.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/elk-layout.d.ts +49 -0
- package/dist/layout/elk-layout.js +144 -0
- package/dist/layout/elk-layout.js.map +1 -0
- package/dist/lib/drawio-cli.d.ts +22 -0
- package/dist/lib/drawio-cli.js +88 -0
- package/dist/lib/drawio-cli.js.map +1 -0
- package/dist/lib/node-types.d.ts +22 -0
- package/dist/lib/node-types.js +174 -0
- package/dist/lib/node-types.js.map +1 -0
- package/dist/lib/stencils/aws.d.ts +2 -0
- package/dist/lib/stencils/aws.js +69 -0
- package/dist/lib/stencils/aws.js.map +1 -0
- package/dist/lib/stencils/azure.d.ts +2 -0
- package/dist/lib/stencils/azure.js +54 -0
- package/dist/lib/stencils/azure.js.map +1 -0
- package/dist/lib/stencils/cisco.d.ts +2 -0
- package/dist/lib/stencils/cisco.js +30 -0
- package/dist/lib/stencils/cisco.js.map +1 -0
- package/dist/lib/stencils/gcp.d.ts +2 -0
- package/dist/lib/stencils/gcp.js +38 -0
- package/dist/lib/stencils/gcp.js.map +1 -0
- package/dist/lib/stencils/ibm.d.ts +2 -0
- package/dist/lib/stencils/ibm.js +32 -0
- package/dist/lib/stencils/ibm.js.map +1 -0
- package/dist/lib/stencils/index.d.ts +10 -0
- package/dist/lib/stencils/index.js +33 -0
- package/dist/lib/stencils/index.js.map +1 -0
- package/dist/lib/stencils/k8s.d.ts +2 -0
- package/dist/lib/stencils/k8s.js +32 -0
- package/dist/lib/stencils/k8s.js.map +1 -0
- package/dist/lib/stencils/types.d.ts +14 -0
- package/dist/lib/stencils/types.js +2 -0
- package/dist/lib/stencils/types.js.map +1 -0
- package/dist/lib/themes.d.ts +8 -0
- package/dist/lib/themes.js +32 -0
- package/dist/lib/themes.js.map +1 -0
- package/dist/model/defaults.d.ts +3 -0
- package/dist/model/defaults.js +26 -0
- package/dist/model/defaults.js.map +1 -0
- package/dist/model/diagram-model.d.ts +110 -0
- package/dist/model/diagram-model.js +938 -0
- package/dist/model/diagram-model.js.map +1 -0
- package/dist/model/event-log.d.ts +30 -0
- package/dist/model/event-log.js +112 -0
- package/dist/model/event-log.js.map +1 -0
- package/dist/model/id.d.ts +9 -0
- package/dist/model/id.js +35 -0
- package/dist/model/id.js.map +1 -0
- package/dist/model/reference-registry.d.ts +33 -0
- package/dist/model/reference-registry.js +143 -0
- package/dist/model/reference-registry.js.map +1 -0
- package/dist/model/spatial.d.ts +20 -0
- package/dist/model/spatial.js +59 -0
- package/dist/model/spatial.js.map +1 -0
- package/dist/parser/parse-op.d.ts +18 -0
- package/dist/parser/parse-op.js +430 -0
- package/dist/parser/parse-op.js.map +1 -0
- package/dist/parser/resolve-ref.d.ts +27 -0
- package/dist/parser/resolve-ref.js +232 -0
- package/dist/parser/resolve-ref.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +6 -0
- package/dist/parser/tokenizer.js +7 -0
- package/dist/parser/tokenizer.js.map +1 -0
- package/dist/serialization/connector-intelligence.d.ts +35 -0
- package/dist/serialization/connector-intelligence.js +336 -0
- package/dist/serialization/connector-intelligence.js.map +1 -0
- package/dist/serialization/deserialize.d.ts +6 -0
- package/dist/serialization/deserialize.js +511 -0
- package/dist/serialization/deserialize.js.map +1 -0
- package/dist/serialization/serialize.d.ts +15 -0
- package/dist/serialization/serialize.js +332 -0
- package/dist/serialization/serialize.js.map +1 -0
- package/dist/server/intent-layer.d.ts +48 -0
- package/dist/server/intent-layer.js +1322 -0
- package/dist/server/intent-layer.js.map +1 -0
- package/dist/server/mcp-server.d.ts +7 -0
- package/dist/server/mcp-server.js +26 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/server/model-map.d.ts +8 -0
- package/dist/server/model-map.js +240 -0
- package/dist/server/model-map.js.map +1 -0
- package/dist/server/query-handler.d.ts +19 -0
- package/dist/server/query-handler.js +148 -0
- package/dist/server/query-handler.js.map +1 -0
- package/dist/server/response-formatter.d.ts +56 -0
- package/dist/server/response-formatter.js +351 -0
- package/dist/server/response-formatter.js.map +1 -0
- package/dist/server/session-handler.d.ts +6 -0
- package/dist/server/session-handler.js +127 -0
- package/dist/server/session-handler.js.map +1 -0
- package/dist/types/index.d.ts +238 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/verb-specs.d.ts +6 -0
- package/dist/verb-specs.js +144 -0
- package/dist/verb-specs.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 5-level reference resolution cascade.
|
|
3
|
+
*
|
|
4
|
+
* 1. Exact label match (case-sensitive)
|
|
5
|
+
* 2. Case-insensitive match
|
|
6
|
+
* 3. Normalized match (strip hyphens, underscores, spaces)
|
|
7
|
+
* 4. Prefix match
|
|
8
|
+
* 5. Recency match (@recent)
|
|
9
|
+
*
|
|
10
|
+
* Short-circuits at the first level producing exactly one result.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveRef(ref, registry, model) {
|
|
13
|
+
// Handle selectors
|
|
14
|
+
if (ref.startsWith("@")) {
|
|
15
|
+
return resolveSelector(ref, registry, model);
|
|
16
|
+
}
|
|
17
|
+
// Handle type-qualified references: db:UserDB
|
|
18
|
+
if (ref.includes(":") && !ref.startsWith("#")) {
|
|
19
|
+
const [typeHint, label] = ref.split(":", 2);
|
|
20
|
+
const byType = registry.getByType(typeHint);
|
|
21
|
+
const match = byType.filter((s) => s.label === label);
|
|
22
|
+
if (match.length === 1)
|
|
23
|
+
return { kind: "single", shape: match[0] };
|
|
24
|
+
if (match.length > 1) {
|
|
25
|
+
return { kind: "multiple", shapes: match, message: `"${ref}" matches ${match.length} shapes` };
|
|
26
|
+
}
|
|
27
|
+
// Fall through to normal resolution with just the label part
|
|
28
|
+
return resolveRef(label, registry, model);
|
|
29
|
+
}
|
|
30
|
+
// Handle group-qualified references: Backend/AuthService
|
|
31
|
+
if (ref.includes("/")) {
|
|
32
|
+
const [groupName, label] = ref.split("/", 2);
|
|
33
|
+
const group = model.getGroupByName(groupName);
|
|
34
|
+
if (group) {
|
|
35
|
+
const page = model.getActivePage();
|
|
36
|
+
for (const memberId of group.memberIds) {
|
|
37
|
+
const shape = page.shapes.get(memberId);
|
|
38
|
+
if (shape && shape.label === label) {
|
|
39
|
+
return { kind: "single", shape };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Level 1: Exact label match
|
|
45
|
+
const exact = registry.getByExactLabel(ref);
|
|
46
|
+
if (exact.length === 1)
|
|
47
|
+
return { kind: "single", shape: exact[0] };
|
|
48
|
+
if (exact.length > 1) {
|
|
49
|
+
return {
|
|
50
|
+
kind: "multiple",
|
|
51
|
+
shapes: exact,
|
|
52
|
+
message: `"${ref}" matches ${exact.length}: ${exact.map(s => `${s.label}(${s.type})`).join(", ")}. Qualify with type (e.g., db:${ref}) or group (e.g., Backend/${ref})`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Level 2: Case-insensitive match
|
|
56
|
+
const ci = registry.getByCaseInsensitiveLabel(ref);
|
|
57
|
+
if (ci.length === 1)
|
|
58
|
+
return { kind: "single", shape: ci[0] };
|
|
59
|
+
if (ci.length > 1) {
|
|
60
|
+
return {
|
|
61
|
+
kind: "multiple",
|
|
62
|
+
shapes: ci,
|
|
63
|
+
message: `"${ref}" matches ${ci.length}: ${ci.map(s => s.label).join(", ")}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Level 3: Normalized match
|
|
67
|
+
const norm = registry.getByNormalizedLabel(ref);
|
|
68
|
+
if (norm.length === 1)
|
|
69
|
+
return { kind: "single", shape: norm[0] };
|
|
70
|
+
if (norm.length > 1) {
|
|
71
|
+
return {
|
|
72
|
+
kind: "multiple",
|
|
73
|
+
shapes: norm,
|
|
74
|
+
message: `"${ref}" matches ${norm.length}: ${norm.map(s => s.label).join(", ")}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Level 4: Prefix match
|
|
78
|
+
const prefix = registry.getByPrefixLabel(ref);
|
|
79
|
+
if (prefix.length === 1)
|
|
80
|
+
return { kind: "single", shape: prefix[0] };
|
|
81
|
+
if (prefix.length > 1) {
|
|
82
|
+
return {
|
|
83
|
+
kind: "multiple",
|
|
84
|
+
shapes: prefix,
|
|
85
|
+
message: `"${ref}" matches ${prefix.length}: ${prefix.map(s => s.label).join(", ")}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Level 5: Nothing found — suggest similar labels
|
|
89
|
+
const all = registry.getAllShapes();
|
|
90
|
+
const suggestions = findSimilar(ref, all.map((s) => s.label));
|
|
91
|
+
if (suggestions.length > 0) {
|
|
92
|
+
return {
|
|
93
|
+
kind: "none",
|
|
94
|
+
message: `unknown ref "${ref}". Did you mean "${suggestions[0]}"?`,
|
|
95
|
+
suggestedLabel: suggestions[0],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
kind: "none",
|
|
100
|
+
message: `unknown ref "${ref}". No shapes on this page.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Resolve a selector to matching shapes.
|
|
105
|
+
*/
|
|
106
|
+
function resolveSelector(selector, registry, model) {
|
|
107
|
+
const page = model.getActivePage();
|
|
108
|
+
if (selector === "@all") {
|
|
109
|
+
const shapes = registry.getAllShapes();
|
|
110
|
+
if (shapes.length === 0)
|
|
111
|
+
return { kind: "none", message: "@all matched 0 shapes" };
|
|
112
|
+
return { kind: "multiple", shapes, message: `@all: ${shapes.length} shapes` };
|
|
113
|
+
}
|
|
114
|
+
if (selector === "@recent") {
|
|
115
|
+
const recent = registry.getMostRecent(1);
|
|
116
|
+
if (recent.length === 0)
|
|
117
|
+
return { kind: "none", message: "no recent shapes" };
|
|
118
|
+
return { kind: "single", shape: recent[0] };
|
|
119
|
+
}
|
|
120
|
+
if (selector.startsWith("@recent:")) {
|
|
121
|
+
const count = parseInt(selector.slice(8), 10);
|
|
122
|
+
if (isNaN(count) || count <= 0)
|
|
123
|
+
return { kind: "none", message: `invalid count in "${selector}"` };
|
|
124
|
+
const recent = registry.getMostRecent(count);
|
|
125
|
+
if (recent.length === 0)
|
|
126
|
+
return { kind: "none", message: "no recent shapes" };
|
|
127
|
+
return { kind: "multiple", shapes: recent, message: `@recent:${count}: ${recent.length} shapes` };
|
|
128
|
+
}
|
|
129
|
+
if (selector === "@orphan") {
|
|
130
|
+
const orphans = registry.getOrphans(page);
|
|
131
|
+
if (orphans.length === 0)
|
|
132
|
+
return { kind: "none", message: "@orphan matched 0 shapes" };
|
|
133
|
+
return { kind: "multiple", shapes: orphans, message: `@orphan: ${orphans.length} shapes` };
|
|
134
|
+
}
|
|
135
|
+
if (selector.startsWith("@type:")) {
|
|
136
|
+
const type = selector.slice(6);
|
|
137
|
+
const shapes = registry.getByType(type);
|
|
138
|
+
if (shapes.length === 0) {
|
|
139
|
+
const allTypes = new Map();
|
|
140
|
+
for (const s of registry.getAllShapes()) {
|
|
141
|
+
allTypes.set(s.type, (allTypes.get(s.type) ?? 0) + 1);
|
|
142
|
+
}
|
|
143
|
+
const available = [...allTypes.entries()].map(([t, c]) => `${c} ${t}`).join(", ");
|
|
144
|
+
return { kind: "none", message: `@type:${type} matched 0 shapes (page has: ${available || "no shapes"})` };
|
|
145
|
+
}
|
|
146
|
+
return { kind: "multiple", shapes, message: `@type:${type}: ${shapes.length} shapes` };
|
|
147
|
+
}
|
|
148
|
+
if (selector.startsWith("@group:")) {
|
|
149
|
+
const groupName = selector.slice(7);
|
|
150
|
+
const group = model.getGroupByName(groupName);
|
|
151
|
+
if (!group)
|
|
152
|
+
return { kind: "none", message: `unknown group "${groupName}"` };
|
|
153
|
+
const shapes = [];
|
|
154
|
+
for (const id of group.memberIds) {
|
|
155
|
+
const shape = page.shapes.get(id);
|
|
156
|
+
if (shape)
|
|
157
|
+
shapes.push(shape);
|
|
158
|
+
}
|
|
159
|
+
if (shapes.length === 0)
|
|
160
|
+
return { kind: "none", message: `@group:${groupName} has 0 members` };
|
|
161
|
+
return { kind: "multiple", shapes, message: `@group:${groupName}: ${shapes.length} shapes` };
|
|
162
|
+
}
|
|
163
|
+
if (selector.startsWith("@page:")) {
|
|
164
|
+
const pageName = selector.slice(6);
|
|
165
|
+
const targetPage = model.getPageByName(pageName);
|
|
166
|
+
if (!targetPage)
|
|
167
|
+
return { kind: "none", message: `unknown page "${pageName}"` };
|
|
168
|
+
const shapes = [...targetPage.shapes.values()];
|
|
169
|
+
if (shapes.length === 0)
|
|
170
|
+
return { kind: "none", message: `@page:${pageName} has 0 shapes` };
|
|
171
|
+
return { kind: "multiple", shapes, message: `@page:${pageName}: ${shapes.length} shapes` };
|
|
172
|
+
}
|
|
173
|
+
if (selector.startsWith("@layer:")) {
|
|
174
|
+
const layerName = selector.slice(7);
|
|
175
|
+
const shapes = registry.getAllShapes().filter((s) => {
|
|
176
|
+
const layer = page.layers.find((l) => l.id === s.layer);
|
|
177
|
+
return layer && layer.name === layerName;
|
|
178
|
+
});
|
|
179
|
+
if (shapes.length === 0)
|
|
180
|
+
return { kind: "none", message: `@layer:${layerName} matched 0 shapes` };
|
|
181
|
+
return { kind: "multiple", shapes, message: `@layer:${layerName}: ${shapes.length} shapes` };
|
|
182
|
+
}
|
|
183
|
+
if (selector.startsWith("@connected:")) {
|
|
184
|
+
const innerRef = selector.slice(11);
|
|
185
|
+
// Resolve the inner reference to find the anchor shape
|
|
186
|
+
const innerResult = resolveRef(innerRef, registry, model);
|
|
187
|
+
if (innerResult.kind === "none") {
|
|
188
|
+
return { kind: "none", message: `@connected:${innerRef} — ${innerResult.message}` };
|
|
189
|
+
}
|
|
190
|
+
if (innerResult.kind === "multiple") {
|
|
191
|
+
return { kind: "none", message: `@connected:${innerRef} — ambiguous: ${innerResult.message}` };
|
|
192
|
+
}
|
|
193
|
+
// innerResult.kind === "single" at this point
|
|
194
|
+
if (innerResult.kind !== "single") {
|
|
195
|
+
return { kind: "none", message: `@connected:${innerRef} — cannot use group as anchor` };
|
|
196
|
+
}
|
|
197
|
+
const connected = registry.getConnectedShapes(innerResult.shape.id, page);
|
|
198
|
+
if (connected.length === 0)
|
|
199
|
+
return { kind: "none", message: `@connected:${innerRef} matched 0 shapes` };
|
|
200
|
+
return { kind: "multiple", shapes: connected, message: `@connected:${innerRef}: ${connected.length} shapes` };
|
|
201
|
+
}
|
|
202
|
+
return { kind: "none", message: `unknown selector "${selector}"` };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Find similar labels using simple edit distance.
|
|
206
|
+
* Returns up to 3 suggestions sorted by similarity.
|
|
207
|
+
*/
|
|
208
|
+
function findSimilar(target, candidates) {
|
|
209
|
+
const lower = target.toLowerCase();
|
|
210
|
+
const scored = candidates
|
|
211
|
+
.map((c) => ({ label: c, distance: levenshtein(lower, c.toLowerCase()) }))
|
|
212
|
+
.filter((s) => s.distance <= Math.max(3, Math.floor(target.length / 2)))
|
|
213
|
+
.sort((a, b) => a.distance - b.distance);
|
|
214
|
+
return scored.slice(0, 3).map((s) => s.label);
|
|
215
|
+
}
|
|
216
|
+
function levenshtein(a, b) {
|
|
217
|
+
const m = a.length, n = b.length;
|
|
218
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
219
|
+
for (let i = 0; i <= m; i++)
|
|
220
|
+
dp[i][0] = i;
|
|
221
|
+
for (let j = 0; j <= n; j++)
|
|
222
|
+
dp[0][j] = j;
|
|
223
|
+
for (let i = 1; i <= m; i++) {
|
|
224
|
+
for (let j = 1; j <= n; j++) {
|
|
225
|
+
dp[i][j] = a[i - 1] === b[j - 1]
|
|
226
|
+
? dp[i - 1][j - 1]
|
|
227
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return dp[m][n];
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=resolve-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-ref.js","sourceRoot":"","sources":["../../src/parser/resolve-ref.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export tokenizer functions from @aetherwing/fcp-core.
|
|
3
|
+
* This file previously contained a local implementation that is now
|
|
4
|
+
* provided by the framework.
|
|
5
|
+
*/
|
|
6
|
+
export { tokenize, isKeyValue, parseKeyValue, isArrow, isSelector, } from "@aetherwing/fcp-core";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export tokenizer functions from @aetherwing/fcp-core.
|
|
3
|
+
* This file previously contained a local implementation that is now
|
|
4
|
+
* provided by the framework.
|
|
5
|
+
*/
|
|
6
|
+
export { tokenize, isKeyValue, parseKeyValue, isArrow, isSelector, } from "@aetherwing/fcp-core";
|
|
7
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/parser/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,QAAQ,EACR,UAAU,EACV,aAAa,EACb,OAAO,EACP,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Edge, Page, Shape } from "../types/index.js";
|
|
2
|
+
export interface PortAssignment {
|
|
3
|
+
exitX: number;
|
|
4
|
+
exitY: number;
|
|
5
|
+
entryX: number;
|
|
6
|
+
entryY: number;
|
|
7
|
+
}
|
|
8
|
+
export type Face = "right" | "bottom" | "left" | "top";
|
|
9
|
+
export interface EdgeRenderInfo {
|
|
10
|
+
ports: PortAssignment | null;
|
|
11
|
+
exitFace: Face | null;
|
|
12
|
+
entryFace: Face | null;
|
|
13
|
+
labelOffsetX: number;
|
|
14
|
+
labelOffsetY: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Pre-compute render info (port assignments and label offsets) for all edges on a page.
|
|
18
|
+
* Returns a Map keyed by edge ID.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeAllEdgeRenderInfo(page: Page): Map<string, EdgeRenderInfo>;
|
|
21
|
+
/**
|
|
22
|
+
* Compute render info for a single edge.
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeEdgeRenderInfo(edge: Edge, page: Page): EdgeRenderInfo;
|
|
25
|
+
/**
|
|
26
|
+
* Map an angle to the dominant exit face.
|
|
27
|
+
* Right: [-45, 45), Bottom: [45, 135), Left: [135, 180] or [-180, -135), Top: [-135, -45)
|
|
28
|
+
*/
|
|
29
|
+
export declare function angleFace(angleDeg: number): Face;
|
|
30
|
+
/**
|
|
31
|
+
* Given source and target shapes, compute smart port assignments.
|
|
32
|
+
* The exit point is on the face of the source closest to the target,
|
|
33
|
+
* with slight variation based on the angle offset from face center.
|
|
34
|
+
*/
|
|
35
|
+
export declare function computeSmartPorts(source: Shape, target: Shape): PortAssignment;
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
// ── Main entry point ─────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Pre-compute render info (port assignments and label offsets) for all edges on a page.
|
|
4
|
+
* Returns a Map keyed by edge ID.
|
|
5
|
+
*/
|
|
6
|
+
export function computeAllEdgeRenderInfo(page) {
|
|
7
|
+
const result = new Map();
|
|
8
|
+
const edges = [...page.edges.values()];
|
|
9
|
+
// Phase 1: Compute smart ports for each edge individually
|
|
10
|
+
for (const edge of edges) {
|
|
11
|
+
result.set(edge.id, computeEdgeRenderInfo(edge, page));
|
|
12
|
+
}
|
|
13
|
+
// Phase 2: Fan-out spreading — distribute ports when multiple edges share same source+face
|
|
14
|
+
applyFanOutSpreading(result, edges, page);
|
|
15
|
+
// Phase 3: Label x-offset spreading — spread labeled edges so labels don't cluster at midpoints
|
|
16
|
+
applyLabelOffsetSpreading(result, edges);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compute render info for a single edge.
|
|
21
|
+
*/
|
|
22
|
+
export function computeEdgeRenderInfo(edge, page) {
|
|
23
|
+
const source = page.shapes.get(edge.sourceId);
|
|
24
|
+
const target = page.shapes.get(edge.targetId);
|
|
25
|
+
if (!source || !target) {
|
|
26
|
+
return { ports: null, exitFace: null, entryFace: null, labelOffsetX: 0, labelOffsetY: 0 };
|
|
27
|
+
}
|
|
28
|
+
// Check if edge has explicitly set ports (from deserialization) — preserve them
|
|
29
|
+
const style = edge.style;
|
|
30
|
+
if (style["exitX"] !== undefined && style["exitX"] !== "") {
|
|
31
|
+
return {
|
|
32
|
+
ports: {
|
|
33
|
+
exitX: parseFloat(String(style["exitX"])),
|
|
34
|
+
exitY: parseFloat(String(style["exitY"] ?? "0.5")),
|
|
35
|
+
entryX: parseFloat(String(style["entryX"] ?? "0.5")),
|
|
36
|
+
entryY: parseFloat(String(style["entryY"] ?? "0.5")),
|
|
37
|
+
},
|
|
38
|
+
exitFace: null,
|
|
39
|
+
entryFace: null,
|
|
40
|
+
labelOffsetX: 0,
|
|
41
|
+
labelOffsetY: 0,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Compute smart ports — use cross-group hint if shapes are in different groups
|
|
45
|
+
const crossGroup = source.parentGroup !== target.parentGroup;
|
|
46
|
+
const ports = crossGroup
|
|
47
|
+
? computeCrossGroupPorts(source, target, page)
|
|
48
|
+
: computeSmartPorts(source, target);
|
|
49
|
+
const exitFace = angleFace(computeAngle(source.bounds, target.bounds));
|
|
50
|
+
return {
|
|
51
|
+
ports,
|
|
52
|
+
exitFace,
|
|
53
|
+
entryFace: mirrorFace(exitFace),
|
|
54
|
+
labelOffsetX: 0,
|
|
55
|
+
labelOffsetY: 0,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// ── Smart port computation ───────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Compute angle (in degrees) from source center to target center.
|
|
61
|
+
* Returns angle in range [-180, 180] where 0 = right, 90 = down, -90 = up.
|
|
62
|
+
*/
|
|
63
|
+
function computeAngle(source, target) {
|
|
64
|
+
const sx = source.x + source.width / 2;
|
|
65
|
+
const sy = source.y + source.height / 2;
|
|
66
|
+
const tx = target.x + target.width / 2;
|
|
67
|
+
const ty = target.y + target.height / 2;
|
|
68
|
+
return Math.atan2(ty - sy, tx - sx) * (180 / Math.PI);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Map an angle to the dominant exit face.
|
|
72
|
+
* Right: [-45, 45), Bottom: [45, 135), Left: [135, 180] or [-180, -135), Top: [-135, -45)
|
|
73
|
+
*/
|
|
74
|
+
export function angleFace(angleDeg) {
|
|
75
|
+
if (angleDeg >= -45 && angleDeg < 45)
|
|
76
|
+
return "right";
|
|
77
|
+
if (angleDeg >= 45 && angleDeg < 135)
|
|
78
|
+
return "bottom";
|
|
79
|
+
if (angleDeg >= -135 && angleDeg < -45)
|
|
80
|
+
return "top";
|
|
81
|
+
return "left"; // [135, 180] or [-180, -135)
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Mirror a face: source exits right → target enters left, etc.
|
|
85
|
+
*/
|
|
86
|
+
function mirrorFace(face) {
|
|
87
|
+
switch (face) {
|
|
88
|
+
case "right": return "left";
|
|
89
|
+
case "left": return "right";
|
|
90
|
+
case "top": return "bottom";
|
|
91
|
+
case "bottom": return "top";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Given source and target shapes, compute smart port assignments.
|
|
96
|
+
* The exit point is on the face of the source closest to the target,
|
|
97
|
+
* with slight variation based on the angle offset from face center.
|
|
98
|
+
*/
|
|
99
|
+
export function computeSmartPorts(source, target) {
|
|
100
|
+
const angleDeg = computeAngle(source.bounds, target.bounds);
|
|
101
|
+
const face = angleFace(angleDeg);
|
|
102
|
+
// Compute fine-tuned position within the face based on angle offset.
|
|
103
|
+
// This gives slight variation so edges don't all leave from dead center.
|
|
104
|
+
const fineOffset = computeFineOffset(angleDeg, face);
|
|
105
|
+
const exit = faceToPort(face, fineOffset);
|
|
106
|
+
const entryFace = mirrorFace(face);
|
|
107
|
+
const entry = faceToPort(entryFace, fineOffset);
|
|
108
|
+
return {
|
|
109
|
+
exitX: exit.x,
|
|
110
|
+
exitY: exit.y,
|
|
111
|
+
entryX: entry.x,
|
|
112
|
+
entryY: entry.y,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Compute port assignments for edges crossing group boundaries.
|
|
117
|
+
* When source and target are in different groups (or one is ungrouped),
|
|
118
|
+
* compute the angle toward the target's group bounding box edge (not target center directly).
|
|
119
|
+
* This biases the exit port toward the group boundary.
|
|
120
|
+
*/
|
|
121
|
+
function computeCrossGroupPorts(source, target, page) {
|
|
122
|
+
// If target is in a group, use the nearest edge of the group bounding box
|
|
123
|
+
// as the angle target instead of the target shape center directly
|
|
124
|
+
let targetBounds = target.bounds;
|
|
125
|
+
if (target.parentGroup) {
|
|
126
|
+
const group = page.groups.get(target.parentGroup);
|
|
127
|
+
if (group) {
|
|
128
|
+
targetBounds = group.bounds;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Compute angle from source center to target group boundary
|
|
132
|
+
const angleDeg = computeAngle(source.bounds, targetBounds);
|
|
133
|
+
const face = angleFace(angleDeg);
|
|
134
|
+
const fineOffset = computeFineOffset(angleDeg, face);
|
|
135
|
+
const exit = faceToPort(face, fineOffset);
|
|
136
|
+
// For entry, compute from target's perspective toward source (or source's group)
|
|
137
|
+
let sourceBounds = source.bounds;
|
|
138
|
+
if (source.parentGroup) {
|
|
139
|
+
const group = page.groups.get(source.parentGroup);
|
|
140
|
+
if (group) {
|
|
141
|
+
sourceBounds = group.bounds;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const entryAngleDeg = computeAngle(target.bounds, sourceBounds);
|
|
145
|
+
const entryFace = angleFace(entryAngleDeg);
|
|
146
|
+
const entryFineOffset = computeFineOffset(entryAngleDeg, entryFace);
|
|
147
|
+
const entry = faceToPort(entryFace, entryFineOffset);
|
|
148
|
+
return {
|
|
149
|
+
exitX: exit.x,
|
|
150
|
+
exitY: exit.y,
|
|
151
|
+
entryX: entry.x,
|
|
152
|
+
entryY: entry.y,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Compute a fine offset within a face [-0.25, 0.25] based on angle deviation from face center.
|
|
157
|
+
*/
|
|
158
|
+
function computeFineOffset(angleDeg, face) {
|
|
159
|
+
// Face center angles: right=0, bottom=90, left=180/-180, top=-90
|
|
160
|
+
let faceCenter;
|
|
161
|
+
switch (face) {
|
|
162
|
+
case "right":
|
|
163
|
+
faceCenter = 0;
|
|
164
|
+
break;
|
|
165
|
+
case "bottom":
|
|
166
|
+
faceCenter = 90;
|
|
167
|
+
break;
|
|
168
|
+
case "left":
|
|
169
|
+
faceCenter = angleDeg >= 0 ? 180 : -180;
|
|
170
|
+
break;
|
|
171
|
+
case "top":
|
|
172
|
+
faceCenter = -90;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
// Deviation from face center, normalized to [-0.25, 0.25]
|
|
176
|
+
const deviation = angleDeg - faceCenter;
|
|
177
|
+
return clamp(deviation / 180, -0.25, 0.25);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Convert a face + fine offset to exit/entry port coordinates.
|
|
181
|
+
* The offset shifts position along the face axis.
|
|
182
|
+
*/
|
|
183
|
+
function faceToPort(face, fineOffset) {
|
|
184
|
+
switch (face) {
|
|
185
|
+
case "right": return { x: 1.0, y: clamp(0.5 + fineOffset, 0.1, 0.9) };
|
|
186
|
+
case "left": return { x: 0.0, y: clamp(0.5 + fineOffset, 0.1, 0.9) };
|
|
187
|
+
case "bottom": return { x: clamp(0.5 + fineOffset, 0.1, 0.9), y: 1.0 };
|
|
188
|
+
case "top": return { x: clamp(0.5 + fineOffset, 0.1, 0.9), y: 0.0 };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function clamp(v, min, max) {
|
|
192
|
+
return Math.max(min, Math.min(max, v));
|
|
193
|
+
}
|
|
194
|
+
// ── Fan-out spreading ────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Post-process edge render infos to spread port positions when multiple edges
|
|
197
|
+
* exit from the same face of the same source shape (or enter the same face of the same target).
|
|
198
|
+
*/
|
|
199
|
+
function applyFanOutSpreading(infos, edges, page) {
|
|
200
|
+
// Group edges by (sourceId, exitFace)
|
|
201
|
+
const exitGroups = new Map();
|
|
202
|
+
// Group edges by (targetId, entryFace)
|
|
203
|
+
const entryGroups = new Map();
|
|
204
|
+
for (const edge of edges) {
|
|
205
|
+
const info = infos.get(edge.id);
|
|
206
|
+
if (!info?.ports || !info.exitFace)
|
|
207
|
+
continue;
|
|
208
|
+
const exitKey = `${edge.sourceId}:${info.exitFace}`;
|
|
209
|
+
if (!exitGroups.has(exitKey))
|
|
210
|
+
exitGroups.set(exitKey, []);
|
|
211
|
+
exitGroups.get(exitKey).push({ edge, info });
|
|
212
|
+
const entryKey = `${edge.targetId}:${info.entryFace}`;
|
|
213
|
+
if (!entryGroups.has(entryKey))
|
|
214
|
+
entryGroups.set(entryKey, []);
|
|
215
|
+
entryGroups.get(entryKey).push({ edge, info });
|
|
216
|
+
}
|
|
217
|
+
// Spread exit ports for groups with N > 1
|
|
218
|
+
for (const [key, group] of exitGroups) {
|
|
219
|
+
if (group.length <= 1)
|
|
220
|
+
continue;
|
|
221
|
+
const face = key.split(":")[1];
|
|
222
|
+
spreadExitPorts(group, face, page);
|
|
223
|
+
}
|
|
224
|
+
// Spread entry ports for groups with N > 1
|
|
225
|
+
for (const [key, group] of entryGroups) {
|
|
226
|
+
if (group.length <= 1)
|
|
227
|
+
continue;
|
|
228
|
+
const face = key.split(":")[1];
|
|
229
|
+
spreadEntryPorts(group, face, page);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Spread exit port positions across a face when N edges leave from the same source face.
|
|
234
|
+
* Sort by target position along the face axis, then distribute evenly.
|
|
235
|
+
*/
|
|
236
|
+
function spreadExitPorts(group, face, page) {
|
|
237
|
+
const n = group.length;
|
|
238
|
+
// Sort by target position along the face's variable axis
|
|
239
|
+
group.sort((a, b) => {
|
|
240
|
+
const ta = page.shapes.get(a.edge.targetId);
|
|
241
|
+
const tb = page.shapes.get(b.edge.targetId);
|
|
242
|
+
if (!ta || !tb)
|
|
243
|
+
return 0;
|
|
244
|
+
const taCx = ta.bounds.x + ta.bounds.width / 2;
|
|
245
|
+
const taCy = ta.bounds.y + ta.bounds.height / 2;
|
|
246
|
+
const tbCx = tb.bounds.x + tb.bounds.width / 2;
|
|
247
|
+
const tbCy = tb.bounds.y + tb.bounds.height / 2;
|
|
248
|
+
// For top/bottom faces, sort by target X; for left/right, sort by target Y
|
|
249
|
+
if (face === "top" || face === "bottom")
|
|
250
|
+
return taCx - tbCx;
|
|
251
|
+
return taCy - tbCy;
|
|
252
|
+
});
|
|
253
|
+
// Spread positions: (i + 1) / (N + 1) for i in [0, N-1]
|
|
254
|
+
for (let i = 0; i < n; i++) {
|
|
255
|
+
const pos = (i + 1) / (n + 1);
|
|
256
|
+
const info = group[i].info;
|
|
257
|
+
if (!info.ports)
|
|
258
|
+
continue;
|
|
259
|
+
if (face === "top" || face === "bottom") {
|
|
260
|
+
info.ports.exitX = pos;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
info.ports.exitY = pos;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Spread entry port positions across a face when N edges enter the same target face.
|
|
269
|
+
*/
|
|
270
|
+
function spreadEntryPorts(group, face, page) {
|
|
271
|
+
const n = group.length;
|
|
272
|
+
// Sort by source position along the face's variable axis
|
|
273
|
+
group.sort((a, b) => {
|
|
274
|
+
const sa = page.shapes.get(a.edge.sourceId);
|
|
275
|
+
const sb = page.shapes.get(b.edge.sourceId);
|
|
276
|
+
if (!sa || !sb)
|
|
277
|
+
return 0;
|
|
278
|
+
const saCx = sa.bounds.x + sa.bounds.width / 2;
|
|
279
|
+
const saCy = sa.bounds.y + sa.bounds.height / 2;
|
|
280
|
+
const sbCx = sb.bounds.x + sb.bounds.width / 2;
|
|
281
|
+
const sbCy = sb.bounds.y + sb.bounds.height / 2;
|
|
282
|
+
if (face === "top" || face === "bottom")
|
|
283
|
+
return saCx - sbCx;
|
|
284
|
+
return saCy - sbCy;
|
|
285
|
+
});
|
|
286
|
+
for (let i = 0; i < n; i++) {
|
|
287
|
+
const pos = (i + 1) / (n + 1);
|
|
288
|
+
const info = group[i].info;
|
|
289
|
+
if (!info.ports)
|
|
290
|
+
continue;
|
|
291
|
+
if (face === "top" || face === "bottom") {
|
|
292
|
+
info.ports.entryX = pos;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
info.ports.entryY = pos;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ── Label x-offset spreading ─────────────────────────────────
|
|
300
|
+
/**
|
|
301
|
+
* Spread label x-offsets for labeled edges sharing the same source shape,
|
|
302
|
+
* so labels don't all cluster at the midpoint.
|
|
303
|
+
*
|
|
304
|
+
* For N labeled edges from same source:
|
|
305
|
+
* N=1 → x=0 (centered)
|
|
306
|
+
* N=2 → x at -0.15, +0.15
|
|
307
|
+
* N=3 → x at -0.3, 0, +0.3
|
|
308
|
+
* General: x = -0.3 + (i * 0.6) / (N - 1)
|
|
309
|
+
*/
|
|
310
|
+
function applyLabelOffsetSpreading(infos, edges) {
|
|
311
|
+
// Group labeled edges by source shape
|
|
312
|
+
const labelGroups = new Map();
|
|
313
|
+
for (const edge of edges) {
|
|
314
|
+
if (!edge.label)
|
|
315
|
+
continue;
|
|
316
|
+
const info = infos.get(edge.id);
|
|
317
|
+
if (!info)
|
|
318
|
+
continue;
|
|
319
|
+
const key = edge.sourceId;
|
|
320
|
+
if (!labelGroups.has(key))
|
|
321
|
+
labelGroups.set(key, []);
|
|
322
|
+
labelGroups.get(key).push({ edge, info });
|
|
323
|
+
}
|
|
324
|
+
for (const [, group] of labelGroups) {
|
|
325
|
+
const n = group.length;
|
|
326
|
+
if (n <= 1)
|
|
327
|
+
continue;
|
|
328
|
+
// Sort by target ID for deterministic ordering
|
|
329
|
+
group.sort((a, b) => a.edge.targetId.localeCompare(b.edge.targetId));
|
|
330
|
+
for (let i = 0; i < n; i++) {
|
|
331
|
+
const x = -0.3 + (i * 0.6) / (n - 1);
|
|
332
|
+
group[i].info.labelOffsetX = Math.round(x * 100) / 100;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=connector-intelligence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-intelligence.js","sourceRoot":"","sources":["../../src/serialization/connector-intelligence.ts"],"names":[],"mappings":"AAqBA,gEAAgE;AAEhE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAU;IAEV,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvC,0DAA0D;IAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,2FAA2F;IAC3F,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE1C,gGAAgG;IAChG,yBAAyB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAU,EACV,IAAU;IAEV,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE9C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC5F,CAAC;IAED,gFAAgF;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAgC,CAAC;IACpD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QAC1D,OAAO;YACL,KAAK,EAAE;gBACL,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBACzC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;gBAClD,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC;gBACpD,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC;aACrD;YACD,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;SAChB,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,CAAC;IAC7D,MAAM,KAAK,GAAG,UAAU;QACtB,CAAC,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC;QAC9C,CAAC,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,KAAK;QACL,QAAQ;QACR,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC;QAC/B,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;KAChB,CAAC;AACJ,CAAC;AAED,gEAAgE;AAEhE;;;GAGG;AACH,SAAS,YAAY,CAAC,MAAc,EAAE,MAAc;IAClD,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,QAAQ,IAAI,CAAC,EAAE,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,OAAO,CAAC;IACrD,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,GAAG,GAAG;QAAE,OAAO,QAAQ,CAAC;IACtD,IAAI,QAAQ,IAAI,CAAC,GAAG,IAAI,QAAQ,GAAG,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,MAAM,CAAC,CAAC,6BAA6B;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,IAAU;IAC5B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC;QAC5B,KAAK,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC;QAC5B,KAAK,KAAK,CAAC,CAAC,OAAO,QAAQ,CAAC;QAC5B,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC;IAC9B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAa,EAAE,MAAa;IAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEjC,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEhD,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,CAAC;QACb,KAAK,EAAE,IAAI,CAAC,CAAC;QACb,MAAM,EAAE,KAAK,CAAC,CAAC;QACf,MAAM,EAAE,KAAK,CAAC,CAAC;KAChB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,MAAa,EAAE,MAAa,EAAE,IAAU;IACtE,0EAA0E;IAC1E,kEAAkE;IAClE,IAAI,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE1C,iFAAiF;IACjF,IAAI,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,eAAe,GAAG,iBAAiB,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAErD,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,CAAC;QACb,KAAK,EAAE,IAAI,CAAC,CAAC;QACb,MAAM,EAAE,KAAK,CAAC,CAAC;QACf,MAAM,EAAE,KAAK,CAAC,CAAC;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAgB,EAAE,IAAU;IACrD,iEAAiE;IACjE,IAAI,UAAkB,CAAC;IACvB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YAAE,UAAU,GAAG,CAAC,CAAC;YAAC,MAAM;QACpC,KAAK,QAAQ;YAAE,UAAU,GAAG,EAAE,CAAC;YAAC,MAAM;QACtC,KAAK,MAAM;YAAE,UAAU,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAAC,MAAM;QAC5D,KAAK,KAAK;YAAE,UAAU,GAAG,CAAC,EAAE,CAAC;YAAC,MAAM;IACtC,CAAC;IAED,0DAA0D;IAC1D,MAAM,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACxC,OAAO,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,IAAU,EAAE,UAAkB;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO,CAAC,CAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QACvE,KAAK,MAAM,CAAC,CAAG,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QACvE,KAAK,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;QACvE,KAAK,KAAK,CAAC,CAAI,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IACzE,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,CAAS,EAAE,GAAW,EAAE,GAAW;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,gEAAgE;AAEhE;;;GAGG;AACH,SAAS,oBAAoB,CAC3B,KAAkC,EAClC,KAAa,EACb,IAAU;IAEV,sCAAsC;IACtC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkD,CAAC;IAC7E,uCAAuC;IACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAC;IAE9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,SAAS;QAE7C,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1D,UAAU,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACtD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC9D,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,0CAA0C;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,SAAS;QAEhC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAS,CAAC;QACvC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,2CAA2C;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,SAAS;QAEhC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAS,CAAC;QACvC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CACtB,KAA6C,EAC7C,IAAU,EACV,IAAU;IAEV,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAEvB,yDAAyD;IACzD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhD,2EAA2E;QAC3E,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,GAAG,IAAI,CAAC;QAC5D,OAAO,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,wDAAwD;IACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,SAAS;QAE1B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,KAA6C,EAC7C,IAAU,EACV,IAAU;IAEV,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAEvB,yDAAyD;IACzD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,GAAG,IAAI,CAAC;QAC5D,OAAO,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,SAAS;QAE1B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC;AAED,gEAAgE;AAEhE;;;;;;;;;GASG;AACH,SAAS,yBAAyB,CAChC,KAAkC,EAClC,KAAa;IAEb,sCAAsC;IACtC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAC;IAE9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,SAAS;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACpD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAErB,+CAA+C;QAC/C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAErE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACrC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACzD,CAAC;IACH,CAAC;AACH,CAAC"}
|