@msdshsk/react-er-canvas 0.0.1
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/NOTICE.md +48 -0
- package/README.ja.md +216 -0
- package/README.md +216 -0
- package/dist/components/JoinEdge.d.ts +10 -0
- package/dist/components/JoinEdge.d.ts.map +1 -0
- package/dist/components/MermaidER.d.ts +46 -0
- package/dist/components/MermaidER.d.ts.map +1 -0
- package/dist/components/TableNode.d.ts +30 -0
- package/dist/components/TableNode.d.ts.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/layout.d.ts +58 -0
- package/dist/core/layout.d.ts.map +1 -0
- package/dist/core/layout.test.d.ts +2 -0
- package/dist/core/layout.test.d.ts.map +1 -0
- package/dist/core/model.d.ts +55 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/parser/grammar.d.ts +22 -0
- package/dist/core/parser/grammar.d.ts.map +1 -0
- package/dist/core/parser/index.d.ts +15 -0
- package/dist/core/parser/index.d.ts.map +1 -0
- package/dist/core/parser/lexer.d.ts +18 -0
- package/dist/core/parser/lexer.d.ts.map +1 -0
- package/dist/core/parser/parser.test.d.ts +2 -0
- package/dist/core/parser/parser.test.d.ts.map +1 -0
- package/dist/core/parser/resolve.test.d.ts +2 -0
- package/dist/core/parser/resolve.test.d.ts.map +1 -0
- package/dist/core-BtdV83x9.cjs +2 -0
- package/dist/core-BtdV83x9.cjs.map +1 -0
- package/dist/core-DZ30VgUT.js +345 -0
- package/dist/core-DZ30VgUT.js.map +1 -0
- package/dist/core.cjs +1 -0
- package/dist/core.js +2 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +592 -0
- package/dist/index.js.map +1 -0
- package/package.json +92 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
import { a as e, c as t, i as n, n as r, o as i, r as a, s as o, t as s } from "./core-DZ30VgUT.js";
|
|
2
|
+
import { Fragment as c, createContext as l, memo as u, useCallback as d, useContext as f, useEffect as p, useMemo as m, useState as h } from "react";
|
|
3
|
+
import { Background as ee, BaseEdge as g, Controls as _, EdgeLabelRenderer as v, Handle as y, MiniMap as te, Position as b, ReactFlow as ne, getSmoothStepPath as x, useNodesState as S } from "@xyflow/react";
|
|
4
|
+
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/TableNode.tsx
|
|
6
|
+
var E = l(/* @__PURE__ */ new Map()), D = l({
|
|
7
|
+
enabled: !1,
|
|
8
|
+
selected: /* @__PURE__ */ new Set(),
|
|
9
|
+
onToggle: () => void 0
|
|
10
|
+
}), O = l(!1), k = l({}), A = {
|
|
11
|
+
pk: {
|
|
12
|
+
label: "PK",
|
|
13
|
+
bg: "#f59e0b"
|
|
14
|
+
},
|
|
15
|
+
fk: {
|
|
16
|
+
label: "FK",
|
|
17
|
+
bg: "#3b82f6"
|
|
18
|
+
},
|
|
19
|
+
uk: {
|
|
20
|
+
label: "UK",
|
|
21
|
+
bg: "#10b981"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
function j({ tableName: e, column: t, highlighted: n, onClick: r, selectionEnabled: i, selected: a, onSelectToggle: o }) {
|
|
25
|
+
let s = [];
|
|
26
|
+
return t.keys.pk && s.push(A.pk), t.keys.fk && s.push(A.fk), t.keys.uk && s.push(A.uk), /* @__PURE__ */ T("div", {
|
|
27
|
+
title: t.comment,
|
|
28
|
+
onClick: r ? () => r(e, t.name) : void 0,
|
|
29
|
+
style: {
|
|
30
|
+
display: "flex",
|
|
31
|
+
alignItems: "center",
|
|
32
|
+
gap: 6,
|
|
33
|
+
padding: "0 10px",
|
|
34
|
+
fontSize: 12,
|
|
35
|
+
fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
|
|
36
|
+
borderTop: "1px solid #eee",
|
|
37
|
+
height: 22,
|
|
38
|
+
boxSizing: "border-box",
|
|
39
|
+
cursor: r ? "pointer" : "default",
|
|
40
|
+
background: n ? "#fef3c7" : a ? "#eff6ff" : "transparent",
|
|
41
|
+
transition: "background 0.15s"
|
|
42
|
+
},
|
|
43
|
+
children: [
|
|
44
|
+
i && /* @__PURE__ */ w("input", {
|
|
45
|
+
type: "checkbox",
|
|
46
|
+
checked: a,
|
|
47
|
+
onChange: (e) => o(e.target.checked),
|
|
48
|
+
onClick: (e) => e.stopPropagation(),
|
|
49
|
+
style: {
|
|
50
|
+
width: 13,
|
|
51
|
+
height: 13,
|
|
52
|
+
margin: 0,
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
cursor: "pointer"
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ w("span", {
|
|
58
|
+
style: {
|
|
59
|
+
display: "flex",
|
|
60
|
+
gap: 2,
|
|
61
|
+
flexShrink: 0,
|
|
62
|
+
minWidth: 18
|
|
63
|
+
},
|
|
64
|
+
children: s.map((e) => /* @__PURE__ */ w("span", {
|
|
65
|
+
style: {
|
|
66
|
+
display: "inline-block",
|
|
67
|
+
padding: "0 4px",
|
|
68
|
+
borderRadius: 3,
|
|
69
|
+
background: e.bg,
|
|
70
|
+
color: "#fff",
|
|
71
|
+
fontSize: 9,
|
|
72
|
+
fontWeight: 700,
|
|
73
|
+
lineHeight: "14px"
|
|
74
|
+
},
|
|
75
|
+
children: e.label
|
|
76
|
+
}, e.label))
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ w("span", {
|
|
79
|
+
style: {
|
|
80
|
+
flexShrink: 0,
|
|
81
|
+
fontWeight: t.keys.pk ? 600 : 400,
|
|
82
|
+
color: "#1f2937"
|
|
83
|
+
},
|
|
84
|
+
children: t.name
|
|
85
|
+
}),
|
|
86
|
+
t.type && /* @__PURE__ */ w("span", {
|
|
87
|
+
style: {
|
|
88
|
+
flex: 1,
|
|
89
|
+
textAlign: "right",
|
|
90
|
+
color: "#9ca3af",
|
|
91
|
+
fontStyle: "italic",
|
|
92
|
+
overflow: "hidden",
|
|
93
|
+
textOverflow: "ellipsis",
|
|
94
|
+
whiteSpace: "nowrap"
|
|
95
|
+
},
|
|
96
|
+
children: t.type
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
var M = u(function({ data: e }) {
|
|
102
|
+
let { table: t } = e, n = f(E), r = f(D), i = f(O), a = f(k), o = a.onColumnClick, s = n.get(t.name), l = t.group ? "#1e40af" : "#374151", u = (e) => ({
|
|
103
|
+
...e,
|
|
104
|
+
width: i ? 9 : 6,
|
|
105
|
+
height: i ? 9 : 6,
|
|
106
|
+
background: i ? "#3b82f6" : "transparent",
|
|
107
|
+
border: i ? "1.5px solid #fff" : "none",
|
|
108
|
+
boxShadow: i ? "0 0 0 1px rgba(59,130,246,0.4)" : "none",
|
|
109
|
+
opacity: i ? .85 : 0,
|
|
110
|
+
pointerEvents: i ? "auto" : "none",
|
|
111
|
+
cursor: i ? "crosshair" : "default"
|
|
112
|
+
});
|
|
113
|
+
return /* @__PURE__ */ T("div", {
|
|
114
|
+
style: {
|
|
115
|
+
background: "#fff",
|
|
116
|
+
border: "1px solid #c4c4c4",
|
|
117
|
+
borderRadius: 6,
|
|
118
|
+
boxShadow: "0 2px 6px rgba(0,0,0,0.08)",
|
|
119
|
+
overflow: "visible",
|
|
120
|
+
width: "100%",
|
|
121
|
+
height: "100%",
|
|
122
|
+
display: "flex",
|
|
123
|
+
flexDirection: "column",
|
|
124
|
+
position: "relative"
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
/* @__PURE__ */ w(y, {
|
|
128
|
+
id: "__default-target",
|
|
129
|
+
type: "target",
|
|
130
|
+
position: b.Left,
|
|
131
|
+
style: u({ top: 32 / 2 })
|
|
132
|
+
}),
|
|
133
|
+
/* @__PURE__ */ w(y, {
|
|
134
|
+
id: "__default-source",
|
|
135
|
+
type: "source",
|
|
136
|
+
position: b.Right,
|
|
137
|
+
style: u({ top: 32 / 2 })
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ T("div", {
|
|
140
|
+
style: {
|
|
141
|
+
padding: "6px 10px",
|
|
142
|
+
background: l,
|
|
143
|
+
color: "#fff",
|
|
144
|
+
fontWeight: 600,
|
|
145
|
+
fontSize: 13,
|
|
146
|
+
height: 32,
|
|
147
|
+
boxSizing: "border-box",
|
|
148
|
+
display: "flex",
|
|
149
|
+
alignItems: "center",
|
|
150
|
+
justifyContent: "space-between",
|
|
151
|
+
gap: 8,
|
|
152
|
+
borderTopLeftRadius: 6,
|
|
153
|
+
borderTopRightRadius: 6
|
|
154
|
+
},
|
|
155
|
+
children: [/* @__PURE__ */ w("span", {
|
|
156
|
+
style: {
|
|
157
|
+
overflow: "hidden",
|
|
158
|
+
textOverflow: "ellipsis",
|
|
159
|
+
whiteSpace: "nowrap"
|
|
160
|
+
},
|
|
161
|
+
children: t.name
|
|
162
|
+
}), /* @__PURE__ */ T("span", {
|
|
163
|
+
style: {
|
|
164
|
+
display: "flex",
|
|
165
|
+
alignItems: "center",
|
|
166
|
+
gap: 4,
|
|
167
|
+
flexShrink: 0
|
|
168
|
+
},
|
|
169
|
+
children: [t.group && /* @__PURE__ */ w("span", {
|
|
170
|
+
style: {
|
|
171
|
+
fontSize: 10,
|
|
172
|
+
opacity: .75,
|
|
173
|
+
fontWeight: 400,
|
|
174
|
+
padding: "1px 5px",
|
|
175
|
+
border: "1px solid rgba(255,255,255,0.3)",
|
|
176
|
+
borderRadius: 3
|
|
177
|
+
},
|
|
178
|
+
children: t.group
|
|
179
|
+
}), a.onTableRemove && /* @__PURE__ */ w("button", {
|
|
180
|
+
className: "nodrag",
|
|
181
|
+
onClick: (e) => {
|
|
182
|
+
e.stopPropagation(), a.onTableRemove?.(t.name);
|
|
183
|
+
},
|
|
184
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
185
|
+
title: "Remove this table",
|
|
186
|
+
style: {
|
|
187
|
+
background: "rgba(255,255,255,0.18)",
|
|
188
|
+
border: "none",
|
|
189
|
+
color: "#fff",
|
|
190
|
+
width: 18,
|
|
191
|
+
height: 18,
|
|
192
|
+
borderRadius: 3,
|
|
193
|
+
cursor: "pointer",
|
|
194
|
+
fontSize: 13,
|
|
195
|
+
fontWeight: 700,
|
|
196
|
+
padding: 0,
|
|
197
|
+
lineHeight: 1,
|
|
198
|
+
display: "flex",
|
|
199
|
+
alignItems: "center",
|
|
200
|
+
justifyContent: "center"
|
|
201
|
+
},
|
|
202
|
+
children: "×"
|
|
203
|
+
})]
|
|
204
|
+
})]
|
|
205
|
+
}),
|
|
206
|
+
t.columns.map((e, n) => {
|
|
207
|
+
let i = 32 + n * 22 + 22 / 2, a = s?.has(e.name) ?? !1, l = `${t.name}.${e.name}`, d = r.enabled && r.selected.has(l);
|
|
208
|
+
return /* @__PURE__ */ T(c, { children: [
|
|
209
|
+
/* @__PURE__ */ w(y, {
|
|
210
|
+
id: `${e.name}__target`,
|
|
211
|
+
type: "target",
|
|
212
|
+
position: b.Left,
|
|
213
|
+
style: u({ top: i })
|
|
214
|
+
}),
|
|
215
|
+
/* @__PURE__ */ w(y, {
|
|
216
|
+
id: `${e.name}__source`,
|
|
217
|
+
type: "source",
|
|
218
|
+
position: b.Right,
|
|
219
|
+
style: u({ top: i })
|
|
220
|
+
}),
|
|
221
|
+
/* @__PURE__ */ w(j, {
|
|
222
|
+
tableName: t.name,
|
|
223
|
+
column: e,
|
|
224
|
+
highlighted: a,
|
|
225
|
+
onClick: o,
|
|
226
|
+
selectionEnabled: r.enabled,
|
|
227
|
+
selected: d,
|
|
228
|
+
onSelectToggle: (n) => r.onToggle(t.name, e.name, n)
|
|
229
|
+
})
|
|
230
|
+
] }, `${e.name}-${n}`);
|
|
231
|
+
})
|
|
232
|
+
]
|
|
233
|
+
});
|
|
234
|
+
}), N = u(function({ id: e, sourceX: t, sourceY: n, targetX: r, targetY: i, sourcePosition: a, targetPosition: o, data: s, selected: c }) {
|
|
235
|
+
let [l, u, d] = x({
|
|
236
|
+
sourceX: t,
|
|
237
|
+
sourceY: n,
|
|
238
|
+
sourcePosition: a,
|
|
239
|
+
targetX: r,
|
|
240
|
+
targetY: i,
|
|
241
|
+
targetPosition: o
|
|
242
|
+
}), f = s ?? {}, p = !!c || !!f.hovered, m = f.color || "#3b82f6";
|
|
243
|
+
return /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(g, {
|
|
244
|
+
id: e,
|
|
245
|
+
path: l,
|
|
246
|
+
style: {
|
|
247
|
+
stroke: m,
|
|
248
|
+
strokeWidth: p ? 2.5 : 2,
|
|
249
|
+
strokeDasharray: "6 3"
|
|
250
|
+
}
|
|
251
|
+
}), /* @__PURE__ */ w(v, { children: /* @__PURE__ */ T("div", {
|
|
252
|
+
className: "nodrag nopan",
|
|
253
|
+
style: {
|
|
254
|
+
position: "absolute",
|
|
255
|
+
transform: `translate(-50%, -50%) translate(${u}px, ${d}px)`,
|
|
256
|
+
background: m,
|
|
257
|
+
color: "#fff",
|
|
258
|
+
fontSize: 10,
|
|
259
|
+
fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
|
|
260
|
+
fontWeight: 700,
|
|
261
|
+
borderRadius: 3,
|
|
262
|
+
padding: "2px 4px 2px 6px",
|
|
263
|
+
display: "flex",
|
|
264
|
+
alignItems: "center",
|
|
265
|
+
gap: 4,
|
|
266
|
+
pointerEvents: "all",
|
|
267
|
+
boxShadow: p ? "0 0 0 2px rgba(0,0,0,0.4)" : "0 1px 2px rgba(0,0,0,0.15)",
|
|
268
|
+
userSelect: "none"
|
|
269
|
+
},
|
|
270
|
+
children: [/* @__PURE__ */ w("span", { children: f.type }), f.onDelete && /* @__PURE__ */ w("button", {
|
|
271
|
+
type: "button",
|
|
272
|
+
onClick: (e) => {
|
|
273
|
+
e.stopPropagation(), f.onDelete?.();
|
|
274
|
+
},
|
|
275
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
276
|
+
title: "Remove this JOIN",
|
|
277
|
+
style: {
|
|
278
|
+
background: "rgba(255,255,255,0.25)",
|
|
279
|
+
border: "none",
|
|
280
|
+
color: "#fff",
|
|
281
|
+
width: 14,
|
|
282
|
+
height: 14,
|
|
283
|
+
borderRadius: 2,
|
|
284
|
+
cursor: "pointer",
|
|
285
|
+
fontSize: 11,
|
|
286
|
+
fontWeight: 700,
|
|
287
|
+
padding: 0,
|
|
288
|
+
lineHeight: 1,
|
|
289
|
+
display: "flex",
|
|
290
|
+
alignItems: "center",
|
|
291
|
+
justifyContent: "center"
|
|
292
|
+
},
|
|
293
|
+
children: "×"
|
|
294
|
+
})]
|
|
295
|
+
}) })] });
|
|
296
|
+
}), P = { table: M }, re = { joinEdge: N };
|
|
297
|
+
function ie(e) {
|
|
298
|
+
try {
|
|
299
|
+
return {
|
|
300
|
+
model: t(e),
|
|
301
|
+
error: null
|
|
302
|
+
};
|
|
303
|
+
} catch (e) {
|
|
304
|
+
if (e instanceof o) return {
|
|
305
|
+
model: null,
|
|
306
|
+
error: e
|
|
307
|
+
};
|
|
308
|
+
throw e;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function F(e, t) {
|
|
312
|
+
return t ? `${t}__${e}` : `__default-${e}`;
|
|
313
|
+
}
|
|
314
|
+
var I = "join:";
|
|
315
|
+
function L(e) {
|
|
316
|
+
if (!e || e.startsWith("__default-")) return;
|
|
317
|
+
let t = /^(.+)__(?:source|target)$/.exec(e);
|
|
318
|
+
return t ? t[1] : void 0;
|
|
319
|
+
}
|
|
320
|
+
function R(e) {
|
|
321
|
+
return `${e.table}.${e.column}`;
|
|
322
|
+
}
|
|
323
|
+
var ae = {
|
|
324
|
+
INNER: "#3b82f6",
|
|
325
|
+
LEFT: "#8b5cf6",
|
|
326
|
+
RIGHT: "#a855f7",
|
|
327
|
+
FULL: "#ec4899",
|
|
328
|
+
CROSS: "#6b7280"
|
|
329
|
+
};
|
|
330
|
+
function z(e) {
|
|
331
|
+
let { source: t, model: n, algorithm: r, direction: a, aspectRatio: o, positions: s, onPositionsChange: c, showColumnCheckboxes: l, selectedColumns: u, onColumnSelectionChange: f, enableManualJoins: g, joins: v, onJoinConnect: y, onJoinDelete: b, onTableRemove: x, onColumnClick: C, onTableClick: A, deleteKeyCode: j = "Delete", className: M, style: N, highlightReferencesOnHover: z = !0 } = e, { model: B, error: V } = m(() => n ? {
|
|
332
|
+
model: n,
|
|
333
|
+
error: null
|
|
334
|
+
} : t == null ? {
|
|
335
|
+
model: null,
|
|
336
|
+
error: null
|
|
337
|
+
} : ie(t), [t, n]), [H, U] = h(null), [W, G] = h(null);
|
|
338
|
+
p(() => {
|
|
339
|
+
if (!B) {
|
|
340
|
+
U(null);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
let e = !1;
|
|
344
|
+
return i(B, {
|
|
345
|
+
algorithm: r,
|
|
346
|
+
direction: a,
|
|
347
|
+
aspectRatio: o
|
|
348
|
+
}).then((t) => {
|
|
349
|
+
e || U(t);
|
|
350
|
+
}), () => {
|
|
351
|
+
e = !0;
|
|
352
|
+
};
|
|
353
|
+
}, [
|
|
354
|
+
B,
|
|
355
|
+
r,
|
|
356
|
+
a,
|
|
357
|
+
o
|
|
358
|
+
]);
|
|
359
|
+
let K = m(() => {
|
|
360
|
+
if (!H || !B) return [];
|
|
361
|
+
let e = new Map(B.tables.map((e) => [e.name, e])), t = [];
|
|
362
|
+
for (let n of H.nodes) {
|
|
363
|
+
let r = e.get(n.id);
|
|
364
|
+
if (!r) continue;
|
|
365
|
+
let i = s?.[n.id], a = { table: r };
|
|
366
|
+
t.push({
|
|
367
|
+
id: n.id,
|
|
368
|
+
type: "table",
|
|
369
|
+
position: i ?? {
|
|
370
|
+
x: n.x,
|
|
371
|
+
y: n.y
|
|
372
|
+
},
|
|
373
|
+
data: a,
|
|
374
|
+
width: n.width,
|
|
375
|
+
height: n.height,
|
|
376
|
+
draggable: !0,
|
|
377
|
+
deletable: !1
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return t;
|
|
381
|
+
}, [
|
|
382
|
+
H,
|
|
383
|
+
B,
|
|
384
|
+
s
|
|
385
|
+
]), [q, J, oe] = S(K);
|
|
386
|
+
p(() => {
|
|
387
|
+
J(K);
|
|
388
|
+
}, [K, J]);
|
|
389
|
+
let se = d((e, t, n) => {
|
|
390
|
+
if (!c) return;
|
|
391
|
+
let r = { ...s ?? {} };
|
|
392
|
+
for (let e of n) r[e.id] = {
|
|
393
|
+
x: e.position.x,
|
|
394
|
+
y: e.position.y
|
|
395
|
+
};
|
|
396
|
+
c(r);
|
|
397
|
+
}, [s, c]), Y = m(() => {
|
|
398
|
+
if (!(!W || !B)) return B.relations.find((e) => e.id === W);
|
|
399
|
+
}, [W, B]), X = m(() => {
|
|
400
|
+
if (!W || !v || !W.startsWith(I)) return;
|
|
401
|
+
let e = W.slice(5);
|
|
402
|
+
return v.find((t) => t.id === e);
|
|
403
|
+
}, [W, v]), ce = m(() => {
|
|
404
|
+
let e = /* @__PURE__ */ new Map();
|
|
405
|
+
if (!z) return e;
|
|
406
|
+
let t = (t, n) => {
|
|
407
|
+
if (!n) return;
|
|
408
|
+
let r = e.get(t) ?? /* @__PURE__ */ new Set();
|
|
409
|
+
r.add(n), e.set(t, r);
|
|
410
|
+
};
|
|
411
|
+
return Y && (t(Y.from, Y.fromColumn), t(Y.to, Y.toColumn)), X && (t(X.source.table, X.source.column), t(X.target.table, X.target.column)), e;
|
|
412
|
+
}, [
|
|
413
|
+
Y,
|
|
414
|
+
X,
|
|
415
|
+
z
|
|
416
|
+
]), Z = m(() => new Set((u ?? []).map(R)), [u]), Q = d((e, t, n) => {
|
|
417
|
+
if (!f) return;
|
|
418
|
+
let r = u ?? [];
|
|
419
|
+
if (n) {
|
|
420
|
+
if (r.some((n) => n.table === e && n.column === t)) return;
|
|
421
|
+
f([...r, {
|
|
422
|
+
table: e,
|
|
423
|
+
column: t
|
|
424
|
+
}]);
|
|
425
|
+
} else f(r.filter((n) => !(n.table === e && n.column === t)));
|
|
426
|
+
}, [u, f]), le = m(() => ({
|
|
427
|
+
enabled: l ?? !1,
|
|
428
|
+
selected: Z,
|
|
429
|
+
onToggle: Q
|
|
430
|
+
}), [
|
|
431
|
+
l,
|
|
432
|
+
Z,
|
|
433
|
+
Q
|
|
434
|
+
]), ue = m(() => {
|
|
435
|
+
if (!H || !B) return [];
|
|
436
|
+
let e = new Set(B.tables.map((e) => e.name)), t = new Map(B.relations.map((e) => [e.id, e])), n = [];
|
|
437
|
+
for (let r of H.edges) {
|
|
438
|
+
if (!e.has(r.source) || !e.has(r.target)) continue;
|
|
439
|
+
let i = t.get(r.id), a = r.id === W;
|
|
440
|
+
n.push({
|
|
441
|
+
id: r.id,
|
|
442
|
+
source: r.source,
|
|
443
|
+
target: r.target,
|
|
444
|
+
sourceHandle: F("source", i?.fromColumn),
|
|
445
|
+
targetHandle: F("target", i?.toColumn),
|
|
446
|
+
type: "smoothstep",
|
|
447
|
+
animated: a,
|
|
448
|
+
deletable: !1,
|
|
449
|
+
style: {
|
|
450
|
+
stroke: a ? "#f59e0b" : "#9ca3af",
|
|
451
|
+
strokeWidth: a ? 2 : 1.5
|
|
452
|
+
},
|
|
453
|
+
label: i?.label,
|
|
454
|
+
labelStyle: {
|
|
455
|
+
fontSize: 10,
|
|
456
|
+
fill: "#6b7280"
|
|
457
|
+
},
|
|
458
|
+
labelBgStyle: {
|
|
459
|
+
fill: "#fff",
|
|
460
|
+
fillOpacity: .85
|
|
461
|
+
},
|
|
462
|
+
labelBgPadding: [4, 2],
|
|
463
|
+
labelBgBorderRadius: 3
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
let r = [];
|
|
467
|
+
for (let t of v ?? []) {
|
|
468
|
+
if (!e.has(t.source.table) || !e.has(t.target.table)) continue;
|
|
469
|
+
let n = `${I}${t.id}`, i = n === W, a = ae[t.type] ?? "#3b82f6", o = {
|
|
470
|
+
type: t.type,
|
|
471
|
+
color: a,
|
|
472
|
+
hovered: i,
|
|
473
|
+
onDelete: b ? () => b(t.id) : void 0
|
|
474
|
+
};
|
|
475
|
+
r.push({
|
|
476
|
+
id: n,
|
|
477
|
+
source: t.source.table,
|
|
478
|
+
target: t.target.table,
|
|
479
|
+
sourceHandle: F("source", t.source.column),
|
|
480
|
+
targetHandle: F("target", t.target.column),
|
|
481
|
+
type: "joinEdge",
|
|
482
|
+
deletable: !0,
|
|
483
|
+
data: o
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
return [...n, ...r];
|
|
487
|
+
}, [
|
|
488
|
+
H,
|
|
489
|
+
B,
|
|
490
|
+
v,
|
|
491
|
+
W,
|
|
492
|
+
b
|
|
493
|
+
]), de = d((e) => {
|
|
494
|
+
y && (!e.source || !e.target || y({
|
|
495
|
+
table: e.source,
|
|
496
|
+
column: L(e.sourceHandle)
|
|
497
|
+
}, {
|
|
498
|
+
table: e.target,
|
|
499
|
+
column: L(e.targetHandle)
|
|
500
|
+
}));
|
|
501
|
+
}, [y]), fe = d((e) => {
|
|
502
|
+
if (b) for (let t of e) t.id.startsWith(I) && b(t.id.slice(5));
|
|
503
|
+
}, [b]), $ = !!g, pe = m(() => ({
|
|
504
|
+
onTableRemove: x,
|
|
505
|
+
onColumnClick: C
|
|
506
|
+
}), [x, C]);
|
|
507
|
+
return /* @__PURE__ */ T("div", {
|
|
508
|
+
className: M,
|
|
509
|
+
style: {
|
|
510
|
+
width: "100%",
|
|
511
|
+
height: "100%",
|
|
512
|
+
position: "relative",
|
|
513
|
+
...N
|
|
514
|
+
},
|
|
515
|
+
children: [
|
|
516
|
+
V && /* @__PURE__ */ w("div", {
|
|
517
|
+
style: {
|
|
518
|
+
position: "absolute",
|
|
519
|
+
top: 8,
|
|
520
|
+
left: 8,
|
|
521
|
+
right: 8,
|
|
522
|
+
zIndex: 10,
|
|
523
|
+
padding: "8px 12px",
|
|
524
|
+
background: "#fef2f2",
|
|
525
|
+
border: "1px solid #fecaca",
|
|
526
|
+
borderRadius: 6,
|
|
527
|
+
color: "#991b1b",
|
|
528
|
+
fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
|
|
529
|
+
fontSize: 12,
|
|
530
|
+
whiteSpace: "pre-wrap"
|
|
531
|
+
},
|
|
532
|
+
children: V.message
|
|
533
|
+
}),
|
|
534
|
+
!V && !H && /* @__PURE__ */ w("div", {
|
|
535
|
+
style: {
|
|
536
|
+
position: "absolute",
|
|
537
|
+
inset: 0,
|
|
538
|
+
display: "flex",
|
|
539
|
+
alignItems: "center",
|
|
540
|
+
justifyContent: "center",
|
|
541
|
+
color: "#9ca3af",
|
|
542
|
+
fontSize: 13
|
|
543
|
+
},
|
|
544
|
+
children: "Computing layout…"
|
|
545
|
+
}),
|
|
546
|
+
/* @__PURE__ */ w(E.Provider, {
|
|
547
|
+
value: ce,
|
|
548
|
+
children: /* @__PURE__ */ w(D.Provider, {
|
|
549
|
+
value: le,
|
|
550
|
+
children: /* @__PURE__ */ w(O.Provider, {
|
|
551
|
+
value: $,
|
|
552
|
+
children: /* @__PURE__ */ w(k.Provider, {
|
|
553
|
+
value: pe,
|
|
554
|
+
children: /* @__PURE__ */ T(ne, {
|
|
555
|
+
nodes: q,
|
|
556
|
+
edges: ue,
|
|
557
|
+
nodeTypes: P,
|
|
558
|
+
edgeTypes: re,
|
|
559
|
+
fitView: !0,
|
|
560
|
+
onNodesChange: oe,
|
|
561
|
+
onNodeDragStop: se,
|
|
562
|
+
onNodeClick: A ? (e, t) => A(t.id) : void 0,
|
|
563
|
+
onEdgeMouseEnter: (e, t) => G(t.id),
|
|
564
|
+
onEdgeMouseLeave: () => G(null),
|
|
565
|
+
onConnect: de,
|
|
566
|
+
onEdgesDelete: fe,
|
|
567
|
+
nodesDraggable: !0,
|
|
568
|
+
nodesConnectable: $,
|
|
569
|
+
elementsSelectable: !0,
|
|
570
|
+
deleteKeyCode: j,
|
|
571
|
+
minZoom: .1,
|
|
572
|
+
maxZoom: 4,
|
|
573
|
+
children: [
|
|
574
|
+
/* @__PURE__ */ w(ee, {}),
|
|
575
|
+
/* @__PURE__ */ w(_, {}),
|
|
576
|
+
/* @__PURE__ */ w(te, {
|
|
577
|
+
pannable: !0,
|
|
578
|
+
zoomable: !0
|
|
579
|
+
})
|
|
580
|
+
]
|
|
581
|
+
})
|
|
582
|
+
})
|
|
583
|
+
})
|
|
584
|
+
})
|
|
585
|
+
})
|
|
586
|
+
]
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
//#endregion
|
|
590
|
+
export { s as HEADER_HEIGHT, z as MermaidER, o as MermaidERParseError, r as NODE_WIDTH, a as ROW_HEIGHT, n as VERTICAL_PADDING, e as estimateNodeHeight, i as layoutER, t as parseMermaidER };
|
|
591
|
+
|
|
592
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/components/TableNode.tsx","../src/components/JoinEdge.tsx","../src/components/MermaidER.tsx"],"sourcesContent":["import { Fragment, createContext, memo, useContext } from 'react';\nimport { Handle, Position } from '@xyflow/react';\nimport type { NodeProps } from '@xyflow/react';\nimport type { Column, Table } from '../core/model';\nimport { HEADER_HEIGHT, ROW_HEIGHT } from '../core/layout';\n\nexport interface TableNodeData extends Record<string, unknown> {\n table: Table;\n}\n\n/**\n * Map from table name -> set of highlighted column names.\n * Provided by MermaidER, consumed by TableNode for hover-driven highlighting\n * without forcing the whole node array to recompute on every hover change.\n */\nexport const HighlightContext = createContext<ReadonlyMap<string, ReadonlySet<string>>>(new Map());\n\nexport interface ColumnSelectionContextValue {\n enabled: boolean;\n /** \"table.column\" keys for fast lookup. */\n selected: ReadonlySet<string>;\n onToggle: (table: string, column: string, checked: boolean) => void;\n}\n\nexport const ColumnSelectionContext = createContext<ColumnSelectionContextValue>({\n enabled: false,\n selected: new Set(),\n onToggle: () => undefined,\n});\n\n/** When true, column handles become visible/connectable for manual JOIN drawing. */\nexport const ConnectModeContext = createContext<boolean>(false);\n\nexport interface TableActionsContextValue {\n /** When provided, a delete affordance is shown on the table header. */\n onTableRemove?: (table: string) => void;\n /** Per-column click handler. Provided via context (not node data) so its\n * identity can change without invalidating the React Flow node array. */\n onColumnClick?: (table: string, column: string) => void;\n}\n\nexport const TableActionsContext = createContext<TableActionsContextValue>({});\n\nconst KEY_STYLES: Record<'pk' | 'fk' | 'uk', { label: string; bg: string }> = {\n pk: { label: 'PK', bg: '#f59e0b' },\n fk: { label: 'FK', bg: '#3b82f6' },\n uk: { label: 'UK', bg: '#10b981' },\n};\n\nfunction ColumnRow({\n tableName,\n column,\n highlighted,\n onClick,\n selectionEnabled,\n selected,\n onSelectToggle,\n}: {\n tableName: string;\n column: Column;\n highlighted: boolean;\n onClick?: (table: string, column: string) => void;\n selectionEnabled: boolean;\n selected: boolean;\n onSelectToggle: (checked: boolean) => void;\n}) {\n const badges: Array<{ label: string; bg: string }> = [];\n if (column.keys.pk) badges.push(KEY_STYLES.pk);\n if (column.keys.fk) badges.push(KEY_STYLES.fk);\n if (column.keys.uk) badges.push(KEY_STYLES.uk);\n\n return (\n <div\n title={column.comment}\n onClick={onClick ? () => onClick(tableName, column.name) : undefined}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 10px',\n fontSize: 12,\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n borderTop: '1px solid #eee',\n height: ROW_HEIGHT,\n boxSizing: 'border-box',\n cursor: onClick ? 'pointer' : 'default',\n background: highlighted ? '#fef3c7' : selected ? '#eff6ff' : 'transparent',\n transition: 'background 0.15s',\n }}\n >\n {selectionEnabled && (\n <input\n type=\"checkbox\"\n checked={selected}\n onChange={(e) => onSelectToggle(e.target.checked)}\n onClick={(e) => e.stopPropagation()}\n style={{\n width: 13,\n height: 13,\n margin: 0,\n flexShrink: 0,\n cursor: 'pointer',\n }}\n />\n )}\n <span style={{ display: 'flex', gap: 2, flexShrink: 0, minWidth: 18 }}>\n {badges.map((b) => (\n <span\n key={b.label}\n style={{\n display: 'inline-block',\n padding: '0 4px',\n borderRadius: 3,\n background: b.bg,\n color: '#fff',\n fontSize: 9,\n fontWeight: 700,\n lineHeight: '14px',\n }}\n >\n {b.label}\n </span>\n ))}\n </span>\n <span\n style={{\n flexShrink: 0,\n fontWeight: column.keys.pk ? 600 : 400,\n color: '#1f2937',\n }}\n >\n {column.name}\n </span>\n {column.type && (\n <span\n style={{\n flex: 1,\n textAlign: 'right',\n color: '#9ca3af',\n fontStyle: 'italic',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {column.type}\n </span>\n )}\n </div>\n );\n}\n\nexport const TableNode = memo(function TableNode({ data }: NodeProps) {\n const { table } = data as TableNodeData;\n const highlightMap = useContext(HighlightContext);\n const selection = useContext(ColumnSelectionContext);\n const connectMode = useContext(ConnectModeContext);\n const tableActions = useContext(TableActionsContext);\n const onColumnClick = tableActions.onColumnClick;\n const highlightedCols = highlightMap.get(table.name);\n const headerBg = table.group ? '#1e40af' : '#374151';\n\n const handleStyle = (extra: { top?: number }): React.CSSProperties => ({\n ...extra,\n width: connectMode ? 9 : 6,\n height: connectMode ? 9 : 6,\n background: connectMode ? '#3b82f6' : 'transparent',\n border: connectMode ? '1.5px solid #fff' : 'none',\n boxShadow: connectMode ? '0 0 0 1px rgba(59,130,246,0.4)' : 'none',\n opacity: connectMode ? 0.85 : 0,\n pointerEvents: connectMode ? 'auto' : 'none',\n cursor: connectMode ? 'crosshair' : 'default',\n });\n\n return (\n <div\n style={{\n background: '#fff',\n border: '1px solid #c4c4c4',\n borderRadius: 6,\n boxShadow: '0 2px 6px rgba(0,0,0,0.08)',\n overflow: 'visible',\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n position: 'relative',\n }}\n >\n <Handle\n id=\"__default-target\"\n type=\"target\"\n position={Position.Left}\n style={handleStyle({ top: HEADER_HEIGHT / 2 })}\n />\n <Handle\n id=\"__default-source\"\n type=\"source\"\n position={Position.Right}\n style={handleStyle({ top: HEADER_HEIGHT / 2 })}\n />\n\n <div\n style={{\n padding: '6px 10px',\n background: headerBg,\n color: '#fff',\n fontWeight: 600,\n fontSize: 13,\n height: HEADER_HEIGHT,\n boxSizing: 'border-box',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n borderTopLeftRadius: 6,\n borderTopRightRadius: 6,\n }}\n >\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {table.name}\n </span>\n <span style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {table.group && (\n <span\n style={{\n fontSize: 10,\n opacity: 0.75,\n fontWeight: 400,\n padding: '1px 5px',\n border: '1px solid rgba(255,255,255,0.3)',\n borderRadius: 3,\n }}\n >\n {table.group}\n </span>\n )}\n {tableActions.onTableRemove && (\n <button\n className=\"nodrag\"\n onClick={(e) => {\n e.stopPropagation();\n tableActions.onTableRemove?.(table.name);\n }}\n onMouseDown={(e) => e.stopPropagation()}\n title=\"Remove this table\"\n style={{\n background: 'rgba(255,255,255,0.18)',\n border: 'none',\n color: '#fff',\n width: 18,\n height: 18,\n borderRadius: 3,\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: 700,\n padding: 0,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n ×\n </button>\n )}\n </span>\n </div>\n\n {table.columns.map((col, i) => {\n const handleY = HEADER_HEIGHT + i * ROW_HEIGHT + ROW_HEIGHT / 2;\n const highlighted = highlightedCols?.has(col.name) ?? false;\n const selectionKey = `${table.name}.${col.name}`;\n const selected = selection.enabled && selection.selected.has(selectionKey);\n return (\n <Fragment key={`${col.name}-${i}`}>\n <Handle\n id={`${col.name}__target`}\n type=\"target\"\n position={Position.Left}\n style={handleStyle({ top: handleY })}\n />\n <Handle\n id={`${col.name}__source`}\n type=\"source\"\n position={Position.Right}\n style={handleStyle({ top: handleY })}\n />\n <ColumnRow\n tableName={table.name}\n column={col}\n highlighted={highlighted}\n onClick={onColumnClick}\n selectionEnabled={selection.enabled}\n selected={selected}\n onSelectToggle={(checked) =>\n selection.onToggle(table.name, col.name, checked)\n }\n />\n </Fragment>\n );\n })}\n </div>\n );\n});\n","import { memo } from 'react';\nimport {\n BaseEdge,\n EdgeLabelRenderer,\n getSmoothStepPath,\n type EdgeProps,\n} from '@xyflow/react';\nimport type { JoinType } from '../core/model';\n\nexport interface JoinEdgeData extends Record<string, unknown> {\n type: JoinType;\n color: string;\n hovered?: boolean;\n onDelete?: () => void;\n}\n\nexport const JoinEdge = memo(function JoinEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n selected,\n}: EdgeProps) {\n const [edgePath, labelX, labelY] = getSmoothStepPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const d = (data ?? {}) as JoinEdgeData;\n const emphasized = !!selected || !!d.hovered;\n const color = d.color || '#3b82f6';\n\n return (\n <>\n <BaseEdge\n id={id}\n path={edgePath}\n style={{\n stroke: color,\n strokeWidth: emphasized ? 2.5 : 2,\n strokeDasharray: '6 3',\n }}\n />\n <EdgeLabelRenderer>\n <div\n className=\"nodrag nopan\"\n style={{\n position: 'absolute',\n transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,\n background: color,\n color: '#fff',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n fontWeight: 700,\n borderRadius: 3,\n padding: '2px 4px 2px 6px',\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n pointerEvents: 'all',\n boxShadow: emphasized\n ? '0 0 0 2px rgba(0,0,0,0.4)'\n : '0 1px 2px rgba(0,0,0,0.15)',\n userSelect: 'none',\n }}\n >\n <span>{d.type}</span>\n {d.onDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n d.onDelete?.();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n title=\"Remove this JOIN\"\n style={{\n background: 'rgba(255,255,255,0.25)',\n border: 'none',\n color: '#fff',\n width: 14,\n height: 14,\n borderRadius: 2,\n cursor: 'pointer',\n fontSize: 11,\n fontWeight: 700,\n padding: 0,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n ×\n </button>\n )}\n </div>\n </EdgeLabelRenderer>\n </>\n );\n});\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n} from 'react';\nimport {\n ReactFlow,\n Background,\n Controls,\n MiniMap,\n useNodesState,\n type Connection,\n type Edge,\n type EdgeTypes,\n type Node,\n type NodeTypes,\n} from '@xyflow/react';\n// React Flow's CSS is intentionally NOT imported here. Consumers must add it\n// once at their app entry point: `import '@xyflow/react/dist/style.css';`.\n// Importing it from this file would cause double-injection in apps that\n// already use React Flow, and inflate this library's bundled assets.\nimport { parseMermaidER, MermaidERParseError } from '../core/parser';\nimport {\n layoutER,\n type LayoutAlgorithm,\n type LayoutDirection,\n type LayoutResult,\n} from '../core/layout';\nimport type {\n ColumnRef,\n ERModel,\n Join,\n PartialColumnRef,\n Relation,\n} from '../core/model';\nimport {\n ColumnSelectionContext,\n ConnectModeContext,\n HighlightContext,\n TableActionsContext,\n TableNode,\n type ColumnSelectionContextValue,\n type TableActionsContextValue,\n type TableNodeData,\n} from './TableNode';\nimport { JoinEdge, type JoinEdgeData } from './JoinEdge';\n\nconst nodeTypes: NodeTypes = {\n table: TableNode,\n};\n\nconst edgeTypes: EdgeTypes = {\n joinEdge: JoinEdge,\n};\n\nexport interface NodePosition {\n x: number;\n y: number;\n}\n\nexport type NodePositions = Record<string, NodePosition>;\n\nexport interface MermaidERProps {\n /** Mermaid ER source. Mutually exclusive with `model`. */\n source?: string;\n /** Pre-built ER model. Takes precedence over `source`. */\n model?: ERModel;\n layout?: 'elk';\n algorithm?: LayoutAlgorithm;\n direction?: LayoutDirection;\n aspectRatio?: number;\n positions?: NodePositions;\n onPositionsChange?: (positions: NodePositions) => void;\n showColumnCheckboxes?: boolean;\n selectedColumns?: ColumnRef[];\n onColumnSelectionChange?: (selectedColumns: ColumnRef[]) => void;\n /** Enable column-to-column / card-to-card drag for manual JOINs. */\n enableManualJoins?: boolean;\n /** Existing manual joins to render alongside FK relations. */\n joins?: Join[];\n /**\n * Fired when the user finishes a connect drag. The consumer typically opens\n * a dialog to ask for join type, then appends a complete `Join` to its state.\n * `column` may be undefined when the drag landed on a default (table-center) handle.\n */\n onJoinConnect?: (source: PartialColumnRef, target: PartialColumnRef) => void;\n /** Fired when the user removes a manual join via Delete or the trash icon. */\n onJoinDelete?: (joinId: string) => void;\n /** When provided, a small × appears on each table header to remove it from the canvas. */\n onTableRemove?: (table: string) => void;\n highlightReferencesOnHover?: boolean;\n onColumnClick?: (table: string, column: string) => void;\n onTableClick?: (table: string) => void;\n /** Override the default delete-key code(s). Default is 'Delete' (Backspace ignored to prevent accidents). */\n deleteKeyCode?: string | string[] | null;\n className?: string;\n style?: CSSProperties;\n}\n\ninterface ParseState {\n model: ERModel | null;\n error: MermaidERParseError | null;\n}\n\nfunction safeParse(source: string): ParseState {\n try {\n return { model: parseMermaidER(source), error: null };\n } catch (e) {\n if (e instanceof MermaidERParseError) {\n return { model: null, error: e };\n }\n throw e;\n }\n}\n\nfunction handleIdFor(side: 'source' | 'target', column: string | undefined): string {\n return column ? `${column}__${side}` : `__default-${side}`;\n}\n\nconst JOIN_EDGE_PREFIX = 'join:';\n\nfunction parseHandleColumn(handleId: string | null | undefined): string | undefined {\n if (!handleId) return undefined;\n if (handleId.startsWith('__default-')) return undefined;\n const m = /^(.+)__(?:source|target)$/.exec(handleId);\n return m ? m[1] : undefined;\n}\n\nfunction refKey(ref: ColumnRef): string {\n return `${ref.table}.${ref.column}`;\n}\n\nconst JOIN_TYPE_COLOR: Record<Join['type'], string> = {\n INNER: '#3b82f6',\n LEFT: '#8b5cf6',\n RIGHT: '#a855f7',\n FULL: '#ec4899',\n CROSS: '#6b7280',\n};\n\nexport function MermaidER(props: MermaidERProps) {\n const {\n source,\n model: modelProp,\n algorithm,\n direction,\n aspectRatio,\n positions,\n onPositionsChange,\n showColumnCheckboxes,\n selectedColumns,\n onColumnSelectionChange,\n enableManualJoins,\n joins,\n onJoinConnect,\n onJoinDelete,\n onTableRemove,\n onColumnClick,\n onTableClick,\n deleteKeyCode = 'Delete',\n className,\n style,\n highlightReferencesOnHover = true,\n } = props;\n\n const { model, error } = useMemo<ParseState>(() => {\n if (modelProp) return { model: modelProp, error: null };\n if (source != null) return safeParse(source);\n return { model: null, error: null };\n }, [source, modelProp]);\n\n const [layout, setLayout] = useState<LayoutResult | null>(null);\n const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!model) {\n setLayout(null);\n return;\n }\n let cancelled = false;\n layoutER(model, { algorithm, direction, aspectRatio }).then((result) => {\n if (!cancelled) setLayout(result);\n });\n return () => {\n cancelled = true;\n };\n }, [model, algorithm, direction, aspectRatio]);\n\n const baseNodes = useMemo<Node[]>(() => {\n if (!layout || !model) return [];\n const tableMap = new Map(model.tables.map((t) => [t.name, t]));\n const result: Node[] = [];\n for (const n of layout.nodes) {\n const table = tableMap.get(n.id);\n // Skip stale nodes: a model update can arrive before the new layout\n // finishes; in that gap, layout may still reference a removed table.\n if (!table) continue;\n const override = positions?.[n.id];\n const data: TableNodeData = { table };\n result.push({\n id: n.id,\n type: 'table',\n position: override ?? { x: n.x, y: n.y },\n data,\n width: n.width,\n height: n.height,\n draggable: true,\n deletable: false,\n });\n }\n return result;\n // `onColumnClick` is intentionally NOT a dep — it flows via TableActionsContext\n // so a non-stable callback identity from the parent doesn't reset React Flow\n // node state (which would clobber an in-flight drag).\n }, [layout, model, positions]);\n\n const [nodes, setNodes, onNodesChange] = useNodesState<Node>(baseNodes);\n\n useEffect(() => {\n setNodes(baseNodes);\n }, [baseNodes, setNodes]);\n\n const handleNodeDragStop = useCallback(\n (_: unknown, _primary: Node, dragged: Node[]) => {\n if (!onPositionsChange) return;\n const next: NodePositions = { ...(positions ?? {}) };\n for (const n of dragged) {\n next[n.id] = { x: n.position.x, y: n.position.y };\n }\n onPositionsChange(next);\n },\n [positions, onPositionsChange],\n );\n\n const hoveredRelation = useMemo<Relation | undefined>(() => {\n if (!hoveredEdgeId || !model) return undefined;\n return model.relations.find((r) => r.id === hoveredEdgeId);\n }, [hoveredEdgeId, model]);\n\n const hoveredJoin = useMemo<Join | undefined>(() => {\n if (!hoveredEdgeId || !joins) return undefined;\n if (!hoveredEdgeId.startsWith(JOIN_EDGE_PREFIX)) return undefined;\n const id = hoveredEdgeId.slice(JOIN_EDGE_PREFIX.length);\n return joins.find((j) => j.id === id);\n }, [hoveredEdgeId, joins]);\n\n const highlightMap = useMemo<ReadonlyMap<string, ReadonlySet<string>>>(() => {\n const map = new Map<string, Set<string>>();\n if (!highlightReferencesOnHover) return map;\n\n const add = (table: string, column: string | undefined) => {\n if (!column) return;\n const set = map.get(table) ?? new Set();\n set.add(column);\n map.set(table, set);\n };\n\n if (hoveredRelation) {\n add(hoveredRelation.from, hoveredRelation.fromColumn);\n add(hoveredRelation.to, hoveredRelation.toColumn);\n }\n if (hoveredJoin) {\n add(hoveredJoin.source.table, hoveredJoin.source.column);\n add(hoveredJoin.target.table, hoveredJoin.target.column);\n }\n return map;\n }, [hoveredRelation, hoveredJoin, highlightReferencesOnHover]);\n\n const selectionSet = useMemo<ReadonlySet<string>>(() => {\n return new Set((selectedColumns ?? []).map(refKey));\n }, [selectedColumns]);\n\n const handleColumnSelectToggle = useCallback(\n (table: string, column: string, checked: boolean) => {\n if (!onColumnSelectionChange) return;\n const list = selectedColumns ?? [];\n if (checked) {\n if (list.some((r) => r.table === table && r.column === column)) return;\n onColumnSelectionChange([...list, { table, column }]);\n } else {\n onColumnSelectionChange(\n list.filter((r) => !(r.table === table && r.column === column)),\n );\n }\n },\n [selectedColumns, onColumnSelectionChange],\n );\n\n const selectionContext = useMemo<ColumnSelectionContextValue>(\n () => ({\n enabled: showColumnCheckboxes ?? false,\n selected: selectionSet,\n onToggle: handleColumnSelectToggle,\n }),\n [showColumnCheckboxes, selectionSet, handleColumnSelectToggle],\n );\n\n const edges = useMemo<Edge[]>(() => {\n if (!layout || !model) return [];\n const tableSet = new Set(model.tables.map((t) => t.name));\n const relMap = new Map(model.relations.map((r) => [r.id, r]));\n\n const fkEdges: Edge[] = [];\n for (const e of layout.edges) {\n // Skip stale edges referencing tables removed since the layout was computed.\n if (!tableSet.has(e.source) || !tableSet.has(e.target)) continue;\n const rel = relMap.get(e.id);\n const isHovered = e.id === hoveredEdgeId;\n fkEdges.push({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: handleIdFor('source', rel?.fromColumn),\n targetHandle: handleIdFor('target', rel?.toColumn),\n type: 'smoothstep',\n animated: isHovered,\n deletable: false,\n style: {\n stroke: isHovered ? '#f59e0b' : '#9ca3af',\n strokeWidth: isHovered ? 2 : 1.5,\n },\n label: rel?.label,\n labelStyle: { fontSize: 10, fill: '#6b7280' },\n labelBgStyle: { fill: '#fff', fillOpacity: 0.85 },\n labelBgPadding: [4, 2] as [number, number],\n labelBgBorderRadius: 3,\n });\n }\n\n const joinEdges: Edge[] = [];\n for (const j of joins ?? []) {\n if (!tableSet.has(j.source.table) || !tableSet.has(j.target.table)) continue;\n const edgeId = `${JOIN_EDGE_PREFIX}${j.id}`;\n const isHovered = edgeId === hoveredEdgeId;\n const color = JOIN_TYPE_COLOR[j.type] ?? '#3b82f6';\n const data: JoinEdgeData = {\n type: j.type,\n color,\n hovered: isHovered,\n onDelete: onJoinDelete ? () => onJoinDelete(j.id) : undefined,\n };\n joinEdges.push({\n id: edgeId,\n source: j.source.table,\n target: j.target.table,\n sourceHandle: handleIdFor('source', j.source.column),\n targetHandle: handleIdFor('target', j.target.column),\n type: 'joinEdge',\n deletable: true,\n data: data as unknown as Record<string, unknown>,\n });\n }\n\n return [...fkEdges, ...joinEdges];\n }, [layout, model, joins, hoveredEdgeId, onJoinDelete]);\n\n const handleConnect = useCallback(\n (conn: Connection) => {\n if (!onJoinConnect) return;\n if (!conn.source || !conn.target) return;\n onJoinConnect(\n { table: conn.source, column: parseHandleColumn(conn.sourceHandle) },\n { table: conn.target, column: parseHandleColumn(conn.targetHandle) },\n );\n },\n [onJoinConnect],\n );\n\n const handleEdgesDelete = useCallback(\n (deleted: Edge[]) => {\n if (!onJoinDelete) return;\n for (const e of deleted) {\n if (e.id.startsWith(JOIN_EDGE_PREFIX)) {\n onJoinDelete(e.id.slice(JOIN_EDGE_PREFIX.length));\n }\n }\n },\n [onJoinDelete],\n );\n\n const connectModeOn = !!enableManualJoins;\n const tableActions = useMemo<TableActionsContextValue>(\n () => ({ onTableRemove, onColumnClick }),\n [onTableRemove, onColumnClick],\n );\n\n return (\n <div\n className={className}\n style={{ width: '100%', height: '100%', position: 'relative', ...style }}\n >\n {error && (\n <div\n style={{\n position: 'absolute',\n top: 8,\n left: 8,\n right: 8,\n zIndex: 10,\n padding: '8px 12px',\n background: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: 6,\n color: '#991b1b',\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n fontSize: 12,\n whiteSpace: 'pre-wrap',\n }}\n >\n {error.message}\n </div>\n )}\n {!error && !layout && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#9ca3af',\n fontSize: 13,\n }}\n >\n Computing layout…\n </div>\n )}\n <HighlightContext.Provider value={highlightMap}>\n <ColumnSelectionContext.Provider value={selectionContext}>\n <ConnectModeContext.Provider value={connectModeOn}>\n <TableActionsContext.Provider value={tableActions}>\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n fitView\n onNodesChange={onNodesChange}\n onNodeDragStop={handleNodeDragStop}\n onNodeClick={\n onTableClick ? (_, node) => onTableClick(node.id) : undefined\n }\n onEdgeMouseEnter={(_, edge) => setHoveredEdgeId(edge.id)}\n onEdgeMouseLeave={() => setHoveredEdgeId(null)}\n onConnect={handleConnect}\n onEdgesDelete={handleEdgesDelete}\n nodesDraggable\n nodesConnectable={connectModeOn}\n elementsSelectable\n deleteKeyCode={deleteKeyCode}\n minZoom={0.1}\n maxZoom={4}\n >\n <Background />\n <Controls />\n <MiniMap pannable zoomable />\n </ReactFlow>\n </TableActionsContext.Provider>\n </ConnectModeContext.Provider>\n </ColumnSelectionContext.Provider>\n </HighlightContext.Provider>\n </div>\n );\n}\n"],"mappings":";;;;;AAeA,IAAa,IAAmB,kBAAwD,IAAI,KAAK,CAAC,EASrF,IAAyB,EAA2C;CAC/E,SAAS;CACT,0BAAU,IAAI,KAAK;CACnB,gBAAgB,KAAA;CACjB,CAAC,EAGW,IAAqB,EAAuB,GAAM,EAUlD,IAAsB,EAAwC,EAAE,CAAC,EAExE,IAAwE;CAC5E,IAAI;EAAE,OAAO;EAAM,IAAI;EAAW;CAClC,IAAI;EAAE,OAAO;EAAM,IAAI;EAAW;CAClC,IAAI;EAAE,OAAO;EAAM,IAAI;EAAW;CACnC;AAED,SAAS,EAAU,EACjB,cACA,WACA,gBACA,YACA,qBACA,aACA,qBASC;CACD,IAAM,IAA+C,EAAE;CAKvD,OAJI,EAAO,KAAK,MAAI,EAAO,KAAK,EAAW,GAAG,EAC1C,EAAO,KAAK,MAAI,EAAO,KAAK,EAAW,GAAG,EAC1C,EAAO,KAAK,MAAI,EAAO,KAAK,EAAW,GAAG,EAG5C,kBAAC,OAAD;EACE,OAAO,EAAO;EACd,SAAS,UAAgB,EAAQ,GAAW,EAAO,KAAK,GAAG,KAAA;EAC3D,OAAO;GACL,SAAS;GACT,YAAY;GACZ,KAAK;GACL,SAAS;GACT,UAAU;GACV,YAAY;GACZ,WAAW;GACX,QAAA;GACA,WAAW;GACX,QAAQ,IAAU,YAAY;GAC9B,YAAY,IAAc,YAAY,IAAW,YAAY;GAC7D,YAAY;GACb;YAhBH;GAkBG,KACC,kBAAC,SAAD;IACE,MAAK;IACL,SAAS;IACT,WAAW,MAAM,EAAe,EAAE,OAAO,QAAQ;IACjD,UAAU,MAAM,EAAE,iBAAiB;IACnC,OAAO;KACL,OAAO;KACP,QAAQ;KACR,QAAQ;KACR,YAAY;KACZ,QAAQ;KACT;IACD,CAAA;GAEJ,kBAAC,QAAD;IAAM,OAAO;KAAE,SAAS;KAAQ,KAAK;KAAG,YAAY;KAAG,UAAU;KAAI;cAClE,EAAO,KAAK,MACX,kBAAC,QAAD;KAEE,OAAO;MACL,SAAS;MACT,SAAS;MACT,cAAc;MACd,YAAY,EAAE;MACd,OAAO;MACP,UAAU;MACV,YAAY;MACZ,YAAY;MACb;eAEA,EAAE;KACE,EAbA,EAAE,MAaF,CACP;IACG,CAAA;GACP,kBAAC,QAAD;IACE,OAAO;KACL,YAAY;KACZ,YAAY,EAAO,KAAK,KAAK,MAAM;KACnC,OAAO;KACR;cAEA,EAAO;IACH,CAAA;GACN,EAAO,QACN,kBAAC,QAAD;IACE,OAAO;KACL,MAAM;KACN,WAAW;KACX,OAAO;KACP,WAAW;KACX,UAAU;KACV,cAAc;KACd,YAAY;KACb;cAEA,EAAO;IACH,CAAA;GAEL;;;AAIV,IAAa,IAAY,EAAK,SAAmB,EAAE,WAAmB;CACpE,IAAM,EAAE,aAAU,GACZ,IAAe,EAAW,EAAiB,EAC3C,IAAY,EAAW,EAAuB,EAC9C,IAAc,EAAW,EAAmB,EAC5C,IAAe,EAAW,EAAoB,EAC9C,IAAgB,EAAa,eAC7B,IAAkB,EAAa,IAAI,EAAM,KAAK,EAC9C,IAAW,EAAM,QAAQ,YAAY,WAErC,KAAe,OAAkD;EACrE,GAAG;EACH,OAAO,IAAc,IAAI;EACzB,QAAQ,IAAc,IAAI;EAC1B,YAAY,IAAc,YAAY;EACtC,QAAQ,IAAc,qBAAqB;EAC3C,WAAW,IAAc,mCAAmC;EAC5D,SAAS,IAAc,MAAO;EAC9B,eAAe,IAAc,SAAS;EACtC,QAAQ,IAAc,cAAc;EACrC;CAED,OACE,kBAAC,OAAD;EACE,OAAO;GACL,YAAY;GACZ,QAAQ;GACR,cAAc;GACd,WAAW;GACX,UAAU;GACV,OAAO;GACP,QAAQ;GACR,SAAS;GACT,eAAe;GACf,UAAU;GACX;YAZH;GAcE,kBAAC,GAAD;IACE,IAAG;IACH,MAAK;IACL,UAAU,EAAS;IACnB,OAAO,EAAY,EAAE,KAAA,KAAqB,GAAG,CAAC;IAC9C,CAAA;GACF,kBAAC,GAAD;IACE,IAAG;IACH,MAAK;IACL,UAAU,EAAS;IACnB,OAAO,EAAY,EAAE,KAAA,KAAqB,GAAG,CAAC;IAC9C,CAAA;GAEF,kBAAC,OAAD;IACE,OAAO;KACL,SAAS;KACT,YAAY;KACZ,OAAO;KACP,YAAY;KACZ,UAAU;KACV,QAAA;KACA,WAAW;KACX,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,KAAK;KACL,qBAAqB;KACrB,sBAAsB;KACvB;cAfH,CAiBE,kBAAC,QAAD;KAAM,OAAO;MAAE,UAAU;MAAU,cAAc;MAAY,YAAY;MAAU;eAChF,EAAM;KACF,CAAA,EACP,kBAAC,QAAD;KAAM,OAAO;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;MAAG,YAAY;MAAG;eAA7E,CACG,EAAM,SACL,kBAAC,QAAD;MACE,OAAO;OACL,UAAU;OACV,SAAS;OACT,YAAY;OACZ,SAAS;OACT,QAAQ;OACR,cAAc;OACf;gBAEA,EAAM;MACF,CAAA,EAER,EAAa,iBACZ,kBAAC,UAAD;MACE,WAAU;MACV,UAAU,MAAM;OAEd,AADA,EAAE,iBAAiB,EACnB,EAAa,gBAAgB,EAAM,KAAK;;MAE1C,cAAc,MAAM,EAAE,iBAAiB;MACvC,OAAM;MACN,OAAO;OACL,YAAY;OACZ,QAAQ;OACR,OAAO;OACP,OAAO;OACP,QAAQ;OACR,cAAc;OACd,QAAQ;OACR,UAAU;OACV,YAAY;OACZ,SAAS;OACT,YAAY;OACZ,SAAS;OACT,YAAY;OACZ,gBAAgB;OACjB;gBACF;MAEQ,CAAA,CAEN;OACH;;GAEL,EAAM,QAAQ,KAAK,GAAK,MAAM;IAC7B,IAAM,IAAA,KAA0B,IAAA,KAAA,KAA8B,GACxD,IAAc,GAAiB,IAAI,EAAI,KAAK,IAAI,IAChD,IAAe,GAAG,EAAM,KAAK,GAAG,EAAI,QACpC,IAAW,EAAU,WAAW,EAAU,SAAS,IAAI,EAAa;IAC1E,OACE,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD;MACE,IAAI,GAAG,EAAI,KAAK;MAChB,MAAK;MACL,UAAU,EAAS;MACnB,OAAO,EAAY,EAAE,KAAK,GAAS,CAAC;MACpC,CAAA;KACF,kBAAC,GAAD;MACE,IAAI,GAAG,EAAI,KAAK;MAChB,MAAK;MACL,UAAU,EAAS;MACnB,OAAO,EAAY,EAAE,KAAK,GAAS,CAAC;MACpC,CAAA;KACF,kBAAC,GAAD;MACE,WAAW,EAAM;MACjB,QAAQ;MACK;MACb,SAAS;MACT,kBAAkB,EAAU;MAClB;MACV,iBAAiB,MACf,EAAU,SAAS,EAAM,MAAM,EAAI,MAAM,EAAQ;MAEnD,CAAA;KACO,EAAA,EAxBI,GAAG,EAAI,KAAK,GAAG,IAwBnB;KAEb;GACE;;EAER,EChSW,IAAW,EAAK,SAAkB,EAC7C,OACA,YACA,YACA,YACA,YACA,mBACA,mBACA,SACA,eACY;CACZ,IAAM,CAAC,GAAU,GAAQ,KAAU,EAAkB;EACnD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,EAEI,IAAK,KAAQ,EAAE,EACf,IAAa,CAAC,CAAC,KAAY,CAAC,CAAC,EAAE,SAC/B,IAAQ,EAAE,SAAS;CAEzB,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACM;EACJ,MAAM;EACN,OAAO;GACL,QAAQ;GACR,aAAa,IAAa,MAAM;GAChC,iBAAiB;GAClB;EACD,CAAA,EACF,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;EACE,WAAU;EACV,OAAO;GACL,UAAU;GACV,WAAW,mCAAmC,EAAO,MAAM,EAAO;GAClE,YAAY;GACZ,OAAO;GACP,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,cAAc;GACd,SAAS;GACT,SAAS;GACT,YAAY;GACZ,KAAK;GACL,eAAe;GACf,WAAW,IACP,8BACA;GACJ,YAAY;GACb;YApBH,CAsBE,kBAAC,QAAD,EAAA,UAAO,EAAE,MAAY,CAAA,EACpB,EAAE,YACD,kBAAC,UAAD;GACE,MAAK;GACL,UAAU,MAAM;IAEd,AADA,EAAE,iBAAiB,EACnB,EAAE,YAAY;;GAEhB,cAAc,MAAM,EAAE,iBAAiB;GACvC,OAAM;GACN,OAAO;IACL,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,OAAO;IACP,QAAQ;IACR,cAAc;IACd,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,gBAAgB;IACjB;aACF;GAEQ,CAAA,CAEP;KACY,CAAA,CACnB,EAAA,CAAA;EAEL,EC3DI,IAAuB,EAC3B,OAAO,GACR,EAEK,KAAuB,EAC3B,UAAU,GACX;AAmDD,SAAS,GAAU,GAA4B;CAC7C,IAAI;EACF,OAAO;GAAE,OAAO,EAAe,EAAO;GAAE,OAAO;GAAM;UAC9C,GAAG;EACV,IAAI,aAAa,GACf,OAAO;GAAE,OAAO;GAAM,OAAO;GAAG;EAElC,MAAM;;;AAIV,SAAS,EAAY,GAA2B,GAAoC;CAClF,OAAO,IAAS,GAAG,EAAO,IAAI,MAAS,aAAa;;AAGtD,IAAM,IAAmB;AAEzB,SAAS,EAAkB,GAAyD;CAElF,IADI,CAAC,KACD,EAAS,WAAW,aAAa,EAAE;CACvC,IAAM,IAAI,4BAA4B,KAAK,EAAS;CACpD,OAAO,IAAI,EAAE,KAAK,KAAA;;AAGpB,SAAS,EAAO,GAAwB;CACtC,OAAO,GAAG,EAAI,MAAM,GAAG,EAAI;;AAG7B,IAAM,KAAgD;CACpD,OAAO;CACP,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;CACR;AAED,SAAgB,EAAU,GAAuB;CAC/C,IAAM,EACJ,WACA,OAAO,GACP,cACA,cACA,gBACA,cACA,sBACA,yBACA,oBACA,4BACA,sBACA,UACA,kBACA,iBACA,kBACA,kBACA,iBACA,mBAAgB,UAChB,cACA,UACA,gCAA6B,OAC3B,GAEE,EAAE,UAAO,aAAU,QACnB,IAAkB;EAAE,OAAO;EAAW,OAAO;EAAM,GACnD,KAAU,OACP;EAAE,OAAO;EAAM,OAAO;EAAM,GADR,GAAU,EAAO,EAE3C,CAAC,GAAQ,EAAU,CAAC,EAEjB,CAAC,GAAQ,KAAa,EAA8B,KAAK,EACzD,CAAC,GAAe,KAAoB,EAAwB,KAAK;CAEvE,QAAgB;EACd,IAAI,CAAC,GAAO;GACV,EAAU,KAAK;GACf;;EAEF,IAAI,IAAY;EAIhB,OAHA,EAAS,GAAO;GAAE;GAAW;GAAW;GAAa,CAAC,CAAC,MAAM,MAAW;GACtE,AAAK,KAAW,EAAU,EAAO;IACjC,QACW;GACX,IAAY;;IAEb;EAAC;EAAO;EAAW;EAAW;EAAY,CAAC;CAE9C,IAAM,IAAY,QAAsB;EACtC,IAAI,CAAC,KAAU,CAAC,GAAO,OAAO,EAAE;EAChC,IAAM,IAAW,IAAI,IAAI,EAAM,OAAO,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EACxD,IAAiB,EAAE;EACzB,KAAK,IAAM,KAAK,EAAO,OAAO;GAC5B,IAAM,IAAQ,EAAS,IAAI,EAAE,GAAG;GAGhC,IAAI,CAAC,GAAO;GACZ,IAAM,IAAW,IAAY,EAAE,KACzB,IAAsB,EAAE,UAAO;GACrC,EAAO,KAAK;IACV,IAAI,EAAE;IACN,MAAM;IACN,UAAU,KAAY;KAAE,GAAG,EAAE;KAAG,GAAG,EAAE;KAAG;IACxC;IACA,OAAO,EAAE;IACT,QAAQ,EAAE;IACV,WAAW;IACX,WAAW;IACZ,CAAC;;EAEJ,OAAO;IAIN;EAAC;EAAQ;EAAO;EAAU,CAAC,EAExB,CAAC,GAAO,GAAU,MAAiB,EAAoB,EAAU;CAEvE,QAAgB;EACd,EAAS,EAAU;IAClB,CAAC,GAAW,EAAS,CAAC;CAEzB,IAAM,KAAqB,GACxB,GAAY,GAAgB,MAAoB;EAC/C,IAAI,CAAC,GAAmB;EACxB,IAAM,IAAsB,EAAE,GAAI,KAAa,EAAE,EAAG;EACpD,KAAK,IAAM,KAAK,GACd,EAAK,EAAE,MAAM;GAAE,GAAG,EAAE,SAAS;GAAG,GAAG,EAAE,SAAS;GAAG;EAEnD,EAAkB,EAAK;IAEzB,CAAC,GAAW,EAAkB,CAC/B,EAEK,IAAkB,QAAoC;EACtD,OAAC,KAAiB,CAAC,IACvB,OAAO,EAAM,UAAU,MAAM,MAAM,EAAE,OAAO,EAAc;IACzD,CAAC,GAAe,EAAM,CAAC,EAEpB,IAAc,QAAgC;EAElD,IADI,CAAC,KAAiB,CAAC,KACnB,CAAC,EAAc,WAAW,EAAiB,EAAE;EACjD,IAAM,IAAK,EAAc,MAAM,EAAwB;EACvD,OAAO,EAAM,MAAM,MAAM,EAAE,OAAO,EAAG;IACpC,CAAC,GAAe,EAAM,CAAC,EAEpB,KAAe,QAAwD;EAC3E,IAAM,oBAAM,IAAI,KAA0B;EAC1C,IAAI,CAAC,GAA4B,OAAO;EAExC,IAAM,KAAO,GAAe,MAA+B;GACzD,IAAI,CAAC,GAAQ;GACb,IAAM,IAAM,EAAI,IAAI,EAAM,oBAAI,IAAI,KAAK;GAEvC,AADA,EAAI,IAAI,EAAO,EACf,EAAI,IAAI,GAAO,EAAI;;EAWrB,OARI,MACF,EAAI,EAAgB,MAAM,EAAgB,WAAW,EACrD,EAAI,EAAgB,IAAI,EAAgB,SAAS,GAE/C,MACF,EAAI,EAAY,OAAO,OAAO,EAAY,OAAO,OAAO,EACxD,EAAI,EAAY,OAAO,OAAO,EAAY,OAAO,OAAO,GAEnD;IACN;EAAC;EAAiB;EAAa;EAA2B,CAAC,EAExD,IAAe,QACZ,IAAI,KAAK,KAAmB,EAAE,EAAE,IAAI,EAAO,CAAC,EAClD,CAAC,EAAgB,CAAC,EAEf,IAA2B,GAC9B,GAAe,GAAgB,MAAqB;EACnD,IAAI,CAAC,GAAyB;EAC9B,IAAM,IAAO,KAAmB,EAAE;EAClC,IAAI,GAAS;GACX,IAAI,EAAK,MAAM,MAAM,EAAE,UAAU,KAAS,EAAE,WAAW,EAAO,EAAE;GAChE,EAAwB,CAAC,GAAG,GAAM;IAAE;IAAO;IAAQ,CAAC,CAAC;SAErD,EACE,EAAK,QAAQ,MAAM,EAAE,EAAE,UAAU,KAAS,EAAE,WAAW,GAAQ,CAChE;IAGL,CAAC,GAAiB,EAAwB,CAC3C,EAEK,KAAmB,SAChB;EACL,SAAS,KAAwB;EACjC,UAAU;EACV,UAAU;EACX,GACD;EAAC;EAAsB;EAAc;EAAyB,CAC/D,EAEK,KAAQ,QAAsB;EAClC,IAAI,CAAC,KAAU,CAAC,GAAO,OAAO,EAAE;EAChC,IAAM,IAAW,IAAI,IAAI,EAAM,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,EACnD,IAAS,IAAI,IAAI,EAAM,UAAU,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAEvD,IAAkB,EAAE;EAC1B,KAAK,IAAM,KAAK,EAAO,OAAO;GAE5B,IAAI,CAAC,EAAS,IAAI,EAAE,OAAO,IAAI,CAAC,EAAS,IAAI,EAAE,OAAO,EAAE;GACxD,IAAM,IAAM,EAAO,IAAI,EAAE,GAAG,EACtB,IAAY,EAAE,OAAO;GAC3B,EAAQ,KAAK;IACX,IAAI,EAAE;IACN,QAAQ,EAAE;IACV,QAAQ,EAAE;IACV,cAAc,EAAY,UAAU,GAAK,WAAW;IACpD,cAAc,EAAY,UAAU,GAAK,SAAS;IAClD,MAAM;IACN,UAAU;IACV,WAAW;IACX,OAAO;KACL,QAAQ,IAAY,YAAY;KAChC,aAAa,IAAY,IAAI;KAC9B;IACD,OAAO,GAAK;IACZ,YAAY;KAAE,UAAU;KAAI,MAAM;KAAW;IAC7C,cAAc;KAAE,MAAM;KAAQ,aAAa;KAAM;IACjD,gBAAgB,CAAC,GAAG,EAAE;IACtB,qBAAqB;IACtB,CAAC;;EAGJ,IAAM,IAAoB,EAAE;EAC5B,KAAK,IAAM,KAAK,KAAS,EAAE,EAAE;GAC3B,IAAI,CAAC,EAAS,IAAI,EAAE,OAAO,MAAM,IAAI,CAAC,EAAS,IAAI,EAAE,OAAO,MAAM,EAAE;GACpE,IAAM,IAAS,GAAG,IAAmB,EAAE,MACjC,IAAY,MAAW,GACvB,IAAQ,GAAgB,EAAE,SAAS,WACnC,IAAqB;IACzB,MAAM,EAAE;IACR;IACA,SAAS;IACT,UAAU,UAAqB,EAAa,EAAE,GAAG,GAAG,KAAA;IACrD;GACD,EAAU,KAAK;IACb,IAAI;IACJ,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE,OAAO;IACjB,cAAc,EAAY,UAAU,EAAE,OAAO,OAAO;IACpD,cAAc,EAAY,UAAU,EAAE,OAAO,OAAO;IACpD,MAAM;IACN,WAAW;IACL;IACP,CAAC;;EAGJ,OAAO,CAAC,GAAG,GAAS,GAAG,EAAU;IAChC;EAAC;EAAQ;EAAO;EAAO;EAAe;EAAa,CAAC,EAEjD,KAAgB,GACnB,MAAqB;EACf,MACD,CAAC,EAAK,UAAU,CAAC,EAAK,UAC1B,EACE;GAAE,OAAO,EAAK;GAAQ,QAAQ,EAAkB,EAAK,aAAa;GAAE,EACpE;GAAE,OAAO,EAAK;GAAQ,QAAQ,EAAkB,EAAK,aAAa;GAAE,CACrE;IAEH,CAAC,EAAc,CAChB,EAEK,KAAoB,GACvB,MAAoB;EACd,OACL,KAAK,IAAM,KAAK,GACd,AAAI,EAAE,GAAG,WAAW,EAAiB,IACnC,EAAa,EAAE,GAAG,MAAM,EAAwB,CAAC;IAIvD,CAAC,EAAa,CACf,EAEK,IAAgB,CAAC,CAAC,GAClB,KAAe,SACZ;EAAE;EAAe;EAAe,GACvC,CAAC,GAAe,EAAc,CAC/B;CAED,OACE,kBAAC,OAAD;EACa;EACX,OAAO;GAAE,OAAO;GAAQ,QAAQ;GAAQ,UAAU;GAAY,GAAG;GAAO;YAF1E;GAIG,KACC,kBAAC,OAAD;IACE,OAAO;KACL,UAAU;KACV,KAAK;KACL,MAAM;KACN,OAAO;KACP,QAAQ;KACR,SAAS;KACT,YAAY;KACZ,QAAQ;KACR,cAAc;KACd,OAAO;KACP,YAAY;KACZ,UAAU;KACV,YAAY;KACb;cAEA,EAAM;IACH,CAAA;GAEP,CAAC,KAAS,CAAC,KACV,kBAAC,OAAD;IACE,OAAO;KACL,UAAU;KACV,OAAO;KACP,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,OAAO;KACP,UAAU;KACX;cACF;IAEK,CAAA;GAER,kBAAC,EAAiB,UAAlB;IAA2B,OAAO;cAChC,kBAAC,EAAuB,UAAxB;KAAiC,OAAO;eACtC,kBAAC,EAAmB,UAApB;MAA6B,OAAO;gBAClC,kBAAC,EAAoB,UAArB;OAA8B,OAAO;iBACnC,kBAAC,IAAD;QACS;QACA;QACI;QACA;QACX,SAAA;QACe;QACf,gBAAgB;QAChB,aACE,KAAgB,GAAG,MAAS,EAAa,EAAK,GAAG,GAAG,KAAA;QAEtD,mBAAmB,GAAG,MAAS,EAAiB,EAAK,GAAG;QACxD,wBAAwB,EAAiB,KAAK;QAC9C,WAAW;QACX,eAAe;QACf,gBAAA;QACA,kBAAkB;QAClB,oBAAA;QACe;QACf,SAAS;QACT,SAAS;kBApBX;SAsBE,kBAAC,IAAD,EAAc,CAAA;SACd,kBAAC,GAAD,EAAY,CAAA;SACZ,kBAAC,IAAD;UAAS,UAAA;UAAS,UAAA;UAAW,CAAA;SACnB;;OACiB,CAAA;MACH,CAAA;KACE,CAAA;IACR,CAAA;GACxB"}
|