diff --git a/canvas/src/App.tsx b/canvas/src/App.tsx index 8ddade2..7b475bb 100644 --- a/canvas/src/App.tsx +++ b/canvas/src/App.tsx @@ -11,6 +11,7 @@ import { sendCommand, } from "./api"; import { directCapabilities } from "./exec"; +import { CanvasDrawer } from "./CanvasDrawer"; import { ModelCanvas, PALETTE, type ModelCanvasHandle } from "./ModelCanvas"; import { SidePanel, type PanelTab } from "./SidePanel"; import { TopBar } from "./TopBar"; @@ -31,6 +32,11 @@ function Canvas() { const [expandedEntities, setExpandedEntities] = useState>(() => new Set()); const [selectedId, setSelectedId] = useState(null); const [panelTab, setPanelTab] = useState(null); + // Left subject-area / layout drawer, and the active subject-area filter it drives. An empty + // `activeAreas` means "show all"; a non-empty set shows ONLY those domains (canvas hides the + // rest and fits to the visible set). + const [drawerOpen, setDrawerOpen] = useState(false); + const [activeAreas, setActiveAreas] = useState>(() => new Set()); const [dirty, setDirty] = useState(false); const [refreshKey, setRefreshKey] = useState(0); // The graph, the inspector and the modals now live in ; the shell @@ -56,6 +62,32 @@ function Canvas() { return m; }, [doc]); + // entity id -> subject-area id, and per-area entity counts, for the drawer filter. Resolved + // the same dual-sourced way ModelCanvas builds `areaByEntity`: the inverted subject_areas[] + // .members (conceptual ULIDs) first, then the direct entity.conceptual.subject_area pointer. + // "" keys the unassigned bucket. Shared with the canvas so the drawer counts and the hide + // filter agree. + const entityArea = useMemo(() => { + const m = new Map(); + if (!doc) return m; + const byConceptual = new Map(); + doc.subject_areas.forEach((sa) => { + (sa.members ?? []).forEach((cid) => byConceptual.set(cid, sa.id)); + }); + doc.entities.forEach((e) => { + const viaMembers = e.conceptual?.id ? byConceptual.get(e.conceptual.id) : undefined; + const id = viaMembers ?? e.conceptual?.subject_area?.id ?? ""; + m.set(e.id, id); + }); + return m; + }, [doc]); + + const countByArea = useMemo(() => { + const m = new Map(); + entityArea.forEach((areaId) => m.set(areaId, (m.get(areaId) ?? 0) + 1)); + return m; + }, [entityArea]); + const readOnly = doc?.read_only ?? true; // The architect canvas writes straight to disk; its capabilities follow the // server's read-only flag exactly. @@ -234,9 +266,8 @@ function Canvas() { collapseDetail={collapseDetail} onToggleCollapse={() => setCollapseDetail((v) => !v)} onFitView={() => canvasRef.current?.fitView()} - onRelayout={(mode) => canvasRef.current?.relayout(mode)} + onRelayout={(mode, dir) => canvasRef.current?.relayout(mode, dir)} onRefresh={refresh} - saColors={saColors} readOnly={readOnly} dirty={dirty} panelTab={panelTab} @@ -246,6 +277,9 @@ function Canvas() { onImported={refresh} onImportBatch={applyImportBatch} openImport={openImport} + onToggleDrawer={() => setDrawerOpen((v) => !v)} + drawerOpen={drawerOpen} + filterCount={activeAreas.size} /> )}
@@ -260,9 +294,21 @@ function Canvas() { collapseDetail={collapseDetail} expandedEntities={expandedEntities} onToggleExpand={onToggleExpand} + activeAreas={activeAreas} onError={setToast} handleRef={canvasRef} /> + {!minimal && ( + setDrawerOpen(false)} + /> + )} {panelTab && ( colour (shared with node colouring + minimap) */ + saColors: Map; + /** area id -> number of entities in it */ + countByArea: Map; + /** the set of area ids currently shown; empty = show all */ + activeAreas: Set; + /** replace the active set (focus = single, toggle = add/remove, clear = empty) */ + onSetActive: (next: Set) => void; + open: boolean; + onClose: () => void; +}) { + const areas = doc.subject_areas; + const filtering = activeAreas.size > 0; + + const focus = (id: string) => onSetActive(new Set([id])); + const toggle = (id: string) => { + const next = new Set(activeAreas); + if (next.has(id)) next.delete(id); + else next.add(id); + onSetActive(next); + }; + + const unassigned = countByArea.get("") ?? 0; + + return ( + + ); +} diff --git a/canvas/src/ModelCanvas.tsx b/canvas/src/ModelCanvas.tsx index d99d580..55de1f4 100644 --- a/canvas/src/ModelCanvas.tsx +++ b/canvas/src/ModelCanvas.tsx @@ -24,7 +24,7 @@ import { } from "./EntityNode"; import type { Capabilities, Exec } from "./exec"; import { Inspector } from "./Inspector"; -import { type LayoutMode, layoutGraph } from "./layout"; +import { type LayoutDir, type LayoutMode, layoutGraph } from "./layout"; import { AlignModal, NewEntityModal, RelEditModal, RelModal, TermMapModal } from "./modals"; import { RelationshipEdge, type RelationshipEdgeData } from "./RelationshipEdge"; import type { Entity, ModelDoc } from "./types"; @@ -61,7 +61,7 @@ export function anchorFor( /** Imperative handle for the things a shell needs to drive from its own chrome * (the toolbar's re-layout and fit buttons, and focus-by-id from search). */ export interface ModelCanvasHandle { - relayout: (mode?: LayoutMode) => void; + relayout: (mode?: LayoutMode, dir?: LayoutDir) => void; fitView: () => void; focusEntity: (id: string) => void; /** Open the New Entity modal — a shell gesture (toolbar button, `n` shortcut). */ @@ -84,6 +84,9 @@ export interface ModelCanvasProps { /** per-entity overrides of the global collapse */ expandedEntities?: Set; onToggleExpand?: (entityId: string) => void; + /** Subject-area filter: when non-empty, show ONLY entities in these area ids (hide the rest) + * and fit to the visible set. Empty = show all. Driven by the left drawer. */ + activeAreas?: Set; /** Surfaced by the shell however it likes (a toast, a banner). */ onError?: (message: string) => void; handleRef?: React.Ref; @@ -108,6 +111,7 @@ export function ModelCanvas({ collapseDetail = false, expandedEntities, onToggleExpand, + activeAreas, onError, handleRef, }: ModelCanvasProps) { @@ -145,6 +149,40 @@ export function ModelCanvas({ return m; }, [doc]); + // entity id -> its subject area {id, name}, for BOTH node coloring and the clustered/grid + // layouts. A reversed or erwin model carries membership only on the area + // (subject_areas[].members lists conceptual ULIDs), leaving entity.conceptual.subject_area + // null — so resolve from BOTH: the inverted members list (via the entity's conceptual id), + // then the direct pointer. Without this, every card falls back to NO_SA_COLOR and the whole + // model reads as one undifferentiated grey blob. + const areaByEntity = useMemo(() => { + const m = new Map(); + const byConceptual = new Map(); // conceptual id -> area + doc.subject_areas.forEach((sa) => { + (sa.members ?? []).forEach((cid) => byConceptual.set(cid, { id: sa.id, name: sa.name })); + }); + doc.entities.forEach((e) => { + const viaMembers = e.conceptual?.id ? byConceptual.get(e.conceptual.id) : undefined; + const direct = e.conceptual?.subject_area; + const area = viaMembers ?? (direct ? { id: direct.id, name: direct.name ?? direct.id } : undefined); + if (area) m.set(e.id, area); + }); + return m; + }, [doc]); + + // The subject-area filter predicate, shared by BOTH the heavy derivation and the lightweight + // hover effect. An entity is hidden when a filter is active and its area is not selected — + // an unassigned entity (no area) is hidden whenever any filter is on. Both effects MUST agree + // on this, or lifting a hover would un-hide filtered nodes. + const hiddenByArea = useCallback( + (id: string) => { + if (!activeAreas || activeAreas.size === 0) return false; + const areaId = areaByEntity.get(id)?.id; + return !(areaId && activeAreas.has(areaId)); + }, + [activeAreas, areaByEntity], + ); + // entity id -> the set of its attribute ULIDs that are an endpoint of some // relationship, for pinning them near the header (issue #5). Built once per model. const endpointAttrsByEntity = useMemo(() => { @@ -185,66 +223,34 @@ export function ModelCanvas({ } } - // --- attribute-level hover (issue #5) ------------------------------------- - // Which relationships does the hovered attribute participate in, and which - // attribute rows does the hovered edge connect? Both feed the dimmed/highlighted - // flags below rather than a parallel highlight system. - const relsForAttr = new Set(); // relationship ids touching hoveredAttr - const entsForAttr = new Set(); // entities on those relationships - // The attribute rows to emphasise at BOTH ends, keyed by entity. Populated for a - // hovered edge (both its paired columns) and for a hovered attribute (that column - // plus the columns it joins to at the other end), so hovering one data element - // lights up the data element it links to on the far side. - const hitAttrsByEntity = new Map>(); - const mark = (entity: string, attrs: string[]) => { - if (!attrs.length) return; - const s = hitAttrsByEntity.get(entity) ?? new Set(); - attrs.forEach((a) => s.add(a)); - hitAttrsByEntity.set(entity, s); - }; - if (hoveredAttr) { - for (const r of doc.relationships) { - if (r.from.attributes.includes(hoveredAttr) || r.to.attributes.includes(hoveredAttr)) { - relsForAttr.add(r.id); - entsForAttr.add(r.from.entity); - entsForAttr.add(r.to.entity); - // light up the joined columns on BOTH sides of this relationship - mark(r.from.entity, r.from.attributes); - mark(r.to.entity, r.to.attributes); - } - } - } - if (hoveredEdge) { - const r = doc.relationships.find((x) => x.id === hoveredEdge); - if (r) { - mark(r.from.entity, r.from.attributes); - mark(r.to.entity, r.to.attributes); - } - } + // NOTE: attribute/edge HOVER highlighting is applied by a separate, lightweight effect + // (see below) that mutates only the dimmed/highlight data fields in place. It is + // deliberately NOT part of this heavy derivation, so moving the mouse over a row does + // not rebuild all N nodes + M edges (that caused a full re-render flicker on a large + // model). This effect handles only the STRUCTURAL view state: search + selection. const newNodes: Node[] = doc.entities.map((e) => { const searchDim = q !== "" && !matches.has(e.id); const neighbourDim = selectedId !== null && !neighbours.has(e.id); - // when hovering an attribute, dim entities not on any of its relationships - const hoverDim = hoveredAttr !== null && !entsForAttr.has(e.id); return { id: e.id, type: "entity", position: { x: 0, y: 0 }, + hidden: hiddenByArea(e.id), data: { entity: e, - color: e.conceptual?.subject_area - ? saColors.get(e.conceptual.subject_area.id) ?? NO_SA_COLOR - : NO_SA_COLOR, - dimmed: searchDim || neighbourDim || hoverDim, - highlighted: - (q !== "" && matches.has(e.id)) || (hoveredAttr !== null && entsForAttr.has(e.id)), + color: (() => { + const area = areaByEntity.get(e.id); + return area ? saColors.get(area.id) ?? NO_SA_COLOR : NO_SA_COLOR; + })(), + dimmed: searchDim || neighbourDim, + highlighted: q !== "" && matches.has(e.id), showTypes, collapseDetail, expanded: expandedEntities?.has(e.id) ?? false, onToggleExpand, endpointAttrs: endpointAttrsByEntity.get(e.id), - highlightAttrs: hitAttrsByEntity.get(e.id), + highlightAttrs: undefined, onHoverAttr: setHoveredAttr, }, }; @@ -254,11 +260,8 @@ export function ModelCanvas({ .filter((r) => entityIndex.has(r.from.entity) && entityIndex.has(r.to.entity)) .map((r) => { const { sourceHandle, targetHandle } = anchorFor(r, entityIndex); - // dim: search/select context, OR (when hovering an attribute) any edge that - // attribute is not part of. const selectDim = selectedId !== null && r.from.entity !== selectedId && r.to.entity !== selectedId; - const hoverDim = hoveredAttr !== null && !relsForAttr.has(r.id); return { id: r.id, source: r.from.entity, @@ -268,7 +271,7 @@ export function ModelCanvas({ type: "relationship", data: { relationship: r, - dimmed: selectDim || hoverDim, + dimmed: selectDim, memberCount: Math.max(r.from.attributes.length, r.to.attributes.length), onHoverEdge: setHoveredEdge, }, @@ -278,14 +281,21 @@ export function ModelCanvas({ setNodes((prev) => { const posById = new Map(prev.map((n) => [n.id, n.position])); const known = newNodes.every((n) => posById.has(n.id)); - if (layoutedRef.current && known && prev.length >= newNodes.length) { + // When a subject-area filter is active, lay out ONLY the visible nodes so the focused + // domain fills the canvas (a stale full-model layout would leave it in a far corner). + // Otherwise keep known positions so a re-derivation (search, selection) doesn't reflow. + const filtering = (activeAreas?.size ?? 0) > 0; + if (layoutedRef.current && known && prev.length >= newNodes.length && !filtering) { return newNodes.map((n) => ({ ...n, position: posById.get(n.id) ?? n.position })); } - // new entity (or first load): layout, keeping existing positions where known - const laid = layoutGraph(newNodes, newEdges, entityIndex); - const merged = laid.map((n) => - posById.has(n.id) && layoutedRef.current ? { ...n, position: posById.get(n.id)! } : n, - ); + const toLay = filtering ? newNodes.filter((n) => !n.hidden) : newNodes; + const laid = layoutGraph(toLay, newEdges, entityIndex, "auto", areaByEntity); + const laidPos = new Map(laid.map((n) => [n.id, n.position])); + const merged = newNodes.map((n) => { + if (laidPos.has(n.id)) return { ...n, position: laidPos.get(n.id)! }; + // a hidden node keeps its prior position (it isn't shown, so it doesn't matter) + return posById.has(n.id) && layoutedRef.current ? { ...n, position: posById.get(n.id)! } : n; + }); layoutedRef.current = true; requestAnimationFrame(() => fitView({ padding: 0.15, duration: 300 })); return merged; @@ -301,12 +311,109 @@ export function ModelCanvas({ onToggleExpand, saColors, entityIndex, + areaByEntity, + hiddenByArea, + activeAreas, endpointAttrsByEntity, - hoveredAttr, - hoveredEdge, fitView, ]); + // --- lightweight hover overlay (issue #5) --------------------------------------- + // Hovering an attribute row or an edge highlights the relationships/columns it joins. + // This is TRANSIENT view state, so it updates the existing nodes/edges IN PLACE (same + // identities + positions, only the dim/highlight data fields change) instead of + // re-running the heavy derivation above — which on a 50+ entity model rebuilt every + // node and edge on each mouse move and made the canvas flicker. + const hover = useMemo(() => { + const relsForAttr = new Set(); + const entsForAttr = new Set(); + const hitAttrsByEntity = new Map>(); + const mark = (entity: string, attrs: string[]) => { + if (!attrs.length) return; + const s = hitAttrsByEntity.get(entity) ?? new Set(); + attrs.forEach((a) => s.add(a)); + hitAttrsByEntity.set(entity, s); + }; + if (hoveredAttr) { + for (const r of doc.relationships) { + if (r.from.attributes.includes(hoveredAttr) || r.to.attributes.includes(hoveredAttr)) { + relsForAttr.add(r.id); + entsForAttr.add(r.from.entity); + entsForAttr.add(r.to.entity); + mark(r.from.entity, r.from.attributes); + mark(r.to.entity, r.to.attributes); + } + } + } + if (hoveredEdge) { + const r = doc.relationships.find((x) => x.id === hoveredEdge); + if (r) { + mark(r.from.entity, r.from.attributes); + mark(r.to.entity, r.to.attributes); + } + } + return { active: hoveredAttr !== null, relsForAttr, entsForAttr, hitAttrsByEntity }; + }, [doc, hoveredAttr, hoveredEdge]); + + useEffect(() => { + // Recompute the base (structural) dim from search + selection so lifting the hover + // restores exactly what the heavy effect would have set — without re-running it. + const q = query.trim().toLowerCase(); + const matches = new Set(); + if (q) { + for (const e of doc.entities) { + const hay = + e.name.toLowerCase() + + " " + + (e.conceptual?.name.toLowerCase() ?? "") + + " " + + e.attributes.map((a) => a.name.toLowerCase()).join(" "); + if (hay.includes(q)) matches.add(e.id); + } + } + const neighbours = new Set(); + if (selectedId) { + neighbours.add(selectedId); + for (const r of doc.relationships) { + if (r.from.entity === selectedId) neighbours.add(r.to.entity); + if (r.to.entity === selectedId) neighbours.add(r.from.entity); + } + } + setNodes((prev) => + prev.map((n) => { + const searchDim = q !== "" && !matches.has(n.id); + const neighbourDim = selectedId !== null && !neighbours.has(n.id); + const hoverDim = hover.active && !hover.entsForAttr.has(n.id); + const dimmed = searchDim || neighbourDim || hoverDim; + const highlighted = + (q !== "" && matches.has(n.id)) || (hover.active && hover.entsForAttr.has(n.id)); + const highlightAttrs = hover.hitAttrsByEntity.get(n.id); + // only replace the node object when a field actually changed (keeps identity + // stable, so React Flow doesn't re-mount unchanged nodes) + if ( + n.data.dimmed === dimmed && + n.data.highlighted === highlighted && + n.data.highlightAttrs === highlightAttrs + ) { + return n; + } + return { ...n, data: { ...n.data, dimmed, highlighted, highlightAttrs } }; + }), + ); + setEdges((prev) => + prev.map((r) => { + const rel = r.data?.relationship; + const selectDim = + selectedId !== null && rel !== undefined && + rel.from.entity !== selectedId && rel.to.entity !== selectedId; + const hoverDim = hover.active && !hover.relsForAttr.has(r.id); + const dimmed = selectDim || hoverDim; + if (r.data?.dimmed === dimmed) return r; + return { ...r, data: { ...r.data!, dimmed } }; + }), + ); + }, [hover, query, selectedId, doc]); + // Frame the matches. In a large model the entities a search hits may be off-screen, // so highlighting alone is not enough — pan/zoom to the matched nodes (like Fit, but // scoped to the hits). Fires only on a query change, so it doesn't fight the main @@ -341,11 +448,11 @@ export function ModelCanvas({ }, [query, doc, getNodes, fitBounds]); const relayout = useCallback( - (mode: LayoutMode = "auto") => { - setNodes((prev) => layoutGraph(prev, edges, entityIndex, mode)); + (mode: LayoutMode = "auto", dir: LayoutDir = "LR") => { + setNodes((prev) => layoutGraph(prev, edges, entityIndex, mode, areaByEntity, dir)); requestAnimationFrame(() => fitView({ padding: 0.15, duration: 300 })); }, - [edges, entityIndex, fitView], + [edges, entityIndex, areaByEntity, fitView], ); const focusEntity = useCallback( diff --git a/canvas/src/TopBar.tsx b/canvas/src/TopBar.tsx index 05d6e96..628d486 100644 --- a/canvas/src/TopBar.tsx +++ b/canvas/src/TopBar.tsx @@ -1,6 +1,25 @@ import { useEffect, useRef, useState } from "react"; import type { Exec } from "./exec"; -import type { LayoutMode } from "./layout"; +import { + IconArrow, + IconChanges, + IconCheck, + IconCollapse, + IconDecisions, + IconEntity, + IconError, + IconFit, + IconLayers, + IconLayout, + IconMenu, + IconOntology, + IconPlus, + IconRefresh, + IconRelationship, + IconTypes, + IconWarn, +} from "./icons"; +import type { LayoutDir, LayoutMode } from "./layout"; import type { PanelTab } from "./SidePanel"; import { ImportExportMenu } from "./sme/ImportExportMenu"; import type { DiagnosticsDoc, ModelDoc } from "./types"; @@ -18,7 +37,6 @@ export function TopBar({ onFitView, onRelayout, onRefresh, - saColors, readOnly, dirty, panelTab, @@ -28,6 +46,9 @@ export function TopBar({ onImported, onImportBatch, openImport, + onToggleDrawer, + drawerOpen, + filterCount, }: { doc: ModelDoc; diagnostics: DiagnosticsDoc | null; @@ -39,9 +60,8 @@ export function TopBar({ collapseDetail: boolean; onToggleCollapse: () => void; onFitView: () => void; - onRelayout: (mode?: LayoutMode) => void; + onRelayout: (mode?: LayoutMode, dir?: LayoutDir) => void; onRefresh: () => void; - saColors: Map; readOnly: boolean; dirty: boolean; panelTab: PanelTab | null; @@ -55,123 +75,209 @@ export function TopBar({ onImportBatch?: (changes: { op: string; payload: Record }[]) => Promise; /** open the Import wizard immediately (VS Code "Import to Model" via `?import=1`) */ openImport?: boolean; + /** toggle the left subject-area / layout drawer */ + onToggleDrawer: () => void; + drawerOpen: boolean; + /** number of subject areas currently filtered to (0 = showing all) — badges the hamburger */ + filterCount: number; }) { const errors = diagnostics?.items.filter((d) => d.severity === "error").length ?? 0; const warnings = diagnostics?.items.filter((d) => d.severity === "warning").length ?? 0; - const tabBtn = (tab: PanelTab, label: string, title: string, badge?: boolean) => ( + // A panel toggle carries an icon + label (the four least-guessable, most-used tools). + const panelBtn = ( + tab: PanelTab, + icon: React.ReactNode, + label: string, + title: string, + badge?: boolean, + ) => ( ); return (
-
- {"◮"} - Modelith - {doc.project.name} - {readOnly && read-only} -
+ {/* Row 1 — identity, search, live status */} +
+ - onQuery(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter") onSubmitQuery(); - }} - id="mdl-search" - /> +
+ {"◮"} + Modelith + {doc.project.name} + {readOnly && read-only} +
-
- {doc.subject_areas.map((sa) => ( - - - {sa.name} - - ))} -
+ onQuery(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") onSubmitQuery(); + }} + id="mdl-search" + /> -
- {doc.counts.entities} ⬛ - {doc.counts.relationships} ⤳ - {diagnostics && ( - `${d.code} ${d.message}`).join("\n") || "model valid"} - > - {errors ? `${errors} ✗` : warnings ? `${warnings} ⚠` : "✓ valid"} +
+ + + {doc.counts.entities} - )} + + + {doc.counts.relationships} + + {diagnostics && ( + `${d.code} ${d.message}`).join("\n") || "model valid" + } + > + {errors ? ( + <> + + {errors} + + ) : warnings ? ( + <> + + {warnings} + + ) : ( + <> + + valid + + )} + + )} +
-
+ {/* Row 2 — actions, grouped by what they do */} +
{!readOnly && ( )} - {tabBtn("ontology", "⬡", "Ontology browser")} - {tabBtn("layers", "≣", "Four-layer stack & coverage")} - {tabBtn("changes", "±", dirty ? "Uncommitted changes!" : "Changes", dirty)} - {tabBtn("decisions", "⚖", "Decision ledger")} - - - - - - - - {/* Interchange: export the model / import SQL DDL, Mermaid, JSON Schema. - Direct-write here (the engineer canvas has no review screen), so the - import applies to the working tree and the shell refreshes. */} - + +
+ Panels + {panelBtn("ontology", , "Ontology", "Ontology browser")} + {panelBtn("layers", , "Layers", "Four-layer stack & coverage")} + {panelBtn( + "changes", + , + "Changes", + dirty ? "Uncommitted changes" : "Changes", + dirty, + )} + {panelBtn("decisions", , "Decisions", "Decision ledger")} +
+ +
+ View + + + + +
+ +
+ Data + + {/* Interchange: export the model / import SQL DDL, Mermaid, JSON Schema. + Direct-write here (the engineer canvas has no review screen), so the + import applies to the working tree and the shell refreshes. The menu + renders its own Export / Import buttons in the toolbar's grp-btn style. */} + +
); } -/** Auto-layout as a small picker. The icon button re-lays out in "auto" (dagre for - * small models, grid past the entity threshold — no regression for existing models). - * The caret opens a menu to force Hierarchical or Grid, so a large model can be - * arranged either way. */ -function LayoutPicker({ onRelayout }: { onRelayout: (mode?: LayoutMode) => void }) { +// The flow-direction cycle for the dagre-based layouts. Grouped with the layout picker so the +// arrow toggle reads as part of one layout control. Grid ignores direction (a no-op). The arrow +// icon rotates to point the flow way. +const DIR_CYCLE: LayoutDir[] = ["LR", "TB", "RL", "BT"]; +const DIR_ROT: Record = { LR: 0, TB: 90, RL: 180, BT: 270 }; +const DIR_LABEL: Record = { + LR: "left → right", + TB: "top → bottom", + RL: "right → left", + BT: "bottom → top", +}; + +/** Auto-layout as a small picker plus a flow-direction toggle. The icon button re-lays out in + * "auto" (dagre for small models, grid past the entity threshold — no regression). The caret + * opens a menu to force Hierarchical / Clustered / Grid. The arrow button cycles the dagre flow + * direction (→ ↓ ← ↑) and re-applies the current layout, so a large model can be arranged either + * way and flowed in any direction. Direction persists across relayouts. */ +function LayoutPicker({ onRelayout }: { onRelayout: (mode?: LayoutMode, dir?: LayoutDir) => void }) { const [open, setOpen] = useState(false); + const [dir, setDir] = useState("LR"); + // Remember the last chosen layout so cycling the direction re-applies THAT layout, not a reset + // to auto. Starts at auto (the on-load default). + const [mode, setMode] = useState("auto"); const ref = useRef(null); useEffect(() => { if (!open) return; @@ -182,27 +288,53 @@ function LayoutPicker({ onRelayout }: { onRelayout: (mode?: LayoutMode) => void return () => document.removeEventListener("mousedown", onDown); }, [open]); - const pick = (mode: LayoutMode) => { - onRelayout(mode); + const apply = (m: LayoutMode) => { + setMode(m); + onRelayout(m, dir); + }; + const pick = (m: LayoutMode) => { + apply(m); setOpen(false); }; + const cycleDir = () => { + const next = DIR_CYCLE[(DIR_CYCLE.indexOf(dir) + 1) % DIR_CYCLE.length]; + setDir(next); + onRelayout(mode, next); + }; return (
- + {open && (
+
)} diff --git a/canvas/src/icons.tsx b/canvas/src/icons.tsx new file mode 100644 index 0000000..713fe96 --- /dev/null +++ b/canvas/src/icons.tsx @@ -0,0 +1,166 @@ +// Inline SVG icons for the canvas toolbar. No icon-font dependency: these ship in the +// bundle as tiny stroke paths, render crisply on every OS (the old Unicode glyphs did +// not), and inherit `currentColor` + size from their button. 16px default, 1.6 stroke. + +type IconProps = { size?: number }; + +function Svg({ size = 16, children }: IconProps & { children: React.ReactNode }) { + return ( + + ); +} + +// --- create --------------------------------------------------------------------- +export const IconPlus = (p: IconProps) => ( + + + +); + +// --- panels --------------------------------------------------------------------- +export const IconOntology = (p: IconProps) => ( + + + +); +export const IconLayers = (p: IconProps) => ( + + + + + +); +export const IconChanges = (p: IconProps) => ( + + + + + + +); +export const IconDecisions = (p: IconProps) => ( + + + + + +); + +// --- view ----------------------------------------------------------------------- +export const IconTypes = (p: IconProps) => ( + + + +); +export const IconCollapse = (p: IconProps) => ( + + + + +); +export const IconLayout = (p: IconProps) => ( + + + + + + +); +export const IconFit = (p: IconProps) => ( + + + +); +export const IconCaret = (p: IconProps) => ( + + + +); + +// --- data ----------------------------------------------------------------------- +export const IconRefresh = (p: IconProps) => ( + + + + +); +export const IconInterchange = (p: IconProps) => ( + + + +); + +// --- status --------------------------------------------------------------------- +export const IconEntity = (p: IconProps) => ( + + + + +); +export const IconRelationship = (p: IconProps) => ( + + + + +); +export const IconCheck = (p: IconProps) => ( + + + + +); +export const IconWarn = (p: IconProps) => ( + + + + +); +export const IconError = (p: IconProps) => ( + + + + +); + +// --- drawer / filter ------------------------------------------------------------ +/** Hamburger — opens the left drawer (subject-area filter). */ +export const IconMenu = (p: IconProps) => ( + + + +); +/** Subject areas / domains — stacked tiles, the "group by area" idea. */ +export const IconDomains = (p: IconProps) => ( + + + + + + +); +/** Close (✕) for the drawer header. */ +export const IconClose = (p: IconProps) => ( + + + +); +/** A single arrow, pointing right by default. The flow-direction toggle rotates it via a + * CSS transform (0/90/180/270deg) so one glyph serves → ↓ ← ↑ crisply. */ +export const IconArrow = (p: IconProps) => ( + + + +); diff --git a/canvas/src/layout.ts b/canvas/src/layout.ts index c6a4fa6..63c06e6 100644 --- a/canvas/src/layout.ts +++ b/canvas/src/layout.ts @@ -14,68 +14,225 @@ export function nodeHeight(entity: Entity): number { return HEADER_H + rows * ROW_H + SECTION_PAD; } -/** Layout style. "hierarchical" is the dagre layered layout (the default, good for - * small/medium star schemas). "grid" packs entities into compact rows — far more - * scannable once a model has dozens of entities, where the layered layout collapses - * a dense constellation schema into a tall stack. "auto" picks by entity count. */ -export type LayoutMode = "auto" | "hierarchical" | "grid"; - -// Above this many entities, "auto" uses the grid packer. A layered layout stops -// paying its way here: a reversed warehouse is a constellation (many facts each -// linking several dims), which dagre stacks rather than spreads. -const GRID_THRESHOLD = 40; - -/** Route to the chosen layout. Default "auto" keeps today's dagre for small models - * (no regression) and switches to grid past the threshold. */ +/** Layout style. "hierarchical" is the dagre layered layout (good for small/medium star + * schemas). "clustered" groups entities by subject area, lays out each group with dagre + * (relationship-aware within a domain), then packs the groups — the readable choice for a + * large, domain-organised model where a single dagre stacks a constellation into a column + * and a blind grid ignores the FKs. "grid" is the plain packer. "auto" picks by size and + * whether the model actually has subject areas. */ +export type LayoutMode = "auto" | "hierarchical" | "clustered" | "grid"; + +/** Flow direction for the dagre-based layouts (hierarchical + clustered): which way ranks + * advance. LR = left→right (default), TB = top→bottom, RL = right→left, BT = bottom→top. + * The grid packer and grid-packed clusters have no meaningful direction — the toggle is a + * no-op there. */ +export type LayoutDir = "LR" | "TB" | "RL" | "BT"; + +// Above this many entities, "auto" leaves the plain dagre layout — a single layered pass +// stops paying its way (a constellation stacks into a tall column). With subject areas it +// switches to clustered; without them, to the grid packer. +const LARGE_THRESHOLD = 40; + +/** Maps an entity id to its subject area (id + name) — resolved by the caller, which knows + * both the direct `conceptual.subject_area` pointer AND the inverted `subject_areas[].members` + * list (a reversed/erwin model carries membership only on the area, so the pointer is null + * there). The layout groups by `name`; entities absent from the map are "unassigned". */ +export type AreaByEntity = Map; + +/** Route to the chosen layout. "auto" keeps dagre for small models (no regression) and, + * past the threshold, clusters by subject area when the model has them (the common case + * for a reversed/erwin model), else falls back to the grid packer. */ export function layoutGraph( nodes: Node[], edges: Edge[], entities: Map, mode: LayoutMode = "auto", + areaByEntity?: AreaByEntity, + dir: LayoutDir = "LR", ): Node[] { - const useGrid = mode === "grid" || (mode === "auto" && nodes.length > GRID_THRESHOLD); - return useGrid ? gridLayout(nodes, entities) : hierarchicalLayout(nodes, edges, entities); + const areaOf = makeAreaOf(entities, areaByEntity); + if (mode === "grid") return gridLayout(nodes, entities, areaOf); + if (mode === "clustered") return clusteredLayout(nodes, edges, entities, areaOf, dir); + if (mode === "hierarchical") return hierarchicalLayout(nodes, edges, entities, dir); + // auto + if (nodes.length <= LARGE_THRESHOLD) return hierarchicalLayout(nodes, edges, entities, dir); + const areas = new Set(nodes.map((n) => areaOf(n.id)).filter(Boolean)); + // clustering only helps when there is real domain structure (>1 area); otherwise grid. + return areas.size > 1 + ? clusteredLayout(nodes, edges, entities, areaOf, dir) + : gridLayout(nodes, entities, areaOf); } -function hierarchicalLayout( +/** Build the entity→area-name lookup. Prefer a caller-supplied map (which resolves the + * inverted `members` membership); fall back to the entity's own `subject_area` pointer so + * callers that don't pass a map still group correctly. Returns "" for unassigned. */ +function makeAreaOf( + entities: Map, + areaByEntity?: AreaByEntity, +): (id: string) => string { + return (id: string) => { + if (areaByEntity) { + const a = areaByEntity.get(id); + if (a) return a.name; + } + return entities.get(id)?.conceptual?.subject_area?.name ?? ""; + }; +} + +/** Run one dagre layered pass over a set of nodes + the edges internal to them. Returns + * the nodes with top-left positions plus the laid-out bounding box (width/height), so a + * caller can pack several such boxes (clustered layout). `compact` tightens the spacing + * for a big graph. */ +function dagrePass( nodes: Node[], edges: Edge[], entities: Map, -): Node[] { + compact = false, + dir: LayoutDir = "LR", +): { nodes: Node[]; width: number; height: number } { const g = new dagre.graphlib.Graph(); - // Wider ranksep = clear vertical lanes between columns for edges to travel - // through; larger nodesep + edgesep keeps parallel edges from overlapping the - // cards. network-simplex gives tidier rank assignment for star schemas. g.setGraph({ - rankdir: "LR", - nodesep: 70, - ranksep: 150, - edgesep: 30, - marginx: 48, - marginy: 48, + rankdir: dir, + nodesep: compact ? 45 : 70, + ranksep: compact ? 110 : 150, + edgesep: compact ? 20 : 30, + marginx: 24, + marginy: 24, ranker: "network-simplex", }); g.setDefaultEdgeLabel(() => ({})); + const ids = new Set(nodes.map((n) => n.id)); for (const n of nodes) { const ent = entities.get(n.id); g.setNode(n.id, { width: NODE_WIDTH, height: ent ? nodeHeight(ent) : 120 }); } - // minlen 2 pushes related entities at least two ranks apart, so the edge has a - // full lane to route in rather than hugging a neighbouring card. - for (const e of edges) g.setEdge(e.source, e.target, { minlen: 1, weight: 2 }); + // only edges whose BOTH ends are in this set (a cluster's internal FKs) + for (const e of edges) { + if (ids.has(e.source) && ids.has(e.target)) g.setEdge(e.source, e.target, { minlen: 1, weight: 2 }); + } dagre.layout(g); - return nodes.map((n) => { + let maxX = 0; + let maxY = 0; + const out = nodes.map((n) => { const pos = g.node(n.id); const ent = entities.get(n.id); const h = ent ? nodeHeight(ent) : 120; - return { - ...n, - position: { x: pos.x - NODE_WIDTH / 2, y: pos.y - h / 2 }, - }; + const x = pos.x - NODE_WIDTH / 2; + const y = pos.y - h / 2; + maxX = Math.max(maxX, x + NODE_WIDTH); + maxY = Math.max(maxY, y + h); + return { ...n, position: { x, y } }; + }); + return { nodes: out, width: maxX, height: maxY }; +} + +function hierarchicalLayout( + nodes: Node[], + edges: Edge[], + entities: Map, + dir: LayoutDir = "LR", +): Node[] { + return dagrePass(nodes, edges, entities, false, dir).nodes; +} + +/** Pack a set of nodes into a compact grid (rows of ~sqrt columns), returning the nodes at + * top-left positions plus the bounding box — same contract as `dagrePass`, so a cluster can + * choose either. Used for a cluster whose entities have few internal FKs, where dagre would + * drop them all into one rank and stack a tall column. */ +function gridPass( + nodes: Node[], + entities: Map, +): { nodes: Node[]; width: number; height: number } { + const heightOf = (id: string) => { + const ent = entities.get(id); + return ent ? nodeHeight(ent) : 120; + }; + const cols = Math.max(1, Math.round(Math.sqrt(nodes.length))); + const out: Node[] = []; + let y = 0; + let maxX = 0; + for (let i = 0; i < nodes.length; i += cols) { + const row = nodes.slice(i, i + cols); + row.forEach((n, c) => { + const x = c * (NODE_WIDTH + GRID_GAP_X); + out.push({ ...n, position: { x, y } }); + maxX = Math.max(maxX, x + NODE_WIDTH); + }); + y += Math.max(...row.map((n) => heightOf(n.id))) + GRID_GAP_Y; + } + return { nodes: out, width: maxX, height: y }; +} + +const CLUSTER_GAP = 120; // space between subject-area clusters + +/** Group entities by subject area, lay each group out with dagre (so FK-connected entities + * within a domain read as a proper sub-diagram), then pack the group boxes into a grid of + * clusters. This keeps a domain's entities together AND relationship-aware, instead of + * stacking the whole constellation into one dagre column or scattering it across a blind + * grid. Entities with no subject area form a trailing "(unassigned)" cluster. */ +function clusteredLayout( + nodes: Node[], + edges: Edge[], + entities: Map, + areaOf: (id: string) => string, + dir: LayoutDir = "LR", +): Node[] { + // bucket nodes by area name (empty string = unassigned, sorted last) + const byArea = new Map(); + for (const n of nodes) { + const a = areaOf(n.id); + (byArea.get(a) ?? byArea.set(a, []).get(a)!).push(n); + } + const areaNames = [...byArea.keys()].sort((a, b) => { + if (a === "") return 1; // unassigned last + if (b === "") return -1; + return a.localeCompare(b); }); + + // Lay out each cluster internally, capturing its box size. A small, well-connected cluster + // reads best as a dagre sub-diagram (its FK chain is legible); but a larger domain, or one + // whose relationships are mostly cross-domain, collapses into one dagre rank — a tall + // column — so pack it as a compact grid instead. Use dagre only for a small cluster with a + // real internal chain (few nodes, edges ≳ nodes); everything else grids. + const clusters = areaNames.map((name) => { + const members = byArea.get(name)!; + const ids = new Set(members.map((n) => n.id)); + let internal = 0; + for (const e of edges) if (ids.has(e.source) && ids.has(e.target)) internal++; + const dagreWorthwhile = members.length <= 8 && internal >= members.length - 1; + const laid = dagreWorthwhile + ? dagrePass(members, edges, entities, true, dir) + : gridPass(members, entities); + return { name, ...laid }; + }); + + // Pack cluster boxes into rows, advancing Y by the tallest box in a row. Bias toward more + // columns than a plain sqrt so a handful of clusters spread across the canvas width rather + // than stacking into a tall strip. + const cols = Math.max(1, Math.ceil(Math.sqrt(clusters.length * 1.6))); + const positioned: Node[] = []; + let rowY = 0; + for (let i = 0; i < clusters.length; i += cols) { + const row = clusters.slice(i, i + cols); + let colX = 0; + let rowH = 0; + for (const cl of row) { + // shift the cluster's already-relative node positions to (colX, rowY) + for (const n of cl.nodes) { + positioned.push({ ...n, position: { x: n.position.x + colX, y: n.position.y + rowY } }); + } + colX += cl.width + CLUSTER_GAP; + rowH = Math.max(rowH, cl.height); + } + rowY += rowH + CLUSTER_GAP; + } + + // preserve input order in the returned array (React Flow keys by id anyway) + const posById = new Map(positioned.map((n) => [n.id, n.position])); + return nodes.map((n) => ({ ...n, position: posById.get(n.id) ?? n.position })); } const GRID_GAP_X = 40; @@ -86,12 +243,15 @@ const GRID_GAP_Y = 40; * column count, then advance Y by the tallest card in that row. Entities are ordered * by subject area (so an area's entities sit together) then by name, giving a stable, * scannable arrangement where the layered layout would stack a dense schema. */ -function gridLayout(nodes: Node[], entities: Map): Node[] { +function gridLayout( + nodes: Node[], + entities: Map, + areaOf: (id: string) => string, +): Node[] { const heightOf = (id: string) => { const ent = entities.get(id); return ent ? nodeHeight(ent) : 120; }; - const areaOf = (id: string) => entities.get(id)?.conceptual?.subject_area?.name ?? ""; const ordered = [...nodes].sort((a, b) => { const aa = areaOf(a.id); diff --git a/canvas/src/styles.css b/canvas/src/styles.css index 04090bc..dd31906 100644 --- a/canvas/src/styles.css +++ b/canvas/src/styles.css @@ -29,40 +29,84 @@ body { font-family: var(--font); background: var(--bg); color: var(--text); } /* ---------- top bar ---------- */ .topbar { - display: flex; align-items: center; gap: 16px; - padding: 10px 16px; background: var(--bg-raised); + display: flex; flex-direction: column; + padding: 8px 16px 0; background: var(--bg-raised); border-bottom: 1px solid var(--border); z-index: 10; } +/* Row 1 (identity + search + status) and Row 2 (grouped actions). Splitting the two + stops the brand, search, status, and 10 controls from fighting for one flex row. */ +.topbar-row { display: flex; align-items: center; gap: 14px; } +.topbar-row.context { padding-bottom: 8px; } +.topbar-row.actions { gap: 10px; padding-bottom: 8px; flex-wrap: wrap; } .brand { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; } .logo { color: var(--accent); font-size: 18px; } .brand-name { font-weight: 700; letter-spacing: 0.02em; } .project-name { color: var(--text-dim); font-size: 13px; } .search { - flex: 0 1 340px; padding: 7px 12px; border-radius: 8px; + flex: 0 1 300px; margin-left: auto; padding: 7px 12px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-card); color: var(--text); font-size: 13px; outline: none; } .search:focus { border-color: var(--accent); } -.legend { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--text-dim); } -.legend-item { display: inline-flex; align-items: center; gap: 5px; } -.swatch { width: 10px; height: 10px; border-radius: 3px; display: inline-block; } -.stats { margin-left: auto; display: flex; gap: 12px; font-size: 12px; color: var(--text-dim); } -.diag-chip { padding: 2px 8px; border-radius: 99px; font-weight: 600; } +.stats { display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--text-dim); } +.stat-item { display: inline-flex; align-items: center; gap: 5px; } +.stat-item svg { color: var(--text-dim); } +.diag-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 99px; font-weight: 600; } .diag-chip.ok { background: rgba(52, 211, 153, 0.15); color: var(--ok); } .diag-chip.warn { background: rgba(251, 191, 36, 0.15); color: var(--warn); } .diag-chip.err { background: rgba(248, 113, 113, 0.15); color: var(--err); } -.actions { display: flex; gap: 6px; } + +/* Hamburger — opens the left subject-area / layout drawer. Sits at the far left of row 1. */ +.hamburger { + position: relative; display: inline-flex; align-items: center; justify-content: center; + padding: 6px; border-radius: 8px; border: 1px solid var(--border); + background: var(--bg-card); color: var(--text-dim); cursor: pointer; +} +.hamburger:hover { color: var(--text); border-color: var(--border-strong); } +.hamburger.active { color: var(--accent); border-color: var(--accent); } +.hamburger-badge { + position: absolute; top: -6px; right: -6px; min-width: 15px; height: 15px; padding: 0 3px; + border-radius: 99px; background: var(--accent); color: var(--accent-ink); + font-size: 10px; font-weight: 700; line-height: 15px; text-align: center; +} + +/* Grouped action segments — a bordered container with a quiet tag, so a panel-opener + never looks like a view action. Each group's buttons sit flush inside it. */ +.btn-group { + display: inline-flex; align-items: center; gap: 2px; + background: var(--bg-card); border: 1px solid var(--border); border-radius: 9px; padding: 2px; +} +.grp-tag { + font-size: 10px; color: var(--text-dim); opacity: 0.75; + padding: 0 6px 0 4px; letter-spacing: 0.03em; text-transform: none; white-space: nowrap; +} +.grp-btn { + display: inline-flex; align-items: center; gap: 5px; + padding: 5px 9px; border-radius: 6px; border: none; background: transparent; + color: var(--text-dim); cursor: pointer; font-size: 12px; white-space: nowrap; +} +.grp-btn.icon-only { padding: 5px 7px; } +.grp-btn:hover { color: var(--text); background: rgba(255,255,255,0.05); } +.grp-btn.active { color: var(--accent); } +.grp-btn.active svg { color: var(--accent); } +.grp-badge { width: 6px; height: 6px; border-radius: 50%; background: var(--warn); display: inline-block; margin-left: 1px; } +/* the flow-direction arrow rotates to point the layout's flow way */ +.dir-arrow { display: inline-flex; transition: transform 0.15s ease; } + +/* The primary "New entity" button stands apart from the groups. */ .tool-btn { - padding: 6px 10px; border-radius: 8px; border: 1px solid var(--border); - background: var(--bg-card); color: var(--text-dim); cursor: pointer; font-size: 13px; + display: inline-flex; align-items: center; gap: 5px; + padding: 6px 11px; border-radius: 8px; border: 1px solid var(--border); + background: var(--bg-card); color: var(--text-dim); cursor: pointer; font-size: 12px; } .tool-btn:hover { color: var(--text); border-color: var(--border-strong); } .tool-btn.active { color: var(--accent); border-color: var(--accent); } +.tool-btn.primary { color: var(--accent); border-color: rgba(224,166,58,0.4); font-weight: 600; } -/* layout style picker (split button: icon + caret + menu) */ +/* layout style picker (split button: icon + caret + direction + menu) */ .layout-picker { position: relative; display: inline-flex; gap: 2px; } -.layout-picker .caret { padding: 6px 6px; font-size: 10px; } +.layout-picker .caret { font-size: 10px; } .layout-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 20; background: var(--bg-raised); border: 1px solid var(--border-strong); @@ -76,6 +120,51 @@ body { font-family: var(--font); background: var(--bg); color: var(--text); } } .layout-menu button:hover { background: var(--bg-card); color: var(--text); } +/* ---------- left subject-area / layout drawer ---------- */ +/* Mirrors the .side-panel card convention but anchored LEFT and animated. It stays mounted so + it can slide; `.open` drives the transform. The first slide transition in the app. */ +.canvas-drawer { + position: absolute; top: 12px; left: 12px; bottom: 12px; width: 300px; + background: var(--bg-raised); border: 1px solid var(--border); border-radius: 14px; + padding: 16px; overflow-y: auto; z-index: 9; box-shadow: 0 12px 40px rgba(0,0,0,0.5); + display: flex; flex-direction: column; gap: 10px; + transform: translateX(calc(-100% - 16px)); opacity: 0; pointer-events: none; + transition: transform 0.2s ease, opacity 0.2s ease; +} +.canvas-drawer.open { transform: translateX(0); opacity: 1; pointer-events: auto; } +.drawer-header { display: flex; align-items: center; justify-content: space-between; } +.drawer-header h2 { + margin: 0; font-size: 15px; display: inline-flex; align-items: center; gap: 7px; +} +.drawer-header h2 svg { color: var(--accent); } +.drawer-hint { font-size: 11px; color: var(--text-dim); line-height: 1.4; } +.sa-all { + align-self: flex-start; padding: 4px 10px; border-radius: 7px; + border: 1px solid var(--border); background: var(--bg-card); color: var(--text-dim); + cursor: pointer; font-size: 12px; +} +.sa-all:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); } +.sa-all.active { color: var(--accent); border-color: var(--accent); } +.sa-all:disabled { opacity: 0.5; cursor: default; } +.sa-list { display: flex; flex-direction: column; gap: 3px; margin-top: 2px; } +.sa-row { + display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 8px; + cursor: pointer; border: 1px solid transparent; user-select: none; +} +.sa-row:hover { background: var(--bg-card); } +.sa-row.active { background: var(--accent-soft); border-color: rgba(224,166,58,0.4); } +.sa-row.muted { cursor: default; opacity: 0.7; } +.sa-row.muted:hover { background: transparent; } +.sa-row input[type="checkbox"] { accent-color: var(--accent); cursor: pointer; } +.sa-chip { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; } +.sa-chip.none { background: repeating-linear-gradient(45deg, #4a3c2c, #4a3c2c 2px, transparent 2px, transparent 4px); } +.sa-name { flex: 1; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.sa-row.muted .sa-name { color: var(--text-dim); } +.sa-count { + font-size: 11px; color: var(--text-dim); background: var(--bg-card); + padding: 1px 7px; border-radius: 99px; flex: 0 0 auto; +} + /* ---------- entity node (erwin-style card) ---------- */ .entity-node { width: 264px; background: var(--bg-card); @@ -297,9 +386,6 @@ body { font-family: var(--font); background: var(--bg); color: var(--text); } .physical-name-input { font-size: 12px; color: var(--text-dim); } .physical-col { display: block; font-size: 10px; color: var(--text-dim); font-family: var(--mono, monospace); } .physical-col-input { display: block; font-size: 10px; color: var(--text-dim); } -.tool-btn.primary { color: var(--accent); border-color: rgba(224,166,58,0.4); font-weight: 600; } -.tool-btn.badged::after { content: "●"; color: var(--warn); margin-left: 4px; font-size: 8px; vertical-align: super; } -.divider { width: 1px; background: var(--border); margin: 0 4px; align-self: stretch; } /* modals */ .modal-backdrop { diff --git a/packages/server/src/mdl_server/static/assets/ModelDiagram-DfdI4kly.js b/packages/server/src/mdl_server/static/assets/ModelDiagram-oAb1enKe.js similarity index 97% rename from packages/server/src/mdl_server/static/assets/ModelDiagram-DfdI4kly.js rename to packages/server/src/mdl_server/static/assets/ModelDiagram-oAb1enKe.js index d9ade3e..26d3511 100644 --- a/packages/server/src/mdl_server/static/assets/ModelDiagram-DfdI4kly.js +++ b/packages/server/src/mdl_server/static/assets/ModelDiagram-oAb1enKe.js @@ -1 +1 @@ -import{r,j as s}from"./client-DOmNpTln.js";import{f as T,t as _,u as O,v as R,E as D,B as P,C as z,w as A}from"./styles-CIm9mWtD.js";const V={entity:D},$={relationship:R},l={breaking:"#f87171",additive:"#34d399",cosmetic:"#fcd34d"},N=["#5eead4","#fcd34d","#a78bfa","#fb923c","#38bdf8","#f472b6","#a3e635"],d="#64748b";function Y({subjectArea:u,severityByUlid:a,focusUlid:m,onSelect:c}){const[t,g]=r.useState(null),[f,w]=r.useState(null),[h,E]=r.useState(!0);r.useEffect(()=>{g(null),T(u).then(g).catch(n=>w(String(n)))},[u]);const{nodes:k,edges:M}=r.useMemo(()=>{if(!t)return{nodes:[],edges:[]};const n=new Map;t.subject_areas.forEach(e=>{let o=2166136261;for(let i=0;i[e.id,e])),b=a&&a.size>0,C=t.entities.map(e=>{var j;const o=(a==null?void 0:a.get(e.id))??(e.conceptual?a==null?void 0:a.get(e.conceptual.id):void 0),i=b?o?l[o]??d:d:(j=e.conceptual)!=null&&j.subject_area?n.get(e.conceptual.subject_area.id)??d:d;return{id:e.id,type:"entity",position:{x:0,y:0},data:{entity:e,color:i,dimmed:!!(b&&!o),highlighted:e.id===m,showTypes:h}}}),x=t.relationships.map(e=>({id:e.id,source:e.from.entity,target:e.to.entity,type:"relationship",data:{relationship:e,dimmed:!1}}));return{nodes:_(C,x,p),edges:x}},[t,a,m,h]);return f?s.jsx("p",{className:"sme-splash error",children:f}):t?t.entities.length?s.jsxs("div",{className:"erd-wrap",children:[s.jsxs("div",{className:"erd-bar",children:[s.jsxs("span",{className:"erd-count",children:[t.entities.length," entities · ",t.relationships.length," relationships",t.scope&&" · scoped"]}),s.jsxs("label",{className:"erd-toggle",children:[s.jsx("input",{type:"checkbox",checked:h,onChange:n=>E(n.target.checked)}),"show types"]}),a&&a.size>0&&s.jsxs("span",{className:"erd-legend",children:[s.jsx("span",{className:"sw",style:{background:l.breaking}})," breaking",s.jsx("span",{className:"sw",style:{background:l.additive}})," added",s.jsx("span",{className:"sw",style:{background:l.cosmetic}})," changed",s.jsx("span",{className:"sw",style:{background:d}})," unchanged"]})]}),s.jsx("div",{className:"erd-canvas",children:s.jsxs(O,{nodes:k,edges:M,nodeTypes:V,edgeTypes:$,fitView:!0,minZoom:.1,nodesConnectable:!1,onNodeClick:(n,p)=>c==null?void 0:c(p.id),onPaneClick:()=>c==null?void 0:c(null),onlyRenderVisibleElements:!0,proOptions:{hideAttribution:!0},children:[s.jsx(P,{gap:16,color:"#1f2937"}),s.jsx(z,{showInteractive:!1}),s.jsx(A,{pannable:!0,zoomable:!0})]})})]}):s.jsx("p",{className:"sme-placeholder",children:"Nothing to draw — this subject area has no entities in it yet."}):s.jsx("div",{className:"sme-splash",children:"◮ drawing the model…"})}export{Y as ModelDiagram}; +import{r,j as s}from"./client-DOmNpTln.js";import{f as T,t as _,u as O,v as R,E as D,B as P,C as z,w as A}from"./styles-BtrhR1xb.js";const V={entity:D},$={relationship:R},l={breaking:"#f87171",additive:"#34d399",cosmetic:"#fcd34d"},N=["#5eead4","#fcd34d","#a78bfa","#fb923c","#38bdf8","#f472b6","#a3e635"],d="#64748b";function Y({subjectArea:u,severityByUlid:a,focusUlid:m,onSelect:c}){const[t,g]=r.useState(null),[f,w]=r.useState(null),[h,E]=r.useState(!0);r.useEffect(()=>{g(null),T(u).then(g).catch(n=>w(String(n)))},[u]);const{nodes:k,edges:M}=r.useMemo(()=>{if(!t)return{nodes:[],edges:[]};const n=new Map;t.subject_areas.forEach(e=>{let o=2166136261;for(let i=0;i[e.id,e])),b=a&&a.size>0,C=t.entities.map(e=>{var j;const o=(a==null?void 0:a.get(e.id))??(e.conceptual?a==null?void 0:a.get(e.conceptual.id):void 0),i=b?o?l[o]??d:d:(j=e.conceptual)!=null&&j.subject_area?n.get(e.conceptual.subject_area.id)??d:d;return{id:e.id,type:"entity",position:{x:0,y:0},data:{entity:e,color:i,dimmed:!!(b&&!o),highlighted:e.id===m,showTypes:h}}}),x=t.relationships.map(e=>({id:e.id,source:e.from.entity,target:e.to.entity,type:"relationship",data:{relationship:e,dimmed:!1}}));return{nodes:_(C,x,p),edges:x}},[t,a,m,h]);return f?s.jsx("p",{className:"sme-splash error",children:f}):t?t.entities.length?s.jsxs("div",{className:"erd-wrap",children:[s.jsxs("div",{className:"erd-bar",children:[s.jsxs("span",{className:"erd-count",children:[t.entities.length," entities · ",t.relationships.length," relationships",t.scope&&" · scoped"]}),s.jsxs("label",{className:"erd-toggle",children:[s.jsx("input",{type:"checkbox",checked:h,onChange:n=>E(n.target.checked)}),"show types"]}),a&&a.size>0&&s.jsxs("span",{className:"erd-legend",children:[s.jsx("span",{className:"sw",style:{background:l.breaking}})," breaking",s.jsx("span",{className:"sw",style:{background:l.additive}})," added",s.jsx("span",{className:"sw",style:{background:l.cosmetic}})," changed",s.jsx("span",{className:"sw",style:{background:d}})," unchanged"]})]}),s.jsx("div",{className:"erd-canvas",children:s.jsxs(O,{nodes:k,edges:M,nodeTypes:V,edgeTypes:$,fitView:!0,minZoom:.1,nodesConnectable:!1,onNodeClick:(n,p)=>c==null?void 0:c(p.id),onPaneClick:()=>c==null?void 0:c(null),onlyRenderVisibleElements:!0,proOptions:{hideAttribution:!0},children:[s.jsx(P,{gap:16,color:"#1f2937"}),s.jsx(z,{showInteractive:!1}),s.jsx(A,{pannable:!0,zoomable:!0})]})})]}):s.jsx("p",{className:"sme-placeholder",children:"Nothing to draw — this subject area has no entities in it yet."}):s.jsx("div",{className:"sme-splash",children:"◮ drawing the model…"})}export{Y as ModelDiagram}; diff --git a/packages/server/src/mdl_server/static/assets/main-CZFuiW_s.js b/packages/server/src/mdl_server/static/assets/main-CZFuiW_s.js deleted file mode 100644 index b1e4d95..0000000 --- a/packages/server/src/mdl_server/static/assets/main-CZFuiW_s.js +++ /dev/null @@ -1,2 +0,0 @@ -import{j as e,r as a,c as Y,R as Z}from"./client-DOmNpTln.js";import{I as O,R as ee,P as U,f as _,a as V,g as z,s as te,A as ne,b as se,M as ae,S as re}from"./styles-CIm9mWtD.js";function oe(n){return{canEdit:!n,mode:"direct",canArbitrate:!n,canCommit:!n}}function le({doc:n,diagnostics:l,query:x,onQuery:u,onSubmitQuery:m,showTypes:d,onToggleTypes:h,collapseDetail:j,onToggleCollapse:y,onFitView:T,onRelayout:R,onRefresh:P,saColors:I,readOnly:g,dirty:L,panelTab:A,onPanelTab:B,onNewEntity:M,exec:b,onImported:E,onImportBatch:F,openImport:v}){const C=(l==null?void 0:l.items.filter(o=>o.severity==="error").length)??0,w=(l==null?void 0:l.items.filter(o=>o.severity==="warning").length)??0,i=(o,N,K,f)=>e.jsx("button",{className:"tool-btn"+(A===o?" active":"")+(f?" badged":""),onClick:()=>B(o),title:K,children:N});return e.jsxs("header",{className:"topbar",children:[e.jsxs("div",{className:"brand",children:[e.jsx("span",{className:"logo",children:"◮"}),e.jsx("span",{className:"brand-name",children:"Modelith"}),e.jsx("span",{className:"project-name",children:n.project.name}),g&&e.jsx("span",{className:"chip",children:"read-only"})]}),e.jsx("input",{className:"search",type:"search",placeholder:"Search entities & attributes… ( / , Enter jumps )",value:x,onChange:o=>u(o.target.value),onKeyDown:o=>{o.key==="Enter"&&m()},id:"mdl-search"}),e.jsx("div",{className:"legend",children:n.subject_areas.map(o=>e.jsxs("span",{className:"legend-item",children:[e.jsx("span",{className:"swatch",style:{background:I.get(o.id)}}),o.name]},o.id))}),e.jsxs("div",{className:"stats",children:[e.jsxs("span",{title:"entities",children:[n.counts.entities," ⬛"]}),e.jsxs("span",{title:"relationships",children:[n.counts.relationships," ⤳"]}),l&&e.jsx("span",{className:"diag-chip"+(C?" err":w?" warn":" ok"),title:l.items.map(o=>`${o.code} ${o.message}`).join(` -`)||"model valid",children:C?`${C} ✗`:w?`${w} ⚠`:"✓ valid"})]}),e.jsxs("div",{className:"actions",children:[!g&&e.jsx("button",{className:"tool-btn primary",onClick:M,title:"New entity (n)",children:"+ Entity"}),i("ontology","⬡","Ontology browser"),i("layers","≣","Four-layer stack & coverage"),i("changes","±",L?"Uncommitted changes!":"Changes",L),i("decisions","⚖","Decision ledger"),e.jsx("span",{className:"divider"}),e.jsx("button",{className:"tool-btn"+(d?" active":""),onClick:h,title:"Toggle data types",children:"{T}"}),e.jsx("button",{className:"tool-btn"+(j?" active":""),onClick:y,title:"Collapse to keys (PK + FK only) — readable for large models",children:"⇕"}),e.jsx("button",{className:"tool-btn",onClick:P,title:"Refresh from disk (picks up terminal / external edits)",children:"⟳"}),e.jsx(ce,{onRelayout:R}),e.jsx("button",{className:"tool-btn",onClick:T,title:"Fit view",children:"⛶"}),e.jsx("span",{className:"divider"}),e.jsx(O,{exec:b,canEdit:!g,onImported:E,submitLabel:"Import",buttonClass:"tool-btn",applyBatch:F,openImport:v})]})]})}function ce({onRelayout:n}){const[l,x]=a.useState(!1),u=a.useRef(null);a.useEffect(()=>{if(!l)return;const d=h=>{u.current&&!u.current.contains(h.target)&&x(!1)};return document.addEventListener("mousedown",d),()=>document.removeEventListener("mousedown",d)},[l]);const m=d=>{n(d),x(!1)};return e.jsxs("div",{className:"layout-picker",ref:u,children:[e.jsx("button",{className:"tool-btn",onClick:()=>n("auto"),title:"Auto-layout",children:"⌗"}),e.jsx("button",{className:"tool-btn caret"+(l?" active":""),onClick:()=>x(d=>!d),title:"Layout style",children:"▾"}),l&&e.jsxs("div",{className:"layout-menu",role:"menu",children:[e.jsx("button",{onClick:()=>m("auto"),children:"Auto (by size)"}),e.jsx("button",{onClick:()=>m("hierarchical"),children:"Hierarchical"}),e.jsx("button",{onClick:()=>m("grid"),children:"Grid"})]})]})}function ie(){const[n,l]=a.useState(null),[x,u]=a.useState(null),[m,d]=a.useState(null),[h,j]=a.useState(null),[y,T]=a.useState(""),[R,P]=a.useState(!0),[I,g]=a.useState(!1),[L,A]=a.useState(()=>new Set),[B,M]=a.useState(null),[b,E]=a.useState(null),[F,v]=a.useState(!1),[C,w]=a.useState(0),i=a.useRef(null),o=a.useRef(""),N=a.useRef(!1),K=a.useMemo(()=>{const t=new Map;return n==null||n.subject_areas.forEach((r,s)=>t.set(r.id,U[s%U.length])),t},[n]),f=(n==null?void 0:n.read_only)??!0,G=a.useMemo(()=>oe(f),[f]),D=a.useMemo(()=>new URLSearchParams(window.location.search),[]),k=D.get("minimal")==="1";a.useEffect(()=>{k&&g(!0)},[k]);const H=a.useCallback(t=>{A(r=>{const s=new Set(r);return s.has(t)?s.delete(t):s.add(t),s})},[]),X=D.get("import")==="1",$=a.useRef(!1),p=a.useCallback(()=>{_().then(l).catch(t=>d(String(t))),V().then(u).catch(()=>u(null)),z().then(t=>v(!!(t.git&&!t.clean))).catch(()=>v(!1)),w(t=>t+1)},[]);a.useEffect(p,[p]),a.useEffect(()=>{const t=setInterval(()=>{_().then(r=>{l(s=>s&&r.fingerprint===s.fingerprint?s:(N.current||(o.current=r.fingerprint),k||(V().then(u).catch(()=>u(null)),z().then(c=>v(!!(c.git&&!c.clean))).catch(()=>v(!1))),w(c=>c+1),r))}).catch(()=>{})},3e3);return()=>clearInterval(t)},[k]),a.useEffect(()=>{n!=null&&n.fingerprint&&(o.current=n.fingerprint)},[n]);const q=a.useCallback(async(t,r)=>{if(n){N.current=!0;try{const s=await te(t,r,o.current||n.fingerprint);return s!=null&&s.fingerprint&&(o.current=s.fingerprint),p(),s}catch(s){throw s instanceof ne&&s.status===409?(j("Model changed on disk — view refreshed, please retry."),p()):j(s instanceof Error?s.message:String(s)),s}finally{N.current=!1}}},[n,p]);a.useEffect(()=>{if(!h)return;const t=setTimeout(()=>j(null),5e3);return()=>clearTimeout(t)},[h]),a.useEffect(()=>{if(!n||$.current)return;const t=D.get("focus");if(!t)return;const r=n.entities.find(s=>{var c;return s.name===t||((c=s.conceptual)==null?void 0:c.name)===t});r&&($.current=!0,requestAnimationFrame(()=>{var s;return(s=i.current)==null?void 0:s.focusEntity(r.id)}))},[n,D]);const J=a.useCallback(()=>{var s;if(!n)return;const t=y.trim().toLowerCase();if(!t)return;const r=n.entities.find(c=>{var S;return(c.name.toLowerCase()+" "+(((S=c.conceptual)==null?void 0:S.name.toLowerCase())??"")+" "+c.attributes.map(W=>W.name.toLowerCase()).join(" ")).includes(t)});r&&((s=i.current)==null||s.focusEntity(r.id))},[n,y]);return a.useEffect(()=>{const t=r=>{var c,Q,S;const s=(c=document.activeElement)==null?void 0:c.tagName;s==="INPUT"||s==="TEXTAREA"||s==="SELECT"||(r.key==="/"&&(r.preventDefault(),(Q=document.getElementById("mdl-search"))==null||Q.focus()),r.key==="n"&&!f&&((S=i.current)==null||S.newEntity()),r.key==="Escape"&&(M(null),T(""),E(null)))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[f]),m?e.jsxs("div",{className:"splash error",children:[e.jsxs("h1",{children:["◮"," Modelith"]}),e.jsx("p",{children:"Could not load the model:"}),e.jsx("pre",{children:m}),e.jsxs("p",{children:["Is ",e.jsx("code",{children:"mdl serve"})," pointed at a model directory?"]})]}):n?e.jsxs("div",{className:"app",children:[!k&&e.jsx(le,{doc:n,diagnostics:x,query:y,onQuery:T,onSubmitQuery:J,showTypes:R,onToggleTypes:()=>P(t=>!t),collapseDetail:I,onToggleCollapse:()=>g(t=>!t),onFitView:()=>{var t;return(t=i.current)==null?void 0:t.fitView()},onRelayout:t=>{var r;return(r=i.current)==null?void 0:r.relayout(t)},onRefresh:p,saColors:K,readOnly:f,dirty:F,panelTab:b,onPanelTab:t=>E(r=>r===t?null:t),onNewEntity:()=>{var t;return(t=i.current)==null?void 0:t.newEntity()},exec:q,onImported:p,onImportBatch:se,openImport:X}),e.jsxs("div",{className:"canvas-wrap",children:[e.jsx(ae,{doc:n,caps:G,exec:q,selectedId:b?null:B,onSelect:M,query:y,showTypes:R,collapseDetail:I,expandedEntities:L,onToggleExpand:H,onError:j,handleRef:i}),b&&e.jsx(re,{tab:b,onClose:()=>E(null),readOnly:f,refreshKey:C,onModelChanged:p,onFocusEntity:t=>{var r;E(null),(r=i.current)==null||r.focusEntity(t)}}),h&&e.jsx("div",{className:"toast",children:h})]})]}):e.jsxs("div",{className:"splash",children:["◮"," loading model…"]})}function ue(){return e.jsx(ee,{children:e.jsx(ie,{})})}Y.createRoot(document.getElementById("root")).render(e.jsx(Z.StrictMode,{children:e.jsx(ue,{})})); diff --git a/packages/server/src/mdl_server/static/assets/main-DgsUduj_.js b/packages/server/src/mdl_server/static/assets/main-DgsUduj_.js new file mode 100644 index 0000000..53d918f --- /dev/null +++ b/packages/server/src/mdl_server/static/assets/main-DgsUduj_.js @@ -0,0 +1,2 @@ +import{j as e,r as a,c as ie,R as oe}from"./client-DOmNpTln.js";import{I as le,R as de,P as Y,f as J,a as Z,g as ee,s as he,A as ue,b as xe,M as je,S as pe}from"./styles-BtrhR1xb.js";function me(s){return{canEdit:!s,mode:"direct",canArbitrate:!s,canCommit:!s}}function l({size:s=16,children:i}){return e.jsx("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.7,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:i})}const fe=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M12 5v14M5 12h14"})}),ge=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M12 3l7.5 4.5v9L12 21l-7.5-4.5v-9L12 3z"})}),ye=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M12 3l9 5-9 5-9-5 9-5z"}),e.jsx("path",{d:"M3 12l9 5 9-5"}),e.jsx("path",{d:"M3 16l9 5 9-5"})]}),be=s=>e.jsxs(l,{...s,children:[e.jsx("circle",{cx:"6",cy:"6",r:"2.4"}),e.jsx("circle",{cx:"6",cy:"18",r:"2.4"}),e.jsx("circle",{cx:"18",cy:"18",r:"2.4"}),e.jsx("path",{d:"M6 8.4v7.2M8.4 6H14a3 3 0 0 1 3 3v6.6"})]}),we=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M12 4v16M6 8h12"}),e.jsx("path",{d:"M6 8l-2.5 5a2.5 2.5 0 0 0 5 0L6 8zM18 8l-2.5 5a2.5 2.5 0 0 0 5 0L18 8z"}),e.jsx("path",{d:"M9 20h6"})]}),ve=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M8 7l-4 5 4 5M16 7l4 5-4 5"})}),Me=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M8 8l4-4 4 4M8 16l4 4 4-4"}),e.jsx("path",{d:"M4 12h16"})]}),Ce=s=>e.jsxs(l,{...s,children:[e.jsx("rect",{x:"3",y:"4",width:"7",height:"7",rx:"1"}),e.jsx("rect",{x:"14",y:"4",width:"7",height:"7",rx:"1"}),e.jsx("rect",{x:"3",y:"15",width:"7",height:"5",rx:"1"}),e.jsx("rect",{x:"14",y:"15",width:"7",height:"5",rx:"1"})]}),Ne=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M4 8V5a1 1 0 0 1 1-1h3M16 4h3a1 1 0 0 1 1 1v3M20 16v3a1 1 0 0 1-1 1h-3M8 20H5a1 1 0 0 1-1-1v-3"})}),Ee=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M20 11a8 8 0 1 0-.5 4"}),e.jsx("path",{d:"M20 4v5h-5"})]}),ke=s=>e.jsxs(l,{...s,children:[e.jsx("rect",{x:"4",y:"4",width:"16",height:"16",rx:"2"}),e.jsx("path",{d:"M4 9h16"})]}),Se=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M4 7h9a4 4 0 0 1 4 4v3"}),e.jsx("path",{d:"M14 11l3 3 3-3"})]}),Ie=s=>e.jsxs(l,{...s,children:[e.jsx("circle",{cx:"12",cy:"12",r:"9"}),e.jsx("path",{d:"M8.5 12.5l2.5 2.5 4.5-5"})]}),Le=s=>e.jsxs(l,{...s,children:[e.jsx("path",{d:"M12 4l9 16H3l9-16z"}),e.jsx("path",{d:"M12 10v4M12 17.5v.5"})]}),Re=s=>e.jsxs(l,{...s,children:[e.jsx("circle",{cx:"12",cy:"12",r:"9"}),e.jsx("path",{d:"M15 9l-6 6M9 9l6 6"})]}),Te=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M4 6h16M4 12h16M4 18h16"})}),ze=s=>e.jsxs(l,{...s,children:[e.jsx("rect",{x:"3",y:"3",width:"7",height:"7",rx:"1.5"}),e.jsx("rect",{x:"14",y:"3",width:"7",height:"7",rx:"1.5"}),e.jsx("rect",{x:"3",y:"14",width:"7",height:"7",rx:"1.5"}),e.jsx("rect",{x:"14",y:"14",width:"7",height:"7",rx:"1.5"})]}),De=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M6 6l12 12M18 6L6 18"})}),Be=s=>e.jsx(l,{...s,children:e.jsx("path",{d:"M5 12h14M13 6l6 6-6 6"})});function Fe({doc:s,saColors:i,countByArea:f,activeAreas:d,onSetActive:g,open:v,onClose:y}){const x=s.subject_areas,j=d.size>0,m=c=>g(new Set([c])),M=c=>{const p=new Set(d);p.has(c)?p.delete(c):p.add(c),g(p)},o=f.get("")??0;return e.jsxs("aside",{className:"canvas-drawer"+(v?" open":""),"aria-hidden":!v,children:[e.jsxs("div",{className:"drawer-header",children:[e.jsxs("h2",{children:[e.jsx(ze,{size:16})," Subject areas"]}),e.jsx("button",{className:"icon-btn",onClick:y,title:"Close","aria-label":"Close drawer",children:e.jsx(De,{size:16})})]}),e.jsx("div",{className:"drawer-hint",children:j?`Showing ${d.size} of ${x.length} — click a domain to focus, tick to add.`:"Click a domain to show only it. Tick several to compare."}),e.jsx("button",{className:"sa-all"+(j?"":" active"),onClick:()=>g(new Set),disabled:!j,children:"Show all"}),e.jsxs("div",{className:"sa-list",children:[x.map(c=>{const p=d.has(c.id),D=f.get(c.id)??c.member_count??0;return e.jsxs("div",{className:"sa-row"+(p?" active":""),onClick:()=>m(c.id),role:"button",tabIndex:0,onKeyDown:w=>{(w.key==="Enter"||w.key===" ")&&(w.preventDefault(),m(c.id))},title:`Focus ${c.name}`,children:[e.jsx("input",{type:"checkbox",checked:p,onClick:w=>w.stopPropagation(),onChange:()=>M(c.id),"aria-label":`Include ${c.name}`}),e.jsx("span",{className:"sa-chip",style:{background:i.get(c.id)}}),e.jsx("span",{className:"sa-name",children:c.name}),e.jsx("span",{className:"sa-count",children:D})]},c.id)}),o>0&&e.jsxs("div",{className:"sa-row muted",title:"Entities with no subject area",children:[e.jsx("span",{className:"sa-chip none"}),e.jsx("span",{className:"sa-name",children:"No subject area"}),e.jsx("span",{className:"sa-count",children:o})]})]})]})}function Pe({doc:s,diagnostics:i,query:f,onQuery:d,onSubmitQuery:g,showTypes:v,onToggleTypes:y,collapseDetail:x,onToggleCollapse:j,onFitView:m,onRelayout:M,onRefresh:o,readOnly:c,dirty:p,panelTab:D,onPanelTab:w,onNewEntity:Q,exec:A,onImported:S,onImportBatch:I,openImport:_,onToggleDrawer:$,drawerOpen:k,filterCount:K}){const B=(i==null?void 0:i.items.filter(u=>u.severity==="error").length)??0,C=(i==null?void 0:i.items.filter(u=>u.severity==="warning").length)??0,L=(u,b,R,F,q)=>e.jsxs("button",{className:"grp-btn"+(D===u?" active":""),onClick:()=>w(u),title:F,children:[b,e.jsx("span",{children:R}),q&&e.jsx("span",{className:"grp-badge","aria-label":"uncommitted changes"})]});return e.jsxs("header",{className:"topbar",children:[e.jsxs("div",{className:"topbar-row context",children:[e.jsxs("button",{className:"hamburger"+(k?" active":""),onClick:$,title:k?"Hide subject areas & layout":"Subject areas & layout","aria-label":"Toggle subject-area & layout drawer","aria-expanded":k,children:[e.jsx(Te,{size:18}),K>0&&e.jsx("span",{className:"hamburger-badge",children:K})]}),e.jsxs("div",{className:"brand",children:[e.jsx("span",{className:"logo",children:"◮"}),e.jsx("span",{className:"brand-name",children:"Modelith"}),e.jsx("span",{className:"project-name",children:s.project.name}),c&&e.jsx("span",{className:"chip",children:"read-only"})]}),e.jsx("input",{className:"search",type:"search",placeholder:"Search entities & attributes… ( / , Enter jumps )",value:f,onChange:u=>d(u.target.value),onKeyDown:u=>{u.key==="Enter"&&g()},id:"mdl-search"}),e.jsxs("div",{className:"stats",children:[e.jsxs("span",{className:"stat-item",title:"entities",children:[e.jsx(ke,{size:14}),s.counts.entities]}),e.jsxs("span",{className:"stat-item",title:"relationships",children:[e.jsx(Se,{size:14}),s.counts.relationships]}),i&&e.jsx("span",{className:"diag-chip"+(B?" err":C?" warn":" ok"),title:i.items.map(u=>`${u.code} ${u.message}`).join(` +`)||"model valid",children:B?e.jsxs(e.Fragment,{children:[e.jsx(Re,{size:14}),B]}):C?e.jsxs(e.Fragment,{children:[e.jsx(Le,{size:14}),C]}):e.jsxs(e.Fragment,{children:[e.jsx(Ie,{size:14}),"valid"]})})]})]}),e.jsxs("div",{className:"topbar-row actions",children:[!c&&e.jsxs("button",{className:"tool-btn primary",onClick:Q,title:"New entity (n)",children:[e.jsx(fe,{size:15}),e.jsx("span",{children:"Entity"})]}),e.jsxs("div",{className:"btn-group",role:"group","aria-label":"Panels",children:[e.jsx("span",{className:"grp-tag",children:"Panels"}),L("ontology",e.jsx(ge,{size:15}),"Ontology","Ontology browser"),L("layers",e.jsx(ye,{size:15}),"Layers","Four-layer stack & coverage"),L("changes",e.jsx(be,{size:15}),"Changes",p?"Uncommitted changes":"Changes",p),L("decisions",e.jsx(we,{size:15}),"Decisions","Decision ledger")]}),e.jsxs("div",{className:"btn-group",role:"group","aria-label":"View",children:[e.jsx("span",{className:"grp-tag",children:"View"}),e.jsx("button",{className:"grp-btn icon-only"+(v?" active":""),onClick:y,title:"Toggle data types","aria-label":"Toggle data types",children:e.jsx(ve,{size:15})}),e.jsx("button",{className:"grp-btn icon-only"+(x?" active":""),onClick:j,title:"Collapse to keys (PK + FK only) — readable for large models","aria-label":"Collapse to keys",children:e.jsx(Me,{size:15})}),e.jsx(_e,{onRelayout:M}),e.jsx("button",{className:"grp-btn icon-only",onClick:m,title:"Fit view","aria-label":"Fit view",children:e.jsx(Ne,{size:15})})]}),e.jsxs("div",{className:"btn-group",role:"group","aria-label":"Data",children:[e.jsx("span",{className:"grp-tag",children:"Data"}),e.jsx("button",{className:"grp-btn icon-only",onClick:o,title:"Refresh from disk (picks up terminal / external edits)","aria-label":"Refresh from disk",children:e.jsx(Ee,{size:15})}),e.jsx(le,{exec:A,canEdit:!c,onImported:S,submitLabel:"Import",buttonClass:"grp-btn",applyBatch:I,openImport:_})]})]})]})}const O=["LR","TB","RL","BT"],Ae={LR:0,TB:90,RL:180,BT:270},se={LR:"left → right",TB:"top → bottom",RL:"right → left",BT:"bottom → top"};function _e({onRelayout:s}){const[i,f]=a.useState(!1),[d,g]=a.useState("LR"),[v,y]=a.useState("auto"),x=a.useRef(null);a.useEffect(()=>{if(!i)return;const o=c=>{x.current&&!x.current.contains(c.target)&&f(!1)};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[i]);const j=o=>{y(o),s(o,d)},m=o=>{j(o),f(!1)},M=()=>{const o=O[(O.indexOf(d)+1)%O.length];g(o),s(v,o)};return e.jsxs("div",{className:"layout-picker",ref:x,children:[e.jsx("button",{className:"grp-btn icon-only",onClick:()=>j("auto"),title:"Auto-layout","aria-label":"Auto-layout",children:e.jsx(Ce,{size:15})}),e.jsx("button",{className:"grp-btn icon-only caret"+(i?" active":""),onClick:()=>f(o=>!o),title:"Layout style","aria-label":"Layout style",children:"▾"}),e.jsx("button",{className:"grp-btn icon-only",onClick:M,title:`Flow direction: ${se[d]} (click to rotate)`,"aria-label":`Flow direction: ${se[d]}`,children:e.jsx("span",{className:"dir-arrow",style:{transform:`rotate(${Ae[d]}deg)`},children:e.jsx(Be,{size:15})})}),i&&e.jsxs("div",{className:"layout-menu",role:"menu",children:[e.jsx("button",{onClick:()=>m("auto"),children:"Auto (by size)"}),e.jsx("button",{onClick:()=>m("hierarchical"),children:"Hierarchical"}),e.jsx("button",{onClick:()=>m("clustered"),children:"Clustered (by area)"}),e.jsx("button",{onClick:()=>m("grid"),children:"Grid"})]})]})}function $e(){const[s,i]=a.useState(null),[f,d]=a.useState(null),[g,v]=a.useState(null),[y,x]=a.useState(null),[j,m]=a.useState(""),[M,o]=a.useState(!0),[c,p]=a.useState(!1),[D,w]=a.useState(()=>new Set),[Q,A]=a.useState(null),[S,I]=a.useState(null),[_,$]=a.useState(!1),[k,K]=a.useState(()=>new Set),[B,C]=a.useState(!1),[L,u]=a.useState(0),b=a.useRef(null),R=a.useRef(""),F=a.useRef(!1),q=a.useMemo(()=>{const t=new Map;return s==null||s.subject_areas.forEach((r,n)=>t.set(r.id,Y[n%Y.length])),t},[s]),U=a.useMemo(()=>{const t=new Map;if(!s)return t;const r=new Map;return s.subject_areas.forEach(n=>{(n.members??[]).forEach(h=>r.set(h,n.id))}),s.entities.forEach(n=>{var E,V,X;const P=((E=n.conceptual)!=null&&E.id?r.get(n.conceptual.id):void 0)??((X=(V=n.conceptual)==null?void 0:V.subject_area)==null?void 0:X.id)??"";t.set(n.id,P)}),t},[s]),te=a.useMemo(()=>{const t=new Map;return U.forEach(r=>t.set(r,(t.get(r)??0)+1)),t},[U]),T=(s==null?void 0:s.read_only)??!0,ne=a.useMemo(()=>me(T),[T]),H=a.useMemo(()=>new URLSearchParams(window.location.search),[]),z=H.get("minimal")==="1";a.useEffect(()=>{z&&p(!0)},[z]);const ae=a.useCallback(t=>{w(r=>{const n=new Set(r);return n.has(t)?n.delete(t):n.add(t),n})},[]),re=H.get("import")==="1",W=a.useRef(!1),N=a.useCallback(()=>{J().then(i).catch(t=>v(String(t))),Z().then(d).catch(()=>d(null)),ee().then(t=>C(!!(t.git&&!t.clean))).catch(()=>C(!1)),u(t=>t+1)},[]);a.useEffect(N,[N]),a.useEffect(()=>{const t=setInterval(()=>{J().then(r=>{i(n=>n&&r.fingerprint===n.fingerprint?n:(F.current||(R.current=r.fingerprint),z||(Z().then(d).catch(()=>d(null)),ee().then(h=>C(!!(h.git&&!h.clean))).catch(()=>C(!1))),u(h=>h+1),r))}).catch(()=>{})},3e3);return()=>clearInterval(t)},[z]),a.useEffect(()=>{s!=null&&s.fingerprint&&(R.current=s.fingerprint)},[s]);const G=a.useCallback(async(t,r)=>{if(s){F.current=!0;try{const n=await he(t,r,R.current||s.fingerprint);return n!=null&&n.fingerprint&&(R.current=n.fingerprint),N(),n}catch(n){throw n instanceof ue&&n.status===409?(x("Model changed on disk — view refreshed, please retry."),N()):x(n instanceof Error?n.message:String(n)),n}finally{F.current=!1}}},[s,N]);a.useEffect(()=>{if(!y)return;const t=setTimeout(()=>x(null),5e3);return()=>clearTimeout(t)},[y]),a.useEffect(()=>{if(!s||W.current)return;const t=H.get("focus");if(!t)return;const r=s.entities.find(n=>{var h;return n.name===t||((h=n.conceptual)==null?void 0:h.name)===t});r&&(W.current=!0,requestAnimationFrame(()=>{var n;return(n=b.current)==null?void 0:n.focusEntity(r.id)}))},[s,H]);const ce=a.useCallback(()=>{var n;if(!s)return;const t=j.trim().toLowerCase();if(!t)return;const r=s.entities.find(h=>{var E;return(h.name.toLowerCase()+" "+(((E=h.conceptual)==null?void 0:E.name.toLowerCase())??"")+" "+h.attributes.map(V=>V.name.toLowerCase()).join(" ")).includes(t)});r&&((n=b.current)==null||n.focusEntity(r.id))},[s,j]);return a.useEffect(()=>{const t=r=>{var h,P,E;const n=(h=document.activeElement)==null?void 0:h.tagName;n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||(r.key==="/"&&(r.preventDefault(),(P=document.getElementById("mdl-search"))==null||P.focus()),r.key==="n"&&!T&&((E=b.current)==null||E.newEntity()),r.key==="Escape"&&(A(null),m(""),I(null)))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[T]),g?e.jsxs("div",{className:"splash error",children:[e.jsxs("h1",{children:["◮"," Modelith"]}),e.jsx("p",{children:"Could not load the model:"}),e.jsx("pre",{children:g}),e.jsxs("p",{children:["Is ",e.jsx("code",{children:"mdl serve"})," pointed at a model directory?"]})]}):s?e.jsxs("div",{className:"app",children:[!z&&e.jsx(Pe,{doc:s,diagnostics:f,query:j,onQuery:m,onSubmitQuery:ce,showTypes:M,onToggleTypes:()=>o(t=>!t),collapseDetail:c,onToggleCollapse:()=>p(t=>!t),onFitView:()=>{var t;return(t=b.current)==null?void 0:t.fitView()},onRelayout:(t,r)=>{var n;return(n=b.current)==null?void 0:n.relayout(t,r)},onRefresh:N,readOnly:T,dirty:B,panelTab:S,onPanelTab:t=>I(r=>r===t?null:t),onNewEntity:()=>{var t;return(t=b.current)==null?void 0:t.newEntity()},exec:G,onImported:N,onImportBatch:xe,openImport:re,onToggleDrawer:()=>$(t=>!t),drawerOpen:_,filterCount:k.size}),e.jsxs("div",{className:"canvas-wrap",children:[e.jsx(je,{doc:s,caps:ne,exec:G,selectedId:S?null:Q,onSelect:A,query:j,showTypes:M,collapseDetail:c,expandedEntities:D,onToggleExpand:ae,activeAreas:k,onError:x,handleRef:b}),!z&&e.jsx(Fe,{doc:s,saColors:q,countByArea:te,activeAreas:k,onSetActive:K,open:_,onClose:()=>$(!1)}),S&&e.jsx(pe,{tab:S,onClose:()=>I(null),readOnly:T,refreshKey:L,onModelChanged:N,onFocusEntity:t=>{var r;I(null),(r=b.current)==null||r.focusEntity(t)}}),y&&e.jsx("div",{className:"toast",children:y})]})]}):e.jsxs("div",{className:"splash",children:["◮"," loading model…"]})}function Ke(){return e.jsx(de,{children:e.jsx($e,{})})}ie.createRoot(document.getElementById("root")).render(e.jsx(oe.StrictMode,{children:e.jsx(Ke,{})})); diff --git a/packages/server/src/mdl_server/static/assets/sme-Ji3JtE2B.js b/packages/server/src/mdl_server/static/assets/sme-rGO675Bx.js similarity index 99% rename from packages/server/src/mdl_server/static/assets/sme-Ji3JtE2B.js rename to packages/server/src/mdl_server/static/assets/sme-rGO675Bx.js index 6bddc66..c7137e3 100644 --- a/packages/server/src/mdl_server/static/assets/sme-Ji3JtE2B.js +++ b/packages/server/src/mdl_server/static/assets/sme-rGO675Bx.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ModelDiagram-DfdI4kly.js","assets/client-DOmNpTln.js","assets/styles-CIm9mWtD.js","assets/styles-BJW39REh.css"])))=>i.map(i=>d[i]); -import{r as n,j as e,c as Ae,R as Ee}from"./client-DOmNpTln.js";import{p as pe,c as je,d as xe,e as $e,h as be,I as Re,R as Me,M as De,O as Pe,L as Ie,i as Oe,j as Te,A as Be,k as Le,l as Fe,m as ze,o as qe,s as We,f as le,n as Ge,q as He,r as Ve}from"./styles-CIm9mWtD.js";/* empty css */const Ke="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ce(s,t){let a="";for(let l=0;l>=5n;return a}function ge(){const s=BigInt(Date.now())&(1n<<48n)-1n,t=new Uint8Array(10);crypto.getRandomValues(t);let a=0n;for(const l of t)a=a<<8n|BigInt(l);return ce(s,10)+ce(a,16)}const Ue={create_entity:["id","conceptual_id"],create_relationship:["id","from_fk_id"],create_subject_area:["id"],create_term:["id"],create_domain:["id"],create_code_set:["id"],create_key_group:["id"],create_category:["id"],add_attribute:["id"]};function Ye(s,t){const a=Ue[s];if(!a)return t;const l={...t};for(const i of a)l[i]||(l[i]=ge());return l}function fe(s,t){if(s.startsWith("create_")||s==="add_attribute")return`${s}:${t.id??t.attribute_id}`;const a=t.id??t.entity_id??"",l=t.attribute_id??"";return l?`${s}:${a}:${l}`:`${s}:${a}`}function Je({subjectArea:s,describe:t}){const[a,l]=n.useState([]),[i,x]=n.useState(null),[c,r]=n.useState(!1),m=n.useRef(null),N=n.useCallback(async(h,g)=>{g=Ye(h,g),h==="set_alignment"&&g.status===void 0&&(g={...g,status:"proposed"});const _=fe(h,g),{label:C,before:T,after:S}=t(h,g);return l(y=>{const A=y.filter(k=>k.key!==_);if(h.startsWith("delete_")){const k=g.id??g.entity_id;if(k&&y.some(o=>o.op.startsWith("create_")&&o.payload.id===k))return A.filter(o=>o.payload.id!==k)}return[...A,{op:h,payload:g,label:C,before:T,after:S,key:_}]}),{ok:!0,fingerprint:"",created_id:g.id??null,diagnostics:[]}},[t]);n.useEffect(()=>{if(!a.length){x(null);return}const h=setTimeout(()=>{var _;(_=m.current)==null||_.abort();const g=new AbortController;m.current=g,r(!0),pe(a.map(C=>({op:C.op,payload:C.payload})),s,g.signal).then(x).catch(C=>{C.name!=="AbortError"&&x(null)}).finally(()=>r(!1))},250);return()=>clearTimeout(h)},[a,s]);const b=n.useCallback(h=>{l(g=>g.filter(_=>_.key!==h))},[]),f=n.useCallback(()=>l([]),[]);return n.useMemo(()=>({pending:a,previewDoc:(i==null?void 0:i.model)??null,previewDiff:(i==null?void 0:i.diff)??null,diagnostics:(i==null?void 0:i.diagnostics)??[],failure:i&&i.failed_index!==null?{index:i.failed_index,error:i.error??"invalid change"}:null,busy:c,exec:N,drop:b,clear:f}),[a,i,c,N,b,f])}function Qe(s){const t=new Map;for(const l of s)for(const i of["id","conceptual_id","from_fk_id"]){const x=l.payload[i];l.op.startsWith("create_")&&typeof x=="string"&&t.set(x,l.key)}if(!t.size)return new Set;const a=new Set;for(const l of s)if(!l.op.startsWith("create_"))for(const i of Object.values(l.payload))typeof i=="string"&&t.has(i)&&(a.add(l.key),a.add(t.get(i)));return a}function Xe({user:s}){const[t,a]=n.useState(null);return n.useEffect(()=>{je(s).then(a).catch(()=>{})},[s]),!(t!=null&&t.ok)||!t.git?null:t.read_only?e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"browse only — editing is disabled on this deployment"})]}):t.dirty?e.jsxs("div",{className:"git-banner warn",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"uncommitted changes in the working tree — a proposal will be refused until they are committed or discarded"})]}):t.on_base?e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"protected — your edits become a pull request"})]}):e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"your proposal branch"}),t.behind?e.jsxs("span",{className:"dim",children:["· ",t.base_branch," is ",t.behind," ahead"]}):null]})}function Ze({exec:s,canEdit:t,stagedMembers:a}){const[l,i]=n.useState([]),[x,c]=n.useState(""),[r,m]=n.useState(null),[N,b]=n.useState(""),[f,h]=n.useState(new Set),[g,_]=n.useState("ancestors"),[C,T]=n.useState(1),[S,y]=n.useState(null),[A,k]=n.useState(new Set),[R,o]=n.useState(null);n.useEffect(()=>{xe().then(d=>{i(d.subject_areas),c(w=>{var M;return w||((M=d.subject_areas[0])==null?void 0:M.id)||""})}).catch(d=>o(String(d)))},[]),n.useEffect(()=>{x&&(y(null),h(new Set),$e(x).then(m).catch(d=>o(String(d))))},[x]);const E=n.useMemo(()=>a[x]??(r==null?void 0:r.members)??[],[a,x,r]),$=n.useMemo(()=>{const d=new Map;for(const w of[...(r==null?void 0:r.included)??[],...(r==null?void 0:r.available)??[]])d.set(w.id,w);return d},[r]),D=N.trim().toLowerCase(),B=d=>!D||d.name.toLowerCase().includes(D),u=n.useMemo(()=>new Set(E),[E]),P=n.useMemo(()=>E.map(d=>$.get(d)).filter(d=>!!d&&B(d)),[E,$,D]),F=n.useMemo(()=>[...$.values()].filter(d=>!u.has(d.id)&&B(d)),[$,u,D]),I=n.useCallback(d=>{if(!r)return;const w=d.filter(q=>!(r.members??[]).includes(q)).length,M=(r.members??[]).filter(q=>!d.includes(q)).length;s("set_subject_area_members",{id:r.id,members:d,__label:`${r.name}: ${d.length} objects (+${w} −${M})`})},[r,s]),z=(d,w)=>{const M=w?[...E,...d.filter(q=>!u.has(q))]:E.filter(q=>!d.includes(q));I(M),h(new Set)},W=(d,w,M)=>{const q=new Set(d);q.has(w)?q.delete(w):q.add(w),M(q)},U=()=>{if(!r)return;const d=f.size?[...f]:E;if(!d.length){o("add an object first, or select one to expand from");return}o(null),be(r.id,{seeds:d,direction:g,levels:C}).then(w=>{y(w.hops),k(new Set(w.added))}).catch(w=>o(String(w)))},K=()=>{z([...A],!0),y(null)};if(R&&!r)return e.jsx("p",{className:"sme-splash error",children:R});if(!l.length)return e.jsx("p",{className:"sme-placeholder",children:"No subject areas yet."});const j=((r==null?void 0:r.inconsistent)??[]).filter(d=>!u.has(d));return e.jsxs("div",{className:"sa-editor",children:[e.jsx("nav",{className:"sme-nav",children:l.map(d=>e.jsxs("button",{className:"sme-sa"+(d.id===x?" active":""),onClick:()=>c(d.id),title:d.definition??void 0,children:[d.name,e.jsx("span",{className:"sme-sa-count",children:(a[d.id]??d.members).length})]},d.id))}),e.jsxs("div",{className:"sa-main",children:[e.jsxs("div",{className:"sa-head",children:[e.jsx("h2",{children:(r==null?void 0:r.name)??"…"}),(r==null?void 0:r.definition)&&e.jsx("p",{className:"sme-muted",children:r.definition}),e.jsx("input",{className:"sme-search sa-filter",type:"search",placeholder:"Filter both lists…",value:N,onChange:d=>b(d.target.value)})]}),j.length>0&&t&&e.jsxs("div",{className:"sa-nudge",children:[j.length," object",j.length>1?"s are":" is"," homed in this area but not included.",e.jsxs("button",{className:"sme-link",onClick:()=>z(j,!0),children:["Add ",j.length>1?"them all":"it"]})]}),e.jsxs("div",{className:"sa-panes",children:[e.jsx(Q,{title:`Available (${F.length})`,rows:F,picked:f,onToggle:d=>W(f,d,h),homedHere:(r==null?void 0:r.homed_here)??[]}),e.jsxs("div",{className:"sa-controls",children:[e.jsx("button",{className:"sme-secondary",disabled:!t||!f.size,onClick:()=>z([...f].filter(d=>!u.has(d)),!0),title:"Add the selected objects",children:"→"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!F.length,onClick:()=>z(F.map(d=>d.id),!0),title:"Add everything matching the filter",children:"»"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!f.size,onClick:()=>z([...f].filter(d=>u.has(d)),!1),title:"Remove the selected objects",children:"←"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!P.length,onClick:()=>z(P.map(d=>d.id),!1),title:"Remove everything matching the filter",children:"«"})]}),e.jsx(Q,{title:`Included (${P.length})`,rows:P,picked:f,onToggle:d=>W(f,d,h),homedHere:(r==null?void 0:r.homed_here)??[]})]}),e.jsxs("div",{className:"sa-expand",children:[e.jsx("h3",{children:"Add related objects"}),e.jsxs("div",{className:"sa-expand-row",children:[e.jsxs("select",{value:g,onChange:d=>_(d.target.value),children:[e.jsx("option",{value:"ancestors",children:"ancestors — the parents its keys point at"}),e.jsx("option",{value:"descendants",children:"descendants — what points at it"}),e.jsx("option",{value:"both",children:"both"})]}),e.jsxs("label",{children:["levels",e.jsx("input",{type:"number",min:1,max:10,value:C,onChange:d=>T(Math.max(1,Math.min(10,Number(d.target.value))))})]}),e.jsx("button",{className:"sme-secondary",onClick:U,disabled:!t,children:"Preview"})]}),R&&e.jsx("p",{className:"sme-error-line",children:R}),S&&e.jsxs("div",{className:"sa-hops",children:[S.length===0&&e.jsx("p",{className:"sme-muted",children:"nothing new to add"}),S.map(d=>e.jsxs("label",{className:"sa-hop",children:[e.jsx("input",{type:"checkbox",checked:A.has(d.id),onChange:()=>W(A,d.id,k)}),e.jsx("span",{className:"sa-hop-name",children:d.name}),e.jsxs("span",{className:"sa-hop-why",children:["via ",d.via_name," · ",d.direction.replace(/s$/,""),", level ",d.level]})]},d.id)),S.length>0&&e.jsxs("div",{className:"sa-hop-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:()=>y(null),children:"Cancel"}),e.jsxs("button",{className:"sme-primary",onClick:K,disabled:!A.size,children:["Add ",A.size," object",A.size===1?"":"s"]})]})]})]})]})]})}function Q({title:s,rows:t,picked:a,onToggle:l,homedHere:i}){const x=n.useMemo(()=>new Set(i),[i]);return e.jsxs("div",{className:"sa-pane",children:[e.jsx("h3",{children:s}),e.jsxs("ul",{children:[t.map(c=>e.jsxs("li",{className:"sa-row"+(a.has(c.id)?" picked":""),onClick:()=>l(c.id),children:[e.jsx("input",{type:"checkbox",readOnly:!0,checked:a.has(c.id)}),e.jsx("span",{className:"sa-row-name",children:c.name}),x.has(c.id)?e.jsx("span",{className:"sme-badge",children:"home"}):e.jsx("span",{className:"sme-badge borrowed",children:"borrowed"})]},c.id)),!t.length&&e.jsx("li",{className:"sme-empty",children:"nothing here"})]})]})}function es({objects:s,onCreate:t,onClose:a}){const[l,i]=n.useState(""),[x,c]=n.useState(""),[r]=n.useState(s),[m,N]=n.useState([]),[b,f]=n.useState(new Set),[h,g]=n.useState(""),[_,C]=n.useState("ancestors"),[T,S]=n.useState(1),[y,A]=n.useState(null),[k,R]=n.useState(new Set),[o,E]=n.useState(""),[$,D]=n.useState(null);n.useEffect(()=>{xe().then(j=>{j.subject_areas[0]&&E(j.subject_areas[0].id)}).catch(()=>{})},[]);const B=n.useMemo(()=>new Set(m),[m]),u=h.trim().toLowerCase(),P=j=>!u||j.name.toLowerCase().includes(u),F=n.useMemo(()=>m.map(j=>r.find(d=>d.id===j)).filter(j=>!!j&&P(j)),[m,r,u]),I=n.useMemo(()=>r.filter(j=>!B.has(j.id)&&P(j)),[r,B,u]),z=(j,d)=>{N(w=>d?[...w,...j.filter(M=>!w.includes(M))]:w.filter(M=>!j.includes(M))),f(new Set)},W=(j,d,w)=>{const M=new Set(j);M.has(d)?M.delete(d):M.add(d),w(M)},U=()=>{const j=b.size?[...b]:m;if(!j.length){D("pick an object to expand from first");return}o&&(D(null),be(o,{seeds:j,direction:_,levels:T}).then(d=>{const w=d.hops.filter(M=>!B.has(M.id));A(w),R(new Set(w.map(M=>M.id)))}).catch(d=>D(String(d))))},K=()=>{l.trim()&&t(l.trim(),x.trim(),m)};return e.jsx("div",{className:"sme-modal-backdrop",onClick:a,children:e.jsxs("div",{className:"sme-modal sa-modal",onClick:j=>j.stopPropagation(),children:[e.jsx("h2",{children:"New subject area"}),e.jsx("p",{className:"sme-hint",children:"A subject area is a filtered view of the model. Name it and choose what it contains — both land as one proposal."}),e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{autoFocus:!0,value:l,placeholder:"e.g. UseCase-ApraStressTesting",onChange:j=>i(j.target.value),onKeyDown:j=>j.key==="Enter"&&m.length===0&&K()})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Definition (optional)"}),e.jsx("input",{value:x,placeholder:"what this view is for",onChange:j=>c(j.target.value)})]})]}),e.jsx("input",{className:"sme-search sa-filter",type:"search",placeholder:"Filter both lists…",value:h,onChange:j=>g(j.target.value)}),e.jsxs("div",{className:"sa-panes",children:[e.jsx(Q,{title:`Available (${I.length})`,rows:I,picked:b,onToggle:j=>W(b,j,f),homedHere:[]}),e.jsxs("div",{className:"sa-controls",children:[e.jsx("button",{className:"sme-secondary",disabled:!b.size,onClick:()=>z([...b].filter(j=>!B.has(j)),!0),title:"Add the selected objects",children:"→"}),e.jsx("button",{className:"sme-secondary",disabled:!I.length,onClick:()=>z(I.map(j=>j.id),!0),title:"Add everything matching the filter",children:"»"}),e.jsx("button",{className:"sme-secondary",disabled:!b.size,onClick:()=>z([...b].filter(j=>B.has(j)),!1),title:"Remove the selected objects",children:"←"}),e.jsx("button",{className:"sme-secondary",disabled:!F.length,onClick:()=>z(F.map(j=>j.id),!1),title:"Remove everything matching the filter",children:"«"})]}),e.jsx(Q,{title:`Included (${F.length})`,rows:F,picked:b,onToggle:j=>W(b,j,f),homedHere:[]})]}),e.jsxs("div",{className:"sa-expand",children:[e.jsx("h3",{children:"Add related objects"}),e.jsxs("div",{className:"sa-expand-row",children:[e.jsxs("select",{value:_,onChange:j=>C(j.target.value),children:[e.jsx("option",{value:"ancestors",children:"ancestors — the parents its keys point at"}),e.jsx("option",{value:"descendants",children:"descendants — what points at it"}),e.jsx("option",{value:"both",children:"both"})]}),e.jsxs("label",{children:["levels",e.jsx("input",{type:"number",min:1,max:10,value:T,onChange:j=>S(Math.max(1,Math.min(10,Number(j.target.value))))})]}),e.jsx("button",{className:"sme-secondary",onClick:U,disabled:!o,title:o?"Preview related objects to add":"Available once the model has at least one saved subject area to walk the graph from",children:"Preview"})]}),y&&e.jsxs("div",{className:"sa-hops",children:[y.length===0&&e.jsx("p",{className:"sme-muted",children:"nothing new to add"}),y.map(j=>e.jsxs("label",{className:"sa-hop",children:[e.jsx("input",{type:"checkbox",checked:k.has(j.id),onChange:()=>W(k,j.id,R)}),e.jsx("span",{className:"sa-hop-name",children:j.name}),e.jsxs("span",{className:"sa-hop-why",children:["via ",j.via_name," · ",j.direction.replace(/s$/,""),", level ",j.level]})]},j.id)),y.length>0&&e.jsxs("div",{className:"sa-hop-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:()=>A(null),children:"Cancel"}),e.jsxs("button",{className:"sme-primary",disabled:!k.size,onClick:()=>{z([...k],!0),A(null)},children:["Add ",k.size]})]})]})]}),$&&e.jsx("p",{className:"sme-error-line",children:$}),e.jsxs("div",{className:"sme-modal-foot",children:[e.jsx("button",{className:"sme-secondary",onClick:a,children:"Cancel"}),e.jsxs("button",{className:"sme-primary",disabled:!l.trim(),onClick:K,children:["Create",m.length>0&&` with ${m.length} object${m.length===1?"":"s"}`]})]})]})})}const ss=new Set(["set_definition","set_stewardship","set_subject_area","set_pattern","rename_entity","add_attribute","update_attribute","delete_attribute","set_alignment","clear_alignment","set_term_map","clear_term_map","update_synonyms","set_object_definition","set_subject_area_members","create_subject_area","update_subject_area","create_entity","delete_entity","create_relationship","rename_relationship","update_relationship","delete_relationship"]);function ns({doc:s,subjectArea:t,onSubjectArea:a,exec:l,canEdit:i,direct:x=!1,onSelectEntity:c,onImported:r,query:m="",busy:N}){var R;const[b,f]=n.useState(null),[h,g]=n.useState(null),[_,C]=n.useState(!1),[T,S]=n.useState(null),y=n.useRef(null),A=n.useMemo(()=>({canEdit:i,mode:x?"direct":"staged",allow:x?void 0:ss,canArbitrate:x,canCommit:x}),[i,x]),k=n.useCallback(o=>{f(o),o&&(c==null||c(o))},[c]);return e.jsxs("div",{className:"sme-model-view",children:[e.jsxs("nav",{className:"sme-nav",children:[e.jsxs("div",{className:"sme-nav-head",children:[e.jsx("span",{children:"Subject areas"}),i&&e.jsx("button",{className:"sme-nav-add",title:"New subject area",onClick:()=>C(!0),children:"+"})]}),e.jsxs("button",{className:"sme-sa"+(t===""?" active":""),onClick:()=>a(""),children:["Whole model",e.jsx("span",{className:"sme-sa-count",children:((R=s.counts)==null?void 0:R.entities_total)??s.entities.length})]}),s.subject_areas.map(o=>e.jsxs("button",{className:"sme-sa"+(t===o.id?" active":""),onClick:()=>a(o.id),title:o.definition??void 0,children:[o.name,e.jsx("span",{className:"sme-sa-count",children:o.member_count??0})]},o.id))]}),_&&e.jsx(es,{objects:s.entities.flatMap(o=>o.conceptual?[{id:o.conceptual.id,kind:"conceptual_entity",name:o.conceptual.name,definition:o.conceptual.definition??null,synonyms:[],subject_area:o.conceptual.subject_area??null,stewardship:null,ontology:null,where_used:[]}]:[]),onClose:()=>C(!1),onCreate:(o,E,$)=>{const D=ge();l("create_subject_area",{name:o,...E?{definition:E}:{},id:D}),$.length&&l("set_subject_area_members",{id:D,members:$}),C(!1),a(D)}}),e.jsxs("div",{className:"erd-wrap",children:[e.jsxs("div",{className:"erd-bar",children:[e.jsxs("span",{className:"erd-count",children:[s.entities.length," entities · ",s.relationships.length," relationships",s.scope&&" · scoped"]}),i&&e.jsx("button",{className:"erd-action",onClick:()=>{var o;return(o=y.current)==null?void 0:o.newEntity()},title:"Add an entity (n)",children:"+ Entity"}),e.jsx("span",{className:"erd-hint",children:"drag between entities to relate them"}),e.jsxs("span",{className:"erd-group",children:[e.jsxs("button",{className:"erd-action ghost",onClick:()=>{var o;return(o=y.current)==null?void 0:o.relayout()},title:"Auto-arrange the diagram",children:[e.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"⟲"}),"Re-layout"]}),e.jsxs("button",{className:"erd-action ghost",onClick:()=>{var o;return(o=y.current)==null?void 0:o.fitView()},title:"Fit the whole model in view",children:[e.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"⛶"}),"Fit"]})]}),e.jsx("span",{className:"erd-sep","aria-hidden":"true"}),e.jsxs("span",{className:"erd-group",children:[e.jsx("button",{className:"erd-action ghost"+(h==="ontology"?" on":""),onClick:()=>g(o=>o==="ontology"?null:"ontology"),children:"Ontology"}),e.jsx("button",{className:"erd-action ghost"+(h==="layers"?" on":""),onClick:()=>g(o=>o==="layers"?null:"layers"),children:"Layers"})]}),e.jsx("span",{className:"erd-sep","aria-hidden":"true"}),e.jsx(Re,{exec:l,canEdit:i,onImported:r}),N&&e.jsx("span",{className:"erd-busy",children:"updating…"}),!i&&e.jsx("span",{className:"sme-chip",children:"read-only"}),T&&e.jsx("span",{className:"erd-error",children:T})]}),e.jsxs("div",{className:"erd-canvas canvas-wrap",children:[e.jsx(Me,{children:e.jsx(De,{doc:s,caps:A,exec:l,selectedId:b,onSelect:k,query:m,onError:S,handleRef:y})}),h&&e.jsxs("aside",{className:"side-panel",children:[e.jsxs("div",{className:"detail-header",children:[e.jsx("h2",{children:h==="ontology"?"Ontology":"Ontology layers"}),e.jsx("button",{className:"icon-btn",onClick:()=>g(null),children:"✕"})]}),h==="ontology"?e.jsx(Pe,{}):e.jsx(Ie,{refreshKey:0,onFocusEntity:o=>{var E;g(null),(E=y.current)==null||E.focusEntity(o)}})]})]})]})]})}function as({user:s,onView:t}){const[a,l]=n.useState(null),[i,x]=n.useState(null);if(n.useEffect(()=>{Oe(s).then(l).catch(r=>x(String(r)))},[s]),i)return e.jsx("p",{className:"sme-splash error",children:i});if(!a)return e.jsx("div",{className:"sme-splash",children:"◮ looking for your proposals…"});if(!a.git)return e.jsx("p",{className:"sme-placeholder",children:"This model isn't in a git repository."});const c=a.proposals.filter(r=>!r.merged).length;return e.jsxs("div",{className:"pr-wrap",children:[e.jsxs("div",{className:"pr-head",children:[e.jsx("h2",{children:"My proposals"}),e.jsxs("span",{className:"meta",children:[c," open · base: ",a.base]})]}),!a.proposals.length&&e.jsx("p",{className:"sme-placeholder",children:"Nothing proposed yet. Edits you submit for review will appear here."}),a.proposals.map(r=>e.jsx(rs,{p:r,gh:a.gh,onView:()=>t(r.branch)},r.branch)),!a.gh&&a.proposals.length>0&&e.jsxs("div",{className:"pr-degrade",children:["Review status isn't available here (",e.jsx("code",{children:"gh"})," is not installed or not signed in). Branch, contents, merge state and conflicts all still come from git — each card links out to the compare view."]})]})}function ts(s,t){var a,l;return s.merged?{kind:"accepted",text:"✅ Accepted"}:s.pushed?t&&((a=s.pr)==null?void 0:a.state)==="CLOSED"?{kind:"declined",text:"✖ Declined"}:t&&((l=s.pr)==null?void 0:l.reviews)==="CHANGES_REQUESTED"?{kind:"changes",text:"💬 Changes requested"}:{kind:"awaiting",text:"⏳ Awaiting review"}:{kind:"local",text:"📥 Saved locally"}}function rs({p:s,gh:t,onView:a}){const l=ts(s,t);return e.jsxs("div",{className:"pr-card"+(l.kind==="attention"?" attention":""),children:[e.jsxs("div",{className:"pr-top",children:[e.jsx("span",{className:"pr-title",children:s.title}),e.jsx("span",{className:"pr-chip "+l.kind,children:l.text})]}),e.jsxs("div",{className:"pr-branch",children:[s.branch," · ",s.created,s.behind>0&&` · ${s.behind} behind`]}),e.jsxs("div",{className:"pr-foot",children:[e.jsx("span",{className:"pr-link",children:s.merged?e.jsxs(e.Fragment,{children:["merged",t&&s.pr?` · PR #${s.pr.number}`:""]}):s.pushed?t&&s.pr?e.jsxs("a",{href:s.pr.url,target:"_blank",rel:"noreferrer",children:["PR #",s.pr.number]}):s.compare_url?e.jsx("a",{href:s.compare_url,target:"_blank",rel:"noreferrer",children:"open the compare view →"}):"pushed":"not sent yet — no connection to the shared repo"}),e.jsx("span",{className:"pr-btns",children:e.jsx("button",{className:"sme-secondary",onClick:a,children:"View"})})]})]})}function is({changes:s,routeAdvice:t,identity:a,user:l,onUser:i,onDrop:x,onClose:c,onProposed:r}){const m=!!(a&&a.source!=="anonymous"),[N,b]=n.useState(l||(localStorage.getItem("mdl.sme.user")??"")),[f,h]=n.useState(s.length===1?`Update ${s[0].label.toLowerCase()}`:"Glossary updates"),[g,_]=n.useState(""),[C,T]=n.useState(!1),S=ve(C?g:f),[y,A]=n.useState(""),[k,R]=n.useState(!1),[o,E]=n.useState(null),[$,D]=n.useState(null),B=()=>{!m&&!N.trim()||(m||(localStorage.setItem("mdl.sme.user",N.trim()),i==null||i(N.trim())),R(!0),D(null),Te({user:m?"":N.trim(),slug:S,title:f,body:y.trim(),changes:s.map(u=>({op:u.op,payload:u.payload}))}).then(E).catch(u=>D(u instanceof Be?u.message:String(u))).finally(()=>R(!1)))};return o!=null&&o.ok?e.jsx("div",{className:"sme-modal-backdrop",onClick:()=>r(o),children:e.jsxs("div",{className:"sme-modal",onClick:u=>u.stopPropagation(),children:[e.jsx("h2",{children:"✓ Sent for review"}),e.jsx("p",{children:o.message}),o.pr_url&&e.jsx("p",{children:e.jsx("a",{href:o.pr_url,target:"_blank",rel:"noreferrer",children:"View pull request →"})}),o.compare_url&&e.jsx("p",{children:e.jsx("a",{href:o.compare_url,target:"_blank",rel:"noreferrer",children:"Open the pull request →"})}),e.jsxs("p",{className:"sme-muted",children:["Your suggestion is on branch ",e.jsx("code",{children:o.branch}),". A steward will review it."]}),e.jsx("div",{className:"sme-modal-foot",children:e.jsx("button",{className:"sme-primary",onClick:()=>r(o),children:"Done"})})]})}):e.jsx("div",{className:"sme-modal-backdrop",onClick:c,children:e.jsxs("div",{className:"sme-modal",onClick:u=>u.stopPropagation(),children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsx("h2",{children:"Submit for review"}),e.jsx("button",{className:"sme-secondary",onClick:c,children:"✕"})]}),e.jsx("h3",{children:"Your changes"}),e.jsx("ul",{className:"sme-diff",children:s.map((u,P)=>e.jsxs("li",{children:[e.jsxs("div",{className:"sme-diff-head",children:[e.jsx("b",{children:u.label}),e.jsx("button",{className:"sme-link danger",onClick:()=>x(P),children:"discard"})]}),e.jsx("div",{className:"sme-diff-before",children:u.before}),e.jsx("div",{className:"sme-diff-after",children:u.after})]},P))}),m?e.jsxs("p",{className:"sme-signed-in",children:["Signed in as ",e.jsx("strong",{children:a.name}),a.email?` (${a.email})`:""," — this proposal is attributed to you."]}):e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Your name (for attribution)"}),e.jsx("input",{value:N,onChange:u=>b(u.target.value),placeholder:"e.g. a.hough"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Title"}),e.jsx("input",{value:f,onChange:u=>h(u.target.value)})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Branch name (edit to add a ticket id, e.g. PROJ-123)"}),e.jsx("input",{value:C?g:S,onChange:u=>{T(!0),_(u.target.value)},placeholder:"clarify-counterparty"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Note for the reviewer (optional)"}),e.jsx("textarea",{rows:2,value:y,onChange:u=>A(u.target.value)})]}),e.jsx(ls,{cl:t,user:m?a.name:N,changeSlug:S}),$&&e.jsx("p",{className:"sme-error-line",children:$}),e.jsxs("div",{className:"sme-modal-foot",children:[e.jsx("button",{className:"sme-secondary",onClick:c,children:"Keep editing"}),e.jsx("button",{className:"sme-primary",disabled:k||!m&&!N.trim()||s.length===0,onClick:B,children:k?"Submitting…":"Submit for review"})]})]})})}function ls({cl:s,user:t,changeSlug:a}){if(!(s!=null&&s.primary))return null;const l=s.reviewers_actual??s.reviewers,i=ve(t||"you"),x=s.routes.length>1;return e.jsxs(e.Fragment,{children:[x&&e.jsxs("div",{className:"sub-advice",children:[e.jsx("span",{className:"i",children:"ⓘ"})," These changes span routes"," ",e.jsx("strong",{children:s.routes.join(" and ")}),". The whole proposal will be reviewed as route ",s.primary," (",s.primary_name,") — the strictest gate wins, so it needs"," ",l.join(", ")," plus ",e.jsx("code",{children:s.gates[s.gates.length-1]}),". Proposing the meaning-only changes separately would get them reviewed faster."]}),e.jsxs("div",{className:"sub-dest",children:[e.jsxs("div",{className:"row",children:[e.jsx("span",{className:"k",children:"Goes to"}),e.jsxs("code",{children:["sme/",i,"/",a||"…"]})]}),e.jsxs("div",{className:"row",children:[e.jsx("span",{className:"k",children:"Reviewers"}),e.jsx("span",{children:l.join(", ")})]})]})]})}function ve(s){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"change"}const cs="modulepreload",os=function(s){return"/"+s},oe={},ds=function(t,a,l){let i=Promise.resolve();if(a&&a.length>0){document.getElementsByTagName("link");const c=document.querySelector("meta[property=csp-nonce]"),r=(c==null?void 0:c.nonce)||(c==null?void 0:c.getAttribute("nonce"));i=Promise.allSettled(a.map(m=>{if(m=os(m),m in oe)return;oe[m]=!0;const N=m.endsWith(".css"),b=N?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${b}`))return;const f=document.createElement("link");if(f.rel=N?"stylesheet":cs,N||(f.as="script"),f.crossOrigin="",f.href=m,r&&f.setAttribute("nonce",r),document.head.appendChild(f),N)return new Promise((h,g)=>{f.addEventListener("load",h),f.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${m}`)))})}))}function x(c){const r=new Event("vite:preloadError",{cancelable:!0});if(r.payload=c,window.dispatchEvent(r),!r.defaultPrevented)throw c}return i.then(c=>{for(const r of c||[])r.status==="rejected"&&x(r.reason);return t().catch(x)})};function hs({diff:s,selectable:t,selected:a,onToggle:l}){var r;const[i,x]=n.useState(((r=s.objects[0])==null?void 0:r.ulid)??null),c=n.useMemo(()=>s.objects.find(m=>m.ulid===i)??s.objects[0]??null,[s,i]);return s.objects.length?e.jsxs("div",{className:"rv-body",children:[e.jsx("div",{className:"rv-list",children:s.objects.map(m=>e.jsx(us,{obj:m,active:m.ulid===((c==null?void 0:c.ulid)??""),checked:(a==null?void 0:a.has(m.ulid))??!0,selectable:t,onSelect:()=>x(m.ulid),onToggle:()=>l==null?void 0:l(m.ulid)},m.ulid))}),e.jsx("div",{className:"rv-detail",children:c&&e.jsx(ps,{obj:c})})]}):e.jsxs("p",{className:"sme-placeholder",children:["No model changes against ",s.base.label,"."]})}function ms(s){return s.renamed?"renamed":s.severity==="breaking"?"breaking":s.change}function us({obj:s,active:t,checked:a,selectable:l,onSelect:i,onToggle:x}){return e.jsxs("div",{className:"rv-obj"+(t?" active":""),onClick:i,children:[e.jsxs("div",{className:"rv-obj-head",children:[l&&e.jsx("input",{type:"checkbox",checked:a,onClick:c=>c.stopPropagation(),onChange:x,"aria-label":`include ${s.name_before??s.name_after}`}),e.jsx("span",{className:"rv-obj-name",children:s.name_before??s.name_after}),e.jsx("span",{className:"rv-obj-kind",children:s.object_kind_label}),e.jsxs("span",{className:"sev "+(s.renamed?"renamed":s.severity),children:[s.severity==="breaking"&&"⚠ ",ms(s)]})]}),e.jsxs("ul",{className:"rv-obj-fields",children:[s.fields.map((c,r)=>e.jsx("li",{children:c.label},c.field+r)),s.children.flatMap(c=>c.fields.map((r,m)=>e.jsxs("li",{children:[r.label,": ",c.name_before??c.name_after]},c.ulid+m)))]})]})}function ps({obj:s}){const t=s.children.flatMap(a=>a.fields.map(l=>({field:l,on:a.name_before??a.name_after??""})));return e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:s.renamed?`${s.name_before} → ${s.name_after}`:s.name_before??s.name_after}),e.jsxs("div",{className:"rv-detail-kind",children:[s.object_kind_label,s.renamed&&" · renamed",s.path&&e.jsxs("span",{className:"rv-src",children:[" · ",s.path]})]}),s.fields.map((a,l)=>e.jsx(de,{f:a},a.field+l)),t.map(({field:a,on:l},i)=>e.jsx(de,{f:a,on:l},"c"+i)),s.severity==="breaking"&&e.jsxs("div",{className:"rv-note",children:[e.jsx("span",{className:"i",children:"ⓘ"}),e.jsxs("span",{children:["This is a structural change (route B). It will need an architect's review, and CI will run ",e.jsx("code",{children:"mdl drift --check"}),"."]})]})]})}function de({f:s,on:t}){var l,i,x;const a=t?`${s.label}: ${t}`:s.label;if((l=s.breaks)!=null&&l.length)return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-break",children:[e.jsxs("div",{className:"rv-break-head",children:[e.jsx("span",{children:"⚠"}),e.jsxs("span",{children:[t??String(s.before??"")," removed"]}),s.detail&&e.jsx("span",{className:"rv-break-meta",children:s.detail})]}),e.jsxs("div",{className:"rv-break-body",children:["This is realised by ",s.breaks.length," dbt model",s.breaks.length>1?"s":"",". Removing it will break ",s.breaks.length>1?"them":"it","."]}),e.jsx("ul",{className:"rv-usage",children:s.breaks.map(c=>e.jsxs("li",{children:[e.jsxs("span",{className:"m",children:["→ ",c.name]}),e.jsxs("span",{className:"p",children:[c.target," · ",c.materialization]})]},c.name))})]})]});if(s.kind==="definition_changed"){const c=String(s.before??""),r=String(s.after??"");return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-ba",children:[e.jsxs("div",{className:"rv-ba-col",children:[e.jsx("div",{className:"rv-ba-label",children:"before"}),e.jsx("div",{className:"rv-ba-text",children:me(c,r,"del")})]}),e.jsxs("div",{className:"rv-ba-col",children:[e.jsx("div",{className:"rv-ba-label",children:"after"}),e.jsx("div",{className:"rv-ba-text",children:me(r,c,"ins")})]})]})]})}if(Array.isArray(s.before)||Array.isArray(s.after)){const c=new Set(((i=s.before)==null?void 0:i.map(String))??[]),r=new Set(((x=s.after)==null?void 0:x.map(String))??[]),m=[...r].filter(b=>!c.has(b)),N=[...c].filter(b=>!r.has(b));return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-chips",children:[m.map(b=>e.jsxs("span",{className:"rv-chip-add",children:["+ ",b]},"a"+b)),N.map(b=>e.jsxs("span",{className:"rv-chip-del",children:["− ",b]},"r"+b))]})]})}return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-scalar",children:[e.jsx("span",{className:"from",children:he(s.before)}),e.jsx("span",{className:"arrow",children:"→"}),e.jsx("span",{className:"to",children:he(s.after)})]})]})}function he(s){return s==null||s===""?"—":typeof s=="boolean"?s?"yes":"no":typeof s=="object"?JSON.stringify(s):String(s)}function me(s,t,a){const l=s.split(/(\s+)/),i=t.split(/(\s+)/),x=h=>h.toLowerCase().replace(/[.,;:]/g,""),c=l.length,r=i.length,m=Array.from({length:c+1},()=>new Array(r+1).fill(0));for(let h=c-1;h>=0;h--)for(let g=r-1;g>=0;g--)m[h][g]=x(l[h])===x(i[g])?m[h+1][g+1]+1:Math.max(m[h+1][g],m[h][g+1]);const N=new Set;let b=0,f=0;for(;b=m[b][f+1]?b++:f++;return l.map((h,g)=>!h.trim()||N.has(g)?e.jsx("span",{children:h},g):a==="del"?e.jsx("del",{children:h},g):e.jsx("ins",{children:h},g))}const js=n.lazy(()=>ds(()=>import("./ModelDiagram-DfdI4kly.js"),__vite__mapDeps([0,1,2,3])).then(s=>({default:s.ModelDiagram})));function xs({stagedDiff:s,stagedRoute:t,user:a,onBack:l,onSubmit:i,excluded:x,onToggleObject:c,selectable:r}){const[m,N]=n.useState(null),[b,f]=n.useState(null),[h,g]=n.useState(null),[_,C]=n.useState(null),[T,S]=n.useState(null),[y,A]=n.useState("changes"),k=n.useCallback(()=>{je(a).then(o=>{C(o);const E=o.base_branch??"main";s?N(s):Le("HEAD").then($=>$.ok?N($):S($.error??"could not read the model")).catch($=>S(String($))),t?f(t):Fe("HEAD").then(f).catch(()=>{}),ze(E).then(g).catch(()=>{})}).catch(o=>S(String(o)))},[a,s,t]);if(n.useEffect(k,[k]),T)return e.jsxs("div",{className:"rv-shell",children:[e.jsx(ue,{onBack:l,diff:null}),e.jsx("p",{className:"sme-splash error",children:e.jsx("pre",{children:T})})]});if(!m)return e.jsx("div",{className:"sme-splash",children:"◮ reading your changes…"});const R=new Set(m.objects.map(o=>o.ulid).filter(o=>!x.has(o)));return e.jsxs("div",{className:"rv-shell",children:[e.jsx(ue,{onBack:l,diff:m,tab:y,onTab:A}),y==="changes"?e.jsx(hs,{diff:m,selectable:r,selected:R,onToggle:c}):e.jsx(n.Suspense,{fallback:e.jsx("div",{className:"sme-splash",children:"◮ drawing the model…"}),children:e.jsx(js,{severityByUlid:bs(m)})}),e.jsxs("div",{className:"rv-foot",children:[e.jsx(gs,{cl:b}),e.jsx(fs,{conf:h,ctx:_}),e.jsxs("div",{className:"rv-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:l,children:"Keep editing"}),e.jsx("button",{className:"sme-primary",disabled:!m.objects.length||(_?!_.can_propose:!1),title:_&&!_.can_propose?"the working tree has uncommitted changes":"",onClick:()=>i(b),children:"Submit for review →"})]})]})]})}function bs(s){const t=new Map;for(const a of s.objects)t.set(a.ulid,a.severity);return t}function ue({onBack:s,diff:t,tab:a,onTab:l}){const i=t==null?void 0:t.counts;return e.jsxs("div",{className:"rv-head",children:[e.jsxs("div",{children:[e.jsx("button",{className:"rv-back",onClick:s,children:"‹ Back to terms"}),e.jsx("h1",{className:"rv-title",children:"Review your changes"}),i&&e.jsxs("div",{className:"rv-sub",children:[i.objects," object",i.objects===1?"":"s"," ·"," ",(i.breaking??0)+(i.additive??0)+(i.cosmetic??0)," changes",(t==null?void 0:t.has_breaking)&&e.jsxs("span",{className:"warn",children:[" · ⚠ ",i.breaking," breaking"]})," · comparing to ",e.jsx("code",{children:t==null?void 0:t.base.label})]})]}),l&&e.jsxs("div",{className:"rv-tabs",children:[e.jsxs("button",{className:"rv-tab"+(a==="changes"?" active":""),onClick:()=>l("changes"),children:["Changes ",(t==null?void 0:t.objects.length)??0]}),e.jsx("button",{className:"rv-tab"+(a==="diagram"?" active":""),onClick:()=>l("diagram"),children:"Diagram"})]})]})}function gs({cl:s}){if(!(s!=null&&s.primary))return null;const t=s.reviewers_actual??s.reviewers;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rv-route",children:[e.jsxs("span",{className:"rv-route-badge",children:["Route ",s.primary," · ",s.primary_name]}),e.jsx("span",{className:"k",children:"Reviewers"}),e.jsx("span",{children:t.join(", ")}),s.reviewers_actual&&e.jsx("span",{className:"rv-src",children:"from .github/CODEOWNERS"})]}),e.jsxs("div",{className:"rv-gates",children:["CI gates"," ",s.gates.map(a=>e.jsx("code",{children:a},a))]})]})}function fs({conf:s,ctx:t}){return s!=null&&s.ok?s.clean?e.jsxs("div",{className:"rv-conflict ok",children:[e.jsx("span",{children:"✓"}),e.jsxs("span",{children:["Merges cleanly onto ",s.base]}),s.behind>0&&e.jsxs("span",{className:"detail",children:["· ",s.base," is ",s.behind," commit",s.behind===1?"":"s"," ahead"]}),(t==null?void 0:t.dirty)&&e.jsx("span",{className:"detail",children:"· uncommitted changes in the working tree"})]}):e.jsxs("div",{className:"rv-conflict bad",children:[e.jsx("span",{children:"⚠"}),e.jsxs("span",{children:[s.base," has changed and ",s.files.length," file",s.files.length===1?"":"s"," now conflict"]}),e.jsx("span",{className:"detail",children:s.files.map(a=>a.path).join(", ")})]}):null}function vs({term:s,canEdit:t,pendingCount:a,onEdit:l}){var i,x;return e.jsxs("div",{className:"sme-card",children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsxs("div",{children:[e.jsx("h1",{children:s.name}),((i=s.subject_area)==null?void 0:i.name)&&e.jsx("span",{className:"sme-chip",children:s.subject_area.name}),s.kind==="term"&&e.jsx("span",{className:"sme-chip",children:"glossary term"})]}),t&&e.jsx("button",{className:"sme-primary",onClick:l,children:a>0?"Continue editing":"Suggest an edit"})]}),e.jsx("p",{className:"sme-definition",children:s.definition??e.jsx("em",{children:"No definition yet."})}),s.synonyms.length>0&&e.jsxs("section",{children:[e.jsx("h3",{children:"Also called"}),e.jsx("div",{children:s.synonyms.map(c=>e.jsx("span",{className:"sme-chip",children:c},c))})]}),s.stewardship&&(s.stewardship.owner||s.stewardship.steward)&&e.jsxs("section",{children:[e.jsx("h3",{children:"Who owns this"}),s.stewardship.owner&&e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"owner"}),e.jsx("span",{children:s.stewardship.owner})]}),s.stewardship.steward&&e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"steward"}),e.jsx("span",{children:s.stewardship.steward})]})]}),((x=s.ontology)==null?void 0:x.aligns_to)&&e.jsxs("section",{children:[e.jsx("h3",{children:"Standard it maps to"}),e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"aligned to"}),e.jsx("code",{children:s.ontology.aligns_to}),s.ontology.status==="proposed"&&e.jsx("span",{className:"sme-badge proposed",children:"awaiting architect"})]})]}),e.jsxs("section",{children:[e.jsx("h3",{children:"Where it's used"}),s.where_used.length===0?e.jsx("p",{className:"sme-muted",children:s.kind==="term"?"A glossary term — not yet realised by a data model.":"Not yet realised by any data model."}):e.jsx("ul",{className:"sme-usage",children:s.where_used.map(c=>e.jsxs("li",{children:[e.jsx("span",{className:"sme-usage-model",children:c.logical_entity}),c.unmanaged&&e.jsx("span",{className:"sme-badge",children:"engineer-owned"}),c.physical.length>0&&e.jsx("span",{className:"sme-usage-phys",children:c.physical.map(r=>r.name).join(", ")})]},c.logical_id))})]})]})}function Ns({term:s,pending:t,onStage:a,onDone:l,catalogOwned:i=[],catalog:x=null}){var E,$,D,B;const c=u=>i.includes(u),r=u=>t.find(P=>P.label===u),m=(u,P)=>{const F=r(u);return F?F.after:P},[N,b]=n.useState(m("Definition",s.definition??"")),[f,h]=n.useState(s.synonyms),[g,_]=n.useState(""),[C,T]=n.useState(((E=s.stewardship)==null?void 0:E.owner)??""),[S,y]=n.useState((($=s.stewardship)==null?void 0:$.steward)??""),A=()=>{N.trim()!==(s.definition??"").trim()&&a({op:"set_definition",payload:{id:s.id,definition:N.trim()},label:"Definition",before:s.definition??"(none)",after:N.trim()||"(none)"})},k=(u,P)=>{var F,I;a({op:"set_stewardship",payload:{id:s.id,owner:u||null,steward:P||null},label:"Stewardship",before:`owner: ${((F=s.stewardship)==null?void 0:F.owner)??"—"} · steward: ${((I=s.stewardship)==null?void 0:I.steward)??"—"}`,after:`owner: ${u||"—"} · steward: ${P||"—"}`})},R=u=>{h(u),a({op:"update_synonyms",payload:{id:s.id,synonyms:u},label:"Also called",before:s.synonyms.join(", ")||"(none)",after:u.join(", ")||"(none)"})},o=s.kind==="term";return e.jsxs("div",{className:"sme-editor",children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsxs("h1",{children:["Suggest an edit — ",s.name]}),e.jsx("button",{className:"sme-secondary",onClick:l,children:"Back"})]}),e.jsxs("p",{className:"sme-hint",children:["You can refine what this term ",e.jsx("em",{children:"means"}),". Structure (keys, relationships, how it's built) stays with the data team."]}),(c("definition")||c("synonyms")||c("stewardship"))&&x&&e.jsxs("div",{className:"sme-catalog-banner",children:["Definitions, synonyms, and ownership are mastered in ",e.jsx("b",{children:x.name}),". Edit them there — this glossary mirrors them read-only.",x.url&&e.jsxs(e.Fragment,{children:[" ",e.jsxs("a",{href:x.url,target:"_blank",rel:"noreferrer",children:["Open in ",x.name," →"]})]}),e.jsx("div",{className:"sme-catalog-note",children:"You can still propose a standard mapping below."})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Definition"}),c("definition")?e.jsx("p",{className:"sme-readonly-value",children:s.definition??"—"}):e.jsx("textarea",{rows:4,value:N,onChange:u=>b(u.target.value),onBlur:A,placeholder:"A plain-language business definition…"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Also called (synonyms)"}),c("synonyms")?e.jsx("div",{className:"sme-syn-row",children:s.synonyms.length?s.synonyms.map(u=>e.jsx("span",{className:"sme-chip",children:u},u)):e.jsx("span",{className:"sme-muted",children:"none"})}):e.jsxs("div",{className:"sme-syn-row",children:[f.map(u=>e.jsxs("span",{className:"sme-chip removable",onClick:()=>R(f.filter(P=>P!==u)),children:[u," ✕"]},u)),e.jsx("input",{value:g,placeholder:"add + Enter",onChange:u=>_(u.target.value),onKeyDown:u=>{u.key==="Enter"&&g.trim()&&(R([...f,g.trim()]),_(""))}})]})]}),!o&&(c("stewardship")?e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Owner"}),e.jsx("p",{className:"sme-readonly-value",children:((D=s.stewardship)==null?void 0:D.owner)??"—"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Steward"}),e.jsx("p",{className:"sme-readonly-value",children:((B=s.stewardship)==null?void 0:B.steward)??"—"})]})]}):e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Owner"}),e.jsx("input",{value:C,onChange:u=>T(u.target.value),onBlur:()=>k(C,S)})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Steward"}),e.jsx("input",{value:S,onChange:u=>y(u.target.value),onBlur:()=>k(C,S)})]})]})),e.jsx(ys,{term:s,onStage:a}),e.jsx("p",{className:"sme-note",children:t.length>0?`${t.length} change(s) staged — use “Submit for review” at the top when you're done.`:"Changes you make are collected until you submit them for review."})]})}const ws=["skos:exactMatch","skos:closeMatch","skos:broadMatch","skos:narrowMatch"];function ys({term:s,onStage:t}){var f;const[a,l]=n.useState(!1),[i,x]=n.useState(s.name),[c,r]=n.useState([]),[m,N]=n.useState("skos:closeMatch"),b=h=>{x(h),qe(h).then(g=>r(g.results)).catch(()=>r([]))};return a?e.jsxs("div",{className:"sme-field sme-align",children:[e.jsx("span",{children:"Propose a standard mapping (a suggestion; the architect confirms)"}),e.jsx("input",{value:i,onChange:h=>b(h.target.value),placeholder:"Search standards…",autoFocus:!0}),e.jsx("div",{className:"sme-align-results",children:c.map(h=>e.jsxs("button",{className:"sme-align-card",onClick:()=>{var g;t({op:"set_alignment",payload:{id:s.id,aligns_to:h.prefixed,alignment:m,status:"proposed"},label:"Standard mapping",before:((g=s.ontology)==null?void 0:g.aligns_to)??"(none)",after:`${h.prefixed} (${m}, proposed)`}),l(!1)},children:[e.jsx("strong",{children:h.label})," ",e.jsx("code",{children:h.prefixed}),h.definition&&e.jsx("span",{className:"sme-align-def",children:h.definition})]},h.iri))}),e.jsx("select",{value:m,onChange:h=>N(h.target.value),children:ws.map(h=>e.jsx("option",{children:h},h))})]}):e.jsxs("div",{className:"sme-field",children:[e.jsx("span",{children:"Standard mapping"}),e.jsxs("div",{children:[(f=s.ontology)!=null&&f.aligns_to?e.jsx("code",{className:"sme-current-align",children:s.ontology.aligns_to}):e.jsx("span",{className:"sme-muted",children:"not mapped to a standard"}),e.jsx("button",{className:"sme-link",onClick:()=>l(!0),children:"Propose a mapping…"})]})]})}function _s(){const[s,t]=n.useState(null),[a,l]=n.useState(!0),[i,x]=n.useState(null),[c,r]=n.useState(""),[m,N]=n.useState(null),[b,f]=n.useState(""),[h,g]=n.useState(""),[_,C]=n.useState(null),[T,S]=n.useState(!1),[y,A]=n.useState([]),[k,R]=n.useState(!1),[o,E]=n.useState(window.location.hash==="#proposals"?"proposals":"browse"),[$,D]=n.useState(new Set),[B,u]=n.useState(()=>localStorage.getItem("mdl.sme.user")??""),[P,F]=n.useState(null),[I,z]=n.useState(null),[W,U]=n.useState(!1),[K,j]=n.useState(null),d=n.useCallback((p,v)=>{var ae;const O=J=>{var te;const V=I==null?void 0:I.entities.find(re=>{var ie;return re.id===J||((ie=re.conceptual)==null?void 0:ie.id)===J});return((te=V==null?void 0:V.conceptual)==null?void 0:te.name)??(V==null?void 0:V.name)??"object"},L=O(v.id??v.entity_id);switch(p){case"create_entity":return{label:`New entity: ${v.name}`,before:"—",after:String(v.name??"")};case"create_relationship":return{label:`New relationship: ${O(v.from_entity)} → ${O(v.to_entity)}`,before:"—",after:String(v.cardinality??"many_to_one")};case"delete_entity":return{label:`Deleted ${L}`,before:L,after:"—"};case"delete_relationship":return{label:"Relationship removed",before:"",after:"—"};case"update_relationship":return{label:"Relationship changed",before:"",after:[v.cardinality,v.optionality,v.identifying?"identifying":""].filter(Boolean).join(", ")};case"set_definition":return{label:`Definition: ${L}`,before:"",after:String(v.definition??"")};case"add_attribute":return{label:`Attribute added to ${L}`,before:"—",after:String(v.name??"")};case"delete_attribute":return{label:`Attribute removed from ${L}`,before:"",after:"—"};case"update_attribute":return{label:`Attribute changed on ${L}`,before:"",after:JSON.stringify(v)};case"rename_entity":return{label:`Renamed ${L}`,before:L,after:String(v.name??"")};case"set_subject_area":return{label:`Subject area: ${L}`,before:"",after:String(v.subject_area??"none")};case"set_stewardship":return{label:`Stewardship: ${L}`,before:"",after:String(v.steward??"")};case"set_subject_area_members":{const J=v.__label,V=((ae=v.members)==null?void 0:ae.length)??0;return{label:J??"Subject area members",before:"",after:`${V} object${V===1?"":"s"}`}}case"set_alignment":return{label:`Alignment: ${L}`,before:"",after:String(v.aligns_to??"")};default:return{label:`${p.replace(/_/g," ")}: ${L}`,before:"",after:""}}},[I]),w=Je({subjectArea:b,describe:d}),M=n.useCallback(async(p,v)=>{const O=(I==null?void 0:I.fingerprint)??"",L=await We(p,v,O);return await le(b||void 0).then(z),L},[I,b]),q=n.useMemo(()=>{const p={};for(const v of w.pending)v.op==="set_subject_area_members"&&(p[v.payload.id]=v.payload.members??[]);return p},[w.pending]),G=n.useMemo(()=>[...y,...w.pending],[y,w.pending]),[Ne,X]=n.useState(null),[we,Z]=n.useState(null);n.useEffect(()=>{if(!G.length){X(null),Z(null);return}const p=new AbortController,v=G.map(O=>({op:O.op,payload:O.payload}));return pe(v,b||void 0,p.signal).then(O=>X(O.diff??null)).catch(O=>{O.name!=="AbortError"&&X(null)}),Ge(v).then(Z).catch(()=>Z(null)),()=>p.abort()},[G,b]);const ye=n.useMemo(()=>Qe(G),[G]).size{E(p),window.location.hash=p==="browse"?"":`#${p}`},[]);n.useEffect(()=>{const p=()=>{const v=window.location.hash;E(v==="#proposals"?"proposals":v==="#review"?"review":v==="#model"?"model":v==="#areas"?"areas":"browse")};return p(),window.addEventListener("hashchange",p),()=>window.removeEventListener("hashchange",p)},[]);const ee=n.useCallback(()=>{He({subject_area:b,q:h}).then(t).catch(p=>N(String(p)))},[b,h]);n.useEffect(ee,[ee]),n.useEffect(()=>{le(b||void 0).then(p=>{l(p.read_only),r(p.project.name),z(p),U(!!p.direct),F(p.identity??null),p.identity&&p.identity.source!=="anonymous"&&p.identity.name&&u(p.identity.name)}).catch(()=>{}),Ve().then(x).catch(()=>{})},[b]);const se=n.useMemo(()=>(s==null?void 0:s.terms.find(p=>p.id===_))??null,[s,_]),_e=n.useCallback(p=>{const v=p.key??fe(p.op,p.payload);A(O=>[...O.filter(L=>L.key!==v),{...p,key:v}])},[]),Se=p=>A(v=>v.filter((O,L)=>L!==p)),ke=()=>{A([]),R(!1),S(!1),ee()};if(m)return e.jsxs("div",{className:"sme-splash error",children:[e.jsx("h1",{children:"◮ Glossary"}),e.jsx("pre",{children:m}),e.jsxs("p",{children:["Is ",e.jsx("code",{children:"mdl glossary"})," pointed at a model?"]})]});if(!s)return e.jsx("div",{className:"sme-splash",children:"◮ loading glossary…"});const Y=!a,ne=(i==null?void 0:i.catalog_owned_fields)??[],Ce=ne.length>0;return e.jsxs("div",{className:"sme",children:[e.jsxs("header",{className:"sme-top",children:[e.jsxs("div",{className:"sme-brand",children:[e.jsx("span",{className:"sme-logo",children:"◮"}),e.jsx("span",{children:"Glossary"}),e.jsx("span",{className:"sme-project",children:c}),a&&e.jsx("span",{className:"sme-chip",children:"read-only"}),Ce&&e.jsxs("span",{className:"sme-chip catalog",title:`Definitions are mastered in ${i==null?void 0:i.catalog_name}`,children:["mirrors ",i==null?void 0:i.catalog_name]})]}),e.jsx("input",{className:"sme-search",type:"search",placeholder:"Search terms & definitions…",value:h,onChange:p=>g(p.target.value)}),e.jsxs("nav",{className:"sme-tabs",children:[e.jsx("button",{className:"sme-tab"+(o==="browse"?" active":""),onClick:()=>H("browse"),children:"Terms"}),e.jsx("button",{className:"sme-tab"+(o==="model"?" active":""),onClick:()=>H("model"),children:"Model"}),e.jsx("button",{className:"sme-tab"+(o==="areas"?" active":""),onClick:()=>H("areas"),children:"Subject areas"}),e.jsx("button",{className:"sme-tab"+(o==="proposals"?" active":""),onClick:()=>H("proposals"),children:"My proposals"})]}),G.length>0&&e.jsxs("button",{className:"sme-tray",onClick:()=>H("review"),children:[G.length," change",G.length>1?"s":""," · Review →"]})]}),o==="browse"&&e.jsx(Xe,{user:B}),o==="review"?e.jsx(xs,{stagedDiff:Ne,stagedRoute:we,user:B,selectable:ye,excluded:$,onToggleObject:p=>D(v=>{const O=new Set(v);return O.has(p)?O.delete(p):O.add(p),O}),onBack:()=>H("browse"),onSubmit:p=>{j(p),R(!0)}}):o==="model"?w.previewDoc??I?e.jsx(ns,{doc:w.previewDoc??I,subjectArea:b,onSubjectArea:f,exec:W?M:w.exec,canEdit:Y,direct:W,onImported:()=>H("review"),query:h,busy:w.busy}):e.jsx("div",{className:"sme-splash",children:"◮ loading the model…"}):o==="areas"?e.jsx(Ze,{exec:w.exec,canEdit:Y,stagedMembers:q}):o==="proposals"?e.jsx(as,{user:B,onView:()=>H("review")}):e.jsxs("div",{className:"sme-body",children:[e.jsxs("nav",{className:"sme-nav",children:[e.jsx("button",{className:"sme-sa"+(b===""?" active":""),onClick:()=>f(""),children:"All subject areas"}),s.subject_areas.map(p=>e.jsx("button",{className:"sme-sa"+(b===p.id?" active":""),onClick:()=>f(p.id),title:p.definition??void 0,children:p.name},p.id))]}),e.jsxs("ul",{className:"sme-list",children:[s.terms.map(p=>{var v;return e.jsxs("li",{className:"sme-list-item"+(p.id===_?" active":""),onClick:()=>{C(p.id),S(!1)},children:[e.jsx("span",{className:"sme-term-name",children:p.name}),p.kind==="term"&&e.jsx("span",{className:"sme-kind",children:"term"}),((v=p.ontology)==null?void 0:v.status)==="proposed"&&e.jsx("span",{className:"sme-badge proposed",title:"alignment awaiting architect",children:"proposed"}),e.jsx("span",{className:"sme-term-def",children:p.definition??"no definition yet"})]},p.id)}),s.terms.length===0&&e.jsx("li",{className:"sme-empty",children:"no terms match"})]}),e.jsx("section",{className:"sme-detail",children:se?T&&Y?e.jsx(Ns,{term:se,pending:y,onStage:_e,onDone:()=>S(!1),catalogOwned:ne,catalog:i?{name:i.catalog_name,url:i.catalog_url}:null}):e.jsx(vs,{term:se,canEdit:Y,pendingCount:y.length,onEdit:()=>S(!0)}):e.jsx("div",{className:"sme-placeholder",children:"Select a term to see its definition."})})]}),k&&e.jsx(is,{changes:G,routeAdvice:K,identity:P,user:B,onUser:p=>{u(p),localStorage.setItem("mdl.sme.user",p)},onDrop:Se,onClose:()=>R(!1),onProposed:()=>{ke(),w.clear(),D(new Set),H("proposals")}})]})}Ae.createRoot(document.getElementById("root")).render(e.jsx(Ee.StrictMode,{children:e.jsx(_s,{})})); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ModelDiagram-oAb1enKe.js","assets/client-DOmNpTln.js","assets/styles-BtrhR1xb.js","assets/styles-DxhL4SV-.css"])))=>i.map(i=>d[i]); +import{r as n,j as e,c as Ae,R as Ee}from"./client-DOmNpTln.js";import{p as pe,c as je,d as xe,e as $e,h as be,I as Re,R as Me,M as De,O as Pe,L as Ie,i as Oe,j as Te,A as Be,k as Le,l as Fe,m as ze,o as qe,s as We,f as le,n as Ge,q as He,r as Ve}from"./styles-BtrhR1xb.js";/* empty css */const Ke="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ce(s,t){let a="";for(let l=0;l>=5n;return a}function ge(){const s=BigInt(Date.now())&(1n<<48n)-1n,t=new Uint8Array(10);crypto.getRandomValues(t);let a=0n;for(const l of t)a=a<<8n|BigInt(l);return ce(s,10)+ce(a,16)}const Ue={create_entity:["id","conceptual_id"],create_relationship:["id","from_fk_id"],create_subject_area:["id"],create_term:["id"],create_domain:["id"],create_code_set:["id"],create_key_group:["id"],create_category:["id"],add_attribute:["id"]};function Ye(s,t){const a=Ue[s];if(!a)return t;const l={...t};for(const i of a)l[i]||(l[i]=ge());return l}function fe(s,t){if(s.startsWith("create_")||s==="add_attribute")return`${s}:${t.id??t.attribute_id}`;const a=t.id??t.entity_id??"",l=t.attribute_id??"";return l?`${s}:${a}:${l}`:`${s}:${a}`}function Je({subjectArea:s,describe:t}){const[a,l]=n.useState([]),[i,x]=n.useState(null),[c,r]=n.useState(!1),m=n.useRef(null),N=n.useCallback(async(h,g)=>{g=Ye(h,g),h==="set_alignment"&&g.status===void 0&&(g={...g,status:"proposed"});const _=fe(h,g),{label:C,before:T,after:S}=t(h,g);return l(y=>{const A=y.filter(k=>k.key!==_);if(h.startsWith("delete_")){const k=g.id??g.entity_id;if(k&&y.some(o=>o.op.startsWith("create_")&&o.payload.id===k))return A.filter(o=>o.payload.id!==k)}return[...A,{op:h,payload:g,label:C,before:T,after:S,key:_}]}),{ok:!0,fingerprint:"",created_id:g.id??null,diagnostics:[]}},[t]);n.useEffect(()=>{if(!a.length){x(null);return}const h=setTimeout(()=>{var _;(_=m.current)==null||_.abort();const g=new AbortController;m.current=g,r(!0),pe(a.map(C=>({op:C.op,payload:C.payload})),s,g.signal).then(x).catch(C=>{C.name!=="AbortError"&&x(null)}).finally(()=>r(!1))},250);return()=>clearTimeout(h)},[a,s]);const b=n.useCallback(h=>{l(g=>g.filter(_=>_.key!==h))},[]),f=n.useCallback(()=>l([]),[]);return n.useMemo(()=>({pending:a,previewDoc:(i==null?void 0:i.model)??null,previewDiff:(i==null?void 0:i.diff)??null,diagnostics:(i==null?void 0:i.diagnostics)??[],failure:i&&i.failed_index!==null?{index:i.failed_index,error:i.error??"invalid change"}:null,busy:c,exec:N,drop:b,clear:f}),[a,i,c,N,b,f])}function Qe(s){const t=new Map;for(const l of s)for(const i of["id","conceptual_id","from_fk_id"]){const x=l.payload[i];l.op.startsWith("create_")&&typeof x=="string"&&t.set(x,l.key)}if(!t.size)return new Set;const a=new Set;for(const l of s)if(!l.op.startsWith("create_"))for(const i of Object.values(l.payload))typeof i=="string"&&t.has(i)&&(a.add(l.key),a.add(t.get(i)));return a}function Xe({user:s}){const[t,a]=n.useState(null);return n.useEffect(()=>{je(s).then(a).catch(()=>{})},[s]),!(t!=null&&t.ok)||!t.git?null:t.read_only?e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"browse only — editing is disabled on this deployment"})]}):t.dirty?e.jsxs("div",{className:"git-banner warn",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"uncommitted changes in the working tree — a proposal will be refused until they are committed or discarded"})]}):t.on_base?e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"protected — your edits become a pull request"})]}):e.jsxs("div",{className:"git-banner",children:[e.jsx("code",{children:t.branch}),e.jsx("span",{children:"your proposal branch"}),t.behind?e.jsxs("span",{className:"dim",children:["· ",t.base_branch," is ",t.behind," ahead"]}):null]})}function Ze({exec:s,canEdit:t,stagedMembers:a}){const[l,i]=n.useState([]),[x,c]=n.useState(""),[r,m]=n.useState(null),[N,b]=n.useState(""),[f,h]=n.useState(new Set),[g,_]=n.useState("ancestors"),[C,T]=n.useState(1),[S,y]=n.useState(null),[A,k]=n.useState(new Set),[R,o]=n.useState(null);n.useEffect(()=>{xe().then(d=>{i(d.subject_areas),c(w=>{var M;return w||((M=d.subject_areas[0])==null?void 0:M.id)||""})}).catch(d=>o(String(d)))},[]),n.useEffect(()=>{x&&(y(null),h(new Set),$e(x).then(m).catch(d=>o(String(d))))},[x]);const E=n.useMemo(()=>a[x]??(r==null?void 0:r.members)??[],[a,x,r]),$=n.useMemo(()=>{const d=new Map;for(const w of[...(r==null?void 0:r.included)??[],...(r==null?void 0:r.available)??[]])d.set(w.id,w);return d},[r]),D=N.trim().toLowerCase(),B=d=>!D||d.name.toLowerCase().includes(D),u=n.useMemo(()=>new Set(E),[E]),P=n.useMemo(()=>E.map(d=>$.get(d)).filter(d=>!!d&&B(d)),[E,$,D]),F=n.useMemo(()=>[...$.values()].filter(d=>!u.has(d.id)&&B(d)),[$,u,D]),I=n.useCallback(d=>{if(!r)return;const w=d.filter(q=>!(r.members??[]).includes(q)).length,M=(r.members??[]).filter(q=>!d.includes(q)).length;s("set_subject_area_members",{id:r.id,members:d,__label:`${r.name}: ${d.length} objects (+${w} −${M})`})},[r,s]),z=(d,w)=>{const M=w?[...E,...d.filter(q=>!u.has(q))]:E.filter(q=>!d.includes(q));I(M),h(new Set)},W=(d,w,M)=>{const q=new Set(d);q.has(w)?q.delete(w):q.add(w),M(q)},U=()=>{if(!r)return;const d=f.size?[...f]:E;if(!d.length){o("add an object first, or select one to expand from");return}o(null),be(r.id,{seeds:d,direction:g,levels:C}).then(w=>{y(w.hops),k(new Set(w.added))}).catch(w=>o(String(w)))},K=()=>{z([...A],!0),y(null)};if(R&&!r)return e.jsx("p",{className:"sme-splash error",children:R});if(!l.length)return e.jsx("p",{className:"sme-placeholder",children:"No subject areas yet."});const j=((r==null?void 0:r.inconsistent)??[]).filter(d=>!u.has(d));return e.jsxs("div",{className:"sa-editor",children:[e.jsx("nav",{className:"sme-nav",children:l.map(d=>e.jsxs("button",{className:"sme-sa"+(d.id===x?" active":""),onClick:()=>c(d.id),title:d.definition??void 0,children:[d.name,e.jsx("span",{className:"sme-sa-count",children:(a[d.id]??d.members).length})]},d.id))}),e.jsxs("div",{className:"sa-main",children:[e.jsxs("div",{className:"sa-head",children:[e.jsx("h2",{children:(r==null?void 0:r.name)??"…"}),(r==null?void 0:r.definition)&&e.jsx("p",{className:"sme-muted",children:r.definition}),e.jsx("input",{className:"sme-search sa-filter",type:"search",placeholder:"Filter both lists…",value:N,onChange:d=>b(d.target.value)})]}),j.length>0&&t&&e.jsxs("div",{className:"sa-nudge",children:[j.length," object",j.length>1?"s are":" is"," homed in this area but not included.",e.jsxs("button",{className:"sme-link",onClick:()=>z(j,!0),children:["Add ",j.length>1?"them all":"it"]})]}),e.jsxs("div",{className:"sa-panes",children:[e.jsx(Q,{title:`Available (${F.length})`,rows:F,picked:f,onToggle:d=>W(f,d,h),homedHere:(r==null?void 0:r.homed_here)??[]}),e.jsxs("div",{className:"sa-controls",children:[e.jsx("button",{className:"sme-secondary",disabled:!t||!f.size,onClick:()=>z([...f].filter(d=>!u.has(d)),!0),title:"Add the selected objects",children:"→"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!F.length,onClick:()=>z(F.map(d=>d.id),!0),title:"Add everything matching the filter",children:"»"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!f.size,onClick:()=>z([...f].filter(d=>u.has(d)),!1),title:"Remove the selected objects",children:"←"}),e.jsx("button",{className:"sme-secondary",disabled:!t||!P.length,onClick:()=>z(P.map(d=>d.id),!1),title:"Remove everything matching the filter",children:"«"})]}),e.jsx(Q,{title:`Included (${P.length})`,rows:P,picked:f,onToggle:d=>W(f,d,h),homedHere:(r==null?void 0:r.homed_here)??[]})]}),e.jsxs("div",{className:"sa-expand",children:[e.jsx("h3",{children:"Add related objects"}),e.jsxs("div",{className:"sa-expand-row",children:[e.jsxs("select",{value:g,onChange:d=>_(d.target.value),children:[e.jsx("option",{value:"ancestors",children:"ancestors — the parents its keys point at"}),e.jsx("option",{value:"descendants",children:"descendants — what points at it"}),e.jsx("option",{value:"both",children:"both"})]}),e.jsxs("label",{children:["levels",e.jsx("input",{type:"number",min:1,max:10,value:C,onChange:d=>T(Math.max(1,Math.min(10,Number(d.target.value))))})]}),e.jsx("button",{className:"sme-secondary",onClick:U,disabled:!t,children:"Preview"})]}),R&&e.jsx("p",{className:"sme-error-line",children:R}),S&&e.jsxs("div",{className:"sa-hops",children:[S.length===0&&e.jsx("p",{className:"sme-muted",children:"nothing new to add"}),S.map(d=>e.jsxs("label",{className:"sa-hop",children:[e.jsx("input",{type:"checkbox",checked:A.has(d.id),onChange:()=>W(A,d.id,k)}),e.jsx("span",{className:"sa-hop-name",children:d.name}),e.jsxs("span",{className:"sa-hop-why",children:["via ",d.via_name," · ",d.direction.replace(/s$/,""),", level ",d.level]})]},d.id)),S.length>0&&e.jsxs("div",{className:"sa-hop-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:()=>y(null),children:"Cancel"}),e.jsxs("button",{className:"sme-primary",onClick:K,disabled:!A.size,children:["Add ",A.size," object",A.size===1?"":"s"]})]})]})]})]})]})}function Q({title:s,rows:t,picked:a,onToggle:l,homedHere:i}){const x=n.useMemo(()=>new Set(i),[i]);return e.jsxs("div",{className:"sa-pane",children:[e.jsx("h3",{children:s}),e.jsxs("ul",{children:[t.map(c=>e.jsxs("li",{className:"sa-row"+(a.has(c.id)?" picked":""),onClick:()=>l(c.id),children:[e.jsx("input",{type:"checkbox",readOnly:!0,checked:a.has(c.id)}),e.jsx("span",{className:"sa-row-name",children:c.name}),x.has(c.id)?e.jsx("span",{className:"sme-badge",children:"home"}):e.jsx("span",{className:"sme-badge borrowed",children:"borrowed"})]},c.id)),!t.length&&e.jsx("li",{className:"sme-empty",children:"nothing here"})]})]})}function es({objects:s,onCreate:t,onClose:a}){const[l,i]=n.useState(""),[x,c]=n.useState(""),[r]=n.useState(s),[m,N]=n.useState([]),[b,f]=n.useState(new Set),[h,g]=n.useState(""),[_,C]=n.useState("ancestors"),[T,S]=n.useState(1),[y,A]=n.useState(null),[k,R]=n.useState(new Set),[o,E]=n.useState(""),[$,D]=n.useState(null);n.useEffect(()=>{xe().then(j=>{j.subject_areas[0]&&E(j.subject_areas[0].id)}).catch(()=>{})},[]);const B=n.useMemo(()=>new Set(m),[m]),u=h.trim().toLowerCase(),P=j=>!u||j.name.toLowerCase().includes(u),F=n.useMemo(()=>m.map(j=>r.find(d=>d.id===j)).filter(j=>!!j&&P(j)),[m,r,u]),I=n.useMemo(()=>r.filter(j=>!B.has(j.id)&&P(j)),[r,B,u]),z=(j,d)=>{N(w=>d?[...w,...j.filter(M=>!w.includes(M))]:w.filter(M=>!j.includes(M))),f(new Set)},W=(j,d,w)=>{const M=new Set(j);M.has(d)?M.delete(d):M.add(d),w(M)},U=()=>{const j=b.size?[...b]:m;if(!j.length){D("pick an object to expand from first");return}o&&(D(null),be(o,{seeds:j,direction:_,levels:T}).then(d=>{const w=d.hops.filter(M=>!B.has(M.id));A(w),R(new Set(w.map(M=>M.id)))}).catch(d=>D(String(d))))},K=()=>{l.trim()&&t(l.trim(),x.trim(),m)};return e.jsx("div",{className:"sme-modal-backdrop",onClick:a,children:e.jsxs("div",{className:"sme-modal sa-modal",onClick:j=>j.stopPropagation(),children:[e.jsx("h2",{children:"New subject area"}),e.jsx("p",{className:"sme-hint",children:"A subject area is a filtered view of the model. Name it and choose what it contains — both land as one proposal."}),e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{autoFocus:!0,value:l,placeholder:"e.g. UseCase-ApraStressTesting",onChange:j=>i(j.target.value),onKeyDown:j=>j.key==="Enter"&&m.length===0&&K()})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Definition (optional)"}),e.jsx("input",{value:x,placeholder:"what this view is for",onChange:j=>c(j.target.value)})]})]}),e.jsx("input",{className:"sme-search sa-filter",type:"search",placeholder:"Filter both lists…",value:h,onChange:j=>g(j.target.value)}),e.jsxs("div",{className:"sa-panes",children:[e.jsx(Q,{title:`Available (${I.length})`,rows:I,picked:b,onToggle:j=>W(b,j,f),homedHere:[]}),e.jsxs("div",{className:"sa-controls",children:[e.jsx("button",{className:"sme-secondary",disabled:!b.size,onClick:()=>z([...b].filter(j=>!B.has(j)),!0),title:"Add the selected objects",children:"→"}),e.jsx("button",{className:"sme-secondary",disabled:!I.length,onClick:()=>z(I.map(j=>j.id),!0),title:"Add everything matching the filter",children:"»"}),e.jsx("button",{className:"sme-secondary",disabled:!b.size,onClick:()=>z([...b].filter(j=>B.has(j)),!1),title:"Remove the selected objects",children:"←"}),e.jsx("button",{className:"sme-secondary",disabled:!F.length,onClick:()=>z(F.map(j=>j.id),!1),title:"Remove everything matching the filter",children:"«"})]}),e.jsx(Q,{title:`Included (${F.length})`,rows:F,picked:b,onToggle:j=>W(b,j,f),homedHere:[]})]}),e.jsxs("div",{className:"sa-expand",children:[e.jsx("h3",{children:"Add related objects"}),e.jsxs("div",{className:"sa-expand-row",children:[e.jsxs("select",{value:_,onChange:j=>C(j.target.value),children:[e.jsx("option",{value:"ancestors",children:"ancestors — the parents its keys point at"}),e.jsx("option",{value:"descendants",children:"descendants — what points at it"}),e.jsx("option",{value:"both",children:"both"})]}),e.jsxs("label",{children:["levels",e.jsx("input",{type:"number",min:1,max:10,value:T,onChange:j=>S(Math.max(1,Math.min(10,Number(j.target.value))))})]}),e.jsx("button",{className:"sme-secondary",onClick:U,disabled:!o,title:o?"Preview related objects to add":"Available once the model has at least one saved subject area to walk the graph from",children:"Preview"})]}),y&&e.jsxs("div",{className:"sa-hops",children:[y.length===0&&e.jsx("p",{className:"sme-muted",children:"nothing new to add"}),y.map(j=>e.jsxs("label",{className:"sa-hop",children:[e.jsx("input",{type:"checkbox",checked:k.has(j.id),onChange:()=>W(k,j.id,R)}),e.jsx("span",{className:"sa-hop-name",children:j.name}),e.jsxs("span",{className:"sa-hop-why",children:["via ",j.via_name," · ",j.direction.replace(/s$/,""),", level ",j.level]})]},j.id)),y.length>0&&e.jsxs("div",{className:"sa-hop-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:()=>A(null),children:"Cancel"}),e.jsxs("button",{className:"sme-primary",disabled:!k.size,onClick:()=>{z([...k],!0),A(null)},children:["Add ",k.size]})]})]})]}),$&&e.jsx("p",{className:"sme-error-line",children:$}),e.jsxs("div",{className:"sme-modal-foot",children:[e.jsx("button",{className:"sme-secondary",onClick:a,children:"Cancel"}),e.jsxs("button",{className:"sme-primary",disabled:!l.trim(),onClick:K,children:["Create",m.length>0&&` with ${m.length} object${m.length===1?"":"s"}`]})]})]})})}const ss=new Set(["set_definition","set_stewardship","set_subject_area","set_pattern","rename_entity","add_attribute","update_attribute","delete_attribute","set_alignment","clear_alignment","set_term_map","clear_term_map","update_synonyms","set_object_definition","set_subject_area_members","create_subject_area","update_subject_area","create_entity","delete_entity","create_relationship","rename_relationship","update_relationship","delete_relationship"]);function ns({doc:s,subjectArea:t,onSubjectArea:a,exec:l,canEdit:i,direct:x=!1,onSelectEntity:c,onImported:r,query:m="",busy:N}){var R;const[b,f]=n.useState(null),[h,g]=n.useState(null),[_,C]=n.useState(!1),[T,S]=n.useState(null),y=n.useRef(null),A=n.useMemo(()=>({canEdit:i,mode:x?"direct":"staged",allow:x?void 0:ss,canArbitrate:x,canCommit:x}),[i,x]),k=n.useCallback(o=>{f(o),o&&(c==null||c(o))},[c]);return e.jsxs("div",{className:"sme-model-view",children:[e.jsxs("nav",{className:"sme-nav",children:[e.jsxs("div",{className:"sme-nav-head",children:[e.jsx("span",{children:"Subject areas"}),i&&e.jsx("button",{className:"sme-nav-add",title:"New subject area",onClick:()=>C(!0),children:"+"})]}),e.jsxs("button",{className:"sme-sa"+(t===""?" active":""),onClick:()=>a(""),children:["Whole model",e.jsx("span",{className:"sme-sa-count",children:((R=s.counts)==null?void 0:R.entities_total)??s.entities.length})]}),s.subject_areas.map(o=>e.jsxs("button",{className:"sme-sa"+(t===o.id?" active":""),onClick:()=>a(o.id),title:o.definition??void 0,children:[o.name,e.jsx("span",{className:"sme-sa-count",children:o.member_count??0})]},o.id))]}),_&&e.jsx(es,{objects:s.entities.flatMap(o=>o.conceptual?[{id:o.conceptual.id,kind:"conceptual_entity",name:o.conceptual.name,definition:o.conceptual.definition??null,synonyms:[],subject_area:o.conceptual.subject_area??null,stewardship:null,ontology:null,where_used:[]}]:[]),onClose:()=>C(!1),onCreate:(o,E,$)=>{const D=ge();l("create_subject_area",{name:o,...E?{definition:E}:{},id:D}),$.length&&l("set_subject_area_members",{id:D,members:$}),C(!1),a(D)}}),e.jsxs("div",{className:"erd-wrap",children:[e.jsxs("div",{className:"erd-bar",children:[e.jsxs("span",{className:"erd-count",children:[s.entities.length," entities · ",s.relationships.length," relationships",s.scope&&" · scoped"]}),i&&e.jsx("button",{className:"erd-action",onClick:()=>{var o;return(o=y.current)==null?void 0:o.newEntity()},title:"Add an entity (n)",children:"+ Entity"}),e.jsx("span",{className:"erd-hint",children:"drag between entities to relate them"}),e.jsxs("span",{className:"erd-group",children:[e.jsxs("button",{className:"erd-action ghost",onClick:()=>{var o;return(o=y.current)==null?void 0:o.relayout()},title:"Auto-arrange the diagram",children:[e.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"⟲"}),"Re-layout"]}),e.jsxs("button",{className:"erd-action ghost",onClick:()=>{var o;return(o=y.current)==null?void 0:o.fitView()},title:"Fit the whole model in view",children:[e.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"⛶"}),"Fit"]})]}),e.jsx("span",{className:"erd-sep","aria-hidden":"true"}),e.jsxs("span",{className:"erd-group",children:[e.jsx("button",{className:"erd-action ghost"+(h==="ontology"?" on":""),onClick:()=>g(o=>o==="ontology"?null:"ontology"),children:"Ontology"}),e.jsx("button",{className:"erd-action ghost"+(h==="layers"?" on":""),onClick:()=>g(o=>o==="layers"?null:"layers"),children:"Layers"})]}),e.jsx("span",{className:"erd-sep","aria-hidden":"true"}),e.jsx(Re,{exec:l,canEdit:i,onImported:r}),N&&e.jsx("span",{className:"erd-busy",children:"updating…"}),!i&&e.jsx("span",{className:"sme-chip",children:"read-only"}),T&&e.jsx("span",{className:"erd-error",children:T})]}),e.jsxs("div",{className:"erd-canvas canvas-wrap",children:[e.jsx(Me,{children:e.jsx(De,{doc:s,caps:A,exec:l,selectedId:b,onSelect:k,query:m,onError:S,handleRef:y})}),h&&e.jsxs("aside",{className:"side-panel",children:[e.jsxs("div",{className:"detail-header",children:[e.jsx("h2",{children:h==="ontology"?"Ontology":"Ontology layers"}),e.jsx("button",{className:"icon-btn",onClick:()=>g(null),children:"✕"})]}),h==="ontology"?e.jsx(Pe,{}):e.jsx(Ie,{refreshKey:0,onFocusEntity:o=>{var E;g(null),(E=y.current)==null||E.focusEntity(o)}})]})]})]})]})}function as({user:s,onView:t}){const[a,l]=n.useState(null),[i,x]=n.useState(null);if(n.useEffect(()=>{Oe(s).then(l).catch(r=>x(String(r)))},[s]),i)return e.jsx("p",{className:"sme-splash error",children:i});if(!a)return e.jsx("div",{className:"sme-splash",children:"◮ looking for your proposals…"});if(!a.git)return e.jsx("p",{className:"sme-placeholder",children:"This model isn't in a git repository."});const c=a.proposals.filter(r=>!r.merged).length;return e.jsxs("div",{className:"pr-wrap",children:[e.jsxs("div",{className:"pr-head",children:[e.jsx("h2",{children:"My proposals"}),e.jsxs("span",{className:"meta",children:[c," open · base: ",a.base]})]}),!a.proposals.length&&e.jsx("p",{className:"sme-placeholder",children:"Nothing proposed yet. Edits you submit for review will appear here."}),a.proposals.map(r=>e.jsx(rs,{p:r,gh:a.gh,onView:()=>t(r.branch)},r.branch)),!a.gh&&a.proposals.length>0&&e.jsxs("div",{className:"pr-degrade",children:["Review status isn't available here (",e.jsx("code",{children:"gh"})," is not installed or not signed in). Branch, contents, merge state and conflicts all still come from git — each card links out to the compare view."]})]})}function ts(s,t){var a,l;return s.merged?{kind:"accepted",text:"✅ Accepted"}:s.pushed?t&&((a=s.pr)==null?void 0:a.state)==="CLOSED"?{kind:"declined",text:"✖ Declined"}:t&&((l=s.pr)==null?void 0:l.reviews)==="CHANGES_REQUESTED"?{kind:"changes",text:"💬 Changes requested"}:{kind:"awaiting",text:"⏳ Awaiting review"}:{kind:"local",text:"📥 Saved locally"}}function rs({p:s,gh:t,onView:a}){const l=ts(s,t);return e.jsxs("div",{className:"pr-card"+(l.kind==="attention"?" attention":""),children:[e.jsxs("div",{className:"pr-top",children:[e.jsx("span",{className:"pr-title",children:s.title}),e.jsx("span",{className:"pr-chip "+l.kind,children:l.text})]}),e.jsxs("div",{className:"pr-branch",children:[s.branch," · ",s.created,s.behind>0&&` · ${s.behind} behind`]}),e.jsxs("div",{className:"pr-foot",children:[e.jsx("span",{className:"pr-link",children:s.merged?e.jsxs(e.Fragment,{children:["merged",t&&s.pr?` · PR #${s.pr.number}`:""]}):s.pushed?t&&s.pr?e.jsxs("a",{href:s.pr.url,target:"_blank",rel:"noreferrer",children:["PR #",s.pr.number]}):s.compare_url?e.jsx("a",{href:s.compare_url,target:"_blank",rel:"noreferrer",children:"open the compare view →"}):"pushed":"not sent yet — no connection to the shared repo"}),e.jsx("span",{className:"pr-btns",children:e.jsx("button",{className:"sme-secondary",onClick:a,children:"View"})})]})]})}function is({changes:s,routeAdvice:t,identity:a,user:l,onUser:i,onDrop:x,onClose:c,onProposed:r}){const m=!!(a&&a.source!=="anonymous"),[N,b]=n.useState(l||(localStorage.getItem("mdl.sme.user")??"")),[f,h]=n.useState(s.length===1?`Update ${s[0].label.toLowerCase()}`:"Glossary updates"),[g,_]=n.useState(""),[C,T]=n.useState(!1),S=ve(C?g:f),[y,A]=n.useState(""),[k,R]=n.useState(!1),[o,E]=n.useState(null),[$,D]=n.useState(null),B=()=>{!m&&!N.trim()||(m||(localStorage.setItem("mdl.sme.user",N.trim()),i==null||i(N.trim())),R(!0),D(null),Te({user:m?"":N.trim(),slug:S,title:f,body:y.trim(),changes:s.map(u=>({op:u.op,payload:u.payload}))}).then(E).catch(u=>D(u instanceof Be?u.message:String(u))).finally(()=>R(!1)))};return o!=null&&o.ok?e.jsx("div",{className:"sme-modal-backdrop",onClick:()=>r(o),children:e.jsxs("div",{className:"sme-modal",onClick:u=>u.stopPropagation(),children:[e.jsx("h2",{children:"✓ Sent for review"}),e.jsx("p",{children:o.message}),o.pr_url&&e.jsx("p",{children:e.jsx("a",{href:o.pr_url,target:"_blank",rel:"noreferrer",children:"View pull request →"})}),o.compare_url&&e.jsx("p",{children:e.jsx("a",{href:o.compare_url,target:"_blank",rel:"noreferrer",children:"Open the pull request →"})}),e.jsxs("p",{className:"sme-muted",children:["Your suggestion is on branch ",e.jsx("code",{children:o.branch}),". A steward will review it."]}),e.jsx("div",{className:"sme-modal-foot",children:e.jsx("button",{className:"sme-primary",onClick:()=>r(o),children:"Done"})})]})}):e.jsx("div",{className:"sme-modal-backdrop",onClick:c,children:e.jsxs("div",{className:"sme-modal",onClick:u=>u.stopPropagation(),children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsx("h2",{children:"Submit for review"}),e.jsx("button",{className:"sme-secondary",onClick:c,children:"✕"})]}),e.jsx("h3",{children:"Your changes"}),e.jsx("ul",{className:"sme-diff",children:s.map((u,P)=>e.jsxs("li",{children:[e.jsxs("div",{className:"sme-diff-head",children:[e.jsx("b",{children:u.label}),e.jsx("button",{className:"sme-link danger",onClick:()=>x(P),children:"discard"})]}),e.jsx("div",{className:"sme-diff-before",children:u.before}),e.jsx("div",{className:"sme-diff-after",children:u.after})]},P))}),m?e.jsxs("p",{className:"sme-signed-in",children:["Signed in as ",e.jsx("strong",{children:a.name}),a.email?` (${a.email})`:""," — this proposal is attributed to you."]}):e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Your name (for attribution)"}),e.jsx("input",{value:N,onChange:u=>b(u.target.value),placeholder:"e.g. a.hough"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Title"}),e.jsx("input",{value:f,onChange:u=>h(u.target.value)})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Branch name (edit to add a ticket id, e.g. PROJ-123)"}),e.jsx("input",{value:C?g:S,onChange:u=>{T(!0),_(u.target.value)},placeholder:"clarify-counterparty"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Note for the reviewer (optional)"}),e.jsx("textarea",{rows:2,value:y,onChange:u=>A(u.target.value)})]}),e.jsx(ls,{cl:t,user:m?a.name:N,changeSlug:S}),$&&e.jsx("p",{className:"sme-error-line",children:$}),e.jsxs("div",{className:"sme-modal-foot",children:[e.jsx("button",{className:"sme-secondary",onClick:c,children:"Keep editing"}),e.jsx("button",{className:"sme-primary",disabled:k||!m&&!N.trim()||s.length===0,onClick:B,children:k?"Submitting…":"Submit for review"})]})]})})}function ls({cl:s,user:t,changeSlug:a}){if(!(s!=null&&s.primary))return null;const l=s.reviewers_actual??s.reviewers,i=ve(t||"you"),x=s.routes.length>1;return e.jsxs(e.Fragment,{children:[x&&e.jsxs("div",{className:"sub-advice",children:[e.jsx("span",{className:"i",children:"ⓘ"})," These changes span routes"," ",e.jsx("strong",{children:s.routes.join(" and ")}),". The whole proposal will be reviewed as route ",s.primary," (",s.primary_name,") — the strictest gate wins, so it needs"," ",l.join(", ")," plus ",e.jsx("code",{children:s.gates[s.gates.length-1]}),". Proposing the meaning-only changes separately would get them reviewed faster."]}),e.jsxs("div",{className:"sub-dest",children:[e.jsxs("div",{className:"row",children:[e.jsx("span",{className:"k",children:"Goes to"}),e.jsxs("code",{children:["sme/",i,"/",a||"…"]})]}),e.jsxs("div",{className:"row",children:[e.jsx("span",{className:"k",children:"Reviewers"}),e.jsx("span",{children:l.join(", ")})]})]})]})}function ve(s){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"change"}const cs="modulepreload",os=function(s){return"/"+s},oe={},ds=function(t,a,l){let i=Promise.resolve();if(a&&a.length>0){document.getElementsByTagName("link");const c=document.querySelector("meta[property=csp-nonce]"),r=(c==null?void 0:c.nonce)||(c==null?void 0:c.getAttribute("nonce"));i=Promise.allSettled(a.map(m=>{if(m=os(m),m in oe)return;oe[m]=!0;const N=m.endsWith(".css"),b=N?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${b}`))return;const f=document.createElement("link");if(f.rel=N?"stylesheet":cs,N||(f.as="script"),f.crossOrigin="",f.href=m,r&&f.setAttribute("nonce",r),document.head.appendChild(f),N)return new Promise((h,g)=>{f.addEventListener("load",h),f.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${m}`)))})}))}function x(c){const r=new Event("vite:preloadError",{cancelable:!0});if(r.payload=c,window.dispatchEvent(r),!r.defaultPrevented)throw c}return i.then(c=>{for(const r of c||[])r.status==="rejected"&&x(r.reason);return t().catch(x)})};function hs({diff:s,selectable:t,selected:a,onToggle:l}){var r;const[i,x]=n.useState(((r=s.objects[0])==null?void 0:r.ulid)??null),c=n.useMemo(()=>s.objects.find(m=>m.ulid===i)??s.objects[0]??null,[s,i]);return s.objects.length?e.jsxs("div",{className:"rv-body",children:[e.jsx("div",{className:"rv-list",children:s.objects.map(m=>e.jsx(us,{obj:m,active:m.ulid===((c==null?void 0:c.ulid)??""),checked:(a==null?void 0:a.has(m.ulid))??!0,selectable:t,onSelect:()=>x(m.ulid),onToggle:()=>l==null?void 0:l(m.ulid)},m.ulid))}),e.jsx("div",{className:"rv-detail",children:c&&e.jsx(ps,{obj:c})})]}):e.jsxs("p",{className:"sme-placeholder",children:["No model changes against ",s.base.label,"."]})}function ms(s){return s.renamed?"renamed":s.severity==="breaking"?"breaking":s.change}function us({obj:s,active:t,checked:a,selectable:l,onSelect:i,onToggle:x}){return e.jsxs("div",{className:"rv-obj"+(t?" active":""),onClick:i,children:[e.jsxs("div",{className:"rv-obj-head",children:[l&&e.jsx("input",{type:"checkbox",checked:a,onClick:c=>c.stopPropagation(),onChange:x,"aria-label":`include ${s.name_before??s.name_after}`}),e.jsx("span",{className:"rv-obj-name",children:s.name_before??s.name_after}),e.jsx("span",{className:"rv-obj-kind",children:s.object_kind_label}),e.jsxs("span",{className:"sev "+(s.renamed?"renamed":s.severity),children:[s.severity==="breaking"&&"⚠ ",ms(s)]})]}),e.jsxs("ul",{className:"rv-obj-fields",children:[s.fields.map((c,r)=>e.jsx("li",{children:c.label},c.field+r)),s.children.flatMap(c=>c.fields.map((r,m)=>e.jsxs("li",{children:[r.label,": ",c.name_before??c.name_after]},c.ulid+m)))]})]})}function ps({obj:s}){const t=s.children.flatMap(a=>a.fields.map(l=>({field:l,on:a.name_before??a.name_after??""})));return e.jsxs(e.Fragment,{children:[e.jsx("h2",{children:s.renamed?`${s.name_before} → ${s.name_after}`:s.name_before??s.name_after}),e.jsxs("div",{className:"rv-detail-kind",children:[s.object_kind_label,s.renamed&&" · renamed",s.path&&e.jsxs("span",{className:"rv-src",children:[" · ",s.path]})]}),s.fields.map((a,l)=>e.jsx(de,{f:a},a.field+l)),t.map(({field:a,on:l},i)=>e.jsx(de,{f:a,on:l},"c"+i)),s.severity==="breaking"&&e.jsxs("div",{className:"rv-note",children:[e.jsx("span",{className:"i",children:"ⓘ"}),e.jsxs("span",{children:["This is a structural change (route B). It will need an architect's review, and CI will run ",e.jsx("code",{children:"mdl drift --check"}),"."]})]})]})}function de({f:s,on:t}){var l,i,x;const a=t?`${s.label}: ${t}`:s.label;if((l=s.breaks)!=null&&l.length)return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-break",children:[e.jsxs("div",{className:"rv-break-head",children:[e.jsx("span",{children:"⚠"}),e.jsxs("span",{children:[t??String(s.before??"")," removed"]}),s.detail&&e.jsx("span",{className:"rv-break-meta",children:s.detail})]}),e.jsxs("div",{className:"rv-break-body",children:["This is realised by ",s.breaks.length," dbt model",s.breaks.length>1?"s":"",". Removing it will break ",s.breaks.length>1?"them":"it","."]}),e.jsx("ul",{className:"rv-usage",children:s.breaks.map(c=>e.jsxs("li",{children:[e.jsxs("span",{className:"m",children:["→ ",c.name]}),e.jsxs("span",{className:"p",children:[c.target," · ",c.materialization]})]},c.name))})]})]});if(s.kind==="definition_changed"){const c=String(s.before??""),r=String(s.after??"");return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-ba",children:[e.jsxs("div",{className:"rv-ba-col",children:[e.jsx("div",{className:"rv-ba-label",children:"before"}),e.jsx("div",{className:"rv-ba-text",children:me(c,r,"del")})]}),e.jsxs("div",{className:"rv-ba-col",children:[e.jsx("div",{className:"rv-ba-label",children:"after"}),e.jsx("div",{className:"rv-ba-text",children:me(r,c,"ins")})]})]})]})}if(Array.isArray(s.before)||Array.isArray(s.after)){const c=new Set(((i=s.before)==null?void 0:i.map(String))??[]),r=new Set(((x=s.after)==null?void 0:x.map(String))??[]),m=[...r].filter(b=>!c.has(b)),N=[...c].filter(b=>!r.has(b));return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-chips",children:[m.map(b=>e.jsxs("span",{className:"rv-chip-add",children:["+ ",b]},"a"+b)),N.map(b=>e.jsxs("span",{className:"rv-chip-del",children:["− ",b]},"r"+b))]})]})}return e.jsxs("div",{className:"rv-section",children:[e.jsx("h3",{children:a}),e.jsxs("div",{className:"rv-scalar",children:[e.jsx("span",{className:"from",children:he(s.before)}),e.jsx("span",{className:"arrow",children:"→"}),e.jsx("span",{className:"to",children:he(s.after)})]})]})}function he(s){return s==null||s===""?"—":typeof s=="boolean"?s?"yes":"no":typeof s=="object"?JSON.stringify(s):String(s)}function me(s,t,a){const l=s.split(/(\s+)/),i=t.split(/(\s+)/),x=h=>h.toLowerCase().replace(/[.,;:]/g,""),c=l.length,r=i.length,m=Array.from({length:c+1},()=>new Array(r+1).fill(0));for(let h=c-1;h>=0;h--)for(let g=r-1;g>=0;g--)m[h][g]=x(l[h])===x(i[g])?m[h+1][g+1]+1:Math.max(m[h+1][g],m[h][g+1]);const N=new Set;let b=0,f=0;for(;b=m[b][f+1]?b++:f++;return l.map((h,g)=>!h.trim()||N.has(g)?e.jsx("span",{children:h},g):a==="del"?e.jsx("del",{children:h},g):e.jsx("ins",{children:h},g))}const js=n.lazy(()=>ds(()=>import("./ModelDiagram-oAb1enKe.js"),__vite__mapDeps([0,1,2,3])).then(s=>({default:s.ModelDiagram})));function xs({stagedDiff:s,stagedRoute:t,user:a,onBack:l,onSubmit:i,excluded:x,onToggleObject:c,selectable:r}){const[m,N]=n.useState(null),[b,f]=n.useState(null),[h,g]=n.useState(null),[_,C]=n.useState(null),[T,S]=n.useState(null),[y,A]=n.useState("changes"),k=n.useCallback(()=>{je(a).then(o=>{C(o);const E=o.base_branch??"main";s?N(s):Le("HEAD").then($=>$.ok?N($):S($.error??"could not read the model")).catch($=>S(String($))),t?f(t):Fe("HEAD").then(f).catch(()=>{}),ze(E).then(g).catch(()=>{})}).catch(o=>S(String(o)))},[a,s,t]);if(n.useEffect(k,[k]),T)return e.jsxs("div",{className:"rv-shell",children:[e.jsx(ue,{onBack:l,diff:null}),e.jsx("p",{className:"sme-splash error",children:e.jsx("pre",{children:T})})]});if(!m)return e.jsx("div",{className:"sme-splash",children:"◮ reading your changes…"});const R=new Set(m.objects.map(o=>o.ulid).filter(o=>!x.has(o)));return e.jsxs("div",{className:"rv-shell",children:[e.jsx(ue,{onBack:l,diff:m,tab:y,onTab:A}),y==="changes"?e.jsx(hs,{diff:m,selectable:r,selected:R,onToggle:c}):e.jsx(n.Suspense,{fallback:e.jsx("div",{className:"sme-splash",children:"◮ drawing the model…"}),children:e.jsx(js,{severityByUlid:bs(m)})}),e.jsxs("div",{className:"rv-foot",children:[e.jsx(gs,{cl:b}),e.jsx(fs,{conf:h,ctx:_}),e.jsxs("div",{className:"rv-actions",children:[e.jsx("button",{className:"sme-secondary",onClick:l,children:"Keep editing"}),e.jsx("button",{className:"sme-primary",disabled:!m.objects.length||(_?!_.can_propose:!1),title:_&&!_.can_propose?"the working tree has uncommitted changes":"",onClick:()=>i(b),children:"Submit for review →"})]})]})]})}function bs(s){const t=new Map;for(const a of s.objects)t.set(a.ulid,a.severity);return t}function ue({onBack:s,diff:t,tab:a,onTab:l}){const i=t==null?void 0:t.counts;return e.jsxs("div",{className:"rv-head",children:[e.jsxs("div",{children:[e.jsx("button",{className:"rv-back",onClick:s,children:"‹ Back to terms"}),e.jsx("h1",{className:"rv-title",children:"Review your changes"}),i&&e.jsxs("div",{className:"rv-sub",children:[i.objects," object",i.objects===1?"":"s"," ·"," ",(i.breaking??0)+(i.additive??0)+(i.cosmetic??0)," changes",(t==null?void 0:t.has_breaking)&&e.jsxs("span",{className:"warn",children:[" · ⚠ ",i.breaking," breaking"]})," · comparing to ",e.jsx("code",{children:t==null?void 0:t.base.label})]})]}),l&&e.jsxs("div",{className:"rv-tabs",children:[e.jsxs("button",{className:"rv-tab"+(a==="changes"?" active":""),onClick:()=>l("changes"),children:["Changes ",(t==null?void 0:t.objects.length)??0]}),e.jsx("button",{className:"rv-tab"+(a==="diagram"?" active":""),onClick:()=>l("diagram"),children:"Diagram"})]})]})}function gs({cl:s}){if(!(s!=null&&s.primary))return null;const t=s.reviewers_actual??s.reviewers;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rv-route",children:[e.jsxs("span",{className:"rv-route-badge",children:["Route ",s.primary," · ",s.primary_name]}),e.jsx("span",{className:"k",children:"Reviewers"}),e.jsx("span",{children:t.join(", ")}),s.reviewers_actual&&e.jsx("span",{className:"rv-src",children:"from .github/CODEOWNERS"})]}),e.jsxs("div",{className:"rv-gates",children:["CI gates"," ",s.gates.map(a=>e.jsx("code",{children:a},a))]})]})}function fs({conf:s,ctx:t}){return s!=null&&s.ok?s.clean?e.jsxs("div",{className:"rv-conflict ok",children:[e.jsx("span",{children:"✓"}),e.jsxs("span",{children:["Merges cleanly onto ",s.base]}),s.behind>0&&e.jsxs("span",{className:"detail",children:["· ",s.base," is ",s.behind," commit",s.behind===1?"":"s"," ahead"]}),(t==null?void 0:t.dirty)&&e.jsx("span",{className:"detail",children:"· uncommitted changes in the working tree"})]}):e.jsxs("div",{className:"rv-conflict bad",children:[e.jsx("span",{children:"⚠"}),e.jsxs("span",{children:[s.base," has changed and ",s.files.length," file",s.files.length===1?"":"s"," now conflict"]}),e.jsx("span",{className:"detail",children:s.files.map(a=>a.path).join(", ")})]}):null}function vs({term:s,canEdit:t,pendingCount:a,onEdit:l}){var i,x;return e.jsxs("div",{className:"sme-card",children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsxs("div",{children:[e.jsx("h1",{children:s.name}),((i=s.subject_area)==null?void 0:i.name)&&e.jsx("span",{className:"sme-chip",children:s.subject_area.name}),s.kind==="term"&&e.jsx("span",{className:"sme-chip",children:"glossary term"})]}),t&&e.jsx("button",{className:"sme-primary",onClick:l,children:a>0?"Continue editing":"Suggest an edit"})]}),e.jsx("p",{className:"sme-definition",children:s.definition??e.jsx("em",{children:"No definition yet."})}),s.synonyms.length>0&&e.jsxs("section",{children:[e.jsx("h3",{children:"Also called"}),e.jsx("div",{children:s.synonyms.map(c=>e.jsx("span",{className:"sme-chip",children:c},c))})]}),s.stewardship&&(s.stewardship.owner||s.stewardship.steward)&&e.jsxs("section",{children:[e.jsx("h3",{children:"Who owns this"}),s.stewardship.owner&&e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"owner"}),e.jsx("span",{children:s.stewardship.owner})]}),s.stewardship.steward&&e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"steward"}),e.jsx("span",{children:s.stewardship.steward})]})]}),((x=s.ontology)==null?void 0:x.aligns_to)&&e.jsxs("section",{children:[e.jsx("h3",{children:"Standard it maps to"}),e.jsxs("div",{className:"sme-kv",children:[e.jsx("span",{className:"k",children:"aligned to"}),e.jsx("code",{children:s.ontology.aligns_to}),s.ontology.status==="proposed"&&e.jsx("span",{className:"sme-badge proposed",children:"awaiting architect"})]})]}),e.jsxs("section",{children:[e.jsx("h3",{children:"Where it's used"}),s.where_used.length===0?e.jsx("p",{className:"sme-muted",children:s.kind==="term"?"A glossary term — not yet realised by a data model.":"Not yet realised by any data model."}):e.jsx("ul",{className:"sme-usage",children:s.where_used.map(c=>e.jsxs("li",{children:[e.jsx("span",{className:"sme-usage-model",children:c.logical_entity}),c.unmanaged&&e.jsx("span",{className:"sme-badge",children:"engineer-owned"}),c.physical.length>0&&e.jsx("span",{className:"sme-usage-phys",children:c.physical.map(r=>r.name).join(", ")})]},c.logical_id))})]})]})}function Ns({term:s,pending:t,onStage:a,onDone:l,catalogOwned:i=[],catalog:x=null}){var E,$,D,B;const c=u=>i.includes(u),r=u=>t.find(P=>P.label===u),m=(u,P)=>{const F=r(u);return F?F.after:P},[N,b]=n.useState(m("Definition",s.definition??"")),[f,h]=n.useState(s.synonyms),[g,_]=n.useState(""),[C,T]=n.useState(((E=s.stewardship)==null?void 0:E.owner)??""),[S,y]=n.useState((($=s.stewardship)==null?void 0:$.steward)??""),A=()=>{N.trim()!==(s.definition??"").trim()&&a({op:"set_definition",payload:{id:s.id,definition:N.trim()},label:"Definition",before:s.definition??"(none)",after:N.trim()||"(none)"})},k=(u,P)=>{var F,I;a({op:"set_stewardship",payload:{id:s.id,owner:u||null,steward:P||null},label:"Stewardship",before:`owner: ${((F=s.stewardship)==null?void 0:F.owner)??"—"} · steward: ${((I=s.stewardship)==null?void 0:I.steward)??"—"}`,after:`owner: ${u||"—"} · steward: ${P||"—"}`})},R=u=>{h(u),a({op:"update_synonyms",payload:{id:s.id,synonyms:u},label:"Also called",before:s.synonyms.join(", ")||"(none)",after:u.join(", ")||"(none)"})},o=s.kind==="term";return e.jsxs("div",{className:"sme-editor",children:[e.jsxs("div",{className:"sme-card-head",children:[e.jsxs("h1",{children:["Suggest an edit — ",s.name]}),e.jsx("button",{className:"sme-secondary",onClick:l,children:"Back"})]}),e.jsxs("p",{className:"sme-hint",children:["You can refine what this term ",e.jsx("em",{children:"means"}),". Structure (keys, relationships, how it's built) stays with the data team."]}),(c("definition")||c("synonyms")||c("stewardship"))&&x&&e.jsxs("div",{className:"sme-catalog-banner",children:["Definitions, synonyms, and ownership are mastered in ",e.jsx("b",{children:x.name}),". Edit them there — this glossary mirrors them read-only.",x.url&&e.jsxs(e.Fragment,{children:[" ",e.jsxs("a",{href:x.url,target:"_blank",rel:"noreferrer",children:["Open in ",x.name," →"]})]}),e.jsx("div",{className:"sme-catalog-note",children:"You can still propose a standard mapping below."})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Definition"}),c("definition")?e.jsx("p",{className:"sme-readonly-value",children:s.definition??"—"}):e.jsx("textarea",{rows:4,value:N,onChange:u=>b(u.target.value),onBlur:A,placeholder:"A plain-language business definition…"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Also called (synonyms)"}),c("synonyms")?e.jsx("div",{className:"sme-syn-row",children:s.synonyms.length?s.synonyms.map(u=>e.jsx("span",{className:"sme-chip",children:u},u)):e.jsx("span",{className:"sme-muted",children:"none"})}):e.jsxs("div",{className:"sme-syn-row",children:[f.map(u=>e.jsxs("span",{className:"sme-chip removable",onClick:()=>R(f.filter(P=>P!==u)),children:[u," ✕"]},u)),e.jsx("input",{value:g,placeholder:"add + Enter",onChange:u=>_(u.target.value),onKeyDown:u=>{u.key==="Enter"&&g.trim()&&(R([...f,g.trim()]),_(""))}})]})]}),!o&&(c("stewardship")?e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Owner"}),e.jsx("p",{className:"sme-readonly-value",children:((D=s.stewardship)==null?void 0:D.owner)??"—"})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Steward"}),e.jsx("p",{className:"sme-readonly-value",children:((B=s.stewardship)==null?void 0:B.steward)??"—"})]})]}):e.jsxs("div",{className:"sme-field-row",children:[e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Owner"}),e.jsx("input",{value:C,onChange:u=>T(u.target.value),onBlur:()=>k(C,S)})]}),e.jsxs("label",{className:"sme-field",children:[e.jsx("span",{children:"Steward"}),e.jsx("input",{value:S,onChange:u=>y(u.target.value),onBlur:()=>k(C,S)})]})]})),e.jsx(ys,{term:s,onStage:a}),e.jsx("p",{className:"sme-note",children:t.length>0?`${t.length} change(s) staged — use “Submit for review” at the top when you're done.`:"Changes you make are collected until you submit them for review."})]})}const ws=["skos:exactMatch","skos:closeMatch","skos:broadMatch","skos:narrowMatch"];function ys({term:s,onStage:t}){var f;const[a,l]=n.useState(!1),[i,x]=n.useState(s.name),[c,r]=n.useState([]),[m,N]=n.useState("skos:closeMatch"),b=h=>{x(h),qe(h).then(g=>r(g.results)).catch(()=>r([]))};return a?e.jsxs("div",{className:"sme-field sme-align",children:[e.jsx("span",{children:"Propose a standard mapping (a suggestion; the architect confirms)"}),e.jsx("input",{value:i,onChange:h=>b(h.target.value),placeholder:"Search standards…",autoFocus:!0}),e.jsx("div",{className:"sme-align-results",children:c.map(h=>e.jsxs("button",{className:"sme-align-card",onClick:()=>{var g;t({op:"set_alignment",payload:{id:s.id,aligns_to:h.prefixed,alignment:m,status:"proposed"},label:"Standard mapping",before:((g=s.ontology)==null?void 0:g.aligns_to)??"(none)",after:`${h.prefixed} (${m}, proposed)`}),l(!1)},children:[e.jsx("strong",{children:h.label})," ",e.jsx("code",{children:h.prefixed}),h.definition&&e.jsx("span",{className:"sme-align-def",children:h.definition})]},h.iri))}),e.jsx("select",{value:m,onChange:h=>N(h.target.value),children:ws.map(h=>e.jsx("option",{children:h},h))})]}):e.jsxs("div",{className:"sme-field",children:[e.jsx("span",{children:"Standard mapping"}),e.jsxs("div",{children:[(f=s.ontology)!=null&&f.aligns_to?e.jsx("code",{className:"sme-current-align",children:s.ontology.aligns_to}):e.jsx("span",{className:"sme-muted",children:"not mapped to a standard"}),e.jsx("button",{className:"sme-link",onClick:()=>l(!0),children:"Propose a mapping…"})]})]})}function _s(){const[s,t]=n.useState(null),[a,l]=n.useState(!0),[i,x]=n.useState(null),[c,r]=n.useState(""),[m,N]=n.useState(null),[b,f]=n.useState(""),[h,g]=n.useState(""),[_,C]=n.useState(null),[T,S]=n.useState(!1),[y,A]=n.useState([]),[k,R]=n.useState(!1),[o,E]=n.useState(window.location.hash==="#proposals"?"proposals":"browse"),[$,D]=n.useState(new Set),[B,u]=n.useState(()=>localStorage.getItem("mdl.sme.user")??""),[P,F]=n.useState(null),[I,z]=n.useState(null),[W,U]=n.useState(!1),[K,j]=n.useState(null),d=n.useCallback((p,v)=>{var ae;const O=J=>{var te;const V=I==null?void 0:I.entities.find(re=>{var ie;return re.id===J||((ie=re.conceptual)==null?void 0:ie.id)===J});return((te=V==null?void 0:V.conceptual)==null?void 0:te.name)??(V==null?void 0:V.name)??"object"},L=O(v.id??v.entity_id);switch(p){case"create_entity":return{label:`New entity: ${v.name}`,before:"—",after:String(v.name??"")};case"create_relationship":return{label:`New relationship: ${O(v.from_entity)} → ${O(v.to_entity)}`,before:"—",after:String(v.cardinality??"many_to_one")};case"delete_entity":return{label:`Deleted ${L}`,before:L,after:"—"};case"delete_relationship":return{label:"Relationship removed",before:"",after:"—"};case"update_relationship":return{label:"Relationship changed",before:"",after:[v.cardinality,v.optionality,v.identifying?"identifying":""].filter(Boolean).join(", ")};case"set_definition":return{label:`Definition: ${L}`,before:"",after:String(v.definition??"")};case"add_attribute":return{label:`Attribute added to ${L}`,before:"—",after:String(v.name??"")};case"delete_attribute":return{label:`Attribute removed from ${L}`,before:"",after:"—"};case"update_attribute":return{label:`Attribute changed on ${L}`,before:"",after:JSON.stringify(v)};case"rename_entity":return{label:`Renamed ${L}`,before:L,after:String(v.name??"")};case"set_subject_area":return{label:`Subject area: ${L}`,before:"",after:String(v.subject_area??"none")};case"set_stewardship":return{label:`Stewardship: ${L}`,before:"",after:String(v.steward??"")};case"set_subject_area_members":{const J=v.__label,V=((ae=v.members)==null?void 0:ae.length)??0;return{label:J??"Subject area members",before:"",after:`${V} object${V===1?"":"s"}`}}case"set_alignment":return{label:`Alignment: ${L}`,before:"",after:String(v.aligns_to??"")};default:return{label:`${p.replace(/_/g," ")}: ${L}`,before:"",after:""}}},[I]),w=Je({subjectArea:b,describe:d}),M=n.useCallback(async(p,v)=>{const O=(I==null?void 0:I.fingerprint)??"",L=await We(p,v,O);return await le(b||void 0).then(z),L},[I,b]),q=n.useMemo(()=>{const p={};for(const v of w.pending)v.op==="set_subject_area_members"&&(p[v.payload.id]=v.payload.members??[]);return p},[w.pending]),G=n.useMemo(()=>[...y,...w.pending],[y,w.pending]),[Ne,X]=n.useState(null),[we,Z]=n.useState(null);n.useEffect(()=>{if(!G.length){X(null),Z(null);return}const p=new AbortController,v=G.map(O=>({op:O.op,payload:O.payload}));return pe(v,b||void 0,p.signal).then(O=>X(O.diff??null)).catch(O=>{O.name!=="AbortError"&&X(null)}),Ge(v).then(Z).catch(()=>Z(null)),()=>p.abort()},[G,b]);const ye=n.useMemo(()=>Qe(G),[G]).size{E(p),window.location.hash=p==="browse"?"":`#${p}`},[]);n.useEffect(()=>{const p=()=>{const v=window.location.hash;E(v==="#proposals"?"proposals":v==="#review"?"review":v==="#model"?"model":v==="#areas"?"areas":"browse")};return p(),window.addEventListener("hashchange",p),()=>window.removeEventListener("hashchange",p)},[]);const ee=n.useCallback(()=>{He({subject_area:b,q:h}).then(t).catch(p=>N(String(p)))},[b,h]);n.useEffect(ee,[ee]),n.useEffect(()=>{le(b||void 0).then(p=>{l(p.read_only),r(p.project.name),z(p),U(!!p.direct),F(p.identity??null),p.identity&&p.identity.source!=="anonymous"&&p.identity.name&&u(p.identity.name)}).catch(()=>{}),Ve().then(x).catch(()=>{})},[b]);const se=n.useMemo(()=>(s==null?void 0:s.terms.find(p=>p.id===_))??null,[s,_]),_e=n.useCallback(p=>{const v=p.key??fe(p.op,p.payload);A(O=>[...O.filter(L=>L.key!==v),{...p,key:v}])},[]),Se=p=>A(v=>v.filter((O,L)=>L!==p)),ke=()=>{A([]),R(!1),S(!1),ee()};if(m)return e.jsxs("div",{className:"sme-splash error",children:[e.jsx("h1",{children:"◮ Glossary"}),e.jsx("pre",{children:m}),e.jsxs("p",{children:["Is ",e.jsx("code",{children:"mdl glossary"})," pointed at a model?"]})]});if(!s)return e.jsx("div",{className:"sme-splash",children:"◮ loading glossary…"});const Y=!a,ne=(i==null?void 0:i.catalog_owned_fields)??[],Ce=ne.length>0;return e.jsxs("div",{className:"sme",children:[e.jsxs("header",{className:"sme-top",children:[e.jsxs("div",{className:"sme-brand",children:[e.jsx("span",{className:"sme-logo",children:"◮"}),e.jsx("span",{children:"Glossary"}),e.jsx("span",{className:"sme-project",children:c}),a&&e.jsx("span",{className:"sme-chip",children:"read-only"}),Ce&&e.jsxs("span",{className:"sme-chip catalog",title:`Definitions are mastered in ${i==null?void 0:i.catalog_name}`,children:["mirrors ",i==null?void 0:i.catalog_name]})]}),e.jsx("input",{className:"sme-search",type:"search",placeholder:"Search terms & definitions…",value:h,onChange:p=>g(p.target.value)}),e.jsxs("nav",{className:"sme-tabs",children:[e.jsx("button",{className:"sme-tab"+(o==="browse"?" active":""),onClick:()=>H("browse"),children:"Terms"}),e.jsx("button",{className:"sme-tab"+(o==="model"?" active":""),onClick:()=>H("model"),children:"Model"}),e.jsx("button",{className:"sme-tab"+(o==="areas"?" active":""),onClick:()=>H("areas"),children:"Subject areas"}),e.jsx("button",{className:"sme-tab"+(o==="proposals"?" active":""),onClick:()=>H("proposals"),children:"My proposals"})]}),G.length>0&&e.jsxs("button",{className:"sme-tray",onClick:()=>H("review"),children:[G.length," change",G.length>1?"s":""," · Review →"]})]}),o==="browse"&&e.jsx(Xe,{user:B}),o==="review"?e.jsx(xs,{stagedDiff:Ne,stagedRoute:we,user:B,selectable:ye,excluded:$,onToggleObject:p=>D(v=>{const O=new Set(v);return O.has(p)?O.delete(p):O.add(p),O}),onBack:()=>H("browse"),onSubmit:p=>{j(p),R(!0)}}):o==="model"?w.previewDoc??I?e.jsx(ns,{doc:w.previewDoc??I,subjectArea:b,onSubjectArea:f,exec:W?M:w.exec,canEdit:Y,direct:W,onImported:()=>H("review"),query:h,busy:w.busy}):e.jsx("div",{className:"sme-splash",children:"◮ loading the model…"}):o==="areas"?e.jsx(Ze,{exec:w.exec,canEdit:Y,stagedMembers:q}):o==="proposals"?e.jsx(as,{user:B,onView:()=>H("review")}):e.jsxs("div",{className:"sme-body",children:[e.jsxs("nav",{className:"sme-nav",children:[e.jsx("button",{className:"sme-sa"+(b===""?" active":""),onClick:()=>f(""),children:"All subject areas"}),s.subject_areas.map(p=>e.jsx("button",{className:"sme-sa"+(b===p.id?" active":""),onClick:()=>f(p.id),title:p.definition??void 0,children:p.name},p.id))]}),e.jsxs("ul",{className:"sme-list",children:[s.terms.map(p=>{var v;return e.jsxs("li",{className:"sme-list-item"+(p.id===_?" active":""),onClick:()=>{C(p.id),S(!1)},children:[e.jsx("span",{className:"sme-term-name",children:p.name}),p.kind==="term"&&e.jsx("span",{className:"sme-kind",children:"term"}),((v=p.ontology)==null?void 0:v.status)==="proposed"&&e.jsx("span",{className:"sme-badge proposed",title:"alignment awaiting architect",children:"proposed"}),e.jsx("span",{className:"sme-term-def",children:p.definition??"no definition yet"})]},p.id)}),s.terms.length===0&&e.jsx("li",{className:"sme-empty",children:"no terms match"})]}),e.jsx("section",{className:"sme-detail",children:se?T&&Y?e.jsx(Ns,{term:se,pending:y,onStage:_e,onDone:()=>S(!1),catalogOwned:ne,catalog:i?{name:i.catalog_name,url:i.catalog_url}:null}):e.jsx(vs,{term:se,canEdit:Y,pendingCount:y.length,onEdit:()=>S(!0)}):e.jsx("div",{className:"sme-placeholder",children:"Select a term to see its definition."})})]}),k&&e.jsx(is,{changes:G,routeAdvice:K,identity:P,user:B,onUser:p=>{u(p),localStorage.setItem("mdl.sme.user",p)},onDrop:Se,onClose:()=>R(!1),onProposed:()=>{ke(),w.clear(),D(new Set),H("proposals")}})]})}Ae.createRoot(document.getElementById("root")).render(e.jsx(Ee.StrictMode,{children:e.jsx(_s,{})})); diff --git a/packages/server/src/mdl_server/static/assets/styles-BJW39REh.css b/packages/server/src/mdl_server/static/assets/styles-BJW39REh.css deleted file mode 100644 index f1c1d8c..0000000 --- a/packages/server/src/mdl_server/static/assets/styles-BJW39REh.css +++ /dev/null @@ -1 +0,0 @@ -.react-flow{direction:ltr}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;cursor:-webkit-grab;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;-webkit-animation:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:-webkit-grab;cursor:grab}.react-flow__node.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:-webkit-grab;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background:#1a192b;border:1px solid white;border-radius:100%}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:-4px;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{font-size:10px;background:#ffffff80;padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@-webkit-keyframes dashdraw{0%{stroke-dashoffset:10}}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:3px;width:150px;font-size:12px;color:#222;text-align:center;border-width:1px;border-style:solid;border-color:#1a192b;background-color:#fff}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{border:none;background:#fefefe;border-bottom:1px solid #eee;box-sizing:content-box;display:flex;justify-content:center;align-items:center;width:16px;height:16px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:5px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:#3367d9;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:#3367d9;border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.ie-wrap{position:relative;display:inline-flex;gap:6px}.erd-ico{font-size:13px;line-height:1;opacity:.85;margin-right:1px}.ie-wrap button:hover .erd-ico,.ie-wrap button.on .erd-ico,.ie-wrap button.active .erd-ico{opacity:1}.erd-caret{opacity:.55;margin-left:1px}.ie-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:30;min-width:220px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:6px;box-shadow:0 12px 32px #00000073;display:flex;flex-direction:column;gap:2px}.ie-item{display:block;padding:8px 10px;border-radius:6px;color:var(--text);text-decoration:none;font-size:13px;cursor:pointer}.ie-item:hover{background:#5eead424;color:var(--accent)}.ie-dialect{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px 8px;margin-bottom:4px;border-bottom:1px solid var(--border);font-size:12px;color:var(--text-dim)}.ie-dialect select{background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:3px 6px;font-size:12px}.ie-import{width:380px;padding:12px;gap:8px}.ie-tabs{display:flex;gap:4px}.ie-tab{flex:1;padding:6px 8px;border-radius:6px;font-size:12px;cursor:pointer;background:none;border:1px solid var(--border);color:var(--text-dim)}.ie-tab.active{border-color:var(--accent);color:var(--accent);background:#5eead41a}.ie-hint{font-size:11px;color:var(--text-dim);margin:0}.ie-textarea{width:100%;font-family:var(--mono);font-size:12px;resize:vertical;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px;box-sizing:border-box}.ie-textarea:focus{border-color:var(--accent);outline:none}.ie-file{font-size:11px;color:var(--text-dim)}.ie-warn{font-size:11px;color:var(--pk);margin:0}.ie-error{font-size:12px;color:var(--err);margin:0}.ie-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}:root{--bg: #14110f;--bg-raised: #1c1815;--bg-card: #221d19;--border: #33291f;--border-strong: #4a3c2c;--text: #ece6dd;--text-dim: #a89a86;--accent: #e0a63a;--accent-soft: rgba(224, 166, 58, .15);--accent-ink: #241a08;--pk: #f2c14e;--err: #f0857a;--warn: #e6a94a;--ok: #6cbf73;--font: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;--mono: "SF Mono", ui-monospace, "Cascadia Code", Menlo, monospace}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:var(--font);background:var(--bg);color:var(--text)}.app{display:flex;flex-direction:column;height:100%}.canvas-wrap{flex:1;position:relative;min-height:0}.react-flow{background:var(--bg)}.topbar{display:flex;align-items:center;gap:16px;padding:10px 16px;background:var(--bg-raised);border-bottom:1px solid var(--border);z-index:10}.brand{display:flex;align-items:baseline;gap:8px;white-space:nowrap}.logo{color:var(--accent);font-size:18px}.brand-name{font-weight:700;letter-spacing:.02em}.project-name{color:var(--text-dim);font-size:13px}.search{flex:0 1 340px;padding:7px 12px;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);font-size:13px;outline:none}.search:focus{border-color:var(--accent)}.legend{display:flex;gap:12px;flex-wrap:wrap;font-size:12px;color:var(--text-dim)}.legend-item{display:inline-flex;align-items:center;gap:5px}.swatch{width:10px;height:10px;border-radius:3px;display:inline-block}.stats{margin-left:auto;display:flex;gap:12px;font-size:12px;color:var(--text-dim)}.diag-chip{padding:2px 8px;border-radius:99px;font-weight:600}.diag-chip.ok{background:#34d39926;color:var(--ok)}.diag-chip.warn{background:#fbbf2426;color:var(--warn)}.diag-chip.err{background:#f8717126;color:var(--err)}.actions{display:flex;gap:6px}.tool-btn{padding:6px 10px;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim);cursor:pointer;font-size:13px}.tool-btn:hover{color:var(--text);border-color:var(--border-strong)}.tool-btn.active{color:var(--accent);border-color:var(--accent)}.layout-picker{position:relative;display:inline-flex;gap:2px}.layout-picker .caret{padding:6px;font-size:10px}.layout-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:20;background:var(--bg-raised);border:1px solid var(--border-strong);border-radius:8px;padding:4px;min-width:150px;box-shadow:0 8px 24px #0006}.layout-menu button{display:block;width:100%;text-align:left;padding:7px 10px;border:0;border-radius:6px;background:transparent;color:var(--text-dim);cursor:pointer;font-size:13px}.layout-menu button:hover{background:var(--bg-card);color:var(--text)}.entity-node{width:264px;background:var(--bg-card);border:1px solid var(--border);border-top:3px solid var(--accent);border-radius:10px;overflow:hidden;box-shadow:0 4px 18px #00000059;font-size:12px;transition:opacity .15s,box-shadow .15s,border-color .15s}.entity-node.selected{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent),0 8px 24px #00000080}.entity-node.highlighted{box-shadow:0 0 0 2px var(--pk),0 8px 24px #00000080}.entity-node.dimmed{opacity:.18}.entity-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:#ffffff08;border-bottom:1px solid var(--border)}.entity-name{font-weight:700;font-size:13px;letter-spacing:.01em}.entity-badges{display:flex;gap:4px}.badge{font-size:10px;padding:1px 6px;border-radius:99px;background:var(--accent-soft);color:var(--accent);text-transform:uppercase;letter-spacing:.05em}.badge.ontology{background:#93c5fd1f;color:#93c5fd}.attr-section{padding:4px 0}.attr-section.keys{border-bottom:1px solid var(--border);background:#fcd34d0a}.attr-row{display:flex;align-items:center;gap:6px;padding:3px 12px;height:26px;line-height:20px;position:relative}.attr-row.empty{color:var(--text-dim);font-style:italic}.attr-row.more{color:var(--text-dim);font-style:italic;cursor:pointer;justify-content:center;height:22px;font-size:11px}.attr-row.more:hover{color:var(--accent);background:var(--accent-soft)}.attr-row.rel-hit{background:var(--accent-soft);box-shadow:inset 2px 0 0 var(--accent)}.attr-row.rel-hit .attr-name{color:var(--accent);font-weight:600}.attr-row.rel-dim{opacity:.35}.attr-row.endpoint .attr-name{font-style:normal}.attr-port{width:8px!important;height:8px!important;opacity:0;top:50%!important}.attr-port.react-flow__handle-left{left:-5px!important}.attr-port.react-flow__handle-right{right:-5px!important}.entity-node:hover .attr-port{opacity:.5}.attr-row:hover .attr-port{opacity:1!important;background:var(--accent)!important}.attr-icon{width:14px;text-align:center;font-size:10px;flex:none}.attr-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attr-name.pk{color:var(--pk);font-weight:600}.attr-type{color:var(--text-dim);font-family:var(--mono);font-size:10px;flex:none}.attr-notnull{color:var(--text-dim);font-size:8px;flex:none}.port{width:11px!important;height:11px!important;background:var(--border-strong)!important;border:2px solid var(--bg)!important;opacity:.55;transition:transform .12s ease,background .12s ease,opacity .12s ease}.entity-node:hover .port{opacity:1;background:var(--accent)!important;transform:scale(1.25);box-shadow:0 0 0 4px var(--accent-soft);cursor:crosshair}.port:hover{transform:scale(1.6)!important;cursor:crosshair}.entity-node:hover{border-color:var(--accent);box-shadow:0 0 0 1px #e0a63a40}.react-flow__connectionline .react-flow__edge-path,.react-flow__connection-path{stroke:var(--accent)!important;stroke-width:2!important}.rel-path{stroke:var(--border-strong);stroke-width:1.6}.rel-edge{cursor:pointer}.rel-glyph{stroke:var(--border-strong);stroke-width:1.6;fill:none}.rel-glyph.ring{fill:var(--bg)}.rel-edge:hover .rel-path,.rel-edge.selected .rel-path,.rel-edge:hover .rel-glyph,.rel-edge.selected .rel-glyph{stroke:var(--accent)}.rel-edge.dimmed{opacity:.12}.rel-label{fill:var(--text);font-size:11px;text-anchor:middle;paint-order:stroke;stroke:var(--bg);stroke-width:4px}.detail-panel{position:absolute;top:12px;right:12px;bottom:12px;width:340px;background:var(--bg-raised);border:1px solid var(--border);border-radius:14px;padding:18px;overflow-y:auto;z-index:9;box-shadow:0 12px 40px #00000080}.detail-header{display:flex;justify-content:space-between;align-items:flex-start}.detail-header h2{margin:0 0 6px;font-size:18px}.icon-btn{background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:14px}.icon-btn:hover{color:var(--text)}.definition{color:var(--text-dim);font-size:13px;line-height:1.5}.detail-panel section{margin-top:18px}.detail-panel h3{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim)}.kv{display:flex;gap:8px;margin:4px 0;font-size:12px;align-items:baseline}.kv .k{color:var(--text-dim);min-width:72px}.kv .v{word-break:break-all}.chip{display:inline-block;font-size:11px;padding:2px 8px;margin:2px 4px 2px 0;border-radius:99px;background:#94a3b81f;color:var(--text-dim)}.chip.pattern{background:var(--accent-soft);color:var(--accent)}.chip.layer-industry{background:#93c5fd26;color:#93c5fd}.chip.layer-core{background:var(--accent-soft);color:var(--accent)}.chip.layer-domain{background:#f0abfc26;color:#f0abfc}.chip.layer-specialised{background:#fcd34d26;color:var(--pk)}.cat-badge{font-size:10px;font-weight:700;margin-left:6px;padding:2px 8px;border-radius:5px;cursor:help}.cat-badge.supertype{background:#a78bfa2e;color:#a78bfa}.cat-badge.subtype{background:var(--accent-soft);color:var(--accent)}.udp-row td{padding:3px 6px;border-bottom:1px solid var(--border);font-size:12px}.udp-key{color:var(--text-dim);font-family:var(--mono);font-size:11px}.udp-val{color:var(--text)}.enum-badge{font-size:8px;font-weight:700;margin-left:6px;padding:1px 5px;border-radius:4px;background:#a78bfa2e;color:#a78bfa;vertical-align:middle;cursor:help}.key-row{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px}.key-badge{font-size:9px;font-weight:700;padding:2px 6px;border-radius:5px;background:#94a3b826;color:var(--text-dim);flex:none}.key-badge.pk{background:#fcd34d2e;color:var(--pk)}.key-badge.unique,.key-badge.alternate{background:var(--accent-soft);color:var(--accent)}.key-name{font-weight:600}.key-cols{color:var(--text-dim);font-family:var(--mono);font-size:11px}.attr-table{width:100%;border-collapse:collapse;font-size:12px;table-layout:auto}.attr-table td{padding:4px 6px;border-bottom:1px solid var(--border)}.attr-table td:first-child{width:100%}.attr-table td:first-child .edit-input{min-width:120px}.attr-table td.pk{color:var(--pk);font-weight:600}.attr-table td.type{color:var(--text-dim);font-family:var(--mono);font-size:11px}.attr-table td.null{color:var(--text-dim);font-size:10px;text-align:right}.rel-link{display:flex;gap:8px;align-items:center;width:100%;background:var(--bg-card);border:1px solid var(--border);border-radius:8px;color:var(--text);padding:7px 10px;margin:4px 0;cursor:pointer;font-size:12px;text-align:left}.rel-link:hover{border-color:var(--accent)}.rel-card{color:var(--text-dim);font-family:var(--mono);font-size:11px}.ulid{font-family:var(--mono);font-size:11px;color:var(--text-dim);cursor:copy;word-break:break-all}.ulid:hover{color:var(--accent)}.splash{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:var(--text-dim)}.splash.error pre{background:var(--bg-card);padding:12px 16px;border-radius:8px;max-width:640px;overflow:auto;color:var(--err);font-size:12px}.react-flow__minimap{background:var(--bg-raised)!important;border-radius:10px}.react-flow__controls{border-radius:10px;overflow:hidden;box-shadow:none!important}.react-flow__controls-button{background:var(--bg-raised)!important;border-bottom:1px solid var(--border)!important;fill:var(--text-dim)!important}.react-flow__controls-button:hover{fill:var(--text)!important}.edit-input{width:100%;padding:6px 9px;border-radius:7px;font-size:12px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);font-family:var(--font);outline:none}.edit-input:focus{border-color:var(--accent)}.entity-title-input{font-size:17px;font-weight:700;background:transparent;border-color:transparent;padding-left:0}.entity-title-input:hover,.entity-title-input:focus{border-color:var(--border);background:var(--bg-card);padding-left:9px}.definition-input{color:var(--text-dim);line-height:1.5;resize:vertical}.chip-select,.cell-select{font-size:11px;padding:2px 6px;margin:2px 6px 2px 0;border-radius:99px;background:#94a3b81f;color:var(--text-dim);border:1px solid transparent;outline:none}.chip-select:hover,.cell-select:hover{border-color:var(--border-strong);color:var(--text)}.cell-select{border-radius:6px;background:transparent;max-width:110px}.mini-btn{font-size:11px;padding:3px 9px;border-radius:7px;cursor:pointer;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim)}.mini-btn:hover{color:var(--accent);border-color:var(--accent)}.mini-btn.danger:hover{color:var(--err);border-color:var(--err)}.h3-actions{float:right;display:inline-flex;gap:6px}.empty-hint{color:var(--text-dim);font-size:12px;font-style:italic}.add-attr{display:flex;gap:6px;margin-top:8px}.rel-row{display:flex;gap:6px;align-items:flex-start}.rel-row .rel-main{flex:1}.verb-phrases{display:flex;align-items:center;gap:4px;margin-top:2px;padding-left:4px}.verb-phrases .verb-input{font-size:11px;font-style:italic;color:var(--text-dim);min-width:40px}.verb-phrases .verb-sep{color:var(--text-dim);font-size:11px}.physical-name-row{display:flex;align-items:center;gap:6px;margin-top:2px}.physical-name-row .physical-label{font-size:9px;text-transform:uppercase;color:var(--text-dim);letter-spacing:.04em}.physical-name-input{font-size:12px;color:var(--text-dim)}.physical-col{display:block;font-size:10px;color:var(--text-dim);font-family:var(--mono, monospace)}.physical-col-input{display:block;font-size:10px;color:var(--text-dim)}.tool-btn.primary{color:var(--accent);border-color:#e0a63a66;font-weight:600}.tool-btn.badged:after{content:"●";color:var(--warn);margin-left:4px;font-size:8px;vertical-align:super}.divider{width:1px;background:var(--border);margin:0 4px;align-self:stretch}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#05080db3;z-index:50;display:flex;align-items:center;justify-content:center}.modal{width:440px;max-height:80vh;overflow-y:auto;background:var(--bg-raised);border:1px solid var(--border-strong);border-radius:14px;padding:20px;box-shadow:0 24px 80px #0009}.modal.wide{width:600px}.modal-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}.modal-header h2{margin:0;font-size:16px}.modal-search{margin-bottom:10px}.modal-footer{display:flex;gap:10px;justify-content:flex-end;align-items:center;margin-top:14px}.modal-footer label{font-size:11px;color:var(--text-dim);display:flex;flex-direction:column;gap:3px}.modal-footer select,.form-row select{background:var(--bg-card);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:5px 8px;font-size:12px}.primary-btn{padding:8px 16px;border-radius:8px;border:none;cursor:pointer;background:var(--accent);color:var(--accent-ink);font-weight:700;font-size:13px}.primary-btn:disabled{opacity:.4;cursor:default}.danger-btn{padding:8px 16px;border-radius:8px;border:1px solid var(--err);cursor:pointer;background:#f8717124;color:var(--err);font-weight:700;font-size:13px}.form-row{display:flex;flex-direction:column;gap:4px;margin-bottom:14px;font-size:12px;color:var(--text-dim)}.form-row>label{font-weight:600;letter-spacing:.02em;text-transform:uppercase;font-size:10px}.form-error{color:var(--err);font-size:11px}.form-preview{color:var(--text-dim);font-size:11px;word-break:break-all;opacity:.85}.form-preview:before{content:""}.form-hint{color:var(--text-dim);font-size:11px;font-style:italic;opacity:.75;word-break:break-word}.term-results{display:flex;flex-direction:column;gap:8px;max-height:44vh;overflow-y:auto}.term-card{text-align:left;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:10px 12px;cursor:pointer;color:var(--text)}.term-card:hover{border-color:var(--border-strong)}.term-card.picked{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.term-head{display:flex;justify-content:space-between;align-items:baseline}.term-label{font-weight:600;font-size:13px}.term-source{font-size:10px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.06em}.term-iri{font-size:10px;color:var(--accent);display:block;margin:2px 0;word-break:break-all}.term-def{font-size:11px;color:var(--text-dim);margin:4px 0 0;line-height:1.45}.kind-badge{font-size:8px;padding:1px 5px;margin-right:6px;border-radius:999px;background:#f0abfc26;color:#f0abfc;letter-spacing:.04em}.src-picker{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}.src-chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:3px 9px;border-radius:999px;background:var(--bg);border:1px solid var(--border);color:var(--text-dim);cursor:pointer}.src-chip:hover{border-color:var(--border-strong);color:var(--text)}.src-chip.active{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}.src-layer{font-size:8px;padding:0 5px;border-radius:999px;text-transform:uppercase;letter-spacing:.04em}.side-panel{position:absolute;top:12px;right:12px;bottom:12px;width:380px;background:var(--bg-raised);border:1px solid var(--border);border-radius:14px;padding:18px;overflow-y:auto;z-index:9;box-shadow:0 12px 40px #00000080}.side-panel h2{margin:0;font-size:16px}.side-panel h4{margin:10px 0 6px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim)}.panel-body{margin-top:12px}.panel-body.ok{color:var(--ok)}.meta-line{font-size:10px;color:var(--text-dim);margin:6px 0 10px}.coverage-banner{font-size:12px;padding:8px 12px;border-radius:9px;margin-bottom:12px;background:#34d3991a;color:var(--ok)}.coverage-banner.warn{background:#fbbf241a;color:var(--warn)}.layer-band{border:1px dashed var(--border);border-radius:10px;padding:8px 12px 10px;margin-bottom:10px}.layer-band.external{border-style:solid;background:#93c5fd0a}.stack-term{display:flex;justify-content:space-between;align-items:baseline;gap:8px;width:100%;background:var(--bg-card);border:1px solid var(--border);color:var(--text);border-radius:7px;padding:5px 10px;margin:4px 0;font-size:12px;cursor:pointer;text-align:left}div.stack-term{cursor:default}.stack-term:hover{border-color:var(--border-strong)}.stack-term.uncovered{border-color:var(--err)}.align-arrow{font-size:10px;color:var(--accent);white-space:nowrap}.align-arrow.unresolved{color:var(--warn)}.align-arrow.missing{color:var(--err);font-style:italic}.align-arrow.proposed{color:var(--warn);font-style:italic}.ref-list{display:flex;flex-direction:column;gap:6px;margin-top:4px}.ref-card{border:1px solid var(--border);border-radius:8px;padding:6px 8px;background:var(--bg)}.ref-card.proposed{border-color:var(--warn)}.ref-head{display:flex;align-items:baseline;gap:8px;justify-content:space-between}.ref-uri{font-family:var(--mono);font-size:12px;word-break:break-all}.ref-status{font-size:9px;text-transform:uppercase;letter-spacing:.04em}.ref-status.accepted{color:var(--accent)}.ref-status.proposed{color:var(--warn)}.ref-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:5px}.ref-pill{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--accent-soft);color:var(--accent)}.ref-via{font-size:10px;color:var(--text-dim)}.ref-actions{display:flex;gap:6px;margin-top:6px}.dirty-list{list-style:none;padding:0;margin:0 0 10px;font-size:12px}.dirty-list li{padding:2px 0}.dirty-state{color:var(--warn);margin-right:6px;font-family:var(--mono)}.diff-view{background:var(--bg);border:1px solid var(--border);border-radius:9px;padding:10px;font-size:10.5px;line-height:1.5;overflow:auto;max-height:42vh;font-family:var(--mono);white-space:pre;margin-bottom:10px}.diff-add{color:var(--ok)}.diff-del{color:var(--err)}.diff-hunk{color:#93c5fd}.decision{border:1px solid var(--border);border-radius:9px;padding:8px 12px;margin-bottom:8px}.decision.accepted{opacity:.65}.decision.rejected{opacity:.45}.decision-head{display:flex;gap:6px;align-items:center}.decision-mark{font-weight:700}.decision-subject{font-size:12px;margin:6px 0}.decision-actions{display:flex;gap:6px}.toast{position:absolute;bottom:20px;left:50%;transform:translate(-50%);background:var(--bg-raised);border:1px solid var(--warn);color:var(--text);border-radius:10px;padding:10px 18px;font-size:12px;z-index:60;box-shadow:0 10px 30px #00000080} diff --git a/packages/server/src/mdl_server/static/assets/styles-BtrhR1xb.js b/packages/server/src/mdl_server/static/assets/styles-BtrhR1xb.js new file mode 100644 index 0000000..f158962 --- /dev/null +++ b/packages/server/src/mdl_server/static/assets/styles-BtrhR1xb.js @@ -0,0 +1,23 @@ +var tl=Object.defineProperty;var nl=(e,t,n)=>t in e?tl(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ue=(e,t,n)=>nl(e,typeof t!="symbol"?t+"":t,n);import{r as w,g as fi,R as A,j as h}from"./client-DOmNpTln.js";function ye(e){if(typeof e=="string"||typeof e=="number")return""+e;let t="";if(Array.isArray(e))for(let n=0,r;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?ul:cl;gi.useSyncExternalStore=Et.useSyncExternalStore!==void 0?Et.useSyncExternalStore:dl;pi.exports=gi;var fl=pi.exports;/** + * @license React + * use-sync-external-store-shim/with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var kn=w,hl=fl;function ml(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var pl=typeof Object.is=="function"?Object.is:ml,gl=hl.useSyncExternalStore,yl=kn.useRef,xl=kn.useEffect,wl=kn.useMemo,bl=kn.useDebugValue;mi.useSyncExternalStoreWithSelector=function(e,t,n,r,s){var i=yl(null);if(i.current===null){var o={hasValue:!1,value:null};i.current=o}else o=i.current;i=wl(function(){function l(f){if(!c){if(c=!0,u=f,f=r(f),s!==void 0&&o.hasValue){var y=o.value;if(s(y,f))return d=y}return d=f}if(y=d,pl(u,f))return y;var p=r(f);return s!==void 0&&s(y,p)?(u=f,y):(u=f,d=p)}var c=!1,u,d,m=n===void 0?null:n;return[function(){return l(t())},m===null?void 0:function(){return l(m())}]},[t,n,r,s]);var a=gl(e,i[0],i[1]);return xl(function(){o.hasValue=!0,o.value=a},[a]),bl(a),a};hi.exports=mi;var vl=hi.exports;const _l=fi(vl),El={},Wr=e=>{let t;const n=new Set,r=(u,d)=>{const m=typeof u=="function"?u(t):u;if(!Object.is(m,t)){const f=t;t=d??(typeof m!="object"||m===null)?m:Object.assign({},t,m),n.forEach(y=>y(t,f))}},s=()=>t,l={setState:r,getState:s,getInitialState:()=>c,subscribe:u=>(n.add(u),()=>n.delete(u)),destroy:()=>{(El?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},c=t=e(r,s,l);return l},Nl=e=>e?Wr(e):Wr,{useDebugValue:Sl}=A,{useSyncExternalStoreWithSelector:kl}=_l,jl=e=>e;function yi(e,t=jl,n){const r=kl(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return Sl(r),r}const Ur=(e,t)=>{const n=Nl(e),r=(s,i=t)=>yi(n,s,i);return Object.assign(r,n),r},Cl=(e,t)=>e?Ur(e,t):Ur;function ge(e,t){if(Object.is(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const[r,s]of e)if(!Object.is(s,t.get(r)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const r of e)if(!t.has(r))return!1;return!0}const n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(t,r)||!Object.is(e[r],t[r]))return!1;return!0}var $l={value:()=>{}};function jn(){for(var e=0,t=arguments.length,n={},r;e=0&&(r=n.slice(s+1),n=n.slice(0,s)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}cn.prototype=jn.prototype={constructor:cn,on:function(e,t){var n=this._,r=Ml(e+"",n),s,i=-1,o=r.length;if(arguments.length<2){for(;++i0)for(var n=new Array(s),r=0,s,i;r=0&&(t=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),qr.hasOwnProperty(t)?{space:qr[t],local:e}:e}function Il(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===nr&&t.documentElement.namespaceURI===nr?t.createElement(e):t.createElementNS(n,e)}}function Rl(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function xi(e){var t=Cn(e);return(t.local?Rl:Il)(t)}function Tl(){}function wr(e){return e==null?Tl:function(){return this.querySelector(e)}}function Ol(e){typeof e!="function"&&(e=wr(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s=M&&(M=_+1);!(j=v[M])&&++M=0;)(o=r[s])&&(i&&o.compareDocumentPosition(i)^4&&i.parentNode.insertBefore(o,i),i=o);return this}function oc(e){e||(e=ac);function t(d,m){return d&&m?e(d.__data__,m.__data__):!d-!m}for(var n=this._groups,r=n.length,s=new Array(r),i=0;it?1:e>=t?0:NaN}function lc(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function cc(){return Array.from(this)}function uc(){for(var e=this._groups,t=0,n=e.length;t1?this.each((t==null?vc:typeof t=="function"?Ec:_c)(e,t,n??"")):Nt(this.node(),e)}function Nt(e,t){return e.style.getPropertyValue(t)||Ei(e).getComputedStyle(e,null).getPropertyValue(t)}function Sc(e){return function(){delete this[e]}}function kc(e,t){return function(){this[e]=t}}function jc(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function Cc(e,t){return arguments.length>1?this.each((t==null?Sc:typeof t=="function"?jc:kc)(e,t)):this.node()[e]}function Ni(e){return e.trim().split(/^|\s+/)}function br(e){return e.classList||new Si(e)}function Si(e){this._node=e,this._names=Ni(e.getAttribute("class")||"")}Si.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function ki(e,t){for(var n=br(e),r=-1,s=t.length;++r=0&&(n=t.slice(r+1),t=t.slice(0,r)),{type:t,name:n}})}function nu(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,s=t.length,i;n()=>e;function rr(e,{sourceEvent:t,subject:n,target:r,identifier:s,active:i,x:o,y:a,dx:l,dy:c,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:s,enumerable:!0,configurable:!0},active:{value:i,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:a,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:c,enumerable:!0,configurable:!0},_:{value:u}})}rr.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function fu(e){return!e.ctrlKey&&!e.button}function hu(){return this.parentNode}function mu(e,t){return t??{x:e.x,y:e.y}}function pu(){return navigator.maxTouchPoints||"ontouchstart"in this}function gu(){var e=fu,t=hu,n=mu,r=pu,s={},i=jn("start","drag","end"),o=0,a,l,c,u,d=0;function m(b){b.on("mousedown.drag",f).filter(r).on("touchstart.drag",v).on("touchmove.drag",x,du).on("touchend.drag touchcancel.drag",_).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function f(b,j){if(!(u||!e.call(this,b,j))){var C=M(this,t.call(this,b,j),b,j,"mouse");C&&(Ne(b.view).on("mousemove.drag",y,zt).on("mouseup.drag",p,zt),Mi(b.view),Hn(b),c=!1,a=b.clientX,l=b.clientY,C("start",b))}}function y(b){if(wt(b),!c){var j=b.clientX-a,C=b.clientY-l;c=j*j+C*C>d}s.mouse("drag",b)}function p(b){Ne(b.view).on("mousemove.drag mouseup.drag",null),Ai(b.view,c),wt(b),s.mouse("end",b)}function v(b,j){if(e.call(this,b,j)){var C=b.changedTouches,E=t.call(this,b,j),L=C.length,S,O;for(S=0;S>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?Jt(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?Jt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=xu.exec(e))?new ve(t[1],t[2],t[3],1):(t=wu.exec(e))?new ve(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=bu.exec(e))?Jt(t[1],t[2],t[3],t[4]):(t=vu.exec(e))?Jt(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=_u.exec(e))?ns(t[1],t[2]/100,t[3]/100,1):(t=Eu.exec(e))?ns(t[1],t[2]/100,t[3]/100,t[4]):Kr.hasOwnProperty(e)?Jr(Kr[e]):e==="transparent"?new ve(NaN,NaN,NaN,0):null}function Jr(e){return new ve(e>>16&255,e>>8&255,e&255,1)}function Jt(e,t,n,r){return r<=0&&(e=t=n=NaN),new ve(e,t,n,r)}function ku(e){return e instanceof Xt||(e=Vt(e)),e?(e=e.rgb(),new ve(e.r,e.g,e.b,e.opacity)):new ve}function sr(e,t,n,r){return arguments.length===1?ku(e):new ve(e,t,n,r??1)}function ve(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}vr(ve,sr,Ii(Xt,{brighter(e){return e=e==null?mn:Math.pow(mn,e),new ve(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Ht:Math.pow(Ht,e),new ve(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new ve(at(this.r),at(this.g),at(this.b),pn(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:es,formatHex:es,formatHex8:ju,formatRgb:ts,toString:ts}));function es(){return`#${it(this.r)}${it(this.g)}${it(this.b)}`}function ju(){return`#${it(this.r)}${it(this.g)}${it(this.b)}${it((isNaN(this.opacity)?1:this.opacity)*255)}`}function ts(){const e=pn(this.opacity);return`${e===1?"rgb(":"rgba("}${at(this.r)}, ${at(this.g)}, ${at(this.b)}${e===1?")":`, ${e})`}`}function pn(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function at(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function it(e){return e=at(e),(e<16?"0":"")+e.toString(16)}function ns(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Me(e,t,n,r)}function Ri(e){if(e instanceof Me)return new Me(e.h,e.s,e.l,e.opacity);if(e instanceof Xt||(e=Vt(e)),!e)return new Me;if(e instanceof Me)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,s=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,a=i-s,l=(i+s)/2;return a?(t===i?o=(n-r)/a+(n0&&l<1?0:o,new Me(o,a,l,e.opacity)}function Cu(e,t,n,r){return arguments.length===1?Ri(e):new Me(e,t,n,r??1)}function Me(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}vr(Me,Cu,Ii(Xt,{brighter(e){return e=e==null?mn:Math.pow(mn,e),new Me(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Ht:Math.pow(Ht,e),new Me(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,s=2*n-r;return new ve(Fn(e>=240?e-240:e+120,s,r),Fn(e,s,r),Fn(e<120?e+240:e-120,s,r),this.opacity)},clamp(){return new Me(rs(this.h),en(this.s),en(this.l),pn(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=pn(this.opacity);return`${e===1?"hsl(":"hsla("}${rs(this.h)}, ${en(this.s)*100}%, ${en(this.l)*100}%${e===1?")":`, ${e})`}`}}));function rs(e){return e=(e||0)%360,e<0?e+360:e}function en(e){return Math.max(0,Math.min(1,e||0))}function Fn(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const Ti=e=>()=>e;function $u(e,t){return function(n){return e+n*t}}function Mu(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function Au(e){return(e=+e)==1?Oi:function(t,n){return n-t?Mu(t,n,e):Ti(isNaN(t)?n:t)}}function Oi(e,t){var n=t-e;return n?$u(e,n):Ti(isNaN(e)?t:e)}const ss=function e(t){var n=Au(t);function r(s,i){var o=n((s=sr(s)).r,(i=sr(i)).r),a=n(s.g,i.g),l=n(s.b,i.b),c=Oi(s.opacity,i.opacity);return function(u){return s.r=o(u),s.g=a(u),s.b=l(u),s.opacity=c(u),s+""}}return r.gamma=e,r}(1);function We(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var ir=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Vn=new RegExp(ir.source,"g");function Iu(e){return function(){return e}}function Ru(e){return function(t){return e(t)+""}}function Tu(e,t){var n=ir.lastIndex=Vn.lastIndex=0,r,s,i,o=-1,a=[],l=[];for(e=e+"",t=t+"";(r=ir.exec(e))&&(s=Vn.exec(t));)(i=s.index)>n&&(i=t.slice(n,i),a[o]?a[o]+=i:a[++o]=i),(r=r[0])===(s=s[0])?a[o]?a[o]+=s:a[++o]=s:(a[++o]=null,l.push({i:o,x:We(r,s)})),n=Vn.lastIndex;return n180?u+=360:u-c>180&&(c+=360),m.push({i:d.push(s(d)+"rotate(",null,r)-2,x:We(c,u)})):u&&d.push(s(d)+"rotate("+u+r)}function a(c,u,d,m){c!==u?m.push({i:d.push(s(d)+"skewX(",null,r)-2,x:We(c,u)}):u&&d.push(s(d)+"skewX("+u+r)}function l(c,u,d,m,f,y){if(c!==d||u!==m){var p=f.push(s(f)+"scale(",null,",",null,")");y.push({i:p-4,x:We(c,d)},{i:p-2,x:We(u,m)})}else(d!==1||m!==1)&&f.push(s(f)+"scale("+d+","+m+")")}return function(c,u){var d=[],m=[];return c=e(c),u=e(u),i(c.translateX,c.translateY,u.translateX,u.translateY,d,m),o(c.rotate,u.rotate,d,m),a(c.skewX,u.skewX,d,m),l(c.scaleX,c.scaleY,u.scaleX,u.scaleY,d,m),c=u=null,function(f){for(var y=-1,p=m.length,v;++y=0&&e._call.call(void 0,t),e=e._next;--St}function as(){ct=(yn=Bt.now())+$n,St=Ot=0;try{Gu()}finally{St=0,Wu(),ct=0}}function Yu(){var e=Bt.now(),t=e-yn;t>Pi&&($n-=t,yn=e)}function Wu(){for(var e,t=gn,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:gn=n);Dt=e,ar(r)}function ar(e){if(!St){Ot&&(Ot=clearTimeout(Ot));var t=e-ct;t>24?(e<1/0&&(Ot=setTimeout(as,e-Bt.now()-$n)),Mt&&(Mt=clearInterval(Mt))):(Mt||(yn=Bt.now(),Mt=setInterval(Yu,Pi)),St=1,zi(as))}}function ls(e,t,n){var r=new xn;return t=t==null?0:+t,r.restart(s=>{r.stop(),e(s+t)},t,n),r}var Uu=jn("start","end","cancel","interrupt"),Xu=[],Fi=0,cs=1,lr=2,un=3,us=4,cr=5,dn=6;function Mn(e,t,n,r,s,i){var o=e.__transition;if(!o)e.__transition={};else if(n in o)return;qu(e,n,{name:t,index:r,group:s,on:Uu,tween:Xu,time:i.time,delay:i.delay,duration:i.duration,ease:i.ease,timer:null,state:Fi})}function Er(e,t){var n=Ae(e,t);if(n.state>Fi)throw new Error("too late; already scheduled");return n}function Oe(e,t){var n=Ae(e,t);if(n.state>un)throw new Error("too late; already running");return n}function Ae(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function qu(e,t,n){var r=e.__transition,s;r[t]=n,n.timer=Hi(i,0,n.time);function i(c){n.state=cs,n.timer.restart(o,n.delay,n.time),n.delay<=c&&o(c-n.delay)}function o(c){var u,d,m,f;if(n.state!==cs)return l();for(u in r)if(f=r[u],f.name===n.name){if(f.state===un)return ls(o);f.state===us?(f.state=dn,f.timer.stop(),f.on.call("interrupt",e,e.__data__,f.index,f.group),delete r[u]):+ulr&&r.state=0&&(t=t.slice(0,n)),!t||t==="start"})}function Sd(e,t,n){var r,s,i=Nd(t)?Er:Oe;return function(){var o=i(this,e),a=o.on;a!==r&&(s=(r=a).copy()).on(t,n),o.on=s}}function kd(e,t){var n=this._id;return arguments.length<2?Ae(this.node(),n).on.on(e):this.each(Sd(n,e,t))}function jd(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function Cd(){return this.on("end.remove",jd(this._id))}function $d(e){var t=this._name,n=this._id;typeof e!="function"&&(e=wr(e));for(var r=this._groups,s=r.length,i=new Array(s),o=0;o()=>e;function ef(e,{sourceEvent:t,target:n,transform:r,dispatch:s}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:s}})}function He(e,t,n){this.k=e,this.x=t,this.y=n}He.prototype={constructor:He,scale:function(e){return e===1?this:new He(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new He(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Fe=new He(1,0,0);He.prototype;function Bn(e){e.stopImmediatePropagation()}function At(e){e.preventDefault(),e.stopImmediatePropagation()}function tf(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function nf(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function ds(){return this.__zoom||Fe}function rf(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function sf(){return navigator.maxTouchPoints||"ontouchstart"in this}function of(e,t,n){var r=e.invertX(t[0][0])-n[0][0],s=e.invertX(t[1][0])-n[1][0],i=e.invertY(t[0][1])-n[0][1],o=e.invertY(t[1][1])-n[1][1];return e.translate(s>r?(r+s)/2:Math.min(0,r)||Math.max(0,s),o>i?(i+o)/2:Math.min(0,i)||Math.max(0,o))}function Yi(){var e=tf,t=nf,n=of,r=rf,s=sf,i=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],a=250,l=Vu,c=jn("start","zoom","end"),u,d,m,f=500,y=150,p=0,v=10;function x(g){g.property("__zoom",ds).on("wheel.zoom",L,{passive:!1}).on("mousedown.zoom",S).on("dblclick.zoom",O).filter(s).on("touchstart.zoom",P).on("touchmove.zoom",V).on("touchend.zoom touchcancel.zoom",F).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}x.transform=function(g,$,N,I){var H=g.selection?g.selection():g;H.property("__zoom",ds),g!==H?j(g,$,N,I):H.interrupt().each(function(){C(this,arguments).event(I).start().zoom(null,typeof $=="function"?$.apply(this,arguments):$).end()})},x.scaleBy=function(g,$,N,I){x.scaleTo(g,function(){var H=this.__zoom.k,k=typeof $=="function"?$.apply(this,arguments):$;return H*k},N,I)},x.scaleTo=function(g,$,N,I){x.transform(g,function(){var H=t.apply(this,arguments),k=this.__zoom,R=N==null?b(H):typeof N=="function"?N.apply(this,arguments):N,D=k.invert(R),z=typeof $=="function"?$.apply(this,arguments):$;return n(M(_(k,z),R,D),H,o)},N,I)},x.translateBy=function(g,$,N,I){x.transform(g,function(){return n(this.__zoom.translate(typeof $=="function"?$.apply(this,arguments):$,typeof N=="function"?N.apply(this,arguments):N),t.apply(this,arguments),o)},null,I)},x.translateTo=function(g,$,N,I,H){x.transform(g,function(){var k=t.apply(this,arguments),R=this.__zoom,D=I==null?b(k):typeof I=="function"?I.apply(this,arguments):I;return n(Fe.translate(D[0],D[1]).scale(R.k).translate(typeof $=="function"?-$.apply(this,arguments):-$,typeof N=="function"?-N.apply(this,arguments):-N),k,o)},I,H)};function _(g,$){return $=Math.max(i[0],Math.min(i[1],$)),$===g.k?g:new He($,g.x,g.y)}function M(g,$,N){var I=$[0]-N[0]*g.k,H=$[1]-N[1]*g.k;return I===g.x&&H===g.y?g:new He(g.k,I,H)}function b(g){return[(+g[0][0]+ +g[1][0])/2,(+g[0][1]+ +g[1][1])/2]}function j(g,$,N,I){g.on("start.zoom",function(){C(this,arguments).event(I).start()}).on("interrupt.zoom end.zoom",function(){C(this,arguments).event(I).end()}).tween("zoom",function(){var H=this,k=arguments,R=C(H,k).event(I),D=t.apply(H,k),z=N==null?b(D):typeof N=="function"?N.apply(H,k):N,Y=Math.max(D[1][0]-D[0][0],D[1][1]-D[0][1]),G=H.__zoom,K=typeof $=="function"?$.apply(H,k):$,J=l(G.invert(z).concat(Y/G.k),K.invert(z).concat(Y/K.k));return function(ee){if(ee===1)ee=K;else{var ie=J(ee),te=Y/ie[2];ee=new He(te,z[0]-ie[0]*te,z[1]-ie[1]*te)}R.zoom(null,ee)}})}function C(g,$,N){return!N&&g.__zooming||new E(g,$)}function E(g,$){this.that=g,this.args=$,this.active=0,this.sourceEvent=null,this.extent=t.apply(g,$),this.taps=0}E.prototype={event:function(g){return g&&(this.sourceEvent=g),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(g,$){return this.mouse&&g!=="mouse"&&(this.mouse[1]=$.invert(this.mouse[0])),this.touch0&&g!=="touch"&&(this.touch0[1]=$.invert(this.touch0[0])),this.touch1&&g!=="touch"&&(this.touch1[1]=$.invert(this.touch1[0])),this.that.__zoom=$,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(g){var $=Ne(this.that).datum();c.call(g,this.that,new ef(g,{sourceEvent:this.sourceEvent,target:x,transform:this.that.__zoom,dispatch:c}),$)}};function L(g,...$){if(!e.apply(this,arguments))return;var N=C(this,$).event(g),I=this.__zoom,H=Math.max(i[0],Math.min(i[1],I.k*Math.pow(2,r.apply(this,arguments)))),k=$e(g);if(N.wheel)(N.mouse[0][0]!==k[0]||N.mouse[0][1]!==k[1])&&(N.mouse[1]=I.invert(N.mouse[0]=k)),clearTimeout(N.wheel);else{if(I.k===H)return;N.mouse=[k,I.invert(k)],fn(this),N.start()}At(g),N.wheel=setTimeout(R,y),N.zoom("mouse",n(M(_(I,H),N.mouse[0],N.mouse[1]),N.extent,o));function R(){N.wheel=null,N.end()}}function S(g,...$){if(m||!e.apply(this,arguments))return;var N=g.currentTarget,I=C(this,$,!0).event(g),H=Ne(g.view).on("mousemove.zoom",z,!0).on("mouseup.zoom",Y,!0),k=$e(g,N),R=g.clientX,D=g.clientY;Mi(g.view),Bn(g),I.mouse=[k,this.__zoom.invert(k)],fn(this),I.start();function z(G){if(At(G),!I.moved){var K=G.clientX-R,J=G.clientY-D;I.moved=K*K+J*J>p}I.event(G).zoom("mouse",n(M(I.that.__zoom,I.mouse[0]=$e(G,N),I.mouse[1]),I.extent,o))}function Y(G){H.on("mousemove.zoom mouseup.zoom",null),Ai(G.view,I.moved),At(G),I.event(G).end()}}function O(g,...$){if(e.apply(this,arguments)){var N=this.__zoom,I=$e(g.changedTouches?g.changedTouches[0]:g,this),H=N.invert(I),k=N.k*(g.shiftKey?.5:2),R=n(M(_(N,k),I,H),t.apply(this,$),o);At(g),a>0?Ne(this).transition().duration(a).call(j,R,I,g):Ne(this).call(x.transform,R,I,g)}}function P(g,...$){if(e.apply(this,arguments)){var N=g.touches,I=N.length,H=C(this,$,g.changedTouches.length===I).event(g),k,R,D,z;for(Bn(g),R=0;R"[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001",error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>"The React Flow parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,t)=>`Couldn't create edge for ${e?"target":"source"} handle id: "${e?t.targetHandle:t.sourceHandle}", edge id: ${t.id}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`},Wi=Be.error001();function ae(e,t){const n=w.useContext(An);if(n===null)throw new Error(Wi);return yi(n,e,t)}const pe=()=>{const e=w.useContext(An);if(e===null)throw new Error(Wi);return w.useMemo(()=>({getState:e.getState,setState:e.setState,subscribe:e.subscribe,destroy:e.destroy}),[e])},lf=e=>e.userSelectionActive?"none":"all";function Sr({position:e,children:t,className:n,style:r,...s}){const i=ae(lf),o=`${e}`.split("-");return A.createElement("div",{className:ye(["react-flow__panel",n,...o]),style:{...r,pointerEvents:i},...s},t)}function cf({proOptions:e,position:t="bottom-right"}){return e!=null&&e.hideAttribution?null:A.createElement(Sr,{position:t,className:"react-flow__attribution","data-message":"Please only hide this attribution when you are subscribed to React Flow Pro: https://reactflow.dev/pro"},A.createElement("a",{href:"https://reactflow.dev",target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution"},"React Flow"))}const uf=({x:e,y:t,label:n,labelStyle:r={},labelShowBg:s=!0,labelBgStyle:i={},labelBgPadding:o=[2,4],labelBgBorderRadius:a=2,children:l,className:c,...u})=>{const d=w.useRef(null),[m,f]=w.useState({x:0,y:0,width:0,height:0}),y=ye(["react-flow__edge-textwrapper",c]);return w.useEffect(()=>{if(d.current){const p=d.current.getBBox();f({x:p.x,y:p.y,width:p.width,height:p.height})}},[n]),typeof n>"u"||!n?null:A.createElement("g",{transform:`translate(${e-m.width/2} ${t-m.height/2})`,className:y,visibility:m.width?"visible":"hidden",...u},s&&A.createElement("rect",{width:m.width+2*o[0],x:-o[0],y:-o[1],height:m.height+2*o[1],className:"react-flow__edge-textbg",style:i,rx:a,ry:a}),A.createElement("text",{className:"react-flow__edge-text",y:m.height/2,dy:"0.3em",ref:d,style:r},n),l)};var df=w.memo(uf);const kr=e=>({width:e.offsetWidth,height:e.offsetHeight}),kt=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),jr=(e={x:0,y:0},t)=>({x:kt(e.x,t[0][0],t[1][0]),y:kt(e.y,t[0][1],t[1][1])}),fs=(e,t,n)=>en?-kt(Math.abs(e-n),1,50)/50:0,Ui=(e,t)=>{const n=fs(e.x,35,t.width-35)*20,r=fs(e.y,35,t.height-35)*20;return[n,r]},Xi=e=>{var t;return((t=e.getRootNode)==null?void 0:t.call(e))||(window==null?void 0:window.document)},qi=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),Gt=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),Ki=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),hs=e=>({...e.positionAbsolute||{x:0,y:0},width:e.width||0,height:e.height||0}),ff=(e,t)=>Ki(qi(Gt(e),Gt(t))),ur=(e,t)=>{const n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},hf=e=>Se(e.width)&&Se(e.height)&&Se(e.x)&&Se(e.y),Se=e=>!isNaN(e)&&isFinite(e),le=Symbol.for("internals"),Zi=["Enter"," ","Escape"],mf=(e,t)=>{},pf=e=>"nativeEvent"in e;function dr(e){var s,i;const t=pf(e)?e.nativeEvent:e,n=((i=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:i[0])||e.target;return["INPUT","SELECT","TEXTAREA"].includes(n==null?void 0:n.nodeName)||(n==null?void 0:n.hasAttribute("contenteditable"))||!!(n!=null&&n.closest(".nokey"))}const Qi=e=>"clientX"in e,Ke=(e,t)=>{var i,o;const n=Qi(e),r=n?e.clientX:(i=e.touches)==null?void 0:i[0].clientX,s=n?e.clientY:(o=e.touches)==null?void 0:o[0].clientY;return{x:r-((t==null?void 0:t.left)??0),y:s-((t==null?void 0:t.top)??0)}},wn=()=>{var e;return typeof navigator<"u"&&((e=navigator==null?void 0:navigator.userAgent)==null?void 0:e.indexOf("Mac"))>=0},qt=({id:e,path:t,labelX:n,labelY:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:f=20})=>A.createElement(A.Fragment,null,A.createElement("path",{id:e,style:u,d:t,fill:"none",className:"react-flow__edge-path",markerEnd:d,markerStart:m}),f&&A.createElement("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:f,className:"react-flow__edge-interaction"}),s&&Se(n)&&Se(r)?A.createElement(df,{x:n,y:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c}):null);qt.displayName="BaseEdge";function It(e,t,n){return n===void 0?n:r=>{const s=t().edges.find(i=>i.id===e);s&&n(r,{...s})}}function Ji({sourceX:e,sourceY:t,targetX:n,targetY:r}){const s=Math.abs(n-e)/2,i=n{const[v,x,_]=to({sourceX:e,sourceY:t,sourcePosition:s,targetX:n,targetY:r,targetPosition:i});return A.createElement(qt,{path:v,labelX:x,labelY:_,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:f,markerStart:y,interactionWidth:p})});Cr.displayName="SimpleBezierEdge";const ps={[Z.Left]:{x:-1,y:0},[Z.Right]:{x:1,y:0},[Z.Top]:{x:0,y:-1},[Z.Bottom]:{x:0,y:1}},gf=({source:e,sourcePosition:t=Z.Bottom,target:n})=>t===Z.Left||t===Z.Right?e.xMath.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));function yf({source:e,sourcePosition:t=Z.Bottom,target:n,targetPosition:r=Z.Top,center:s,offset:i}){const o=ps[t],a=ps[r],l={x:e.x+o.x*i,y:e.y+o.y*i},c={x:n.x+a.x*i,y:n.y+a.y*i},u=gf({source:l,sourcePosition:t,target:c}),d=u.x!==0?"x":"y",m=u[d];let f=[],y,p;const v={x:0,y:0},x={x:0,y:0},[_,M,b,j]=Ji({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(o[d]*a[d]===-1){y=s.x??_,p=s.y??M;const E=[{x:y,y:l.y},{x:y,y:c.y}],L=[{x:l.x,y:p},{x:c.x,y:p}];o[d]===m?f=d==="x"?E:L:f=d==="x"?L:E}else{const E=[{x:l.x,y:c.y}],L=[{x:c.x,y:l.y}];if(d==="x"?f=o.x===m?L:E:f=o.y===m?E:L,t===r){const F=Math.abs(e[d]-n[d]);if(F<=i){const g=Math.min(i-1,i-F);o[d]===m?v[d]=(l[d]>e[d]?-1:1)*g:x[d]=(c[d]>n[d]?-1:1)*g}}if(t!==r){const F=d==="x"?"y":"x",g=o[d]===a[F],$=l[F]>c[F],N=l[F]=V?(y=(S.x+O.x)/2,p=f[0].y):(y=f[0].x,p=(S.y+O.y)/2)}return[[e,{x:l.x+v.x,y:l.y+v.y},...f,{x:c.x+x.x,y:c.y+x.y},n],y,p,b,j]}function xf(e,t,n,r){const s=Math.min(gs(e,t)/2,gs(t,n)/2,r),{x:i,y:o}=t;if(e.x===i&&i===n.x||e.y===o&&o===n.y)return`L${i} ${o}`;if(e.y===o){const c=e.x{let M="";return _>0&&_{const[x,_,M]=vn({sourceX:e,sourceY:t,sourcePosition:d,targetX:n,targetY:r,targetPosition:m,borderRadius:p==null?void 0:p.borderRadius,offset:p==null?void 0:p.offset});return A.createElement(qt,{path:x,labelX:_,labelY:M,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:f,markerStart:y,interactionWidth:v})});In.displayName="SmoothStepEdge";const $r=w.memo(e=>{var t;return A.createElement(In,{...e,pathOptions:w.useMemo(()=>{var n;return{borderRadius:0,offset:(n=e.pathOptions)==null?void 0:n.offset}},[(t=e.pathOptions)==null?void 0:t.offset])})});$r.displayName="StepEdge";function wf({sourceX:e,sourceY:t,targetX:n,targetY:r}){const[s,i,o,a]=Ji({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,s,i,o,a]}const Mr=w.memo(({sourceX:e,sourceY:t,targetX:n,targetY:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:f})=>{const[y,p,v]=wf({sourceX:e,sourceY:t,targetX:n,targetY:r});return A.createElement(qt,{path:y,labelX:p,labelY:v,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:f})});Mr.displayName="StraightEdge";function rn(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function ys({pos:e,x1:t,y1:n,x2:r,y2:s,c:i}){switch(e){case Z.Left:return[t-rn(t-r,i),n];case Z.Right:return[t+rn(r-t,i),n];case Z.Top:return[t,n-rn(n-s,i)];case Z.Bottom:return[t,n+rn(s-n,i)]}}function no({sourceX:e,sourceY:t,sourcePosition:n=Z.Bottom,targetX:r,targetY:s,targetPosition:i=Z.Top,curvature:o=.25}){const[a,l]=ys({pos:n,x1:e,y1:t,x2:r,y2:s,c:o}),[c,u]=ys({pos:i,x1:r,y1:s,x2:e,y2:t,c:o}),[d,m,f,y]=eo({sourceX:e,sourceY:t,targetX:r,targetY:s,sourceControlX:a,sourceControlY:l,targetControlX:c,targetControlY:u});return[`M${e},${t} C${a},${l} ${c},${u} ${r},${s}`,d,m,f,y]}const _n=w.memo(({sourceX:e,sourceY:t,targetX:n,targetY:r,sourcePosition:s=Z.Bottom,targetPosition:i=Z.Top,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:f,markerStart:y,pathOptions:p,interactionWidth:v})=>{const[x,_,M]=no({sourceX:e,sourceY:t,sourcePosition:s,targetX:n,targetY:r,targetPosition:i,curvature:p==null?void 0:p.curvature});return A.createElement(qt,{path:x,labelX:_,labelY:M,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:f,markerStart:y,interactionWidth:v})});_n.displayName="BezierEdge";const Ar=w.createContext(null),bf=Ar.Provider;Ar.Consumer;const vf=()=>w.useContext(Ar),_f=e=>"id"in e&&"source"in e&&"target"in e,Ef=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`reactflow__edge-${e}${t||""}-${n}${r||""}`,fr=(e,t)=>typeof e>"u"?"":typeof e=="string"?e:`${t?`${t}__`:""}${Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("&")}`,Nf=(e,t)=>t.some(n=>n.source===e.source&&n.target===e.target&&(n.sourceHandle===e.sourceHandle||!n.sourceHandle&&!e.sourceHandle)&&(n.targetHandle===e.targetHandle||!n.targetHandle&&!e.targetHandle)),Sf=(e,t)=>{if(!e.source||!e.target)return t;let n;return _f(e)?n={...e}:n={...e,id:Ef(e)},Nf(n,t)?t:t.concat(n)},hr=({x:e,y:t},[n,r,s],i,[o,a])=>{const l={x:(e-n)/s,y:(t-r)/s};return i?{x:o*Math.round(l.x/o),y:a*Math.round(l.y/a)}:l},ro=({x:e,y:t},[n,r,s])=>({x:e*s+n,y:t*s+r}),lt=(e,t=[0,0])=>{if(!e)return{x:0,y:0,positionAbsolute:{x:0,y:0}};const n=(e.width??0)*t[0],r=(e.height??0)*t[1],s={x:e.position.x-n,y:e.position.y-r};return{...s,positionAbsolute:e.positionAbsolute?{x:e.positionAbsolute.x-n,y:e.positionAbsolute.y-r}:s}},Kt=(e,t=[0,0])=>{if(e.length===0)return{x:0,y:0,width:0,height:0};const n=e.reduce((r,s)=>{const{x:i,y:o}=lt(s,t).positionAbsolute;return qi(r,Gt({x:i,y:o,width:s.width||0,height:s.height||0}))},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return Ki(n)},kf=(e,t=[0,0])=>(console.warn("[DEPRECATED] `getRectOfNodes` is deprecated. Instead use `getNodesBounds` https://reactflow.dev/api-reference/utils/get-nodes-bounds."),Kt(e,t)),so=(e,t,[n,r,s]=[0,0,1],i=!1,o=!1,a=[0,0])=>{const l={x:(t.x-n)/s,y:(t.y-r)/s,width:t.width/s,height:t.height/s},c=[];return e.forEach(u=>{const{width:d,height:m,selectable:f=!0,hidden:y=!1}=u;if(o&&!f||y)return!1;const{positionAbsolute:p}=lt(u,a),v={x:p.x,y:p.y,width:d||0,height:m||0},x=ur(l,v),_=typeof d>"u"||typeof m>"u"||d===null||m===null,M=i&&x>0,b=(d||0)*(m||0);(_||M||x>=b||u.dragging)&&c.push(u)}),c},io=(e,t)=>{const n=e.map(r=>r.id);return t.filter(r=>n.includes(r.source)||n.includes(r.target))},oo=(e,t,n,r,s,i=.1)=>{const o=t/(e.width*(1+i)),a=n/(e.height*(1+i)),l=Math.min(o,a),c=kt(l,r,s),u=e.x+e.width/2,d=e.y+e.height/2,m=t/2-u*c,f=n/2-d*c;return{x:m,y:f,zoom:c}},st=(e,t=0)=>e.transition().duration(t);function xs(e,t,n,r){return(t[n]||[]).reduce((s,i)=>{var o,a;return`${e.id}-${i.id}-${n}`!==r&&s.push({id:i.id||null,type:n,nodeId:e.id,x:(((o=e.positionAbsolute)==null?void 0:o.x)??0)+i.x+i.width/2,y:(((a=e.positionAbsolute)==null?void 0:a.y)??0)+i.y+i.height/2}),s},[])}function jf(e,t,n,r,s,i){const{x:o,y:a}=Ke(e),c=t.elementsFromPoint(o,a).find(y=>y.classList.contains("react-flow__handle"));if(c){const y=c.getAttribute("data-nodeid");if(y){const p=Ir(void 0,c),v=c.getAttribute("data-handleid"),x=i({nodeId:y,id:v,type:p});if(x){const _=s.find(M=>M.nodeId===y&&M.type===p&&M.id===v);return{handle:{id:v,type:p,nodeId:y,x:(_==null?void 0:_.x)||n.x,y:(_==null?void 0:_.y)||n.y},validHandleResult:x}}}}let u=[],d=1/0;if(s.forEach(y=>{const p=Math.sqrt((y.x-n.x)**2+(y.y-n.y)**2);if(p<=r){const v=i(y);p<=d&&(py.isValid),f=u.some(({handle:y})=>y.type==="target");return u.find(({handle:y,validHandleResult:p})=>f?y.type==="target":m?p.isValid:!0)||u[0]}const Cf={source:null,target:null,sourceHandle:null,targetHandle:null},ao=()=>({handleDomNode:null,isValid:!1,connection:Cf,endHandle:null});function lo(e,t,n,r,s,i,o){const a=s==="target",l=o.querySelector(`.react-flow__handle[data-id="${e==null?void 0:e.nodeId}-${e==null?void 0:e.id}-${e==null?void 0:e.type}"]`),c={...ao(),handleDomNode:l};if(l){const u=Ir(void 0,l),d=l.getAttribute("data-nodeid"),m=l.getAttribute("data-handleid"),f=l.classList.contains("connectable"),y=l.classList.contains("connectableend"),p={source:a?d:n,sourceHandle:a?m:r,target:a?n:d,targetHandle:a?r:m};c.connection=p,f&&y&&(t===ut.Strict?a&&u==="source"||!a&&u==="target":d!==n||m!==r)&&(c.endHandle={nodeId:d,handleId:m,type:u},c.isValid=i(p))}return c}function $f({nodes:e,nodeId:t,handleId:n,handleType:r}){return e.reduce((s,i)=>{if(i[le]){const{handleBounds:o}=i[le];let a=[],l=[];o&&(a=xs(i,o,"source",`${t}-${n}-${r}`),l=xs(i,o,"target",`${t}-${n}-${r}`)),s.push(...a,...l)}return s},[])}function Ir(e,t){return e||(t!=null&&t.classList.contains("target")?"target":t!=null&&t.classList.contains("source")?"source":null)}function Gn(e){e==null||e.classList.remove("valid","connecting","react-flow__handle-valid","react-flow__handle-connecting")}function Mf(e,t){let n=null;return t?n="valid":e&&!t&&(n="invalid"),n}function co({event:e,handleId:t,nodeId:n,onConnect:r,isTarget:s,getState:i,setState:o,isValidConnection:a,edgeUpdaterType:l,onReconnectEnd:c}){const u=Xi(e.target),{connectionMode:d,domNode:m,autoPanOnConnect:f,connectionRadius:y,onConnectStart:p,panBy:v,getNodes:x,cancelConnection:_}=i();let M=0,b;const{x:j,y:C}=Ke(e),E=u==null?void 0:u.elementFromPoint(j,C),L=Ir(l,E),S=m==null?void 0:m.getBoundingClientRect();if(!S||!L)return;let O,P=Ke(e,S),V=!1,F=null,g=!1,$=null;const N=$f({nodes:x(),nodeId:n,handleId:t,handleType:L}),I=()=>{if(!f)return;const[R,D]=Ui(P,S);v({x:R,y:D}),M=requestAnimationFrame(I)};o({connectionPosition:P,connectionStatus:null,connectionNodeId:n,connectionHandleId:t,connectionHandleType:L,connectionStartHandle:{nodeId:n,handleId:t,type:L},connectionEndHandle:null}),p==null||p(e,{nodeId:n,handleId:t,handleType:L});function H(R){const{transform:D}=i();P=Ke(R,S);const{handle:z,validHandleResult:Y}=jf(R,u,hr(P,D,!1,[1,1]),y,N,G=>lo(G,d,n,t,s?"target":"source",a,u));if(b=z,V||(I(),V=!0),$=Y.handleDomNode,F=Y.connection,g=Y.isValid,o({connectionPosition:b&&g?ro({x:b.x,y:b.y},D):P,connectionStatus:Mf(!!b,g),connectionEndHandle:Y.endHandle}),!b&&!g&&!$)return Gn(O);F.source!==F.target&&$&&(Gn(O),O=$,$.classList.add("connecting","react-flow__handle-connecting"),$.classList.toggle("valid",g),$.classList.toggle("react-flow__handle-valid",g))}function k(R){var D,z;(b||$)&&F&&g&&(r==null||r(F)),(z=(D=i()).onConnectEnd)==null||z.call(D,R),l&&(c==null||c(R)),Gn(O),_(),cancelAnimationFrame(M),V=!1,g=!1,F=null,$=null,u.removeEventListener("mousemove",H),u.removeEventListener("mouseup",k),u.removeEventListener("touchmove",H),u.removeEventListener("touchend",k)}u.addEventListener("mousemove",H),u.addEventListener("mouseup",k),u.addEventListener("touchmove",H),u.addEventListener("touchend",k)}const ws=()=>!0,Af=e=>({connectionStartHandle:e.connectionStartHandle,connectOnClick:e.connectOnClick,noPanClassName:e.noPanClassName}),If=(e,t,n)=>r=>{const{connectionStartHandle:s,connectionEndHandle:i,connectionClickStartHandle:o}=r;return{connecting:(s==null?void 0:s.nodeId)===e&&(s==null?void 0:s.handleId)===t&&(s==null?void 0:s.type)===n||(i==null?void 0:i.nodeId)===e&&(i==null?void 0:i.handleId)===t&&(i==null?void 0:i.type)===n,clickConnecting:(o==null?void 0:o.nodeId)===e&&(o==null?void 0:o.handleId)===t&&(o==null?void 0:o.type)===n}},uo=w.forwardRef(({type:e="source",position:t=Z.Top,isValidConnection:n,isConnectable:r=!0,isConnectableStart:s=!0,isConnectableEnd:i=!0,id:o,onConnect:a,children:l,className:c,onMouseDown:u,onTouchStart:d,...m},f)=>{var S,O;const y=o||null,p=e==="target",v=pe(),x=vf(),{connectOnClick:_,noPanClassName:M}=ae(Af,ge),{connecting:b,clickConnecting:j}=ae(If(x,y,e),ge);x||(O=(S=v.getState()).onError)==null||O.call(S,"010",Be.error010());const C=P=>{const{defaultEdgeOptions:V,onConnect:F,hasDefaultEdges:g}=v.getState(),$={...V,...P};if(g){const{edges:N,setEdges:I}=v.getState();I(Sf($,N))}F==null||F($),a==null||a($)},E=P=>{if(!x)return;const V=Qi(P);s&&(V&&P.button===0||!V)&&co({event:P,handleId:y,nodeId:x,onConnect:C,isTarget:p,getState:v.getState,setState:v.setState,isValidConnection:n||v.getState().isValidConnection||ws}),V?u==null||u(P):d==null||d(P)},L=P=>{const{onClickConnectStart:V,onClickConnectEnd:F,connectionClickStartHandle:g,connectionMode:$,isValidConnection:N}=v.getState();if(!x||!g&&!s)return;if(!g){V==null||V(P,{nodeId:x,handleId:y,handleType:e}),v.setState({connectionClickStartHandle:{nodeId:x,type:e,handleId:y}});return}const I=Xi(P.target),H=n||N||ws,{connection:k,isValid:R}=lo({nodeId:x,id:y,type:e},$,g.nodeId,g.handleId||null,g.type,H,I);R&&C(k),F==null||F(P),v.setState({connectionClickStartHandle:null})};return A.createElement("div",{"data-handleid":y,"data-nodeid":x,"data-handlepos":t,"data-id":`${x}-${y}-${e}`,className:ye(["react-flow__handle",`react-flow__handle-${t}`,"nodrag",M,c,{source:!p,target:p,connectable:r,connectablestart:s,connectableend:i,connecting:j,connectionindicator:r&&(s&&!b||i&&b)}]),onMouseDown:E,onTouchStart:E,onClick:_?L:void 0,ref:f,...m},l)});uo.displayName="Handle";var qe=w.memo(uo);const fo=({data:e,isConnectable:t,targetPosition:n=Z.Top,sourcePosition:r=Z.Bottom})=>A.createElement(A.Fragment,null,A.createElement(qe,{type:"target",position:n,isConnectable:t}),e==null?void 0:e.label,A.createElement(qe,{type:"source",position:r,isConnectable:t}));fo.displayName="DefaultNode";var mr=w.memo(fo);const ho=({data:e,isConnectable:t,sourcePosition:n=Z.Bottom})=>A.createElement(A.Fragment,null,e==null?void 0:e.label,A.createElement(qe,{type:"source",position:n,isConnectable:t}));ho.displayName="InputNode";var mo=w.memo(ho);const po=({data:e,isConnectable:t,targetPosition:n=Z.Top})=>A.createElement(A.Fragment,null,A.createElement(qe,{type:"target",position:n,isConnectable:t}),e==null?void 0:e.label);po.displayName="OutputNode";var go=w.memo(po);const Rr=()=>null;Rr.displayName="GroupNode";const Rf=e=>({selectedNodes:e.getNodes().filter(t=>t.selected),selectedEdges:e.edges.filter(t=>t.selected).map(t=>({...t}))}),sn=e=>e.id;function Tf(e,t){return ge(e.selectedNodes.map(sn),t.selectedNodes.map(sn))&&ge(e.selectedEdges.map(sn),t.selectedEdges.map(sn))}const yo=w.memo(({onSelectionChange:e})=>{const t=pe(),{selectedNodes:n,selectedEdges:r}=ae(Rf,Tf);return w.useEffect(()=>{const s={nodes:n,edges:r};e==null||e(s),t.getState().onSelectionChange.forEach(i=>i(s))},[n,r,e]),null});yo.displayName="SelectionListener";const Of=e=>!!e.onSelectionChange;function Df({onSelectionChange:e}){const t=ae(Of);return e||t?A.createElement(yo,{onSelectionChange:e}):null}const Lf=e=>({setNodes:e.setNodes,setEdges:e.setEdges,setDefaultNodesAndEdges:e.setDefaultNodesAndEdges,setMinZoom:e.setMinZoom,setMaxZoom:e.setMaxZoom,setTranslateExtent:e.setTranslateExtent,setNodeExtent:e.setNodeExtent,reset:e.reset});function mt(e,t){w.useEffect(()=>{typeof e<"u"&&t(e)},[e])}function ne(e,t,n){w.useEffect(()=>{typeof t<"u"&&n({[e]:t})},[t])}const Pf=({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,onConnect:s,onConnectStart:i,onConnectEnd:o,onClickConnectStart:a,onClickConnectEnd:l,nodesDraggable:c,nodesConnectable:u,nodesFocusable:d,edgesFocusable:m,edgesUpdatable:f,elevateNodesOnSelect:y,minZoom:p,maxZoom:v,nodeExtent:x,onNodesChange:_,onEdgesChange:M,elementsSelectable:b,connectionMode:j,snapGrid:C,snapToGrid:E,translateExtent:L,connectOnClick:S,defaultEdgeOptions:O,fitView:P,fitViewOptions:V,onNodesDelete:F,onEdgesDelete:g,onNodeDrag:$,onNodeDragStart:N,onNodeDragStop:I,onSelectionDrag:H,onSelectionDragStart:k,onSelectionDragStop:R,noPanClassName:D,nodeOrigin:z,rfId:Y,autoPanOnConnect:G,autoPanOnNodeDrag:K,onError:J,connectionRadius:ee,isValidConnection:ie,nodeDragThreshold:te})=>{const{setNodes:re,setEdges:de,setDefaultNodesAndEdges:B,setMinZoom:q,setMaxZoom:W,setTranslateExtent:Q,setNodeExtent:U,reset:X}=ae(Lf,ge),T=pe();return w.useEffect(()=>{const se=r==null?void 0:r.map(ce=>({...ce,...O}));return B(n,se),()=>{X()}},[]),ne("defaultEdgeOptions",O,T.setState),ne("connectionMode",j,T.setState),ne("onConnect",s,T.setState),ne("onConnectStart",i,T.setState),ne("onConnectEnd",o,T.setState),ne("onClickConnectStart",a,T.setState),ne("onClickConnectEnd",l,T.setState),ne("nodesDraggable",c,T.setState),ne("nodesConnectable",u,T.setState),ne("nodesFocusable",d,T.setState),ne("edgesFocusable",m,T.setState),ne("edgesUpdatable",f,T.setState),ne("elementsSelectable",b,T.setState),ne("elevateNodesOnSelect",y,T.setState),ne("snapToGrid",E,T.setState),ne("snapGrid",C,T.setState),ne("onNodesChange",_,T.setState),ne("onEdgesChange",M,T.setState),ne("connectOnClick",S,T.setState),ne("fitViewOnInit",P,T.setState),ne("fitViewOnInitOptions",V,T.setState),ne("onNodesDelete",F,T.setState),ne("onEdgesDelete",g,T.setState),ne("onNodeDrag",$,T.setState),ne("onNodeDragStart",N,T.setState),ne("onNodeDragStop",I,T.setState),ne("onSelectionDrag",H,T.setState),ne("onSelectionDragStart",k,T.setState),ne("onSelectionDragStop",R,T.setState),ne("noPanClassName",D,T.setState),ne("nodeOrigin",z,T.setState),ne("rfId",Y,T.setState),ne("autoPanOnConnect",G,T.setState),ne("autoPanOnNodeDrag",K,T.setState),ne("onError",J,T.setState),ne("connectionRadius",ee,T.setState),ne("isValidConnection",ie,T.setState),ne("nodeDragThreshold",te,T.setState),mt(e,re),mt(t,de),mt(p,q),mt(v,W),mt(L,Q),mt(x,U),null},bs={display:"none"},zf={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},xo="react-flow__node-desc",wo="react-flow__edge-desc",Hf="react-flow__aria-live",Ff=e=>e.ariaLiveMessage;function Vf({rfId:e}){const t=ae(Ff);return A.createElement("div",{id:`${Hf}-${e}`,"aria-live":"assertive","aria-atomic":"true",style:zf},t)}function Bf({rfId:e,disableKeyboardA11y:t}){return A.createElement(A.Fragment,null,A.createElement("div",{id:`${xo}-${e}`,style:bs},"Press enter or space to select a node.",!t&&"You can then use the arrow keys to move the node around."," Press delete to remove it and escape to cancel."," "),A.createElement("div",{id:`${wo}-${e}`,style:bs},"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel."),!t&&A.createElement(Vf,{rfId:e}))}var Wt=(e=null,t={actInsideInputWithModifier:!0})=>{const[n,r]=w.useState(!1),s=w.useRef(!1),i=w.useRef(new Set([])),[o,a]=w.useMemo(()=>{if(e!==null){const c=(Array.isArray(e)?e:[e]).filter(d=>typeof d=="string").map(d=>d.split("+")),u=c.reduce((d,m)=>d.concat(...m),[]);return[c,u]}return[[],[]]},[e]);return w.useEffect(()=>{const l=typeof document<"u"?document:null,c=(t==null?void 0:t.target)||l;if(e!==null){const u=f=>{if(s.current=f.ctrlKey||f.metaKey||f.shiftKey,(!s.current||s.current&&!t.actInsideInputWithModifier)&&dr(f))return!1;const p=_s(f.code,a);i.current.add(f[p]),vs(o,i.current,!1)&&(f.preventDefault(),r(!0))},d=f=>{if((!s.current||s.current&&!t.actInsideInputWithModifier)&&dr(f))return!1;const p=_s(f.code,a);vs(o,i.current,!0)?(r(!1),i.current.clear()):i.current.delete(f[p]),f.key==="Meta"&&i.current.clear(),s.current=!1},m=()=>{i.current.clear(),r(!1)};return c==null||c.addEventListener("keydown",u),c==null||c.addEventListener("keyup",d),window.addEventListener("blur",m),()=>{c==null||c.removeEventListener("keydown",u),c==null||c.removeEventListener("keyup",d),window.removeEventListener("blur",m)}}},[e,r]),n};function vs(e,t,n){return e.filter(r=>n||r.length===t.size).some(r=>r.every(s=>t.has(s)))}function _s(e,t){return t.includes(e)?"code":"key"}function bo(e,t,n,r){var a,l;const s=e.parentNode||e.parentId;if(!s)return n;const i=t.get(s),o=lt(i,r);return bo(i,t,{x:(n.x??0)+o.x,y:(n.y??0)+o.y,z:(((a=i[le])==null?void 0:a.z)??0)>(n.z??0)?((l=i[le])==null?void 0:l.z)??0:n.z??0},r)}function vo(e,t,n){e.forEach(r=>{var i;const s=r.parentNode||r.parentId;if(s&&!e.has(s))throw new Error(`Parent node ${s} not found`);if(s||n!=null&&n[r.id]){const{x:o,y:a,z:l}=bo(r,e,{...r.position,z:((i=r[le])==null?void 0:i.z)??0},t);r.positionAbsolute={x:o,y:a},r[le].z=l,n!=null&&n[r.id]&&(r[le].isParent=!0)}})}function Yn(e,t,n,r){const s=new Map,i={},o=r?1e3:0;return e.forEach(a=>{var f;const l=(Se(a.zIndex)?a.zIndex:0)+(a.selected?o:0),c=t.get(a.id),u={...a,positionAbsolute:{x:a.position.x,y:a.position.y}},d=a.parentNode||a.parentId;d&&(i[d]=!0);const m=(c==null?void 0:c.type)&&(c==null?void 0:c.type)!==a.type;Object.defineProperty(u,le,{enumerable:!1,value:{handleBounds:m||(f=c==null?void 0:c[le])==null?void 0:f.handleBounds,z:l}}),s.set(a.id,u)}),vo(s,n,i),s}function _o(e,t={}){const{getNodes:n,width:r,height:s,minZoom:i,maxZoom:o,d3Zoom:a,d3Selection:l,fitViewOnInitDone:c,fitViewOnInit:u,nodeOrigin:d}=e(),m=t.initial&&!c&&u;if(a&&l&&(m||!t.initial)){const y=n().filter(v=>{var _;const x=t.includeHiddenNodes?v.width&&v.height:!v.hidden;return(_=t.nodes)!=null&&_.length?x&&t.nodes.some(M=>M.id===v.id):x}),p=y.every(v=>v.width&&v.height);if(y.length>0&&p){const v=Kt(y,d),{x,y:_,zoom:M}=oo(v,r,s,t.minZoom??i,t.maxZoom??o,t.padding??.1),b=Fe.translate(x,_).scale(M);return typeof t.duration=="number"&&t.duration>0?a.transform(st(l,t.duration),b):a.transform(l,b),!0}}return!1}function Gf(e,t){return e.forEach(n=>{const r=t.get(n.id);r&&t.set(r.id,{...r,[le]:r[le],selected:n.selected})}),new Map(t)}function Yf(e,t){return t.map(n=>{const r=e.find(s=>s.id===n.id);return r&&(n.selected=r.selected),n})}function on({changedNodes:e,changedEdges:t,get:n,set:r}){const{nodeInternals:s,edges:i,onNodesChange:o,onEdgesChange:a,hasDefaultNodes:l,hasDefaultEdges:c}=n();e!=null&&e.length&&(l&&r({nodeInternals:Gf(e,s)}),o==null||o(e)),t!=null&&t.length&&(c&&r({edges:Yf(t,i)}),a==null||a(t))}const pt=()=>{},Wf={zoomIn:pt,zoomOut:pt,zoomTo:pt,getZoom:()=>1,setViewport:pt,getViewport:()=>({x:0,y:0,zoom:1}),fitView:()=>!1,setCenter:pt,fitBounds:pt,project:e=>e,screenToFlowPosition:e=>e,flowToScreenPosition:e=>e,viewportInitialized:!1},Uf=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection}),Xf=()=>{const e=pe(),{d3Zoom:t,d3Selection:n}=ae(Uf,ge);return w.useMemo(()=>n&&t?{zoomIn:s=>t.scaleBy(st(n,s==null?void 0:s.duration),1.2),zoomOut:s=>t.scaleBy(st(n,s==null?void 0:s.duration),1/1.2),zoomTo:(s,i)=>t.scaleTo(st(n,i==null?void 0:i.duration),s),getZoom:()=>e.getState().transform[2],setViewport:(s,i)=>{const[o,a,l]=e.getState().transform,c=Fe.translate(s.x??o,s.y??a).scale(s.zoom??l);t.transform(st(n,i==null?void 0:i.duration),c)},getViewport:()=>{const[s,i,o]=e.getState().transform;return{x:s,y:i,zoom:o}},fitView:s=>_o(e.getState,s),setCenter:(s,i,o)=>{const{width:a,height:l,maxZoom:c}=e.getState(),u=typeof(o==null?void 0:o.zoom)<"u"?o.zoom:c,d=a/2-s*u,m=l/2-i*u,f=Fe.translate(d,m).scale(u);t.transform(st(n,o==null?void 0:o.duration),f)},fitBounds:(s,i)=>{const{width:o,height:a,minZoom:l,maxZoom:c}=e.getState(),{x:u,y:d,zoom:m}=oo(s,o,a,l,c,(i==null?void 0:i.padding)??.1),f=Fe.translate(u,d).scale(m);t.transform(st(n,i==null?void 0:i.duration),f)},project:s=>{const{transform:i,snapToGrid:o,snapGrid:a}=e.getState();return console.warn("[DEPRECATED] `project` is deprecated. Instead use `screenToFlowPosition`. There is no need to subtract the react flow bounds anymore! https://reactflow.dev/api-reference/types/react-flow-instance#screen-to-flow-position"),hr(s,i,o,a)},screenToFlowPosition:s=>{const{transform:i,snapToGrid:o,snapGrid:a,domNode:l}=e.getState();if(!l)return s;const{x:c,y:u}=l.getBoundingClientRect(),d={x:s.x-c,y:s.y-u};return hr(d,i,o,a)},flowToScreenPosition:s=>{const{transform:i,domNode:o}=e.getState();if(!o)return s;const{x:a,y:l}=o.getBoundingClientRect(),c=ro(s,i);return{x:c.x+a,y:c.y+l}},viewportInitialized:!0}:Wf,[t,n])};function Rn(){const e=Xf(),t=pe(),n=w.useCallback(()=>t.getState().getNodes().map(p=>({...p})),[]),r=w.useCallback(p=>t.getState().nodeInternals.get(p),[]),s=w.useCallback(()=>{const{edges:p=[]}=t.getState();return p.map(v=>({...v}))},[]),i=w.useCallback(p=>{const{edges:v=[]}=t.getState();return v.find(x=>x.id===p)},[]),o=w.useCallback(p=>{const{getNodes:v,setNodes:x,hasDefaultNodes:_,onNodesChange:M}=t.getState(),b=v(),j=typeof p=="function"?p(b):p;if(_)x(j);else if(M){const C=j.length===0?b.map(E=>({type:"remove",id:E.id})):j.map(E=>({item:E,type:"reset"}));M(C)}},[]),a=w.useCallback(p=>{const{edges:v=[],setEdges:x,hasDefaultEdges:_,onEdgesChange:M}=t.getState(),b=typeof p=="function"?p(v):p;if(_)x(b);else if(M){const j=b.length===0?v.map(C=>({type:"remove",id:C.id})):b.map(C=>({item:C,type:"reset"}));M(j)}},[]),l=w.useCallback(p=>{const v=Array.isArray(p)?p:[p],{getNodes:x,setNodes:_,hasDefaultNodes:M,onNodesChange:b}=t.getState();if(M){const C=[...x(),...v];_(C)}else if(b){const j=v.map(C=>({item:C,type:"add"}));b(j)}},[]),c=w.useCallback(p=>{const v=Array.isArray(p)?p:[p],{edges:x=[],setEdges:_,hasDefaultEdges:M,onEdgesChange:b}=t.getState();if(M)_([...x,...v]);else if(b){const j=v.map(C=>({item:C,type:"add"}));b(j)}},[]),u=w.useCallback(()=>{const{getNodes:p,edges:v=[],transform:x}=t.getState(),[_,M,b]=x;return{nodes:p().map(j=>({...j})),edges:v.map(j=>({...j})),viewport:{x:_,y:M,zoom:b}}},[]),d=w.useCallback(({nodes:p,edges:v})=>{const{nodeInternals:x,getNodes:_,edges:M,hasDefaultNodes:b,hasDefaultEdges:j,onNodesDelete:C,onEdgesDelete:E,onNodesChange:L,onEdgesChange:S}=t.getState(),O=(p||[]).map($=>$.id),P=(v||[]).map($=>$.id),V=_().reduce(($,N)=>{const I=N.parentNode||N.parentId,H=!O.includes(N.id)&&I&&$.find(R=>R.id===I);return(typeof N.deletable=="boolean"?N.deletable:!0)&&(O.includes(N.id)||H)&&$.push(N),$},[]),F=M.filter($=>typeof $.deletable=="boolean"?$.deletable:!0),g=F.filter($=>P.includes($.id));if(V||g){const $=io(V,F),N=[...g,...$],I=N.reduce((H,k)=>(H.includes(k.id)||H.push(k.id),H),[]);if((j||b)&&(j&&t.setState({edges:M.filter(H=>!I.includes(H.id))}),b&&(V.forEach(H=>{x.delete(H.id)}),t.setState({nodeInternals:new Map(x)}))),I.length>0&&(E==null||E(N),S&&S(I.map(H=>({id:H,type:"remove"})))),V.length>0&&(C==null||C(V),L)){const H=V.map(k=>({id:k.id,type:"remove"}));L(H)}}},[]),m=w.useCallback(p=>{const v=hf(p),x=v?null:t.getState().nodeInternals.get(p.id);return!v&&!x?[null,null,v]:[v?p:hs(x),x,v]},[]),f=w.useCallback((p,v=!0,x)=>{const[_,M,b]=m(p);return _?(x||t.getState().getNodes()).filter(j=>{if(!b&&(j.id===M.id||!j.positionAbsolute))return!1;const C=hs(j),E=ur(C,_);return v&&E>0||E>=_.width*_.height}):[]},[]),y=w.useCallback((p,v,x=!0)=>{const[_]=m(p);if(!_)return!1;const M=ur(_,v);return x&&M>0||M>=_.width*_.height},[]);return w.useMemo(()=>({...e,getNodes:n,getNode:r,getEdges:s,getEdge:i,setNodes:o,setEdges:a,addNodes:l,addEdges:c,toObject:u,deleteElements:d,getIntersectingNodes:f,isNodeIntersecting:y}),[e,n,r,s,i,o,a,l,c,u,d,f,y])}const qf={actInsideInputWithModifier:!1};var Kf=({deleteKeyCode:e,multiSelectionKeyCode:t})=>{const n=pe(),{deleteElements:r}=Rn(),s=Wt(e,qf),i=Wt(t);w.useEffect(()=>{if(s){const{edges:o,getNodes:a}=n.getState(),l=a().filter(u=>u.selected),c=o.filter(u=>u.selected);r({nodes:l,edges:c}),n.setState({nodesSelectionActive:!1})}},[s]),w.useEffect(()=>{n.setState({multiSelectionActive:i})},[i])};function Zf(e){const t=pe();w.useEffect(()=>{let n;const r=()=>{var i,o;if(!e.current)return;const s=kr(e.current);(s.height===0||s.width===0)&&((o=(i=t.getState()).onError)==null||o.call(i,"004",Be.error004())),t.setState({width:s.width||500,height:s.height||500})};return r(),window.addEventListener("resize",r),e.current&&(n=new ResizeObserver(()=>r()),n.observe(e.current)),()=>{window.removeEventListener("resize",r),n&&e.current&&n.unobserve(e.current)}},[])}const Tr={position:"absolute",width:"100%",height:"100%",top:0,left:0},Qf=(e,t)=>e.x!==t.x||e.y!==t.y||e.zoom!==t.k,an=e=>({x:e.x,y:e.y,zoom:e.k}),gt=(e,t)=>e.target.closest(`.${t}`),Es=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),Ns=e=>{const t=e.ctrlKey&&wn()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t},Jf=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection,d3ZoomHandler:e.d3ZoomHandler,userSelectionActive:e.userSelectionActive}),eh=({onMove:e,onMoveStart:t,onMoveEnd:n,onPaneContextMenu:r,zoomOnScroll:s=!0,zoomOnPinch:i=!0,panOnScroll:o=!1,panOnScrollSpeed:a=.5,panOnScrollMode:l=ot.Free,zoomOnDoubleClick:c=!0,elementsSelectable:u,panOnDrag:d=!0,defaultViewport:m,translateExtent:f,minZoom:y,maxZoom:p,zoomActivationKeyCode:v,preventScrolling:x=!0,children:_,noWheelClassName:M,noPanClassName:b})=>{const j=w.useRef(),C=pe(),E=w.useRef(!1),L=w.useRef(!1),S=w.useRef(null),O=w.useRef({x:0,y:0,zoom:0}),{d3Zoom:P,d3Selection:V,d3ZoomHandler:F,userSelectionActive:g}=ae(Jf,ge),$=Wt(v),N=w.useRef(0),I=w.useRef(!1),H=w.useRef();return Zf(S),w.useEffect(()=>{if(S.current){const k=S.current.getBoundingClientRect(),R=Yi().scaleExtent([y,p]).translateExtent(f),D=Ne(S.current).call(R),z=Fe.translate(m.x,m.y).scale(kt(m.zoom,y,p)),Y=[[0,0],[k.width,k.height]],G=R.constrain()(z,Y,f);R.transform(D,G),R.wheelDelta(Ns),C.setState({d3Zoom:R,d3Selection:D,d3ZoomHandler:D.on("wheel.zoom"),transform:[G.x,G.y,G.k],domNode:S.current.closest(".react-flow")})}},[]),w.useEffect(()=>{V&&P&&(o&&!$&&!g?V.on("wheel.zoom",k=>{if(gt(k,M))return!1;k.preventDefault(),k.stopImmediatePropagation();const R=V.property("__zoom").k||1;if(k.ctrlKey&&i){const ie=$e(k),te=Ns(k),re=R*Math.pow(2,te);P.scaleTo(V,re,ie,k);return}const D=k.deltaMode===1?20:1;let z=l===ot.Vertical?0:k.deltaX*D,Y=l===ot.Horizontal?0:k.deltaY*D;!wn()&&k.shiftKey&&l!==ot.Vertical&&(z=k.deltaY*D,Y=0),P.translateBy(V,-(z/R)*a,-(Y/R)*a,{internal:!0});const G=an(V.property("__zoom")),{onViewportChangeStart:K,onViewportChange:J,onViewportChangeEnd:ee}=C.getState();clearTimeout(H.current),I.current||(I.current=!0,t==null||t(k,G),K==null||K(G)),I.current&&(e==null||e(k,G),J==null||J(G),H.current=setTimeout(()=>{n==null||n(k,G),ee==null||ee(G),I.current=!1},150))},{passive:!1}):typeof F<"u"&&V.on("wheel.zoom",function(k,R){if(!x&&k.type==="wheel"&&!k.ctrlKey||gt(k,M))return null;k.preventDefault(),F.call(this,k,R)},{passive:!1}))},[g,o,l,V,P,F,$,i,x,M,t,e,n]),w.useEffect(()=>{P&&P.on("start",k=>{var z,Y;if(!k.sourceEvent||k.sourceEvent.internal)return null;N.current=(z=k.sourceEvent)==null?void 0:z.button;const{onViewportChangeStart:R}=C.getState(),D=an(k.transform);E.current=!0,O.current=D,((Y=k.sourceEvent)==null?void 0:Y.type)==="mousedown"&&C.setState({paneDragging:!0}),R==null||R(D),t==null||t(k.sourceEvent,D)})},[P,t]),w.useEffect(()=>{P&&(g&&!E.current?P.on("zoom",null):g||P.on("zoom",k=>{var D;const{onViewportChange:R}=C.getState();if(C.setState({transform:[k.transform.x,k.transform.y,k.transform.k]}),L.current=!!(r&&Es(d,N.current??0)),(e||R)&&!((D=k.sourceEvent)!=null&&D.internal)){const z=an(k.transform);R==null||R(z),e==null||e(k.sourceEvent,z)}}))},[g,P,e,d,r]),w.useEffect(()=>{P&&P.on("end",k=>{if(!k.sourceEvent||k.sourceEvent.internal)return null;const{onViewportChangeEnd:R}=C.getState();if(E.current=!1,C.setState({paneDragging:!1}),r&&Es(d,N.current??0)&&!L.current&&r(k.sourceEvent),L.current=!1,(n||R)&&Qf(O.current,k.transform)){const D=an(k.transform);O.current=D,clearTimeout(j.current),j.current=setTimeout(()=>{R==null||R(D),n==null||n(k.sourceEvent,D)},o?150:0)}})},[P,o,d,n,r]),w.useEffect(()=>{P&&P.filter(k=>{const R=$||s,D=i&&k.ctrlKey;if((d===!0||Array.isArray(d)&&d.includes(1))&&k.button===1&&k.type==="mousedown"&&(gt(k,"react-flow__node")||gt(k,"react-flow__edge")))return!0;if(!d&&!R&&!o&&!c&&!i||g||!c&&k.type==="dblclick"||gt(k,M)&&k.type==="wheel"||gt(k,b)&&(k.type!=="wheel"||o&&k.type==="wheel"&&!$)||!i&&k.ctrlKey&&k.type==="wheel"||!R&&!o&&!D&&k.type==="wheel"||!d&&(k.type==="mousedown"||k.type==="touchstart")||Array.isArray(d)&&!d.includes(k.button)&&k.type==="mousedown")return!1;const z=Array.isArray(d)&&d.includes(k.button)||!k.button||k.button<=1;return(!k.ctrlKey||k.type==="wheel")&&z})},[g,P,s,i,o,c,d,u,$]),A.createElement("div",{className:"react-flow__renderer",ref:S,style:Tr},_)},th=e=>({userSelectionActive:e.userSelectionActive,userSelectionRect:e.userSelectionRect});function nh(){const{userSelectionActive:e,userSelectionRect:t}=ae(th,ge);return e&&t?A.createElement("div",{className:"react-flow__selection react-flow__container",style:{width:t.width,height:t.height,transform:`translate(${t.x}px, ${t.y}px)`}}):null}function Ss(e,t){const n=t.parentNode||t.parentId,r=e.find(s=>s.id===n);if(r){const s=t.position.x+t.width-r.width,i=t.position.y+t.height-r.height;if(s>0||i>0||t.position.x<0||t.position.y<0){if(r.style={...r.style},r.style.width=r.style.width??r.width,r.style.height=r.style.height??r.height,s>0&&(r.style.width+=s),i>0&&(r.style.height+=i),t.position.x<0){const o=Math.abs(t.position.x);r.position.x=r.position.x-o,r.style.width+=o,t.position.x=0}if(t.position.y<0){const o=Math.abs(t.position.y);r.position.y=r.position.y-o,r.style.height+=o,t.position.y=0}r.width=r.style.width,r.height=r.style.height}}}function rh(e,t){if(e.some(r=>r.type==="reset"))return e.filter(r=>r.type==="reset").map(r=>r.item);const n=e.filter(r=>r.type==="add").map(r=>r.item);return t.reduce((r,s)=>{const i=e.filter(a=>a.id===s.id);if(i.length===0)return r.push(s),r;const o={...s};for(const a of i)if(a)switch(a.type){case"select":{o.selected=a.selected;break}case"position":{typeof a.position<"u"&&(o.position=a.position),typeof a.positionAbsolute<"u"&&(o.positionAbsolute=a.positionAbsolute),typeof a.dragging<"u"&&(o.dragging=a.dragging),o.expandParent&&Ss(r,o);break}case"dimensions":{typeof a.dimensions<"u"&&(o.width=a.dimensions.width,o.height=a.dimensions.height),typeof a.updateStyle<"u"&&(o.style={...o.style||{},...a.dimensions}),typeof a.resizing=="boolean"&&(o.resizing=a.resizing),o.expandParent&&Ss(r,o);break}case"remove":return r}return r.push(o),r},n)}function sh(e,t){return rh(e,t)}const Ue=(e,t)=>({id:e,type:"select",selected:t});function xt(e,t){return e.reduce((n,r)=>{const s=t.includes(r.id);return!r.selected&&s?(r.selected=!0,n.push(Ue(r.id,!0))):r.selected&&!s&&(r.selected=!1,n.push(Ue(r.id,!1))),n},[])}const Wn=(e,t)=>n=>{n.target===t.current&&(e==null||e(n))},ih=e=>({userSelectionActive:e.userSelectionActive,elementsSelectable:e.elementsSelectable,dragging:e.paneDragging}),Eo=w.memo(({isSelecting:e,selectionMode:t=Yt.Full,panOnDrag:n,onSelectionStart:r,onSelectionEnd:s,onPaneClick:i,onPaneContextMenu:o,onPaneScroll:a,onPaneMouseEnter:l,onPaneMouseMove:c,onPaneMouseLeave:u,children:d})=>{const m=w.useRef(null),f=pe(),y=w.useRef(0),p=w.useRef(0),v=w.useRef(),{userSelectionActive:x,elementsSelectable:_,dragging:M}=ae(ih,ge),b=()=>{f.setState({userSelectionActive:!1,userSelectionRect:null}),y.current=0,p.current=0},j=F=>{i==null||i(F),f.getState().resetSelectedElements(),f.setState({nodesSelectionActive:!1})},C=F=>{if(Array.isArray(n)&&(n!=null&&n.includes(2))){F.preventDefault();return}o==null||o(F)},E=a?F=>a(F):void 0,L=F=>{const{resetSelectedElements:g,domNode:$}=f.getState();if(v.current=$==null?void 0:$.getBoundingClientRect(),!_||!e||F.button!==0||F.target!==m.current||!v.current)return;const{x:N,y:I}=Ke(F,v.current);g(),f.setState({userSelectionRect:{width:0,height:0,startX:N,startY:I,x:N,y:I}}),r==null||r(F)},S=F=>{const{userSelectionRect:g,nodeInternals:$,edges:N,transform:I,onNodesChange:H,onEdgesChange:k,nodeOrigin:R,getNodes:D}=f.getState();if(!e||!v.current||!g)return;f.setState({userSelectionActive:!0,nodesSelectionActive:!1});const z=Ke(F,v.current),Y=g.startX??0,G=g.startY??0,K={...g,x:z.xre.id),te=ee.map(re=>re.id);if(y.current!==te.length){y.current=te.length;const re=xt(J,te);re.length&&(H==null||H(re))}if(p.current!==ie.length){p.current=ie.length;const re=xt(N,ie);re.length&&(k==null||k(re))}f.setState({userSelectionRect:K})},O=F=>{if(F.button!==0)return;const{userSelectionRect:g}=f.getState();!x&&g&&F.target===m.current&&(j==null||j(F)),f.setState({nodesSelectionActive:y.current>0}),b(),s==null||s(F)},P=F=>{x&&(f.setState({nodesSelectionActive:y.current>0}),s==null||s(F)),b()},V=_&&(e||x);return A.createElement("div",{className:ye(["react-flow__pane",{dragging:M,selection:e}]),onClick:V?void 0:Wn(j,m),onContextMenu:Wn(C,m),onWheel:Wn(E,m),onMouseEnter:V?void 0:l,onMouseDown:V?L:void 0,onMouseMove:V?S:c,onMouseUp:V?O:void 0,onMouseLeave:V?P:u,ref:m,style:Tr},d,A.createElement(nh,null))});Eo.displayName="Pane";function No(e,t){const n=e.parentNode||e.parentId;if(!n)return!1;const r=t.get(n);return r?r.selected?!0:No(r,t):!1}function ks(e,t,n){let r=e;do{if(r!=null&&r.matches(t))return!0;if(r===n.current)return!1;r=r.parentElement}while(r);return!1}function oh(e,t,n,r){return Array.from(e.values()).filter(s=>(s.selected||s.id===r)&&(!s.parentNode||s.parentId||!No(s,e))&&(s.draggable||t&&typeof s.draggable>"u")).map(s=>{var i,o;return{id:s.id,position:s.position||{x:0,y:0},positionAbsolute:s.positionAbsolute||{x:0,y:0},distance:{x:n.x-(((i=s.positionAbsolute)==null?void 0:i.x)??0),y:n.y-(((o=s.positionAbsolute)==null?void 0:o.y)??0)},delta:{x:0,y:0},extent:s.extent,parentNode:s.parentNode||s.parentId,parentId:s.parentNode||s.parentId,width:s.width,height:s.height,expandParent:s.expandParent}})}function ah(e,t){return!t||t==="parent"?t:[t[0],[t[1][0]-(e.width||0),t[1][1]-(e.height||0)]]}function So(e,t,n,r,s=[0,0],i){const o=ah(e,e.extent||r);let a=o;const l=e.parentNode||e.parentId;if(e.extent==="parent"&&!e.expandParent)if(l&&e.width&&e.height){const d=n.get(l),{x:m,y:f}=lt(d,s).positionAbsolute;a=d&&Se(m)&&Se(f)&&Se(d.width)&&Se(d.height)?[[m+e.width*s[0],f+e.height*s[1]],[m+d.width-e.width+e.width*s[0],f+d.height-e.height+e.height*s[1]]]:a}else i==null||i("005",Be.error005()),a=o;else if(e.extent&&l&&e.extent!=="parent"){const d=n.get(l),{x:m,y:f}=lt(d,s).positionAbsolute;a=[[e.extent[0][0]+m,e.extent[0][1]+f],[e.extent[1][0]+m,e.extent[1][1]+f]]}let c={x:0,y:0};if(l){const d=n.get(l);c=lt(d,s).positionAbsolute}const u=a&&a!=="parent"?jr(t,a):t;return{position:{x:u.x-c.x,y:u.y-c.y},positionAbsolute:u}}function Un({nodeId:e,dragItems:t,nodeInternals:n}){const r=t.map(s=>({...n.get(s.id),position:s.position,positionAbsolute:s.positionAbsolute}));return[e?r.find(s=>s.id===e):r[0],r]}const js=(e,t,n,r)=>{const s=t.querySelectorAll(e);if(!s||!s.length)return null;const i=Array.from(s),o=t.getBoundingClientRect(),a={x:o.width*r[0],y:o.height*r[1]};return i.map(l=>{const c=l.getBoundingClientRect();return{id:l.getAttribute("data-handleid"),position:l.getAttribute("data-handlepos"),x:(c.left-o.left-a.x)/n,y:(c.top-o.top-a.y)/n,...kr(l)}})};function Rt(e,t,n){return n===void 0?n:r=>{const s=t().nodeInternals.get(e);s&&n(r,{...s})}}function pr({id:e,store:t,unselect:n=!1,nodeRef:r}){const{addSelectedNodes:s,unselectNodesAndEdges:i,multiSelectionActive:o,nodeInternals:a,onError:l}=t.getState(),c=a.get(e);if(!c){l==null||l("012",Be.error012(e));return}t.setState({nodesSelectionActive:!1}),c.selected?(n||c.selected&&o)&&(i({nodes:[c],edges:[]}),requestAnimationFrame(()=>{var u;return(u=r==null?void 0:r.current)==null?void 0:u.blur()})):s([e])}function lh(){const e=pe();return w.useCallback(({sourceEvent:n})=>{const{transform:r,snapGrid:s,snapToGrid:i}=e.getState(),o=n.touches?n.touches[0].clientX:n.clientX,a=n.touches?n.touches[0].clientY:n.clientY,l={x:(o-r[0])/r[2],y:(a-r[1])/r[2]};return{xSnapped:i?s[0]*Math.round(l.x/s[0]):l.x,ySnapped:i?s[1]*Math.round(l.y/s[1]):l.y,...l}},[])}function Xn(e){return(t,n,r)=>e==null?void 0:e(t,r)}function ko({nodeRef:e,disabled:t=!1,noDragClassName:n,handleSelector:r,nodeId:s,isSelectable:i,selectNodesOnDrag:o}){const a=pe(),[l,c]=w.useState(!1),u=w.useRef([]),d=w.useRef({x:null,y:null}),m=w.useRef(0),f=w.useRef(null),y=w.useRef({x:0,y:0}),p=w.useRef(null),v=w.useRef(!1),x=w.useRef(!1),_=w.useRef(!1),M=lh();return w.useEffect(()=>{if(e!=null&&e.current){const b=Ne(e.current),j=({x:L,y:S})=>{const{nodeInternals:O,onNodeDrag:P,onSelectionDrag:V,updateNodePositions:F,nodeExtent:g,snapGrid:$,snapToGrid:N,nodeOrigin:I,onError:H}=a.getState();d.current={x:L,y:S};let k=!1,R={x:0,y:0,x2:0,y2:0};if(u.current.length>1&&g){const z=Kt(u.current,I);R=Gt(z)}if(u.current=u.current.map(z=>{const Y={x:L-z.distance.x,y:S-z.distance.y};N&&(Y.x=$[0]*Math.round(Y.x/$[0]),Y.y=$[1]*Math.round(Y.y/$[1]));const G=[[g[0][0],g[0][1]],[g[1][0],g[1][1]]];u.current.length>1&&g&&!z.extent&&(G[0][0]=z.positionAbsolute.x-R.x+g[0][0],G[1][0]=z.positionAbsolute.x+(z.width??0)-R.x2+g[1][0],G[0][1]=z.positionAbsolute.y-R.y+g[0][1],G[1][1]=z.positionAbsolute.y+(z.height??0)-R.y2+g[1][1]);const K=So(z,Y,O,G,I,H);return k=k||z.position.x!==K.position.x||z.position.y!==K.position.y,z.position=K.position,z.positionAbsolute=K.positionAbsolute,z}),!k)return;F(u.current,!0,!0),c(!0);const D=s?P:Xn(V);if(D&&p.current){const[z,Y]=Un({nodeId:s,dragItems:u.current,nodeInternals:O});D(p.current,z,Y)}},C=()=>{if(!f.current)return;const[L,S]=Ui(y.current,f.current);if(L!==0||S!==0){const{transform:O,panBy:P}=a.getState();d.current.x=(d.current.x??0)-L/O[2],d.current.y=(d.current.y??0)-S/O[2],P({x:L,y:S})&&j(d.current)}m.current=requestAnimationFrame(C)},E=L=>{var I;const{nodeInternals:S,multiSelectionActive:O,nodesDraggable:P,unselectNodesAndEdges:V,onNodeDragStart:F,onSelectionDragStart:g}=a.getState();x.current=!0;const $=s?F:Xn(g);(!o||!i)&&!O&&s&&((I=S.get(s))!=null&&I.selected||V()),s&&i&&o&&pr({id:s,store:a,nodeRef:e});const N=M(L);if(d.current=N,u.current=oh(S,P,N,s),$&&u.current){const[H,k]=Un({nodeId:s,dragItems:u.current,nodeInternals:S});$(L.sourceEvent,H,k)}};if(t)b.on(".drag",null);else{const L=gu().on("start",S=>{const{domNode:O,nodeDragThreshold:P}=a.getState();P===0&&E(S),_.current=!1;const V=M(S);d.current=V,f.current=(O==null?void 0:O.getBoundingClientRect())||null,y.current=Ke(S.sourceEvent,f.current)}).on("drag",S=>{var F,g;const O=M(S),{autoPanOnNodeDrag:P,nodeDragThreshold:V}=a.getState();if(S.sourceEvent.type==="touchmove"&&S.sourceEvent.touches.length>1&&(_.current=!0),!_.current){if(!v.current&&x.current&&P&&(v.current=!0,C()),!x.current){const $=O.xSnapped-(((F=d==null?void 0:d.current)==null?void 0:F.x)??0),N=O.ySnapped-(((g=d==null?void 0:d.current)==null?void 0:g.y)??0);Math.sqrt($*$+N*N)>V&&E(S)}(d.current.x!==O.xSnapped||d.current.y!==O.ySnapped)&&u.current&&x.current&&(p.current=S.sourceEvent,y.current=Ke(S.sourceEvent,f.current),j(O))}}).on("end",S=>{if(!(!x.current||_.current)&&(c(!1),v.current=!1,x.current=!1,cancelAnimationFrame(m.current),u.current)){const{updateNodePositions:O,nodeInternals:P,onNodeDragStop:V,onSelectionDragStop:F}=a.getState(),g=s?V:Xn(F);if(O(u.current,!1,!1),g){const[$,N]=Un({nodeId:s,dragItems:u.current,nodeInternals:P});g(S.sourceEvent,$,N)}}}).filter(S=>{const O=S.target;return!S.button&&(!n||!ks(O,`.${n}`,e))&&(!r||ks(O,r,e))});return b.call(L),()=>{b.on(".drag",null)}}}},[e,t,n,r,i,a,s,o,M]),l}function jo(){const e=pe();return w.useCallback(n=>{const{nodeInternals:r,nodeExtent:s,updateNodePositions:i,getNodes:o,snapToGrid:a,snapGrid:l,onError:c,nodesDraggable:u}=e.getState(),d=o().filter(_=>_.selected&&(_.draggable||u&&typeof _.draggable>"u")),m=a?l[0]:5,f=a?l[1]:5,y=n.isShiftPressed?4:1,p=n.x*m*y,v=n.y*f*y,x=d.map(_=>{if(_.positionAbsolute){const M={x:_.positionAbsolute.x+p,y:_.positionAbsolute.y+v};a&&(M.x=l[0]*Math.round(M.x/l[0]),M.y=l[1]*Math.round(M.y/l[1]));const{positionAbsolute:b,position:j}=So(_,M,r,s,void 0,c);_.position=j,_.positionAbsolute=b}return _});i(x,!0,!1)},[])}const vt={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}};var Tt=e=>{const t=({id:n,type:r,data:s,xPos:i,yPos:o,xPosOrigin:a,yPosOrigin:l,selected:c,onClick:u,onMouseEnter:d,onMouseMove:m,onMouseLeave:f,onContextMenu:y,onDoubleClick:p,style:v,className:x,isDraggable:_,isSelectable:M,isConnectable:b,isFocusable:j,selectNodesOnDrag:C,sourcePosition:E,targetPosition:L,hidden:S,resizeObserver:O,dragHandle:P,zIndex:V,isParent:F,noDragClassName:g,noPanClassName:$,initialized:N,disableKeyboardA11y:I,ariaLabel:H,rfId:k,hasHandleBounds:R})=>{const D=pe(),z=w.useRef(null),Y=w.useRef(null),G=w.useRef(E),K=w.useRef(L),J=w.useRef(r),ee=M||_||u||d||m||f,ie=jo(),te=Rt(n,D.getState,d),re=Rt(n,D.getState,m),de=Rt(n,D.getState,f),B=Rt(n,D.getState,y),q=Rt(n,D.getState,p),W=X=>{const{nodeDragThreshold:T}=D.getState();if(M&&(!C||!_||T>0)&&pr({id:n,store:D,nodeRef:z}),u){const se=D.getState().nodeInternals.get(n);se&&u(X,{...se})}},Q=X=>{if(!dr(X)&&!I)if(Zi.includes(X.key)&&M){const T=X.key==="Escape";pr({id:n,store:D,unselect:T,nodeRef:z})}else _&&c&&Object.prototype.hasOwnProperty.call(vt,X.key)&&(D.setState({ariaLiveMessage:`Moved selected node ${X.key.replace("Arrow","").toLowerCase()}. New position, x: ${~~i}, y: ${~~o}`}),ie({x:vt[X.key].x,y:vt[X.key].y,isShiftPressed:X.shiftKey}))};w.useEffect(()=>()=>{Y.current&&(O==null||O.unobserve(Y.current),Y.current=null)},[]),w.useEffect(()=>{if(z.current&&!S){const X=z.current;(!N||!R||Y.current!==X)&&(Y.current&&(O==null||O.unobserve(Y.current)),O==null||O.observe(X),Y.current=X)}},[S,N,R]),w.useEffect(()=>{const X=J.current!==r,T=G.current!==E,se=K.current!==L;z.current&&(X||T||se)&&(X&&(J.current=r),T&&(G.current=E),se&&(K.current=L),D.getState().updateNodeDimensions([{id:n,nodeElement:z.current,forceUpdate:!0}]))},[n,r,E,L]);const U=ko({nodeRef:z,disabled:S||!_,noDragClassName:g,handleSelector:P,nodeId:n,isSelectable:M,selectNodesOnDrag:C});return S?null:A.createElement("div",{className:ye(["react-flow__node",`react-flow__node-${r}`,{[$]:_},x,{selected:c,selectable:M,parent:F,dragging:U}]),ref:z,style:{zIndex:V,transform:`translate(${a}px,${l}px)`,pointerEvents:ee?"all":"none",visibility:N?"visible":"hidden",...v},"data-id":n,"data-testid":`rf__node-${n}`,onMouseEnter:te,onMouseMove:re,onMouseLeave:de,onContextMenu:B,onClick:W,onDoubleClick:q,onKeyDown:j?Q:void 0,tabIndex:j?0:void 0,role:j?"button":void 0,"aria-describedby":I?void 0:`${xo}-${k}`,"aria-label":H},A.createElement(bf,{value:n},A.createElement(e,{id:n,data:s,type:r,xPos:i,yPos:o,selected:c,isConnectable:b,sourcePosition:E,targetPosition:L,dragging:U,dragHandle:P,zIndex:V})))};return t.displayName="NodeWrapper",w.memo(t)};const ch=e=>{const t=e.getNodes().filter(n=>n.selected);return{...Kt(t,e.nodeOrigin),transformString:`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`,userSelectionActive:e.userSelectionActive}};function uh({onSelectionContextMenu:e,noPanClassName:t,disableKeyboardA11y:n}){const r=pe(),{width:s,height:i,x:o,y:a,transformString:l,userSelectionActive:c}=ae(ch,ge),u=jo(),d=w.useRef(null);if(w.useEffect(()=>{var y;n||(y=d.current)==null||y.focus({preventScroll:!0})},[n]),ko({nodeRef:d}),c||!s||!i)return null;const m=e?y=>{const p=r.getState().getNodes().filter(v=>v.selected);e(y,p)}:void 0,f=y=>{Object.prototype.hasOwnProperty.call(vt,y.key)&&u({x:vt[y.key].x,y:vt[y.key].y,isShiftPressed:y.shiftKey})};return A.createElement("div",{className:ye(["react-flow__nodesselection","react-flow__container",t]),style:{transform:l}},A.createElement("div",{ref:d,className:"react-flow__nodesselection-rect",onContextMenu:m,tabIndex:n?void 0:-1,onKeyDown:n?void 0:f,style:{width:s,height:i,top:a,left:o}}))}var dh=w.memo(uh);const fh=e=>e.nodesSelectionActive,Co=({children:e,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:s,onPaneContextMenu:i,onPaneScroll:o,deleteKeyCode:a,onMove:l,onMoveStart:c,onMoveEnd:u,selectionKeyCode:d,selectionOnDrag:m,selectionMode:f,onSelectionStart:y,onSelectionEnd:p,multiSelectionKeyCode:v,panActivationKeyCode:x,zoomActivationKeyCode:_,elementsSelectable:M,zoomOnScroll:b,zoomOnPinch:j,panOnScroll:C,panOnScrollSpeed:E,panOnScrollMode:L,zoomOnDoubleClick:S,panOnDrag:O,defaultViewport:P,translateExtent:V,minZoom:F,maxZoom:g,preventScrolling:$,onSelectionContextMenu:N,noWheelClassName:I,noPanClassName:H,disableKeyboardA11y:k})=>{const R=ae(fh),D=Wt(d),z=Wt(x),Y=z||O,G=z||C,K=D||m&&Y!==!0;return Kf({deleteKeyCode:a,multiSelectionKeyCode:v}),A.createElement(eh,{onMove:l,onMoveStart:c,onMoveEnd:u,onPaneContextMenu:i,elementsSelectable:M,zoomOnScroll:b,zoomOnPinch:j,panOnScroll:G,panOnScrollSpeed:E,panOnScrollMode:L,zoomOnDoubleClick:S,panOnDrag:!D&&Y,defaultViewport:P,translateExtent:V,minZoom:F,maxZoom:g,zoomActivationKeyCode:_,preventScrolling:$,noWheelClassName:I,noPanClassName:H},A.createElement(Eo,{onSelectionStart:y,onSelectionEnd:p,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:s,onPaneContextMenu:i,onPaneScroll:o,panOnDrag:Y,isSelecting:!!K,selectionMode:f},e,R&&A.createElement(dh,{onSelectionContextMenu:N,noPanClassName:H,disableKeyboardA11y:k})))};Co.displayName="FlowRenderer";var hh=w.memo(Co);function mh(e){return ae(w.useCallback(n=>e?so(n.nodeInternals,{x:0,y:0,width:n.width,height:n.height},n.transform,!0):n.getNodes(),[e]))}function ph(e){const t={input:Tt(e.input||mo),default:Tt(e.default||mr),output:Tt(e.output||go),group:Tt(e.group||Rr)},n={},r=Object.keys(e).filter(s=>!["input","default","output","group"].includes(s)).reduce((s,i)=>(s[i]=Tt(e[i]||mr),s),n);return{...t,...r}}const gh=({x:e,y:t,width:n,height:r,origin:s})=>!n||!r?{x:e,y:t}:s[0]<0||s[1]<0||s[0]>1||s[1]>1?{x:e,y:t}:{x:e-n*s[0],y:t-r*s[1]},yh=e=>({nodesDraggable:e.nodesDraggable,nodesConnectable:e.nodesConnectable,nodesFocusable:e.nodesFocusable,elementsSelectable:e.elementsSelectable,updateNodeDimensions:e.updateNodeDimensions,onError:e.onError}),$o=e=>{const{nodesDraggable:t,nodesConnectable:n,nodesFocusable:r,elementsSelectable:s,updateNodeDimensions:i,onError:o}=ae(yh,ge),a=mh(e.onlyRenderVisibleElements),l=w.useRef(),c=w.useMemo(()=>{if(typeof ResizeObserver>"u")return null;const u=new ResizeObserver(d=>{const m=d.map(f=>({id:f.target.getAttribute("data-id"),nodeElement:f.target,forceUpdate:!0}));i(m)});return l.current=u,u},[]);return w.useEffect(()=>()=>{var u;(u=l==null?void 0:l.current)==null||u.disconnect()},[]),A.createElement("div",{className:"react-flow__nodes",style:Tr},a.map(u=>{var j,C,E;let d=u.type||"default";e.nodeTypes[d]||(o==null||o("003",Be.error003(d)),d="default");const m=e.nodeTypes[d]||e.nodeTypes.default,f=!!(u.draggable||t&&typeof u.draggable>"u"),y=!!(u.selectable||s&&typeof u.selectable>"u"),p=!!(u.connectable||n&&typeof u.connectable>"u"),v=!!(u.focusable||r&&typeof u.focusable>"u"),x=e.nodeExtent?jr(u.positionAbsolute,e.nodeExtent):u.positionAbsolute,_=(x==null?void 0:x.x)??0,M=(x==null?void 0:x.y)??0,b=gh({x:_,y:M,width:u.width??0,height:u.height??0,origin:e.nodeOrigin});return A.createElement(m,{key:u.id,id:u.id,className:u.className,style:u.style,type:d,data:u.data,sourcePosition:u.sourcePosition||Z.Bottom,targetPosition:u.targetPosition||Z.Top,hidden:u.hidden,xPos:_,yPos:M,xPosOrigin:b.x,yPosOrigin:b.y,selectNodesOnDrag:e.selectNodesOnDrag,onClick:e.onNodeClick,onMouseEnter:e.onNodeMouseEnter,onMouseMove:e.onNodeMouseMove,onMouseLeave:e.onNodeMouseLeave,onContextMenu:e.onNodeContextMenu,onDoubleClick:e.onNodeDoubleClick,selected:!!u.selected,isDraggable:f,isSelectable:y,isConnectable:p,isFocusable:v,resizeObserver:c,dragHandle:u.dragHandle,zIndex:((j=u[le])==null?void 0:j.z)??0,isParent:!!((C=u[le])!=null&&C.isParent),noDragClassName:e.noDragClassName,noPanClassName:e.noPanClassName,initialized:!!u.width&&!!u.height,rfId:e.rfId,disableKeyboardA11y:e.disableKeyboardA11y,ariaLabel:u.ariaLabel,hasHandleBounds:!!((E=u[le])!=null&&E.handleBounds)})}))};$o.displayName="NodeRenderer";var xh=w.memo($o);const wh=(e,t,n)=>n===Z.Left?e-t:n===Z.Right?e+t:e,bh=(e,t,n)=>n===Z.Top?e-t:n===Z.Bottom?e+t:e,Cs="react-flow__edgeupdater",$s=({position:e,centerX:t,centerY:n,radius:r=10,onMouseDown:s,onMouseEnter:i,onMouseOut:o,type:a})=>A.createElement("circle",{onMouseDown:s,onMouseEnter:i,onMouseOut:o,className:ye([Cs,`${Cs}-${a}`]),cx:wh(t,r,e),cy:bh(n,r,e),r,stroke:"transparent",fill:"transparent"}),vh=()=>!0;var yt=e=>{const t=({id:n,className:r,type:s,data:i,onClick:o,onEdgeDoubleClick:a,selected:l,animated:c,label:u,labelStyle:d,labelShowBg:m,labelBgStyle:f,labelBgPadding:y,labelBgBorderRadius:p,style:v,source:x,target:_,sourceX:M,sourceY:b,targetX:j,targetY:C,sourcePosition:E,targetPosition:L,elementsSelectable:S,hidden:O,sourceHandleId:P,targetHandleId:V,onContextMenu:F,onMouseEnter:g,onMouseMove:$,onMouseLeave:N,reconnectRadius:I,onReconnect:H,onReconnectStart:k,onReconnectEnd:R,markerEnd:D,markerStart:z,rfId:Y,ariaLabel:G,isFocusable:K,isReconnectable:J,pathOptions:ee,interactionWidth:ie,disableKeyboardA11y:te})=>{const re=w.useRef(null),[de,B]=w.useState(!1),[q,W]=w.useState(!1),Q=pe(),U=w.useMemo(()=>`url('#${fr(z,Y)}')`,[z,Y]),X=w.useMemo(()=>`url('#${fr(D,Y)}')`,[D,Y]);if(O)return null;const T=xe=>{var Re;const{edges:Ce,addSelectedEdges:Je,unselectNodesAndEdges:et,multiSelectionActive:tt}=Q.getState(),De=Ce.find(Ct=>Ct.id===n);De&&(S&&(Q.setState({nodesSelectionActive:!1}),De.selected&&tt?(et({nodes:[],edges:[De]}),(Re=re.current)==null||Re.blur()):Je([n])),o&&o(xe,De))},se=It(n,Q.getState,a),ce=It(n,Q.getState,F),me=It(n,Q.getState,g),we=It(n,Q.getState,$),be=It(n,Q.getState,N),Ee=(xe,Ce)=>{if(xe.button!==0)return;const{edges:Je,isValidConnection:et}=Q.getState(),tt=Ce?_:x,De=(Ce?V:P)||null,Re=Ce?"target":"source",Ct=et||vh,Dn=Ce,$t=Je.find(nt=>nt.id===n);W(!0),k==null||k(xe,$t,Re);const Ln=nt=>{W(!1),R==null||R(nt,$t,Re)};co({event:xe,handleId:De,nodeId:tt,onConnect:nt=>H==null?void 0:H($t,nt),isTarget:Dn,getState:Q.getState,setState:Q.setState,isValidConnection:Ct,edgeUpdaterType:Re,onReconnectEnd:Ln})},Ge=xe=>Ee(xe,!0),oe=xe=>Ee(xe,!1),Qe=()=>B(!0),ft=()=>B(!1),ht=!S&&!o,jt=xe=>{var Ce;if(!te&&Zi.includes(xe.key)&&S){const{unselectNodesAndEdges:Je,addSelectedEdges:et,edges:tt}=Q.getState();xe.key==="Escape"?((Ce=re.current)==null||Ce.blur(),Je({edges:[tt.find(Re=>Re.id===n)]})):et([n])}};return A.createElement("g",{className:ye(["react-flow__edge",`react-flow__edge-${s}`,r,{selected:l,animated:c,inactive:ht,updating:de}]),onClick:T,onDoubleClick:se,onContextMenu:ce,onMouseEnter:me,onMouseMove:we,onMouseLeave:be,onKeyDown:K?jt:void 0,tabIndex:K?0:void 0,role:K?"button":"img","data-testid":`rf__edge-${n}`,"aria-label":G===null?void 0:G||`Edge from ${x} to ${_}`,"aria-describedby":K?`${wo}-${Y}`:void 0,ref:re},!q&&A.createElement(e,{id:n,source:x,target:_,selected:l,animated:c,label:u,labelStyle:d,labelShowBg:m,labelBgStyle:f,labelBgPadding:y,labelBgBorderRadius:p,data:i,style:v,sourceX:M,sourceY:b,targetX:j,targetY:C,sourcePosition:E,targetPosition:L,sourceHandleId:P,targetHandleId:V,markerStart:U,markerEnd:X,pathOptions:ee,interactionWidth:ie}),J&&A.createElement(A.Fragment,null,(J==="source"||J===!0)&&A.createElement($s,{position:E,centerX:M,centerY:b,radius:I,onMouseDown:Ge,onMouseEnter:Qe,onMouseOut:ft,type:"source"}),(J==="target"||J===!0)&&A.createElement($s,{position:L,centerX:j,centerY:C,radius:I,onMouseDown:oe,onMouseEnter:Qe,onMouseOut:ft,type:"target"})))};return t.displayName="EdgeWrapper",w.memo(t)};function _h(e){const t={default:yt(e.default||_n),straight:yt(e.bezier||Mr),step:yt(e.step||$r),smoothstep:yt(e.step||In),simplebezier:yt(e.simplebezier||Cr)},n={},r=Object.keys(e).filter(s=>!["default","bezier"].includes(s)).reduce((s,i)=>(s[i]=yt(e[i]||_n),s),n);return{...t,...r}}function Ms(e,t,n=null){const r=((n==null?void 0:n.x)||0)+t.x,s=((n==null?void 0:n.y)||0)+t.y,i=(n==null?void 0:n.width)||t.width,o=(n==null?void 0:n.height)||t.height;switch(e){case Z.Top:return{x:r+i/2,y:s};case Z.Right:return{x:r+i,y:s+o/2};case Z.Bottom:return{x:r+i/2,y:s+o};case Z.Left:return{x:r,y:s+o/2}}}function As(e,t){return e?e.length===1||!t?e[0]:t&&e.find(n=>n.id===t)||null:null}const Eh=(e,t,n,r,s,i)=>{const o=Ms(n,e,t),a=Ms(i,r,s);return{sourceX:o.x,sourceY:o.y,targetX:a.x,targetY:a.y}};function Nh({sourcePos:e,targetPos:t,sourceWidth:n,sourceHeight:r,targetWidth:s,targetHeight:i,width:o,height:a,transform:l}){const c={x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x+n,t.x+s),y2:Math.max(e.y+r,t.y+i)};c.x===c.x2&&(c.x2+=1),c.y===c.y2&&(c.y2+=1);const u=Gt({x:(0-l[0])/l[2],y:(0-l[1])/l[2],width:o/l[2],height:a/l[2]}),d=Math.max(0,Math.min(u.x2,c.x2)-Math.max(u.x,c.x)),m=Math.max(0,Math.min(u.y2,c.y2)-Math.max(u.y,c.y));return Math.ceil(d*m)>0}function Is(e){var r,s,i,o,a;const t=((r=e==null?void 0:e[le])==null?void 0:r.handleBounds)||null,n=t&&(e==null?void 0:e.width)&&(e==null?void 0:e.height)&&typeof((s=e==null?void 0:e.positionAbsolute)==null?void 0:s.x)<"u"&&typeof((i=e==null?void 0:e.positionAbsolute)==null?void 0:i.y)<"u";return[{x:((o=e==null?void 0:e.positionAbsolute)==null?void 0:o.x)||0,y:((a=e==null?void 0:e.positionAbsolute)==null?void 0:a.y)||0,width:(e==null?void 0:e.width)||0,height:(e==null?void 0:e.height)||0},t,!!n]}const Sh=[{level:0,isMaxLevel:!0,edges:[]}];function kh(e,t,n=!1){let r=-1;const s=e.reduce((o,a)=>{var u,d;const l=Se(a.zIndex);let c=l?a.zIndex:0;if(n){const m=t.get(a.target),f=t.get(a.source),y=a.selected||(m==null?void 0:m.selected)||(f==null?void 0:f.selected),p=Math.max(((u=f==null?void 0:f[le])==null?void 0:u.z)||0,((d=m==null?void 0:m[le])==null?void 0:d.z)||0,1e3);c=(l?a.zIndex:0)+(y?p:0)}return o[c]?o[c].push(a):o[c]=[a],r=c>r?c:r,o},{}),i=Object.entries(s).map(([o,a])=>{const l=+o;return{edges:a,level:l,isMaxLevel:l===r}});return i.length===0?Sh:i}function jh(e,t,n){const r=ae(w.useCallback(s=>e?s.edges.filter(i=>{const o=t.get(i.source),a=t.get(i.target);return(o==null?void 0:o.width)&&(o==null?void 0:o.height)&&(a==null?void 0:a.width)&&(a==null?void 0:a.height)&&Nh({sourcePos:o.positionAbsolute||{x:0,y:0},targetPos:a.positionAbsolute||{x:0,y:0},sourceWidth:o.width,sourceHeight:o.height,targetWidth:a.width,targetHeight:a.height,width:s.width,height:s.height,transform:s.transform})}):s.edges,[e,t]));return kh(r,t,n)}const Ch=({color:e="none",strokeWidth:t=1})=>A.createElement("polyline",{style:{stroke:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",fill:"none",points:"-5,-4 0,0 -5,4"}),$h=({color:e="none",strokeWidth:t=1})=>A.createElement("polyline",{style:{stroke:e,fill:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"}),Rs={[bn.Arrow]:Ch,[bn.ArrowClosed]:$h};function Mh(e){const t=pe();return w.useMemo(()=>{var s,i;return Object.prototype.hasOwnProperty.call(Rs,e)?Rs[e]:((i=(s=t.getState()).onError)==null||i.call(s,"009",Be.error009(e)),null)},[e])}const Ah=({id:e,type:t,color:n,width:r=12.5,height:s=12.5,markerUnits:i="strokeWidth",strokeWidth:o,orient:a="auto-start-reverse"})=>{const l=Mh(t);return l?A.createElement("marker",{className:"react-flow__arrowhead",id:e,markerWidth:`${r}`,markerHeight:`${s}`,viewBox:"-10 -10 20 20",markerUnits:i,orient:a,refX:"0",refY:"0"},A.createElement(l,{color:n,strokeWidth:o})):null},Ih=({defaultColor:e,rfId:t})=>n=>{const r=[];return n.edges.reduce((s,i)=>([i.markerStart,i.markerEnd].forEach(o=>{if(o&&typeof o=="object"){const a=fr(o,t);r.includes(a)||(s.push({id:a,color:o.color||e,...o}),r.push(a))}}),s),[]).sort((s,i)=>s.id.localeCompare(i.id))},Mo=({defaultColor:e,rfId:t})=>{const n=ae(w.useCallback(Ih({defaultColor:e,rfId:t}),[e,t]),(r,s)=>!(r.length!==s.length||r.some((i,o)=>i.id!==s[o].id)));return A.createElement("defs",null,n.map(r=>A.createElement(Ah,{id:r.id,key:r.id,type:r.type,color:r.color,width:r.width,height:r.height,markerUnits:r.markerUnits,strokeWidth:r.strokeWidth,orient:r.orient})))};Mo.displayName="MarkerDefinitions";var Rh=w.memo(Mo);const Th=e=>({nodesConnectable:e.nodesConnectable,edgesFocusable:e.edgesFocusable,edgesUpdatable:e.edgesUpdatable,elementsSelectable:e.elementsSelectable,width:e.width,height:e.height,connectionMode:e.connectionMode,nodeInternals:e.nodeInternals,onError:e.onError}),Ao=({defaultMarkerColor:e,onlyRenderVisibleElements:t,elevateEdgesOnSelect:n,rfId:r,edgeTypes:s,noPanClassName:i,onEdgeContextMenu:o,onEdgeMouseEnter:a,onEdgeMouseMove:l,onEdgeMouseLeave:c,onEdgeClick:u,onEdgeDoubleClick:d,onReconnect:m,onReconnectStart:f,onReconnectEnd:y,reconnectRadius:p,children:v,disableKeyboardA11y:x})=>{const{edgesFocusable:_,edgesUpdatable:M,elementsSelectable:b,width:j,height:C,connectionMode:E,nodeInternals:L,onError:S}=ae(Th,ge),O=jh(t,L,n);return j?A.createElement(A.Fragment,null,O.map(({level:P,edges:V,isMaxLevel:F})=>A.createElement("svg",{key:P,style:{zIndex:P},width:j,height:C,className:"react-flow__edges react-flow__container"},F&&A.createElement(Rh,{defaultColor:e,rfId:r}),A.createElement("g",null,V.map(g=>{const[$,N,I]=Is(L.get(g.source)),[H,k,R]=Is(L.get(g.target));if(!I||!R)return null;let D=g.type||"default";s[D]||(S==null||S("011",Be.error011(D)),D="default");const z=s[D]||s.default,Y=E===ut.Strict?k.target:(k.target??[]).concat(k.source??[]),G=As(N.source,g.sourceHandle),K=As(Y,g.targetHandle),J=(G==null?void 0:G.position)||Z.Bottom,ee=(K==null?void 0:K.position)||Z.Top,ie=!!(g.focusable||_&&typeof g.focusable>"u"),te=g.reconnectable||g.updatable,re=typeof m<"u"&&(te||M&&typeof te>"u");if(!G||!K)return S==null||S("008",Be.error008(G,g)),null;const{sourceX:de,sourceY:B,targetX:q,targetY:W}=Eh($,G,J,H,K,ee);return A.createElement(z,{key:g.id,id:g.id,className:ye([g.className,i]),type:D,data:g.data,selected:!!g.selected,animated:!!g.animated,hidden:!!g.hidden,label:g.label,labelStyle:g.labelStyle,labelShowBg:g.labelShowBg,labelBgStyle:g.labelBgStyle,labelBgPadding:g.labelBgPadding,labelBgBorderRadius:g.labelBgBorderRadius,style:g.style,source:g.source,target:g.target,sourceHandleId:g.sourceHandle,targetHandleId:g.targetHandle,markerEnd:g.markerEnd,markerStart:g.markerStart,sourceX:de,sourceY:B,targetX:q,targetY:W,sourcePosition:J,targetPosition:ee,elementsSelectable:b,onContextMenu:o,onMouseEnter:a,onMouseMove:l,onMouseLeave:c,onClick:u,onEdgeDoubleClick:d,onReconnect:m,onReconnectStart:f,onReconnectEnd:y,reconnectRadius:p,rfId:r,ariaLabel:g.ariaLabel,isFocusable:ie,isReconnectable:re,pathOptions:"pathOptions"in g?g.pathOptions:void 0,interactionWidth:g.interactionWidth,disableKeyboardA11y:x})})))),v):null};Ao.displayName="EdgeRenderer";var Oh=w.memo(Ao);const Dh=e=>`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`;function Lh({children:e}){const t=ae(Dh);return A.createElement("div",{className:"react-flow__viewport react-flow__container",style:{transform:t}},e)}function Ph(e){const t=Rn(),n=w.useRef(!1);w.useEffect(()=>{!n.current&&t.viewportInitialized&&e&&(setTimeout(()=>e(t),1),n.current=!0)},[e,t.viewportInitialized])}const zh={[Z.Left]:Z.Right,[Z.Right]:Z.Left,[Z.Top]:Z.Bottom,[Z.Bottom]:Z.Top},Io=({nodeId:e,handleType:t,style:n,type:r=Xe.Bezier,CustomComponent:s,connectionStatus:i})=>{var C,E,L;const{fromNode:o,handleId:a,toX:l,toY:c,connectionMode:u}=ae(w.useCallback(S=>({fromNode:S.nodeInternals.get(e),handleId:S.connectionHandleId,toX:(S.connectionPosition.x-S.transform[0])/S.transform[2],toY:(S.connectionPosition.y-S.transform[1])/S.transform[2],connectionMode:S.connectionMode}),[e]),ge),d=(C=o==null?void 0:o[le])==null?void 0:C.handleBounds;let m=d==null?void 0:d[t];if(u===ut.Loose&&(m=m||(d==null?void 0:d[t==="source"?"target":"source"])),!o||!m)return null;const f=a?m.find(S=>S.id===a):m[0],y=f?f.x+f.width/2:(o.width??0)/2,p=f?f.y+f.height/2:o.height??0,v=(((E=o.positionAbsolute)==null?void 0:E.x)??0)+y,x=(((L=o.positionAbsolute)==null?void 0:L.y)??0)+p,_=f==null?void 0:f.position,M=_?zh[_]:null;if(!_||!M)return null;if(s)return A.createElement(s,{connectionLineType:r,connectionLineStyle:n,fromNode:o,fromHandle:f,fromX:v,fromY:x,toX:l,toY:c,fromPosition:_,toPosition:M,connectionStatus:i});let b="";const j={sourceX:v,sourceY:x,sourcePosition:_,targetX:l,targetY:c,targetPosition:M};return r===Xe.Bezier?[b]=no(j):r===Xe.Step?[b]=vn({...j,borderRadius:0}):r===Xe.SmoothStep?[b]=vn(j):r===Xe.SimpleBezier?[b]=to(j):b=`M${v},${x} ${l},${c}`,A.createElement("path",{d:b,fill:"none",className:"react-flow__connection-path",style:n})};Io.displayName="ConnectionLine";const Hh=e=>({nodeId:e.connectionNodeId,handleType:e.connectionHandleType,nodesConnectable:e.nodesConnectable,connectionStatus:e.connectionStatus,width:e.width,height:e.height});function Fh({containerStyle:e,style:t,type:n,component:r}){const{nodeId:s,handleType:i,nodesConnectable:o,width:a,height:l,connectionStatus:c}=ae(Hh,ge);return!(s&&i&&a&&o)?null:A.createElement("svg",{style:e,width:a,height:l,className:"react-flow__edges react-flow__connectionline react-flow__container"},A.createElement("g",{className:ye(["react-flow__connection",c])},A.createElement(Io,{nodeId:s,handleType:i,style:t,type:n,CustomComponent:r,connectionStatus:c})))}function Ts(e,t){return w.useRef(null),pe(),w.useMemo(()=>t(e),[e])}const Ro=({nodeTypes:e,edgeTypes:t,onMove:n,onMoveStart:r,onMoveEnd:s,onInit:i,onNodeClick:o,onEdgeClick:a,onNodeDoubleClick:l,onEdgeDoubleClick:c,onNodeMouseEnter:u,onNodeMouseMove:d,onNodeMouseLeave:m,onNodeContextMenu:f,onSelectionContextMenu:y,onSelectionStart:p,onSelectionEnd:v,connectionLineType:x,connectionLineStyle:_,connectionLineComponent:M,connectionLineContainerStyle:b,selectionKeyCode:j,selectionOnDrag:C,selectionMode:E,multiSelectionKeyCode:L,panActivationKeyCode:S,zoomActivationKeyCode:O,deleteKeyCode:P,onlyRenderVisibleElements:V,elementsSelectable:F,selectNodesOnDrag:g,defaultViewport:$,translateExtent:N,minZoom:I,maxZoom:H,preventScrolling:k,defaultMarkerColor:R,zoomOnScroll:D,zoomOnPinch:z,panOnScroll:Y,panOnScrollSpeed:G,panOnScrollMode:K,zoomOnDoubleClick:J,panOnDrag:ee,onPaneClick:ie,onPaneMouseEnter:te,onPaneMouseMove:re,onPaneMouseLeave:de,onPaneScroll:B,onPaneContextMenu:q,onEdgeContextMenu:W,onEdgeMouseEnter:Q,onEdgeMouseMove:U,onEdgeMouseLeave:X,onReconnect:T,onReconnectStart:se,onReconnectEnd:ce,reconnectRadius:me,noDragClassName:we,noWheelClassName:be,noPanClassName:Ee,elevateEdgesOnSelect:Ge,disableKeyboardA11y:oe,nodeOrigin:Qe,nodeExtent:ft,rfId:ht})=>{const jt=Ts(e,ph),xe=Ts(t,_h);return Ph(i),A.createElement(hh,{onPaneClick:ie,onPaneMouseEnter:te,onPaneMouseMove:re,onPaneMouseLeave:de,onPaneContextMenu:q,onPaneScroll:B,deleteKeyCode:P,selectionKeyCode:j,selectionOnDrag:C,selectionMode:E,onSelectionStart:p,onSelectionEnd:v,multiSelectionKeyCode:L,panActivationKeyCode:S,zoomActivationKeyCode:O,elementsSelectable:F,onMove:n,onMoveStart:r,onMoveEnd:s,zoomOnScroll:D,zoomOnPinch:z,zoomOnDoubleClick:J,panOnScroll:Y,panOnScrollSpeed:G,panOnScrollMode:K,panOnDrag:ee,defaultViewport:$,translateExtent:N,minZoom:I,maxZoom:H,onSelectionContextMenu:y,preventScrolling:k,noDragClassName:we,noWheelClassName:be,noPanClassName:Ee,disableKeyboardA11y:oe},A.createElement(Lh,null,A.createElement(Oh,{edgeTypes:xe,onEdgeClick:a,onEdgeDoubleClick:c,onlyRenderVisibleElements:V,onEdgeContextMenu:W,onEdgeMouseEnter:Q,onEdgeMouseMove:U,onEdgeMouseLeave:X,onReconnect:T,onReconnectStart:se,onReconnectEnd:ce,reconnectRadius:me,defaultMarkerColor:R,noPanClassName:Ee,elevateEdgesOnSelect:!!Ge,disableKeyboardA11y:oe,rfId:ht},A.createElement(Fh,{style:_,type:x,component:M,containerStyle:b})),A.createElement("div",{className:"react-flow__edgelabel-renderer"}),A.createElement(xh,{nodeTypes:jt,onNodeClick:o,onNodeDoubleClick:l,onNodeMouseEnter:u,onNodeMouseMove:d,onNodeMouseLeave:m,onNodeContextMenu:f,selectNodesOnDrag:g,onlyRenderVisibleElements:V,noPanClassName:Ee,noDragClassName:we,disableKeyboardA11y:oe,nodeOrigin:Qe,nodeExtent:ft,rfId:ht})))};Ro.displayName="GraphView";var Vh=w.memo(Ro);const gr=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],Ye={rfId:"1",width:0,height:0,transform:[0,0,1],nodeInternals:new Map,edges:[],onNodesChange:null,onEdgesChange:null,hasDefaultNodes:!1,hasDefaultEdges:!1,d3Zoom:null,d3Selection:null,d3ZoomHandler:void 0,minZoom:.5,maxZoom:2,translateExtent:gr,nodeExtent:gr,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionNodeId:null,connectionHandleId:null,connectionHandleType:"source",connectionPosition:{x:0,y:0},connectionStatus:null,connectionMode:ut.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:[0,0],nodeDragThreshold:0,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesUpdatable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,fitViewOnInit:!1,fitViewOnInitDone:!1,fitViewOnInitOptions:void 0,onSelectionChange:[],multiSelectionActive:!1,connectionStartHandle:null,connectionEndHandle:null,connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,connectionRadius:20,onError:mf,isValidConnection:void 0},Bh=()=>Cl((e,t)=>({...Ye,setNodes:n=>{const{nodeInternals:r,nodeOrigin:s,elevateNodesOnSelect:i}=t();e({nodeInternals:Yn(n,r,s,i)})},getNodes:()=>Array.from(t().nodeInternals.values()),setEdges:n=>{const{defaultEdgeOptions:r={}}=t();e({edges:n.map(s=>({...r,...s}))})},setDefaultNodesAndEdges:(n,r)=>{const s=typeof n<"u",i=typeof r<"u",o=s?Yn(n,new Map,t().nodeOrigin,t().elevateNodesOnSelect):new Map;e({nodeInternals:o,edges:i?r:[],hasDefaultNodes:s,hasDefaultEdges:i})},updateNodeDimensions:n=>{const{onNodesChange:r,nodeInternals:s,fitViewOnInit:i,fitViewOnInitDone:o,fitViewOnInitOptions:a,domNode:l,nodeOrigin:c}=t(),u=l==null?void 0:l.querySelector(".react-flow__viewport");if(!u)return;const d=window.getComputedStyle(u),{m22:m}=new window.DOMMatrixReadOnly(d.transform),f=n.reduce((p,v)=>{const x=s.get(v.id);if(x!=null&&x.hidden)s.set(x.id,{...x,[le]:{...x[le],handleBounds:void 0}});else if(x){const _=kr(v.nodeElement);!!(_.width&&_.height&&(x.width!==_.width||x.height!==_.height||v.forceUpdate))&&(s.set(x.id,{...x,[le]:{...x[le],handleBounds:{source:js(".source",v.nodeElement,m,c),target:js(".target",v.nodeElement,m,c)}},..._}),p.push({id:x.id,type:"dimensions",dimensions:_}))}return p},[]);vo(s,c);const y=o||i&&!o&&_o(t,{initial:!0,...a});e({nodeInternals:new Map(s),fitViewOnInitDone:y}),(f==null?void 0:f.length)>0&&(r==null||r(f))},updateNodePositions:(n,r=!0,s=!1)=>{const{triggerNodeChanges:i}=t(),o=n.map(a=>{const l={id:a.id,type:"position",dragging:s};return r&&(l.positionAbsolute=a.positionAbsolute,l.position=a.position),l});i(o)},triggerNodeChanges:n=>{const{onNodesChange:r,nodeInternals:s,hasDefaultNodes:i,nodeOrigin:o,getNodes:a,elevateNodesOnSelect:l}=t();if(n!=null&&n.length){if(i){const c=sh(n,a()),u=Yn(c,s,o,l);e({nodeInternals:u})}r==null||r(n)}},addSelectedNodes:n=>{const{multiSelectionActive:r,edges:s,getNodes:i}=t();let o,a=null;r?o=n.map(l=>Ue(l,!0)):(o=xt(i(),n),a=xt(s,[])),on({changedNodes:o,changedEdges:a,get:t,set:e})},addSelectedEdges:n=>{const{multiSelectionActive:r,edges:s,getNodes:i}=t();let o,a=null;r?o=n.map(l=>Ue(l,!0)):(o=xt(s,n),a=xt(i(),[])),on({changedNodes:a,changedEdges:o,get:t,set:e})},unselectNodesAndEdges:({nodes:n,edges:r}={})=>{const{edges:s,getNodes:i}=t(),o=n||i(),a=r||s,l=o.map(u=>(u.selected=!1,Ue(u.id,!1))),c=a.map(u=>Ue(u.id,!1));on({changedNodes:l,changedEdges:c,get:t,set:e})},setMinZoom:n=>{const{d3Zoom:r,maxZoom:s}=t();r==null||r.scaleExtent([n,s]),e({minZoom:n})},setMaxZoom:n=>{const{d3Zoom:r,minZoom:s}=t();r==null||r.scaleExtent([s,n]),e({maxZoom:n})},setTranslateExtent:n=>{var r;(r=t().d3Zoom)==null||r.translateExtent(n),e({translateExtent:n})},resetSelectedElements:()=>{const{edges:n,getNodes:r}=t(),i=r().filter(a=>a.selected).map(a=>Ue(a.id,!1)),o=n.filter(a=>a.selected).map(a=>Ue(a.id,!1));on({changedNodes:i,changedEdges:o,get:t,set:e})},setNodeExtent:n=>{const{nodeInternals:r}=t();r.forEach(s=>{s.positionAbsolute=jr(s.position,n)}),e({nodeExtent:n,nodeInternals:new Map(r)})},panBy:n=>{const{transform:r,width:s,height:i,d3Zoom:o,d3Selection:a,translateExtent:l}=t();if(!o||!a||!n.x&&!n.y)return!1;const c=Fe.translate(r[0]+n.x,r[1]+n.y).scale(r[2]),u=[[0,0],[s,i]],d=o==null?void 0:o.constrain()(c,u,l);return o.transform(a,d),r[0]!==d.x||r[1]!==d.y||r[2]!==d.k},cancelConnection:()=>e({connectionNodeId:Ye.connectionNodeId,connectionHandleId:Ye.connectionHandleId,connectionHandleType:Ye.connectionHandleType,connectionStatus:Ye.connectionStatus,connectionStartHandle:Ye.connectionStartHandle,connectionEndHandle:Ye.connectionEndHandle}),reset:()=>e({...Ye})}),Object.is),To=({children:e})=>{const t=w.useRef(null);return t.current||(t.current=Bh()),A.createElement(af,{value:t.current},e)};To.displayName="ReactFlowProvider";const Oo=({children:e})=>w.useContext(An)?A.createElement(A.Fragment,null,e):A.createElement(To,null,e);Oo.displayName="ReactFlowWrapper";const Gh={input:mo,default:mr,output:go,group:Rr},Yh={default:_n,straight:Mr,step:$r,smoothstep:In,simplebezier:Cr},Wh=[0,0],Uh=[15,15],Xh={x:0,y:0,zoom:1},qh={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},Do=w.forwardRef(({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,className:s,nodeTypes:i=Gh,edgeTypes:o=Yh,onNodeClick:a,onEdgeClick:l,onInit:c,onMove:u,onMoveStart:d,onMoveEnd:m,onConnect:f,onConnectStart:y,onConnectEnd:p,onClickConnectStart:v,onClickConnectEnd:x,onNodeMouseEnter:_,onNodeMouseMove:M,onNodeMouseLeave:b,onNodeContextMenu:j,onNodeDoubleClick:C,onNodeDragStart:E,onNodeDrag:L,onNodeDragStop:S,onNodesDelete:O,onEdgesDelete:P,onSelectionChange:V,onSelectionDragStart:F,onSelectionDrag:g,onSelectionDragStop:$,onSelectionContextMenu:N,onSelectionStart:I,onSelectionEnd:H,connectionMode:k=ut.Strict,connectionLineType:R=Xe.Bezier,connectionLineStyle:D,connectionLineComponent:z,connectionLineContainerStyle:Y,deleteKeyCode:G="Backspace",selectionKeyCode:K="Shift",selectionOnDrag:J=!1,selectionMode:ee=Yt.Full,panActivationKeyCode:ie="Space",multiSelectionKeyCode:te=wn()?"Meta":"Control",zoomActivationKeyCode:re=wn()?"Meta":"Control",snapToGrid:de=!1,snapGrid:B=Uh,onlyRenderVisibleElements:q=!1,selectNodesOnDrag:W=!0,nodesDraggable:Q,nodesConnectable:U,nodesFocusable:X,nodeOrigin:T=Wh,edgesFocusable:se,edgesUpdatable:ce,elementsSelectable:me,defaultViewport:we=Xh,minZoom:be=.5,maxZoom:Ee=2,translateExtent:Ge=gr,preventScrolling:oe=!0,nodeExtent:Qe,defaultMarkerColor:ft="#b1b1b7",zoomOnScroll:ht=!0,zoomOnPinch:jt=!0,panOnScroll:xe=!1,panOnScrollSpeed:Ce=.5,panOnScrollMode:Je=ot.Free,zoomOnDoubleClick:et=!0,panOnDrag:tt=!0,onPaneClick:De,onPaneMouseEnter:Re,onPaneMouseMove:Ct,onPaneMouseLeave:Dn,onPaneScroll:$t,onPaneContextMenu:Ln,children:Vr,onEdgeContextMenu:nt,onEdgeDoubleClick:_a,onEdgeMouseEnter:Ea,onEdgeMouseMove:Na,onEdgeMouseLeave:Sa,onEdgeUpdate:ka,onEdgeUpdateStart:ja,onEdgeUpdateEnd:Ca,onReconnect:$a,onReconnectStart:Ma,onReconnectEnd:Aa,reconnectRadius:Ia=10,edgeUpdaterRadius:Ra=10,onNodesChange:Ta,onEdgesChange:Oa,noDragClassName:Da="nodrag",noWheelClassName:La="nowheel",noPanClassName:Br="nopan",fitView:Pa=!1,fitViewOptions:za,connectOnClick:Ha=!0,attributionPosition:Fa,proOptions:Va,defaultEdgeOptions:Ba,elevateNodesOnSelect:Ga=!0,elevateEdgesOnSelect:Ya=!1,disableKeyboardA11y:Gr=!1,autoPanOnConnect:Wa=!0,autoPanOnNodeDrag:Ua=!0,connectionRadius:Xa=20,isValidConnection:qa,onError:Ka,style:Za,id:Yr,nodeDragThreshold:Qa,...Ja},el)=>{const Pn=Yr||"1";return A.createElement("div",{...Ja,style:{...Za,...qh},ref:el,className:ye(["react-flow",s]),"data-testid":"rf__wrapper",id:Yr},A.createElement(Oo,null,A.createElement(Vh,{onInit:c,onMove:u,onMoveStart:d,onMoveEnd:m,onNodeClick:a,onEdgeClick:l,onNodeMouseEnter:_,onNodeMouseMove:M,onNodeMouseLeave:b,onNodeContextMenu:j,onNodeDoubleClick:C,nodeTypes:i,edgeTypes:o,connectionLineType:R,connectionLineStyle:D,connectionLineComponent:z,connectionLineContainerStyle:Y,selectionKeyCode:K,selectionOnDrag:J,selectionMode:ee,deleteKeyCode:G,multiSelectionKeyCode:te,panActivationKeyCode:ie,zoomActivationKeyCode:re,onlyRenderVisibleElements:q,selectNodesOnDrag:W,defaultViewport:we,translateExtent:Ge,minZoom:be,maxZoom:Ee,preventScrolling:oe,zoomOnScroll:ht,zoomOnPinch:jt,zoomOnDoubleClick:et,panOnScroll:xe,panOnScrollSpeed:Ce,panOnScrollMode:Je,panOnDrag:tt,onPaneClick:De,onPaneMouseEnter:Re,onPaneMouseMove:Ct,onPaneMouseLeave:Dn,onPaneScroll:$t,onPaneContextMenu:Ln,onSelectionContextMenu:N,onSelectionStart:I,onSelectionEnd:H,onEdgeContextMenu:nt,onEdgeDoubleClick:_a,onEdgeMouseEnter:Ea,onEdgeMouseMove:Na,onEdgeMouseLeave:Sa,onReconnect:$a??ka,onReconnectStart:Ma??ja,onReconnectEnd:Aa??Ca,reconnectRadius:Ia??Ra,defaultMarkerColor:ft,noDragClassName:Da,noWheelClassName:La,noPanClassName:Br,elevateEdgesOnSelect:Ya,rfId:Pn,disableKeyboardA11y:Gr,nodeOrigin:T,nodeExtent:Qe}),A.createElement(Pf,{nodes:e,edges:t,defaultNodes:n,defaultEdges:r,onConnect:f,onConnectStart:y,onConnectEnd:p,onClickConnectStart:v,onClickConnectEnd:x,nodesDraggable:Q,nodesConnectable:U,nodesFocusable:X,edgesFocusable:se,edgesUpdatable:ce,elementsSelectable:me,elevateNodesOnSelect:Ga,minZoom:be,maxZoom:Ee,nodeExtent:Qe,onNodesChange:Ta,onEdgesChange:Oa,snapToGrid:de,snapGrid:B,connectionMode:k,translateExtent:Ge,connectOnClick:Ha,defaultEdgeOptions:Ba,fitView:Pa,fitViewOptions:za,onNodesDelete:O,onEdgesDelete:P,onNodeDragStart:E,onNodeDrag:L,onNodeDragStop:S,onSelectionDrag:g,onSelectionDragStart:F,onSelectionDragStop:$,noPanClassName:Br,nodeOrigin:T,rfId:Pn,autoPanOnConnect:Wa,autoPanOnNodeDrag:Ua,onError:Ka,connectionRadius:Xa,isValidConnection:qa,nodeDragThreshold:Qa}),A.createElement(Df,{onSelectionChange:V}),Vr,A.createElement(cf,{proOptions:Va,position:Fa}),A.createElement(Bf,{rfId:Pn,disableKeyboardA11y:Gr})))});Do.displayName="ReactFlow";const Lo=({id:e,x:t,y:n,width:r,height:s,style:i,color:o,strokeColor:a,strokeWidth:l,className:c,borderRadius:u,shapeRendering:d,onClick:m,selected:f})=>{const{background:y,backgroundColor:p}=i||{},v=o||y||p;return A.createElement("rect",{className:ye(["react-flow__minimap-node",{selected:f},c]),x:t,y:n,rx:u,ry:u,width:r,height:s,fill:v,stroke:a,strokeWidth:l,shapeRendering:d,onClick:m?x=>m(x,e):void 0})};Lo.displayName="MiniMapNode";var Kh=w.memo(Lo);const Zh=e=>e.nodeOrigin,Qh=e=>e.getNodes().filter(t=>!t.hidden&&t.width&&t.height),qn=e=>e instanceof Function?e:()=>e;function Jh({nodeStrokeColor:e="transparent",nodeColor:t="#e2e2e2",nodeClassName:n="",nodeBorderRadius:r=5,nodeStrokeWidth:s=2,nodeComponent:i=Kh,onClick:o}){const a=ae(Qh,ge),l=ae(Zh),c=qn(t),u=qn(e),d=qn(n),m=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return A.createElement(A.Fragment,null,a.map(f=>{const{x:y,y:p}=lt(f,l).positionAbsolute;return A.createElement(i,{key:f.id,x:y,y:p,width:f.width,height:f.height,style:f.style,selected:f.selected,className:d(f),color:c(f),borderRadius:r,strokeColor:u(f),strokeWidth:s,shapeRendering:m,onClick:o,id:f.id})}))}var em=w.memo(Jh);const tm=200,nm=150,rm=e=>{const t=e.getNodes(),n={x:-e.transform[0]/e.transform[2],y:-e.transform[1]/e.transform[2],width:e.width/e.transform[2],height:e.height/e.transform[2]};return{viewBB:n,boundingRect:t.length>0?ff(Kt(t,e.nodeOrigin),n):n,rfId:e.rfId}},sm="react-flow__minimap-desc";function Po({style:e,className:t,nodeStrokeColor:n="transparent",nodeColor:r="#e2e2e2",nodeClassName:s="",nodeBorderRadius:i=5,nodeStrokeWidth:o=2,nodeComponent:a,maskColor:l="rgb(240, 240, 240, 0.6)",maskStrokeColor:c="none",maskStrokeWidth:u=1,position:d="bottom-right",onClick:m,onNodeClick:f,pannable:y=!1,zoomable:p=!1,ariaLabel:v="React Flow mini map",inversePan:x=!1,zoomStep:_=10,offsetScale:M=5}){const b=pe(),j=w.useRef(null),{boundingRect:C,viewBB:E,rfId:L}=ae(rm,ge),S=(e==null?void 0:e.width)??tm,O=(e==null?void 0:e.height)??nm,P=C.width/S,V=C.height/O,F=Math.max(P,V),g=F*S,$=F*O,N=M*F,I=C.x-(g-C.width)/2-N,H=C.y-($-C.height)/2-N,k=g+N*2,R=$+N*2,D=`${sm}-${L}`,z=w.useRef(0);z.current=F,w.useEffect(()=>{if(j.current){const K=Ne(j.current),J=te=>{const{transform:re,d3Selection:de,d3Zoom:B}=b.getState();if(te.sourceEvent.type!=="wheel"||!de||!B)return;const q=-te.sourceEvent.deltaY*(te.sourceEvent.deltaMode===1?.05:te.sourceEvent.deltaMode?1:.002)*_,W=re[2]*Math.pow(2,q);B.scaleTo(de,W)},ee=te=>{const{transform:re,d3Selection:de,d3Zoom:B,translateExtent:q,width:W,height:Q}=b.getState();if(te.sourceEvent.type!=="mousemove"||!de||!B)return;const U=z.current*Math.max(1,re[2])*(x?-1:1),X={x:re[0]-te.sourceEvent.movementX*U,y:re[1]-te.sourceEvent.movementY*U},T=[[0,0],[W,Q]],se=Fe.translate(X.x,X.y).scale(re[2]),ce=B.constrain()(se,T,q);B.transform(de,ce)},ie=Yi().on("zoom",y?ee:null).on("zoom.wheel",p?J:null);return K.call(ie),()=>{K.on("zoom",null)}}},[y,p,x,_]);const Y=m?K=>{const J=$e(K);m(K,{x:J[0],y:J[1]})}:void 0,G=f?(K,J)=>{const ee=b.getState().nodeInternals.get(J);f(K,ee)}:void 0;return A.createElement(Sr,{position:d,style:e,className:ye(["react-flow__minimap",t]),"data-testid":"rf__minimap"},A.createElement("svg",{width:S,height:O,viewBox:`${I} ${H} ${k} ${R}`,role:"img","aria-labelledby":D,ref:j,onClick:Y},v&&A.createElement("title",{id:D},v),A.createElement(em,{onClick:G,nodeColor:r,nodeStrokeColor:n,nodeBorderRadius:i,nodeClassName:s,nodeStrokeWidth:o,nodeComponent:a}),A.createElement("path",{className:"react-flow__minimap-mask",d:`M${I-N},${H-N}h${k+N*2}v${R+N*2}h${-k-N*2}z + M${E.x},${E.y}h${E.width}v${E.height}h${-E.width}z`,fill:l,fillRule:"evenodd",stroke:c,strokeWidth:u,pointerEvents:"none"})))}Po.displayName="MiniMap";var im=w.memo(Po);function om(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32"},A.createElement("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"}))}function am(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5"},A.createElement("path",{d:"M0 0h32v4.2H0z"}))}function lm(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30"},A.createElement("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"}))}function cm(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},A.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"}))}function um(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},A.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"}))}const Lt=({children:e,className:t,...n})=>A.createElement("button",{type:"button",className:ye(["react-flow__controls-button",t]),...n},e);Lt.displayName="ControlButton";const dm=e=>({isInteractive:e.nodesDraggable||e.nodesConnectable||e.elementsSelectable,minZoomReached:e.transform[2]<=e.minZoom,maxZoomReached:e.transform[2]>=e.maxZoom}),zo=({style:e,showZoom:t=!0,showFitView:n=!0,showInteractive:r=!0,fitViewOptions:s,onZoomIn:i,onZoomOut:o,onFitView:a,onInteractiveChange:l,className:c,children:u,position:d="bottom-left"})=>{const m=pe(),[f,y]=w.useState(!1),{isInteractive:p,minZoomReached:v,maxZoomReached:x}=ae(dm,ge),{zoomIn:_,zoomOut:M,fitView:b}=Rn();if(w.useEffect(()=>{y(!0)},[]),!f)return null;const j=()=>{_(),i==null||i()},C=()=>{M(),o==null||o()},E=()=>{b(s),a==null||a()},L=()=>{m.setState({nodesDraggable:!p,nodesConnectable:!p,elementsSelectable:!p}),l==null||l(!p)};return A.createElement(Sr,{className:ye(["react-flow__controls",c]),position:d,style:e,"data-testid":"rf__controls"},t&&A.createElement(A.Fragment,null,A.createElement(Lt,{onClick:j,className:"react-flow__controls-zoomin",title:"zoom in","aria-label":"zoom in",disabled:x},A.createElement(om,null)),A.createElement(Lt,{onClick:C,className:"react-flow__controls-zoomout",title:"zoom out","aria-label":"zoom out",disabled:v},A.createElement(am,null))),n&&A.createElement(Lt,{className:"react-flow__controls-fitview",onClick:E,title:"fit view","aria-label":"fit view"},A.createElement(lm,null)),r&&A.createElement(Lt,{className:"react-flow__controls-interactive",onClick:L,title:"toggle interactivity","aria-label":"toggle interactivity"},p?A.createElement(um,null):A.createElement(cm,null)),u)};zo.displayName="Controls";var fm=w.memo(zo),ke;(function(e){e.Lines="lines",e.Dots="dots",e.Cross="cross"})(ke||(ke={}));function hm({color:e,dimensions:t,lineWidth:n}){return A.createElement("path",{stroke:e,strokeWidth:n,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`})}function mm({color:e,radius:t}){return A.createElement("circle",{cx:t,cy:t,r:t,fill:e})}const pm={[ke.Dots]:"#91919a",[ke.Lines]:"#eee",[ke.Cross]:"#e2e2e2"},gm={[ke.Dots]:1,[ke.Lines]:1,[ke.Cross]:6},ym=e=>({transform:e.transform,patternId:`pattern-${e.rfId}`});function Ho({id:e,variant:t=ke.Dots,gap:n=20,size:r,lineWidth:s=1,offset:i=2,color:o,style:a,className:l}){const c=w.useRef(null),{transform:u,patternId:d}=ae(ym,ge),m=o||pm[t],f=r||gm[t],y=t===ke.Dots,p=t===ke.Cross,v=Array.isArray(n)?n:[n,n],x=[v[0]*u[2]||1,v[1]*u[2]||1],_=f*u[2],M=p?[_,_]:x,b=y?[_/i,_/i]:[M[0]/i,M[1]/i];return A.createElement("svg",{className:ye(["react-flow__background",l]),style:{...a,position:"absolute",width:"100%",height:"100%",top:0,left:0},ref:c,"data-testid":"rf__background"},A.createElement("pattern",{id:d+e,x:u[0]%x[0],y:u[1]%x[1],width:x[0],height:x[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${b[0]},-${b[1]})`},y?A.createElement(mm,{color:m,radius:_/i}):A.createElement(hm,{dimensions:M,color:m,lineWidth:s})),A.createElement("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${d+e})`}))}Ho.displayName="Background";var xm=w.memo(Ho);const Or=(()=>{const e=window.location.pathname.match(/^(\/view\/[^/]+)(?:\/|$)/);return e?e[1]:""})();function Fo(e){return Or+e}async function he(e){const t=await fetch(Fo(e));if(!t.ok)throw new Error(`${e}: ${t.status} ${await t.text()}`);return await t.json()}async function Ze(e,t){const n=await fetch(Fo(e),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),r=await n.json();if(!n.ok)throw new Vo(r.error??`${e}: ${n.status}`,n.status);return r}class Vo extends Error{constructor(n,r){super(n);ue(this,"status");this.status=r}}const yx=e=>he(e?`/api/model?subject_area=${encodeURIComponent(e)}`:"/api/model"),xx=()=>he("/api/diagnostics"),Bo=(e,t)=>he(`/api/ontology/search?q=${encodeURIComponent(e)}`+(t?`&within=${encodeURIComponent(t)}`:"")),Go=()=>he("/api/ontology/ontologies"),wm=e=>he(`/api/ontology/term?ref=${encodeURIComponent(e)}`),bm=()=>he("/api/ontology/stack"),vm=()=>he("/api/ontology/coverage"),_m=(e,t,n)=>Ze("/api/command",{op:e,payload:t,fingerprint:n??""}),Em=()=>he("/api/git/status"),Nm=()=>he("/api/git/diff"),Sm=e=>Ze("/api/git/commit",{message:e}),km=()=>Ze("/api/git/discard",{}),jm=()=>he("/api/decisions"),Os=(e,t)=>Ze(`/api/decisions/${e}/verdict`,{verdict:t}),wx=(e={})=>{const t=new URLSearchParams;return e.subject_area&&t.set("subject_area",e.subject_area),e.q&&t.set("q",e.q),he(`/api/glossary/terms?${t.toString()}`)},bx=()=>he("/api/glossary/config"),vx=e=>Ze("/api/git/propose",e),_x=(e="HEAD")=>he(`/api/git/diff/model?base=${encodeURIComponent(e)}`),Ex=(e="HEAD")=>he(`/api/git/classify?base=${encodeURIComponent(e)}`),Nx=e=>Ze("/api/git/classify",{changes:e}),Sx=e=>he(`/api/git/conflicts?base=${encodeURIComponent(e)}`),kx=(e="")=>he(`/api/git/context?user=${encodeURIComponent(e)}`),jx=(e="")=>he(`/api/git/proposals?user=${encodeURIComponent(e)}`),Cm=()=>he("/api/export"),$m=(e,t)=>{const n=t?`?dialect=${encodeURIComponent(t)}`:"";return`${Or}/api/export/${encodeURIComponent(e)}${n}`},Mm=(e,t,n)=>Ze("/api/import",{format:e,content:t,dialect:n}),Cx=async e=>{for(const t of e)await _m(t.op,t.payload)},$x=(e,t,n)=>fetch(`${Or}/api/preview`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({changes:e,subject_area:t??""}),signal:n}).then(async r=>{if(!r.ok)throw new Vo(await r.text(),r.status);return await r.json()}),Mx=()=>he("/api/glossary/subject-areas"),Ax=e=>he(`/api/glossary/subject-area/${e}`),Ix=(e,t)=>Ze(`/api/glossary/subject-area/${e}/expand`,t),Am={business_key:"🔑",surrogate_key:"#",measure:"Σ",attribute:""};function Im(e){return e??""}const Dr="__entity_source",Lr="__entity_target",Rm=w.memo(function({data:t,selected:n}){var C;const{entity:r,color:s,dimmed:i,highlighted:o,showTypes:a,collapseDetail:l,expanded:c,onToggleExpand:u,endpointAttrs:d,highlightAttrs:m,dimAttrs:f,onHoverAttr:y}=t,p=E=>E.role==="business_key"?0:d!=null&&d.has(E.id)?1:2,v=[...r.attributes].map((E,L)=>({a:E,i:L})).sort((E,L)=>p(E.a)-p(L.a)||E.i-L.i).map(E=>E.a),x=v.filter(E=>E.role==="business_key");let _=v.filter(E=>E.role!=="business_key");const M=!!l&&!c;let b=0;if(M){const E=_.filter(L=>d==null?void 0:d.has(L.id));b=_.length-E.length,_=E}const j=(E,L)=>{const S="attr-row"+(m!=null&&m.has(E.id)?" rel-hit":"")+(f!=null&&f.has(E.id)?" rel-dim":"")+(d!=null&&d.has(E.id)?" endpoint":"");return h.jsxs("div",{className:S,onMouseEnter:y?()=>y(E.id):void 0,onMouseLeave:y?()=>y(null):void 0,children:[h.jsx(qe,{id:E.id,type:"target",position:Z.Left,className:"port attr-port"}),h.jsx(qe,{id:E.id,type:"source",position:Z.Right,className:"port attr-port"}),h.jsx("span",{className:"attr-icon",children:Am[E.role]}),h.jsx("span",{className:"attr-name"+(L?" pk":""),children:E.name}),a&&h.jsx("span",{className:"attr-type",children:Im(E.domain)}),!E.nullable&&h.jsx("span",{className:"attr-notnull",title:"not null",children:"●"})]},E.id)};return h.jsxs("div",{className:"entity-node"+(n?" selected":"")+(i?" dimmed":"")+(o?" highlighted":""),style:{borderTopColor:s},children:[h.jsx(qe,{id:Lr,type:"target",position:Z.Left,className:"port"}),h.jsx(qe,{id:Dr,type:"source",position:Z.Right,className:"port"}),h.jsxs("div",{className:"entity-header",children:[h.jsx("span",{className:"entity-name",title:((C=r.conceptual)==null?void 0:C.definition)??void 0,children:r.name}),h.jsxs("span",{className:"entity-badges",children:[r.pattern&&h.jsx("span",{className:"badge pattern",children:r.pattern}),(()=>{var S;const E=(((S=r.conceptual)==null?void 0:S.ontology_refs)??[]).filter(O=>O.uri);if(E.length===0)return null;const L=E.map(O=>O.uri).join(` +`);return h.jsxs("span",{className:"badge ontology",title:L,children:["⚙",E.length>1?` ${E.length}`:""]})})()]})]}),x.length>0&&h.jsx("div",{className:"attr-section keys",children:x.map(E=>j(E,!0))}),h.jsxs("div",{className:"attr-section",children:[_.map(E=>j(E,!1)),r.attributes.length===0&&h.jsx("div",{className:"attr-row empty",children:"no attributes"}),b>0&&h.jsx("div",{className:"attr-row more",title:"Show all columns",onClick:u?()=>u(r.id):void 0,children:`+${b} more`}),c&&!!l&&h.jsx("div",{className:"attr-row more",title:"Collapse to keys",onClick:u?()=>u(r.id):void 0,children:"− collapse"})]})]})}),Tm=["string","integer","bigint","decimal","boolean","date","timestamp"];function Om({entity:e,doc:t,caps:n,exec:r,onClose:s,onFocusEntity:i,onAlign:o,onEditMapping:a}){var m,f,y,p,v,x,_,M,b,j,C,E,L;const l=!n.canEdit,c=e.conceptual,u=t.relationships.filter(S=>S.from.entity===e.id||S.to.entity===e.id),d=S=>{var O;return((O=t.entities.find(P=>P.id===S))==null?void 0:O.name)??S};return h.jsxs("aside",{className:"detail-panel",children:[h.jsxs("div",{className:"detail-header",children:[h.jsxs("div",{style:{flex:1},children:[h.jsx(Pe,{value:e.name,className:"entity-title-input",readOnly:l,onCommit:S=>r("rename_entity",{id:e.id,name:S})}),(e.physical_name||!l)&&h.jsxs("div",{className:"physical-name-row",title:"Physical table name (erwin Physical_Name)",children:[h.jsx("span",{className:"physical-label",children:"physical"}),h.jsx(Pe,{value:e.physical_name??"",className:"physical-name-input",placeholder:l?"—":"physical table name…",readOnly:l,onCommit:S=>r("rename_entity",{id:e.id,physical_name:S})})]}),h.jsxs("div",{children:[h.jsx(Lm,{entity:e,doc:t,readOnly:l,exec:r}),h.jsx(zm,{entity:e,readOnly:l,exec:r}),e.category&&h.jsx("span",{className:"cat-badge "+e.category.role,title:e.category.role==="supertype"?`Supertype of category "${e.category.category}"`:`Subtype in "${e.category.category}" (${e.category.materialization})`,children:e.category.role==="supertype"?"◆ supertype":"◇ subtype"})]})]}),h.jsx("button",{className:"icon-btn",onClick:s,title:"Close",children:"✕"})]}),h.jsxs("section",{children:[h.jsx("h3",{children:"Definition"}),h.jsx(Pe,{value:((m=c==null?void 0:c.definition)==null?void 0:m.trim())??"",multiline:!0,placeholder:l?"—":"add a business definition…",className:"definition-input",readOnly:l,onCommit:S=>r("set_definition",{id:e.id,definition:S})})]}),h.jsxs("section",{children:[h.jsxs("h3",{children:["Ontology",!l&&h.jsxs("span",{className:"h3-actions",children:[h.jsx("button",{className:"mini-btn",onClick:()=>o(e),children:(((f=c==null?void 0:c.ontology_refs)==null?void 0:f.length)??0)>0?"Add / re-align…":"Align…"}),(((y=c==null?void 0:c.ontology_refs)==null?void 0:y.length)??0)>0&&h.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_alignment",{id:e.id}),title:"Clear every alignment on this object",children:"Clear all"})]})]}),(c==null?void 0:c.ontology_layer)&&h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"layer"}),h.jsx("span",{className:`chip layer-${c.ontology_layer}`,children:c.ontology_layer}),c.no_industry_equivalent&&h.jsx("span",{className:"chip",title:"reviewed: no industry equivalent",children:"no industry equivalent"})]}),h.jsx(Dm,{entityId:e.id,refs:(c==null?void 0:c.ontology_refs)??[],caps:n,exec:r})]}),h.jsxs("section",{children:[h.jsxs("h3",{children:["Knowledge Graph mapping",!l&&h.jsxs("span",{className:"h3-actions",children:[h.jsx("button",{className:"mini-btn",onClick:()=>a(e),children:(p=e.term_map)!=null&&p.subject_template||(v=e.term_map)!=null&&v.class_iri?"Edit mapping…":"Map…"}),(((x=e.term_map)==null?void 0:x.subject_template)||((_=e.term_map)==null?void 0:_.class_iri))&&h.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_term_map",{id:e.id}),children:"Clear"})]})]}),(M=e.term_map)!=null&&M.subject_template||(b=e.term_map)!=null&&b.class_iri?h.jsxs(h.Fragment,{children:[((j=e.term_map)==null?void 0:j.class_iri)&&h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"class IRI"}),h.jsx("code",{className:"v",children:e.term_map.class_iri})]}),((C=e.term_map)==null?void 0:C.subject_template)&&h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"subject"}),h.jsx("code",{className:"v",children:e.term_map.subject_template})]})]}):h.jsxs("p",{className:"empty-hint",children:["uses the default R2RML term-map (base IRI",t.project.kg_base_iri?` ${t.project.kg_base_iri}`:""," + primary key)"]})]}),h.jsxs("section",{children:[h.jsx("h3",{children:"Stewardship"}),h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"owner"}),h.jsx(Pe,{value:((E=c==null?void 0:c.stewardship)==null?void 0:E.owner)??"",placeholder:"—",readOnly:l,onCommit:S=>{var O;return r("set_stewardship",{id:e.id,owner:S,steward:((O=c==null?void 0:c.stewardship)==null?void 0:O.steward)??null})}})]}),h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"steward"}),h.jsx(Pe,{value:((L=c==null?void 0:c.stewardship)==null?void 0:L.steward)??"",placeholder:"—",readOnly:l,onCommit:S=>{var O;return r("set_stewardship",{id:e.id,owner:((O=c==null?void 0:c.stewardship)==null?void 0:O.owner)??null,steward:S})}})]})]}),h.jsxs("section",{children:[h.jsxs("h3",{children:["Attributes (",e.attributes.length,")"]}),h.jsx("table",{className:"attr-table",children:h.jsx("tbody",{children:e.attributes.map(S=>h.jsx(Fm,{a:S,entity:e,doc:t,readOnly:l,exec:r},S.id))})}),!l&&h.jsx(Vm,{entity:e,exec:r})]}),e.key_groups&&e.key_groups.length>0&&h.jsxs("section",{children:[h.jsxs("h3",{children:["Keys (",e.key_groups.length,")"]}),e.key_groups.map(S=>{const O=S.members.map(P=>{var V;return((V=e.attributes.find(F=>F.id===P))==null?void 0:V.name)??"?"}).join(", ");return h.jsxs("div",{className:"key-row",children:[h.jsx("span",{className:"key-badge "+S.type,children:S.type.toUpperCase()}),h.jsx("span",{className:"key-name",children:S.name}),h.jsx("span",{className:"key-cols",children:O})]},S.id)})]}),e.udp&&Object.keys(e.udp).length>0&&h.jsxs("section",{children:[h.jsx("h3",{children:"Properties (UDP)"}),h.jsx("table",{className:"attr-table",children:h.jsx("tbody",{children:Object.entries(e.udp).map(([S,O])=>h.jsxs("tr",{className:"udp-row",children:[h.jsx("td",{className:"udp-key",children:S}),h.jsx("td",{className:"udp-val",children:String(O)})]},S))})})]}),u.length>0&&h.jsxs("section",{children:[h.jsxs("h3",{children:["Relationships (",u.length,")"]}),u.map(S=>{const O=S.from.entity===e.id?S.to.entity:S.from.entity;return h.jsxs("div",{className:"rel-row",children:[h.jsxs("div",{className:"rel-main",children:[h.jsxs("button",{className:"rel-link",onClick:()=>i(O),children:[h.jsx("span",{className:"rel-card",children:Bm(S,e.id)}),d(O)]}),(S.verb_phrase||S.inverse_verb_phrase||!l)&&h.jsxs("div",{className:"verb-phrases",title:"erwin verb phrases (parent → child, and inverse)",children:[h.jsx(Pe,{value:S.verb_phrase??"",className:"verb-input",placeholder:l?"":"verb phrase…",readOnly:l,onCommit:P=>r("update_relationship",{id:S.id,verb_phrase:P})}),h.jsx("span",{className:"verb-sep",children:"/"}),h.jsx(Pe,{value:S.inverse_verb_phrase??"",className:"verb-input",placeholder:l?"":"inverse…",readOnly:l,onCommit:P=>r("update_relationship",{id:S.id,inverse_verb_phrase:P})})]})]}),!l&&h.jsx("button",{className:"mini-btn danger",title:`delete ${S.name}`,onClick:()=>r("delete_relationship",{id:S.id}),children:"✕"})]},S.id)})]}),h.jsxs("section",{children:[h.jsx("h3",{children:"Identity"}),h.jsx("code",{className:"ulid",title:"Immutable ULID — click to copy",onClick:()=>{var S;return(S=navigator.clipboard)==null?void 0:S.writeText(e.id)},children:e.id}),!l&&h.jsx("div",{style:{marginTop:12},children:h.jsx("button",{className:"mini-btn danger",onClick:()=>{confirm(`Delete entity '${e.name}' (and its relationships)?`)&&r("delete_entity",{id:e.id,cascade:!0}).then(s)},children:"Delete entity…"})})]})]})}function Dm({entityId:e,refs:t,caps:n,exec:r}){const s=!n.canEdit,i=t.filter(o=>o.uri);return i.length===0?h.jsx("p",{className:"empty-hint",children:"not aligned to any ontology term"}):h.jsx("div",{className:"ref-list",children:i.map((o,a)=>{const l=o.status==="proposed";return h.jsxs("div",{className:"ref-card"+(l?" proposed":""),children:[h.jsxs("div",{className:"ref-head",children:[h.jsx("code",{className:"ref-uri",title:o.uri??void 0,children:o.uri}),h.jsx("span",{className:"ref-status "+(l?"proposed":"accepted"),children:l?"proposed":"accepted"})]}),h.jsxs("div",{className:"ref-meta",children:[o.predicate&&h.jsx("span",{className:"ref-pill",children:o.predicate}),o.layer&&h.jsx("span",{className:`chip layer-${o.layer}`,children:o.layer}),o.resolved_via&&h.jsxs("span",{className:"ref-via",title:"resolver that found this term",children:["via ",o.resolved_via]}),typeof o.confidence=="number"&&h.jsxs("span",{className:"ref-via",children:["conf ",Math.round(o.confidence*100),"%"]})]}),!s&&h.jsxs("div",{className:"ref-actions",children:[l&&n.canArbitrate&&h.jsx("button",{className:"mini-btn",onClick:()=>r("promote_alignment",{id:e,uri:o.uri}),title:"Accept this proposed alignment (architect action)",children:"Promote"}),h.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_alignment",{id:e,uri:o.uri}),title:"Remove this alignment",children:"Remove"})]})]},`${o.uri}-${a}`)})})}function Pe({value:e,onCommit:t,readOnly:n,multiline:r=!1,placeholder:s="",className:i=""}){const[o,a]=w.useState(e);w.useEffect(()=>a(e),[e]);const l=()=>{o.trim()!==e.trim()&&t(o.trim())};return n?h.jsx("span",{className:i,children:e||s}):r?h.jsx("textarea",{className:`edit-input ${i}`,value:o,placeholder:s,rows:3,onChange:c=>a(c.target.value),onBlur:l}):h.jsx("input",{className:`edit-input ${i}`,value:o,placeholder:s,onChange:c=>a(c.target.value),onBlur:l,onKeyDown:c=>c.key==="Enter"&&c.target.blur()})}function Lm({entity:e,doc:t,readOnly:n,exec:r}){var i,o,a;const s=((o=(i=e.conceptual)==null?void 0:i.subject_area)==null?void 0:o.id)??"";return n?(a=e.conceptual)!=null&&a.subject_area?h.jsx("span",{className:"chip",children:e.conceptual.subject_area.name}):null:h.jsxs("select",{className:"chip-select",value:s,onChange:l=>r("set_subject_area",{id:e.id,subject_area:l.target.value||null}),children:[h.jsx("option",{value:"",children:"no subject area"}),t.subject_areas.map(l=>h.jsx("option",{value:l.id,children:l.name},l.id))]})}const Pm=["","scd2","hub","link","satellite","bridge"];function zm({entity:e,readOnly:t,exec:n}){return t?e.pattern?h.jsx("span",{className:"chip pattern",children:e.pattern}):null:h.jsx("select",{className:"chip-select",value:e.pattern??"",onChange:r=>n("set_pattern",{id:e.id,pattern:r.target.value||null}),children:Pm.map(r=>h.jsx("option",{value:r,children:r||"no pattern"},r))})}const Hm=["attribute","business_key","measure","surrogate_key"];function Fm({a:e,entity:t,doc:n,readOnly:r,exec:s}){if(r)return h.jsxs("tr",{children:[h.jsxs("td",{className:e.role==="business_key"?"pk":"",children:[e.name,e.physical_name&&e.physical_name!==e.name&&h.jsx("span",{className:"physical-col",title:"Physical column name",children:e.physical_name}),e.enum_values&&e.enum_values.length>0&&h.jsx("span",{className:"enum-badge",title:`Allowed: ${e.enum_values.join(", ")}`,children:"enum"})]}),h.jsx("td",{className:"type",children:e.domain??""}),h.jsx("td",{className:"null",children:e.nullable?"":"NN"})]});const i=o=>s("update_attribute",{entity_id:t.id,attribute_id:e.id,...o});return h.jsxs("tr",{children:[h.jsxs("td",{className:e.role==="business_key"?"pk":"",children:[h.jsx(Pe,{value:e.name,readOnly:!1,onCommit:o=>i({name:o})}),(e.physical_name||!1)&&h.jsx(Pe,{value:e.physical_name??"",className:"physical-col-input",placeholder:"physical…",readOnly:!1,onCommit:o=>i({physical_name:o})}),e.enum_values&&e.enum_values.length>0&&h.jsx("span",{className:"enum-badge",title:`Allowed: ${e.enum_values.join(", ")}`,children:"enum"})]}),h.jsx("td",{className:"type",children:h.jsx("select",{className:"cell-select",value:e.domain??"string",onChange:o=>i({domain:o.target.value}),children:[...new Set([...Tm,...n.domains??[],e.domain??"string"])].sort().map(o=>h.jsx("option",{value:o,children:o},o))})}),h.jsx("td",{children:h.jsx("select",{className:"cell-select",value:e.role,onChange:o=>i({role:o.target.value}),title:"role",children:Hm.map(o=>h.jsx("option",{value:o,children:o==="business_key"?"🔑 key":o==="measure"?"Σ measure":o},o))})}),h.jsx("td",{className:"null",children:h.jsx("input",{type:"checkbox",checked:!e.nullable,title:"not null",onChange:o=>i({nullable:!o.target.checked})})}),h.jsx("td",{children:h.jsx("button",{className:"mini-btn danger",title:"delete attribute",onClick:()=>s("delete_attribute",{entity_id:t.id,attribute_id:e.id}),children:"✕"})})]})}function Vm({entity:e,exec:t}){const[n,r]=w.useState(""),s=()=>{n.trim()&&t("add_attribute",{entity_id:e.id,name:n,domain:"string"}).then(()=>r(""))};return h.jsxs("div",{className:"add-attr",children:[h.jsx("input",{className:"edit-input",placeholder:"+ add attribute…",value:n,onChange:i=>r(i.target.value),onKeyDown:i=>i.key==="Enter"&&s()}),n&&h.jsx("button",{className:"mini-btn",onClick:s,children:"Add"})]})}function Bm(e,t){const n=e.from.entity===t;switch(e.cardinality){case"many_to_one":return n?"N:1 →":"1:N ←";case"one_to_many":return n?"1:N →":"N:1 ←";case"one_to_one":return"1:1";default:return"N:M"}}var Gm="\0",rt="\0",Ds="";let Ym=class{constructor(t){ue(this,"_isDirected",!0);ue(this,"_isMultigraph",!1);ue(this,"_isCompound",!1);ue(this,"_label");ue(this,"_defaultNodeLabelFn",()=>{});ue(this,"_defaultEdgeLabelFn",()=>{});ue(this,"_nodes",{});ue(this,"_in",{});ue(this,"_preds",{});ue(this,"_out",{});ue(this,"_sucs",{});ue(this,"_edgeObjs",{});ue(this,"_edgeLabels",{});ue(this,"_nodeCount",0);ue(this,"_edgeCount",0);ue(this,"_parent");ue(this,"_children");t&&(this._isDirected=Object.hasOwn(t,"directed")?t.directed:!0,this._isMultigraph=Object.hasOwn(t,"multigraph")?t.multigraph:!1,this._isCompound=Object.hasOwn(t,"compound")?t.compound:!1),this._isCompound&&(this._parent={},this._children={},this._children[rt]={})}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return this._defaultNodeLabelFn=t,typeof t!="function"&&(this._defaultNodeLabelFn=()=>t),this}nodeCount(){return this._nodeCount}nodes(){return Object.keys(this._nodes)}sources(){var t=this;return this.nodes().filter(n=>Object.keys(t._in[n]).length===0)}sinks(){var t=this;return this.nodes().filter(n=>Object.keys(t._out[n]).length===0)}setNodes(t,n){var r=arguments,s=this;return t.forEach(function(i){r.length>1?s.setNode(i,n):s.setNode(i)}),this}setNode(t,n){return Object.hasOwn(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=n),this):(this._nodes[t]=arguments.length>1?n:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=rt,this._children[t]={},this._children[rt][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return Object.hasOwn(this._nodes,t)}removeNode(t){var n=this;if(Object.hasOwn(this._nodes,t)){var r=s=>n.removeEdge(n._edgeObjs[s]);delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],this.children(t).forEach(function(s){n.setParent(s)}),delete this._children[t]),Object.keys(this._in[t]).forEach(r),delete this._in[t],delete this._preds[t],Object.keys(this._out[t]).forEach(r),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(n===void 0)n=rt;else{n+="";for(var r=n;r!==void 0;r=this.parent(r))if(r===t)throw new Error("Setting "+n+" as parent of "+t+" would create a cycle");this.setNode(n)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=n,this._children[n][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var n=this._parent[t];if(n!==rt)return n}}children(t=rt){if(this._isCompound){var n=this._children[t];if(n)return Object.keys(n)}else{if(t===rt)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var n=this._preds[t];if(n)return Object.keys(n)}successors(t){var n=this._sucs[t];if(n)return Object.keys(n)}neighbors(t){var n=this.predecessors(t);if(n){const s=new Set(n);for(var r of this.successors(t))s.add(r);return Array.from(s.values())}}isLeaf(t){var n;return this.isDirected()?n=this.successors(t):n=this.neighbors(t),n.length===0}filterNodes(t){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var r=this;Object.entries(this._nodes).forEach(function([o,a]){t(o)&&n.setNode(o,a)}),Object.values(this._edgeObjs).forEach(function(o){n.hasNode(o.v)&&n.hasNode(o.w)&&n.setEdge(o,r.edge(o))});var s={};function i(o){var a=r.parent(o);return a===void 0||n.hasNode(a)?(s[o]=a,a):a in s?s[a]:i(a)}return this._isCompound&&n.nodes().forEach(o=>n.setParent(o,i(o))),n}setDefaultEdgeLabel(t){return this._defaultEdgeLabelFn=t,typeof t!="function"&&(this._defaultEdgeLabelFn=()=>t),this}edgeCount(){return this._edgeCount}edges(){return Object.values(this._edgeObjs)}setPath(t,n){var r=this,s=arguments;return t.reduce(function(i,o){return s.length>1?r.setEdge(i,o,n):r.setEdge(i,o),o}),this}setEdge(){var t,n,r,s,i=!1,o=arguments[0];typeof o=="object"&&o!==null&&"v"in o?(t=o.v,n=o.w,r=o.name,arguments.length===2&&(s=arguments[1],i=!0)):(t=o,n=arguments[1],r=arguments[3],arguments.length>2&&(s=arguments[2],i=!0)),t=""+t,n=""+n,r!==void 0&&(r=""+r);var a=Pt(this._isDirected,t,n,r);if(Object.hasOwn(this._edgeLabels,a))return i&&(this._edgeLabels[a]=s),this;if(r!==void 0&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(n),this._edgeLabels[a]=i?s:this._defaultEdgeLabelFn(t,n,r);var l=Wm(this._isDirected,t,n,r);return t=l.v,n=l.w,Object.freeze(l),this._edgeObjs[a]=l,Ls(this._preds[n],t),Ls(this._sucs[t],n),this._in[n][a]=l,this._out[t][a]=l,this._edgeCount++,this}edge(t,n,r){var s=arguments.length===1?Kn(this._isDirected,arguments[0]):Pt(this._isDirected,t,n,r);return this._edgeLabels[s]}edgeAsObj(){const t=this.edge(...arguments);return typeof t!="object"?{label:t}:t}hasEdge(t,n,r){var s=arguments.length===1?Kn(this._isDirected,arguments[0]):Pt(this._isDirected,t,n,r);return Object.hasOwn(this._edgeLabels,s)}removeEdge(t,n,r){var s=arguments.length===1?Kn(this._isDirected,arguments[0]):Pt(this._isDirected,t,n,r),i=this._edgeObjs[s];return i&&(t=i.v,n=i.w,delete this._edgeLabels[s],delete this._edgeObjs[s],Ps(this._preds[n],t),Ps(this._sucs[t],n),delete this._in[n][s],delete this._out[t][s],this._edgeCount--),this}inEdges(t,n){var r=this._in[t];if(r){var s=Object.values(r);return n?s.filter(i=>i.v===n):s}}outEdges(t,n){var r=this._out[t];if(r){var s=Object.values(r);return n?s.filter(i=>i.w===n):s}}nodeEdges(t,n){var r=this.inEdges(t,n);if(r)return r.concat(this.outEdges(t,n))}};function Ls(e,t){e[t]?e[t]++:e[t]=1}function Ps(e,t){--e[t]||delete e[t]}function Pt(e,t,n,r){var s=""+t,i=""+n;if(!e&&s>i){var o=s;s=i,i=o}return s+Ds+i+Ds+(r===void 0?Gm:r)}function Wm(e,t,n,r){var s=""+t,i=""+n;if(!e&&s>i){var o=s;s=i,i=o}var a={v:s,w:i};return r&&(a.name=r),a}function Kn(e,t){return Pt(e,t.v,t.w,t.name)}var Pr=Ym,Um="2.2.4",Xm={Graph:Pr,version:Um},qm=Pr,Km={write:Zm,read:ep};function Zm(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:Qm(e),edges:Jm(e)};return e.graph()!==void 0&&(t.value=structuredClone(e.graph())),t}function Qm(e){return e.nodes().map(function(t){var n=e.node(t),r=e.parent(t),s={v:t};return n!==void 0&&(s.value=n),r!==void 0&&(s.parent=r),s})}function Jm(e){return e.edges().map(function(t){var n=e.edge(t),r={v:t.v,w:t.w};return t.name!==void 0&&(r.name=t.name),n!==void 0&&(r.value=n),r})}function ep(e){var t=new qm(e.options).setGraph(e.value);return e.nodes.forEach(function(n){t.setNode(n.v,n.value),n.parent&&t.setParent(n.v,n.parent)}),e.edges.forEach(function(n){t.setEdge({v:n.v,w:n.w,name:n.name},n.value)}),t}var tp=np;function np(e){var t={},n=[],r;function s(i){Object.hasOwn(t,i)||(t[i]=!0,r.push(i),e.successors(i).forEach(s),e.predecessors(i).forEach(s))}return e.nodes().forEach(function(i){r=[],s(i),r.length&&n.push(r)}),n}let rp=class{constructor(){ue(this,"_arr",[]);ue(this,"_keyIndices",{})}size(){return this._arr.length}keys(){return this._arr.map(function(t){return t.key})}has(t){return Object.hasOwn(this._keyIndices,t)}priority(t){var n=this._keyIndices[t];if(n!==void 0)return this._arr[n].priority}min(){if(this.size()===0)throw new Error("Queue underflow");return this._arr[0].key}add(t,n){var r=this._keyIndices;if(t=String(t),!Object.hasOwn(r,t)){var s=this._arr,i=s.length;return r[t]=i,s.push({key:t,priority:n}),this._decrease(i),!0}return!1}removeMin(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key}decrease(t,n){var r=this._keyIndices[t];if(n>this._arr[r].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[r].priority+" New: "+n);this._arr[r].priority=n,this._decrease(r)}_heapify(t){var n=this._arr,r=2*t,s=r+1,i=t;r>1,!(n[s].priority1;function op(e,t,n,r){return ap(e,String(t),n||ip,r||function(s){return e.outEdges(s)})}function ap(e,t,n,r){var s={},i=new sp,o,a,l=function(c){var u=c.v!==o?c.v:c.w,d=s[u],m=n(c),f=a.distance+m;if(m<0)throw new Error("dijkstra does not allow negative edge weights. Bad edge: "+c+" Weight: "+m);f0&&(o=i.removeMin(),a=s[o],a.distance!==Number.POSITIVE_INFINITY);)r(o).forEach(l);return s}var lp=Wo,cp=up;function up(e,t,n){return e.nodes().reduce(function(r,s){return r[s]=lp(e,s,t,n),r},{})}var Uo=dp;function dp(e){var t=0,n=[],r={},s=[];function i(o){var a=r[o]={onStack:!0,lowlink:t,index:t++};if(n.push(o),e.successors(o).forEach(function(u){Object.hasOwn(r,u)?r[u].onStack&&(a.lowlink=Math.min(a.lowlink,r[u].index)):(i(u),a.lowlink=Math.min(a.lowlink,r[u].lowlink))}),a.lowlink===a.index){var l=[],c;do c=n.pop(),r[c].onStack=!1,l.push(c);while(o!==c);s.push(l)}}return e.nodes().forEach(function(o){Object.hasOwn(r,o)||i(o)}),s}var fp=Uo,hp=mp;function mp(e){return fp(e).filter(function(t){return t.length>1||t.length===1&&e.hasEdge(t[0],t[0])})}var pp=yp,gp=()=>1;function yp(e,t,n){return xp(e,t||gp,n||function(r){return e.outEdges(r)})}function xp(e,t,n){var r={},s=e.nodes();return s.forEach(function(i){r[i]={},r[i][i]={distance:0},s.forEach(function(o){i!==o&&(r[i][o]={distance:Number.POSITIVE_INFINITY})}),n(i).forEach(function(o){var a=o.v===i?o.w:o.v,l=t(o);r[i][a]={distance:l,predecessor:i}})}),s.forEach(function(i){var o=r[i];s.forEach(function(a){var l=r[a];s.forEach(function(c){var u=l[i],d=o[c],m=l[c],f=u.distance+d.distance;fe.successors(a):a=>e.neighbors(a),s=n==="post"?_p:Ep,i=[],o={};return t.forEach(a=>{if(!e.hasNode(a))throw new Error("Graph does not have node: "+a);s(a,r,o,i)}),i}function _p(e,t,n,r){for(var s=[[e,!1]];s.length>0;){var i=s.pop();i[1]?r.push(i[0]):Object.hasOwn(n,i[0])||(n[i[0]]=!0,s.push([i[0],!0]),Zo(t(i[0]),o=>s.push([o,!1])))}}function Ep(e,t,n,r){for(var s=[e];s.length>0;){var i=s.pop();Object.hasOwn(n,i)||(n[i]=!0,r.push(i),Zo(t(i),o=>s.push(o)))}}function Zo(e,t){for(var n=e.length;n--;)t(e[n],n,e);return e}var Np=Ko,Sp=kp;function kp(e,t){return Np(e,t,"post")}var jp=Ko,Cp=$p;function $p(e,t){return jp(e,t,"pre")}var Mp=Pr,Ap=Yo,Ip=Rp;function Rp(e,t){var n=new Mp,r={},s=new Ap,i;function o(l){var c=l.v===i?l.w:l.v,u=s.priority(c);if(u!==void 0){var d=t(l);d0;){if(i=s.removeMin(),Object.hasOwn(r,i))n.setEdge(i,r[i]);else{if(a)throw new Error("Input graph is not connected: "+e);a=!0}e.nodeEdges(i).forEach(o)}return n}var Tp={components:tp,dijkstra:Wo,dijkstraAll:cp,findCycles:hp,floydWarshall:pp,isAcyclic:wp,postorder:Sp,preorder:Cp,prim:Ip,tarjan:Uo,topsort:qo},Hs=Xm,Ie={Graph:Hs.Graph,json:Km,alg:Tp,version:Hs.version};let Op=class{constructor(){let t={};t._next=t._prev=t,this._sentinel=t}dequeue(){let t=this._sentinel,n=t._prev;if(n!==t)return Fs(n),n}enqueue(t){let n=this._sentinel;t._prev&&t._next&&Fs(t),t._next=n._next,n._next._prev=t,n._next=t,t._prev=n}toString(){let t=[],n=this._sentinel,r=n._prev;for(;r!==n;)t.push(JSON.stringify(r,Dp)),r=r._prev;return"["+t.join(", ")+"]"}};function Fs(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function Dp(e,t){if(e!=="_next"&&e!=="_prev")return t}var Lp=Op;let Pp=Ie.Graph,zp=Lp;var Hp=Vp;let Fp=()=>1;function Vp(e,t){if(e.nodeCount()<=1)return[];let n=Gp(e,t||Fp);return Bp(n.graph,n.buckets,n.zeroIdx).flatMap(s=>e.outEdges(s.v,s.w))}function Bp(e,t,n){let r=[],s=t[t.length-1],i=t[0],o;for(;e.nodeCount();){for(;o=i.dequeue();)Zn(e,t,n,o);for(;o=s.dequeue();)Zn(e,t,n,o);if(e.nodeCount()){for(let a=t.length-2;a>0;--a)if(o=t[a].dequeue(),o){r=r.concat(Zn(e,t,n,o,!0));break}}}return r}function Zn(e,t,n,r,s){let i=s?[]:void 0;return e.inEdges(r.v).forEach(o=>{let a=e.edge(o),l=e.node(o.v);s&&i.push({v:o.v,w:o.w}),l.out-=a,xr(t,n,l)}),e.outEdges(r.v).forEach(o=>{let a=e.edge(o),l=o.w,c=e.node(l);c.in-=a,xr(t,n,c)}),e.removeNode(r.v),i}function Gp(e,t){let n=new Pp,r=0,s=0;e.nodes().forEach(a=>{n.setNode(a,{v:a,in:0,out:0})}),e.edges().forEach(a=>{let l=n.edge(a.v,a.w)||0,c=t(a),u=l+c;n.setEdge(a.v,a.w,u),s=Math.max(s,n.node(a.v).out+=c),r=Math.max(r,n.node(a.w).in+=c)});let i=Yp(s+r+3).map(()=>new zp),o=r+1;return n.nodes().forEach(a=>{xr(i,o,n.node(a))}),{graph:n,buckets:i,zeroIdx:o}}function xr(e,t,n){n.out?n.in?e[n.out-n.in+t].enqueue(n):e[e.length-1].enqueue(n):e[0].enqueue(n)}function Yp(e){const t=[];for(let n=0;nt.setNode(n,e.node(n))),e.edges().forEach(n=>{let r=t.edge(n.v,n.w)||{weight:0,minlen:1},s=e.edge(n);t.setEdge(n.v,n.w,{weight:r.weight+s.weight,minlen:Math.max(r.minlen,s.minlen)})}),t}function Up(e){let t=new Qo({multigraph:e.isMultigraph()}).setGraph(e.graph());return e.nodes().forEach(n=>{e.children(n).length||t.setNode(n,e.node(n))}),e.edges().forEach(n=>{t.setEdge(n,e.edge(n))}),t}function Xp(e){let t=e.nodes().map(n=>{let r={};return e.outEdges(n).forEach(s=>{r[s.w]=(r[s.w]||0)+e.edge(s).weight}),r});return zr(e.nodes(),t)}function qp(e){let t=e.nodes().map(n=>{let r={};return e.inEdges(n).forEach(s=>{r[s.v]=(r[s.v]||0)+e.edge(s).weight}),r});return zr(e.nodes(),t)}function Kp(e,t){let n=e.x,r=e.y,s=t.x-n,i=t.y-r,o=e.width/2,a=e.height/2;if(!s&&!i)throw new Error("Not possible to find intersection inside of the rectangle");let l,c;return Math.abs(i)*o>Math.abs(s)*a?(i<0&&(a=-a),l=a*s/i,c=a):(s<0&&(o=-o),l=o,c=o*i/s),{x:n+l,y:r+c}}function Zp(e){let t=ra(ta(e)+1).map(()=>[]);return e.nodes().forEach(n=>{let r=e.node(n),s=r.rank;s!==void 0&&(t[s][r.order]=n)}),t}function Qp(e){let t=e.nodes().map(r=>{let s=e.node(r).rank;return s===void 0?Number.MAX_VALUE:s}),n=Tn(Math.min,t);e.nodes().forEach(r=>{let s=e.node(r);Object.hasOwn(s,"rank")&&(s.rank-=n)})}function Jp(e){let t=e.nodes().map(o=>e.node(o).rank),n=Tn(Math.min,t),r=[];e.nodes().forEach(o=>{let a=e.node(o).rank-n;r[a]||(r[a]=[]),r[a].push(o)});let s=0,i=e.graph().nodeRankFactor;Array.from(r).forEach((o,a)=>{o===void 0&&a%i!==0?--s:o!==void 0&&s&&o.forEach(l=>e.node(l).rank+=s)})}function eg(e,t,n,r){let s={width:0,height:0};return arguments.length>=4&&(s.rank=n,s.order=r),Jo(e,"border",s,t)}function tg(e,t=ea){const n=[];for(let r=0;rea){const n=tg(t);return e.apply(null,n.map(r=>e.apply(null,r)))}else return e.apply(null,t)}function ta(e){const n=e.nodes().map(r=>{let s=e.node(r).rank;return s===void 0?Number.MIN_VALUE:s});return Tn(Math.max,n)}function ng(e,t){let n={lhs:[],rhs:[]};return e.forEach(r=>{t(r)?n.lhs.push(r):n.rhs.push(r)}),n}function rg(e,t){let n=Date.now();try{return t()}finally{console.log(e+" time: "+(Date.now()-n)+"ms")}}function sg(e,t){return t()}let ig=0;function na(e){var t=++ig;return e+(""+t)}function ra(e,t,n=1){t==null&&(t=e,e=0);let r=i=>itr[t]),Object.entries(e).reduce((r,[s,i])=>(r[s]=n(i,s),r),{})}function zr(e,t){return e.reduce((n,r,s)=>(n[r]=t[s],n),{})}let lg=Hp,cg=fe.uniqueId;var ug={run:dg,undo:hg};function dg(e){(e.graph().acyclicer==="greedy"?lg(e,n(e)):fg(e)).forEach(r=>{let s=e.edge(r);e.removeEdge(r),s.forwardName=r.name,s.reversed=!0,e.setEdge(r.w,r.v,s,cg("rev"))});function n(r){return s=>r.edge(s).weight}}function fg(e){let t=[],n={},r={};function s(i){Object.hasOwn(r,i)||(r[i]=!0,n[i]=!0,e.outEdges(i).forEach(o=>{Object.hasOwn(n,o.w)?t.push(o):s(o.w)}),delete n[i])}return e.nodes().forEach(s),t}function hg(e){e.edges().forEach(t=>{let n=e.edge(t);if(n.reversed){e.removeEdge(t);let r=n.forwardName;delete n.reversed,delete n.forwardName,e.setEdge(t.w,t.v,n,r)}})}let mg=fe;var pg={run:gg,undo:xg};function gg(e){e.graph().dummyChains=[],e.edges().forEach(t=>yg(e,t))}function yg(e,t){let n=t.v,r=e.node(n).rank,s=t.w,i=e.node(s).rank,o=t.name,a=e.edge(t),l=a.labelRank;if(i===r+1)return;e.removeEdge(t);let c,u,d;for(d=0,++r;r{let n=e.node(t),r=n.edgeLabel,s;for(e.setEdge(n.edgeObj,r);n.dummy;)s=e.successors(t)[0],e.removeNode(t),r.points.push({x:n.x,y:n.y}),n.dummy==="edge-label"&&(r.x=n.x,r.y=n.y,r.width=n.width,r.height=n.height),t=s,n=e.node(t)})}const{applyWithChunking:wg}=fe;var On={longestPath:bg,slack:vg};function bg(e){var t={};function n(r){var s=e.node(r);if(Object.hasOwn(t,r))return s.rank;t[r]=!0;let i=e.outEdges(r).map(a=>a==null?Number.POSITIVE_INFINITY:n(a.w)-e.edge(a).minlen);var o=wg(Math.min,i);return o===Number.POSITIVE_INFINITY&&(o=0),s.rank=o}e.sources().forEach(n)}function vg(e,t){return e.node(t.w).rank-e.node(t.v).rank-e.edge(t).minlen}var _g=Ie.Graph,En=On.slack,sa=Eg;function Eg(e){var t=new _g({directed:!1}),n=e.nodes()[0],r=e.nodeCount();t.setNode(n,{});for(var s,i;Ng(t,e){var i=s.v,o=r===i?s.w:i;!e.hasNode(o)&&!En(t,s)&&(e.setNode(o,{}),e.setEdge(r,o,{}),n(o))})}return e.nodes().forEach(n),e.nodeCount()}function Sg(e,t){return t.edges().reduce((r,s)=>{let i=Number.POSITIVE_INFINITY;return e.hasNode(s.v)!==e.hasNode(s.w)&&(i=En(t,s)),it.node(r).rank+=n)}var jg=sa,Vs=On.slack,Cg=On.longestPath,$g=Ie.alg.preorder,Mg=Ie.alg.postorder,Ag=fe.simplify,Ig=dt;dt.initLowLimValues=Fr;dt.initCutValues=Hr;dt.calcCutValue=ia;dt.leaveEdge=aa;dt.enterEdge=la;dt.exchangeEdges=ca;function dt(e){e=Ag(e),Cg(e);var t=jg(e);Fr(t),Hr(t,e);for(var n,r;n=aa(t);)r=la(t,e,n),ca(t,e,n,r)}function Hr(e,t){var n=Mg(e,e.nodes());n=n.slice(0,n.length-1),n.forEach(r=>Rg(e,t,r))}function Rg(e,t,n){var r=e.node(n),s=r.parent;e.edge(n,s).cutvalue=ia(e,t,n)}function ia(e,t,n){var r=e.node(n),s=r.parent,i=!0,o=t.edge(n,s),a=0;return o||(i=!1,o=t.edge(s,n)),a=o.weight,t.nodeEdges(n).forEach(l=>{var c=l.v===n,u=c?l.w:l.v;if(u!==s){var d=c===i,m=t.edge(l).weight;if(a+=d?m:-m,Og(e,n,u)){var f=e.edge(n,u).cutvalue;a+=d?-f:f}}}),a}function Fr(e,t){arguments.length<2&&(t=e.nodes()[0]),oa(e,{},1,t)}function oa(e,t,n,r,s){var i=n,o=e.node(r);return t[r]=!0,e.neighbors(r).forEach(a=>{Object.hasOwn(t,a)||(n=oa(e,t,n,a,r))}),o.low=i,o.lim=n++,s?o.parent=s:delete o.parent,n}function aa(e){return e.edges().find(t=>e.edge(t).cutvalue<0)}function la(e,t,n){var r=n.v,s=n.w;t.hasEdge(r,s)||(r=n.w,s=n.v);var i=e.node(r),o=e.node(s),a=i,l=!1;i.lim>o.lim&&(a=o,l=!0);var c=t.edges().filter(u=>l===Bs(e,e.node(u.v),a)&&l!==Bs(e,e.node(u.w),a));return c.reduce((u,d)=>Vs(t,d)!t.node(s).parent),r=$g(e,n);r=r.slice(1),r.forEach(s=>{var i=e.node(s).parent,o=t.edge(s,i),a=!1;o||(o=t.edge(i,s),a=!0),t.node(s).rank=t.node(i).rank+(a?o.minlen:-o.minlen)})}function Og(e,t,n){return e.hasEdge(t,n)}function Bs(e,t,n){return n.low<=t.lim&&t.lim<=n.lim}var Dg=On,ua=Dg.longestPath,Lg=sa,Pg=Ig,zg=Hg;function Hg(e){var t=e.graph().ranker;if(t instanceof Function)return t(e);switch(e.graph().ranker){case"network-simplex":Gs(e);break;case"tight-tree":Vg(e);break;case"longest-path":Fg(e);break;case"none":break;default:Gs(e)}}var Fg=ua;function Vg(e){ua(e),Lg(e)}function Gs(e){Pg(e)}var Bg=Gg;function Gg(e){let t=Wg(e);e.graph().dummyChains.forEach(n=>{let r=e.node(n),s=r.edgeObj,i=Yg(e,t,s.v,s.w),o=i.path,a=i.lca,l=0,c=o[l],u=!0;for(;n!==s.w;){if(r=e.node(n),u){for(;(c=o[l])!==a&&e.node(c).maxRanko||a>t[l].lim));for(c=l,l=r;(l=e.parent(l))!==c;)i.push(l);return{path:s.concat(i.reverse()),lca:c}}function Wg(e){let t={},n=0;function r(s){let i=n;e.children(s).forEach(r),t[s]={low:i,lim:n++}}return e.children().forEach(r),t}let Nn=fe;var Ug={run:Xg,cleanup:Zg};function Xg(e){let t=Nn.addDummyNode(e,"root",{},"_root"),n=qg(e),r=Object.values(n),s=Nn.applyWithChunking(Math.max,r)-1,i=2*s+1;e.graph().nestingRoot=t,e.edges().forEach(a=>e.edge(a).minlen*=i);let o=Kg(e)+1;e.children().forEach(a=>da(e,t,i,o,s,n,a)),e.graph().nodeRankFactor=i}function da(e,t,n,r,s,i,o){let a=e.children(o);if(!a.length){o!==t&&e.setEdge(t,o,{weight:0,minlen:n});return}let l=Nn.addBorderNode(e,"_bt"),c=Nn.addBorderNode(e,"_bb"),u=e.node(o);e.setParent(l,o),u.borderTop=l,e.setParent(c,o),u.borderBottom=c,a.forEach(d=>{da(e,t,n,r,s,i,d);let m=e.node(d),f=m.borderTop?m.borderTop:d,y=m.borderBottom?m.borderBottom:d,p=m.borderTop?r:2*r,v=f!==y?1:s-i[o]+1;e.setEdge(l,f,{weight:p,minlen:v,nestingEdge:!0}),e.setEdge(y,c,{weight:p,minlen:v,nestingEdge:!0})}),e.parent(o)||e.setEdge(t,l,{weight:0,minlen:s+i[o]})}function qg(e){var t={};function n(r,s){var i=e.children(r);i&&i.length&&i.forEach(o=>n(o,s+1)),t[r]=s}return e.children().forEach(r=>n(r,1)),t}function Kg(e){return e.edges().reduce((t,n)=>t+e.edge(n).weight,0)}function Zg(e){var t=e.graph();e.removeNode(t.nestingRoot),delete t.nestingRoot,e.edges().forEach(n=>{var r=e.edge(n);r.nestingEdge&&e.removeEdge(n)})}let Qg=fe;var Jg=e0;function e0(e){function t(n){let r=e.children(n),s=e.node(n);if(r.length&&r.forEach(t),Object.hasOwn(s,"minRank")){s.borderLeft=[],s.borderRight=[];for(let i=s.minRank,o=s.maxRank+1;iWs(e.node(t))),e.edges().forEach(t=>Ws(e.edge(t)))}function Ws(e){let t=e.width;e.width=e.height,e.height=t}function s0(e){e.nodes().forEach(t=>Qn(e.node(t))),e.edges().forEach(t=>{let n=e.edge(t);n.points.forEach(Qn),Object.hasOwn(n,"y")&&Qn(n)})}function Qn(e){e.y=-e.y}function i0(e){e.nodes().forEach(t=>Jn(e.node(t))),e.edges().forEach(t=>{let n=e.edge(t);n.points.forEach(Jn),Object.hasOwn(n,"x")&&Jn(n)})}function Jn(e){let t=e.x;e.x=e.y,e.y=t}let Us=fe;var o0=a0;function a0(e){let t={},n=e.nodes().filter(l=>!e.children(l).length),r=n.map(l=>e.node(l).rank),s=Us.applyWithChunking(Math.max,r),i=Us.range(s+1).map(()=>[]);function o(l){if(t[l])return;t[l]=!0;let c=e.node(l);i[c.rank].push(l),e.successors(l).forEach(o)}return n.sort((l,c)=>e.node(l).rank-e.node(c).rank).forEach(o),i}let l0=fe.zipObject;var c0=u0;function u0(e,t){let n=0;for(let r=1;ru)),s=t.flatMap(c=>e.outEdges(c).map(u=>({pos:r[u.w],weight:e.edge(u).weight})).sort((u,d)=>u.pos-d.pos)),i=1;for(;i{let u=c.pos+i;a[u]+=c.weight;let d=0;for(;u>0;)u%2&&(d+=a[u+1]),u=u-1>>1,a[u]+=c.weight;l+=c.weight*d}),l}var f0=h0;function h0(e,t=[]){return t.map(n=>{let r=e.inEdges(n);if(r.length){let s=r.reduce((i,o)=>{let a=e.edge(o),l=e.node(o.v);return{sum:i.sum+a.weight*l.order,weight:i.weight+a.weight}},{sum:0,weight:0});return{v:n,barycenter:s.sum/s.weight,weight:s.weight}}else return{v:n}})}let m0=fe;var p0=g0;function g0(e,t){let n={};e.forEach((s,i)=>{let o=n[s.v]={indegree:0,in:[],out:[],vs:[s.v],i};s.barycenter!==void 0&&(o.barycenter=s.barycenter,o.weight=s.weight)}),t.edges().forEach(s=>{let i=n[s.v],o=n[s.w];i!==void 0&&o!==void 0&&(o.indegree++,i.out.push(n[s.w]))});let r=Object.values(n).filter(s=>!s.indegree);return y0(r)}function y0(e){let t=[];function n(s){return i=>{i.merged||(i.barycenter===void 0||s.barycenter===void 0||i.barycenter>=s.barycenter)&&x0(s,i)}}function r(s){return i=>{i.in.push(s),--i.indegree===0&&e.push(i)}}for(;e.length;){let s=e.pop();t.push(s),s.in.reverse().forEach(n(s)),s.out.forEach(r(s))}return t.filter(s=>!s.merged).map(s=>m0.pick(s,["vs","i","barycenter","weight"]))}function x0(e,t){let n=0,r=0;e.weight&&(n+=e.barycenter*e.weight,r+=e.weight),t.weight&&(n+=t.barycenter*t.weight,r+=t.weight),e.vs=t.vs.concat(e.vs),e.barycenter=n/r,e.weight=r,e.i=Math.min(t.i,e.i),t.merged=!0}let w0=fe;var b0=v0;function v0(e,t){let n=w0.partition(e,u=>Object.hasOwn(u,"barycenter")),r=n.lhs,s=n.rhs.sort((u,d)=>d.i-u.i),i=[],o=0,a=0,l=0;r.sort(_0(!!t)),l=Xs(i,s,l),r.forEach(u=>{l+=u.vs.length,i.push(u.vs),o+=u.barycenter*u.weight,a+=u.weight,l=Xs(i,s,l)});let c={vs:i.flat(!0)};return a&&(c.barycenter=o/a,c.weight=a),c}function Xs(e,t,n){let r;for(;t.length&&(r=t[t.length-1]).i<=n;)t.pop(),e.push(r.vs),n++;return n}function _0(e){return(t,n)=>t.barycentern.barycenter?1:e?n.i-t.i:t.i-n.i}let E0=f0,N0=p0,S0=b0;var k0=ha;function ha(e,t,n,r){let s=e.children(t),i=e.node(t),o=i?i.borderLeft:void 0,a=i?i.borderRight:void 0,l={};o&&(s=s.filter(m=>m!==o&&m!==a));let c=E0(e,s);c.forEach(m=>{if(e.children(m.v).length){let f=ha(e,m.v,n,r);l[m.v]=f,Object.hasOwn(f,"barycenter")&&C0(m,f)}});let u=N0(c,n);j0(u,l);let d=S0(u,r);if(o&&(d.vs=[o,d.vs,a].flat(!0),e.predecessors(o).length)){let m=e.node(e.predecessors(o)[0]),f=e.node(e.predecessors(a)[0]);Object.hasOwn(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+m.order+f.order)/(d.weight+2),d.weight+=2}return d}function j0(e,t){e.forEach(n=>{n.vs=n.vs.flatMap(r=>t[r]?t[r].vs:r)})}function C0(e,t){e.barycenter!==void 0?(e.barycenter=(e.barycenter*e.weight+t.barycenter*t.weight)/(e.weight+t.weight),e.weight+=t.weight):(e.barycenter=t.barycenter,e.weight=t.weight)}let $0=Ie.Graph,M0=fe;var A0=I0;function I0(e,t,n,r){r||(r=e.nodes());let s=R0(e),i=new $0({compound:!0}).setGraph({root:s}).setDefaultNodeLabel(o=>e.node(o));return r.forEach(o=>{let a=e.node(o),l=e.parent(o);(a.rank===t||a.minRank<=t&&t<=a.maxRank)&&(i.setNode(o),i.setParent(o,l||s),e[n](o).forEach(c=>{let u=c.v===o?c.w:c.v,d=i.edge(u,o),m=d!==void 0?d.weight:0;i.setEdge(u,o,{weight:e.edge(c).weight+m})}),Object.hasOwn(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[t],borderRight:a.borderRight[t]}))}),i}function R0(e){for(var t;e.hasNode(t=M0.uniqueId("_root")););return t}var T0=O0;function O0(e,t,n){let r={},s;n.forEach(i=>{let o=e.parent(i),a,l;for(;o;){if(a=e.parent(o),a?(l=r[a],r[a]=o):(l=s,s=o),l&&l!==o){t.setEdge(l,o);return}o=a}})}let D0=o0,L0=c0,P0=k0,z0=A0,H0=T0,F0=Ie.Graph,ln=fe;var V0=ma;function ma(e,t){if(t&&typeof t.customOrder=="function"){t.customOrder(e,ma);return}let n=ln.maxRank(e),r=qs(e,ln.range(1,n+1),"inEdges"),s=qs(e,ln.range(n-1,-1,-1),"outEdges"),i=D0(e);if(Ks(e,i),t&&t.disableOptimalOrderHeuristic)return;let o=Number.POSITIVE_INFINITY,a;for(let l=0,c=0;c<4;++l,++c){B0(l%2?r:s,l%4>=2),i=ln.buildLayerMatrix(e);let u=L0(e,i);u{r.has(i)||r.set(i,[]),r.get(i).push(o)};for(const i of e.nodes()){const o=e.node(i);if(typeof o.rank=="number"&&s(o.rank,i),typeof o.minRank=="number"&&typeof o.maxRank=="number")for(let a=o.minRank;a<=o.maxRank;a++)a!==o.rank&&s(a,i)}return t.map(function(i){return z0(e,i,n,r.get(i)||[])})}function B0(e,t){let n=new F0;e.forEach(function(r){let s=r.graph().root,i=P0(r,s,n,t);i.vs.forEach((o,a)=>r.node(o).order=a),H0(r,n,i.vs)})}function Ks(e,t){Object.values(t).forEach(n=>n.forEach((r,s)=>e.node(r).order=s))}let G0=Ie.Graph,ze=fe;var Y0={positionX:ny};function W0(e,t){let n={};function r(s,i){let o=0,a=0,l=s.length,c=i[i.length-1];return i.forEach((u,d)=>{let m=X0(e,u),f=m?e.node(m).order:l;(m||u===c)&&(i.slice(a,d+1).forEach(y=>{e.predecessors(y).forEach(p=>{let v=e.node(p),x=v.order;(x{u=i[d],e.node(u).dummy&&e.predecessors(u).forEach(m=>{let f=e.node(m);f.dummy&&(f.orderc)&&pa(n,m,u)})})}function s(i,o){let a=-1,l,c=0;return o.forEach((u,d)=>{if(e.node(u).dummy==="border"){let m=e.predecessors(u);m.length&&(l=e.node(m[0]).order,r(o,c,d,a,l),c=d,a=l)}r(o,c,o.length,l,i.length)}),o}return t.length&&t.reduce(s),n}function X0(e,t){if(e.node(t).dummy)return e.predecessors(t).find(n=>e.node(n).dummy)}function pa(e,t,n){if(t>n){let s=t;t=n,n=s}let r=e[t];r||(e[t]=r={}),r[n]=!0}function q0(e,t,n){if(t>n){let r=t;t=n,n=r}return!!e[t]&&Object.hasOwn(e[t],n)}function K0(e,t,n,r){let s={},i={},o={};return t.forEach(a=>{a.forEach((l,c)=>{s[l]=l,i[l]=l,o[l]=c})}),t.forEach(a=>{let l=-1;a.forEach(c=>{let u=r(c);if(u.length){u=u.sort((m,f)=>o[m]-o[f]);let d=(u.length-1)/2;for(let m=Math.floor(d),f=Math.ceil(d);m<=f;++m){let y=u[m];i[c]===c&&lMath.max(m,i[f.v]+o.edge(f)),0)}function u(d){let m=o.outEdges(d).reduce((y,p)=>Math.min(y,i[p.w]-o.edge(p)),Number.POSITIVE_INFINITY),f=e.node(d);m!==Number.POSITIVE_INFINITY&&f.borderType!==a&&(i[d]=Math.max(i[d],m))}return l(c,o.predecessors.bind(o)),l(u,o.successors.bind(o)),Object.keys(r).forEach(d=>i[d]=i[n[d]]),i}function Q0(e,t,n,r){let s=new G0,i=e.graph(),o=ry(i.nodesep,i.edgesep,r);return t.forEach(a=>{let l;a.forEach(c=>{let u=n[c];if(s.setNode(u),l){var d=n[l],m=s.edge(d,u);s.setEdge(d,u,Math.max(o(e,c,l),m||0))}l=c})}),s}function J0(e,t){return Object.values(t).reduce((n,r)=>{let s=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;Object.entries(r).forEach(([a,l])=>{let c=sy(e,a)/2;s=Math.max(l+c,s),i=Math.min(l-c,i)});const o=s-i;return o{["l","r"].forEach(o=>{let a=i+o,l=e[a];if(l===t)return;let c=Object.values(l),u=r-ze.applyWithChunking(Math.min,c);o!=="l"&&(u=s-ze.applyWithChunking(Math.max,c)),u&&(e[a]=ze.mapValues(l,d=>d+u))})})}function ty(e,t){return ze.mapValues(e.ul,(n,r)=>{if(t)return e[t.toLowerCase()][r];{let s=Object.values(e).map(i=>i[r]).sort((i,o)=>i-o);return(s[1]+s[2])/2}})}function ny(e){let t=ze.buildLayerMatrix(e),n=Object.assign(W0(e,t),U0(e,t)),r={},s;["u","d"].forEach(o=>{s=o==="u"?t:Object.values(t).reverse(),["l","r"].forEach(a=>{a==="r"&&(s=s.map(d=>Object.values(d).reverse()));let l=(o==="u"?e.predecessors:e.successors).bind(e),c=K0(e,s,n,l),u=Z0(e,s,c.root,c.align,a==="r");a==="r"&&(u=ze.mapValues(u,d=>-d)),r[o+a]=u})});let i=J0(e,r);return ey(r,i),ty(r,e.graph().align)}function ry(e,t,n){return(r,s,i)=>{let o=r.node(s),a=r.node(i),l=0,c;if(l+=o.width/2,Object.hasOwn(o,"labelpos"))switch(o.labelpos.toLowerCase()){case"l":c=-o.width/2;break;case"r":c=o.width/2;break}if(c&&(l+=n?c:-c),c=0,l+=(o.dummy?t:e)/2,l+=(a.dummy?t:e)/2,l+=a.width/2,Object.hasOwn(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":c=a.width/2;break;case"r":c=-a.width/2;break}return c&&(l+=n?c:-c),c=0,l}}function sy(e,t){return e.node(t).width}let ga=fe,iy=Y0.positionX;var oy=ay;function ay(e){e=ga.asNonCompoundGraph(e),ly(e),Object.entries(iy(e)).forEach(([t,n])=>e.node(t).x=n)}function ly(e){let t=ga.buildLayerMatrix(e),n=e.graph().ranksep,r=0;t.forEach(s=>{const i=s.reduce((o,a)=>{const l=e.node(a).height;return o>l?o:l},0);s.forEach(o=>e.node(o).y=r+i/2),r+=i+n})}let Zs=ug,Qs=pg,cy=zg,uy=fe.normalizeRanks,dy=Bg,fy=fe.removeEmptyRanks,Js=Ug,hy=Jg,ei=t0,my=V0,py=oy,je=fe,gy=Ie.Graph;var yy=xy;function xy(e,t){let n=t&&t.debugTiming?je.time:je.notime;n("layout",()=>{let r=n(" buildLayoutGraph",()=>Cy(e));n(" runLayout",()=>wy(r,n,t)),n(" updateInputGraph",()=>by(e,r))})}function wy(e,t,n){t(" makeSpaceForEdgeLabels",()=>$y(e)),t(" removeSelfEdges",()=>Py(e)),t(" acyclic",()=>Zs.run(e)),t(" nestingGraph.run",()=>Js.run(e)),t(" rank",()=>cy(je.asNonCompoundGraph(e))),t(" injectEdgeLabelProxies",()=>My(e)),t(" removeEmptyRanks",()=>fy(e)),t(" nestingGraph.cleanup",()=>Js.cleanup(e)),t(" normalizeRanks",()=>uy(e)),t(" assignRankMinMax",()=>Ay(e)),t(" removeEdgeLabelProxies",()=>Iy(e)),t(" normalize.run",()=>Qs.run(e)),t(" parentDummyChains",()=>dy(e)),t(" addBorderSegments",()=>hy(e)),t(" order",()=>my(e,n)),t(" insertSelfEdges",()=>zy(e)),t(" adjustCoordinateSystem",()=>ei.adjust(e)),t(" position",()=>py(e)),t(" positionSelfEdges",()=>Hy(e)),t(" removeBorderNodes",()=>Ly(e)),t(" normalize.undo",()=>Qs.undo(e)),t(" fixupEdgeLabelCoords",()=>Oy(e)),t(" undoCoordinateSystem",()=>ei.undo(e)),t(" translateGraph",()=>Ry(e)),t(" assignNodeIntersects",()=>Ty(e)),t(" reversePoints",()=>Dy(e)),t(" acyclic.undo",()=>Zs.undo(e))}function by(e,t){e.nodes().forEach(n=>{let r=e.node(n),s=t.node(n);r&&(r.x=s.x,r.y=s.y,r.rank=s.rank,t.children(n).length&&(r.width=s.width,r.height=s.height))}),e.edges().forEach(n=>{let r=e.edge(n),s=t.edge(n);r.points=s.points,Object.hasOwn(s,"x")&&(r.x=s.x,r.y=s.y)}),e.graph().width=t.graph().width,e.graph().height=t.graph().height}let vy=["nodesep","edgesep","ranksep","marginx","marginy"],_y={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},Ey=["acyclicer","ranker","rankdir","align"],Ny=["width","height","rank"],ti={width:0,height:0},Sy=["minlen","weight","width","height","labeloffset"],ky={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},jy=["labelpos"];function Cy(e){let t=new gy({multigraph:!0,compound:!0}),n=tr(e.graph());return t.setGraph(Object.assign({},_y,er(n,vy),je.pick(n,Ey))),e.nodes().forEach(r=>{let s=tr(e.node(r));const i=er(s,Ny);Object.keys(ti).forEach(o=>{i[o]===void 0&&(i[o]=ti[o])}),t.setNode(r,i),t.setParent(r,e.parent(r))}),e.edges().forEach(r=>{let s=tr(e.edge(r));t.setEdge(r,Object.assign({},ky,er(s,Sy),je.pick(s,jy)))}),t}function $y(e){let t=e.graph();t.ranksep/=2,e.edges().forEach(n=>{let r=e.edge(n);r.minlen*=2,r.labelpos.toLowerCase()!=="c"&&(t.rankdir==="TB"||t.rankdir==="BT"?r.width+=r.labeloffset:r.height+=r.labeloffset)})}function My(e){e.edges().forEach(t=>{let n=e.edge(t);if(n.width&&n.height){let r=e.node(t.v),i={rank:(e.node(t.w).rank-r.rank)/2+r.rank,e:t};je.addDummyNode(e,"edge-proxy",i,"_ep")}})}function Ay(e){let t=0;e.nodes().forEach(n=>{let r=e.node(n);r.borderTop&&(r.minRank=e.node(r.borderTop).rank,r.maxRank=e.node(r.borderBottom).rank,t=Math.max(t,r.maxRank))}),e.graph().maxRank=t}function Iy(e){e.nodes().forEach(t=>{let n=e.node(t);n.dummy==="edge-proxy"&&(e.edge(n.e).labelRank=n.rank,e.removeNode(t))})}function Ry(e){let t=Number.POSITIVE_INFINITY,n=0,r=Number.POSITIVE_INFINITY,s=0,i=e.graph(),o=i.marginx||0,a=i.marginy||0;function l(c){let u=c.x,d=c.y,m=c.width,f=c.height;t=Math.min(t,u-m/2),n=Math.max(n,u+m/2),r=Math.min(r,d-f/2),s=Math.max(s,d+f/2)}e.nodes().forEach(c=>l(e.node(c))),e.edges().forEach(c=>{let u=e.edge(c);Object.hasOwn(u,"x")&&l(u)}),t-=o,r-=a,e.nodes().forEach(c=>{let u=e.node(c);u.x-=t,u.y-=r}),e.edges().forEach(c=>{let u=e.edge(c);u.points.forEach(d=>{d.x-=t,d.y-=r}),Object.hasOwn(u,"x")&&(u.x-=t),Object.hasOwn(u,"y")&&(u.y-=r)}),i.width=n-t+o,i.height=s-r+a}function Ty(e){e.edges().forEach(t=>{let n=e.edge(t),r=e.node(t.v),s=e.node(t.w),i,o;n.points?(i=n.points[0],o=n.points[n.points.length-1]):(n.points=[],i=s,o=r),n.points.unshift(je.intersectRect(r,i)),n.points.push(je.intersectRect(s,o))})}function Oy(e){e.edges().forEach(t=>{let n=e.edge(t);if(Object.hasOwn(n,"x"))switch((n.labelpos==="l"||n.labelpos==="r")&&(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset;break}})}function Dy(e){e.edges().forEach(t=>{let n=e.edge(t);n.reversed&&n.points.reverse()})}function Ly(e){e.nodes().forEach(t=>{if(e.children(t).length){let n=e.node(t),r=e.node(n.borderTop),s=e.node(n.borderBottom),i=e.node(n.borderLeft[n.borderLeft.length-1]),o=e.node(n.borderRight[n.borderRight.length-1]);n.width=Math.abs(o.x-i.x),n.height=Math.abs(s.y-r.y),n.x=i.x+n.width/2,n.y=r.y+n.height/2}}),e.nodes().forEach(t=>{e.node(t).dummy==="border"&&e.removeNode(t)})}function Py(e){e.edges().forEach(t=>{if(t.v===t.w){var n=e.node(t.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:t,label:e.edge(t)}),e.removeEdge(t)}})}function zy(e){var t=je.buildLayerMatrix(e);t.forEach(n=>{var r=0;n.forEach((s,i)=>{var o=e.node(s);o.order=i+r,(o.selfEdges||[]).forEach(a=>{je.addDummyNode(e,"selfedge",{width:a.label.width,height:a.label.height,rank:o.rank,order:i+ ++r,e:a.e,label:a.label},"_se")}),delete o.selfEdges})})}function Hy(e){e.nodes().forEach(t=>{var n=e.node(t);if(n.dummy==="selfedge"){var r=e.node(n.e.v),s=r.x+r.width/2,i=r.y,o=n.x-s,a=r.height/2;e.setEdge(n.e,n.label),e.removeNode(t),n.label.points=[{x:s+2*o/3,y:i-a},{x:s+5*o/6,y:i-a},{x:s+o,y:i},{x:s+5*o/6,y:i+a},{x:s+2*o/3,y:i+a}],n.label.x=n.x,n.label.y=n.y}})}function er(e,t){return je.mapValues(je.pick(e,t),Number)}function tr(e){var t={};return e&&Object.entries(e).forEach(([n,r])=>{typeof n=="string"&&(n=n.toLowerCase()),t[n]=r}),t}let Fy=fe,Vy=Ie.Graph;var By={debugOrdering:Gy};function Gy(e){let t=Fy.buildLayerMatrix(e),n=new Vy({compound:!0,multigraph:!0}).setGraph({});return e.nodes().forEach(r=>{n.setNode(r,{label:r}),n.setParent(r,"layer"+e.node(r).rank)}),e.edges().forEach(r=>n.setEdge(r.v,r.w,{},r.name)),t.forEach((r,s)=>{let i="layer"+s;n.setNode(i,{rank:"same"}),r.reduce((o,a)=>(n.setEdge(o,a,{style:"invis"}),a))}),n}var Yy="1.1.8",Wy={graphlib:Ie,layout:yy,debug:By,util:{time:fe.time,notime:fe.notime},version:Yy};const ni=fi(Wy),_t=264,Uy=44,Xy=26,qy=14;function Sn(e){const t=Math.max(e.attributes.length,1);return Uy+t*Xy+qy}const Ky=40;function ri(e,t,n,r="auto",s,i="LR"){const o=Zy(n,s);return r==="grid"?ai(e,n,o):r==="clustered"?oi(e,t,n,o,i):r==="hierarchical"||e.length<=Ky?si(e,t,n,i):new Set(e.map(l=>o(l.id)).filter(Boolean)).size>1?oi(e,t,n,o,i):ai(e,n,o)}function Zy(e,t){return n=>{var r,s,i;if(t){const o=t.get(n);if(o)return o.name}return((i=(s=(r=e.get(n))==null?void 0:r.conceptual)==null?void 0:s.subject_area)==null?void 0:i.name)??""}}function ya(e,t,n,r=!1,s="LR"){const i=new ni.graphlib.Graph;i.setGraph({rankdir:s,nodesep:r?45:70,ranksep:r?110:150,edgesep:r?20:30,marginx:24,marginy:24,ranker:"network-simplex"}),i.setDefaultEdgeLabel(()=>({}));const o=new Set(e.map(u=>u.id));for(const u of e){const d=n.get(u.id);i.setNode(u.id,{width:_t,height:d?Sn(d):120})}for(const u of t)o.has(u.source)&&o.has(u.target)&&i.setEdge(u.source,u.target,{minlen:1,weight:2});ni.layout(i);let a=0,l=0;return{nodes:e.map(u=>{const d=i.node(u.id),m=n.get(u.id),f=m?Sn(m):120,y=d.x-_t/2,p=d.y-f/2;return a=Math.max(a,y+_t),l=Math.max(l,p+f),{...u,position:{x:y,y:p}}}),width:a,height:l}}function si(e,t,n,r="LR"){return ya(e,t,n,!1,r).nodes}function Qy(e,t){const n=a=>{const l=t.get(a);return l?Sn(l):120},r=Math.max(1,Math.round(Math.sqrt(e.length))),s=[];let i=0,o=0;for(let a=0;a{const d=u*(_t+xa);s.push({...c,position:{x:d,y:i}}),o=Math.max(o,d+_t)}),i+=Math.max(...l.map(c=>n(c.id)))+wa}return{nodes:s,width:o,height:i}}const ii=120;function oi(e,t,n,r,s="LR"){const i=new Map;for(const m of e){const f=r(m.id);(i.get(f)??i.set(f,[]).get(f)).push(m)}const a=[...i.keys()].sort((m,f)=>m===""?1:f===""?-1:m.localeCompare(f)).map(m=>{const f=i.get(m),y=new Set(f.map(_=>_.id));let p=0;for(const _ of t)y.has(_.source)&&y.has(_.target)&&p++;const x=f.length<=8&&p>=f.length-1?ya(f,t,n,!0,s):Qy(f,n);return{name:m,...x}}),l=Math.max(1,Math.ceil(Math.sqrt(a.length*1.6))),c=[];let u=0;for(let m=0;m[m.id,m.position]));return e.map(m=>({...m,position:d.get(m.id)??m.position}))}const xa=40,wa=40;function ai(e,t,n){const r=c=>{const u=t.get(c);return u?Sn(u):120},s=[...e].sort((c,u)=>{var p,v;const d=n(c.id),m=n(u.id);if(d!==m)return d.localeCompare(m);const f=((p=t.get(c.id))==null?void 0:p.name)??c.id,y=((v=t.get(u.id))==null?void 0:v.name)??u.id;return f.localeCompare(y)}),i=Math.max(1,Math.round(Math.sqrt(s.length))),o=Array.from({length:i},(c,u)=>u*(_t+xa)),a=new Map;let l=0;for(let c=0;ca.set(m.id,{x:o[f],y:l}));const d=Math.max(...u.map(m=>r(m.id)));l+=d+wa}return e.map(c=>({...c,position:a.get(c.id)??c.position}))}function Zt({title:e,onClose:t,children:n,wide:r}){return h.jsx("div",{className:"modal-backdrop",onClick:t,children:h.jsxs("div",{className:"modal"+(r?" wide":""),onClick:s=>s.stopPropagation(),children:[h.jsxs("div",{className:"modal-header",children:[h.jsx("h2",{children:e}),h.jsx("button",{className:"icon-btn",onClick:t,children:"✕"})]}),n]})})}const Jy=["skos:exactMatch","skos:closeMatch","skos:broadMatch","skos:narrowMatch","skos:relatedMatch"],ba=["industry","core","domain","specialised"];function ex({entity:e,exec:t,onClose:n}){var b,j;const[r,s]=w.useState(((b=e.conceptual)==null?void 0:b.name)??e.name),[i,o]=w.useState([]),[a,l]=w.useState(null),[c,u]=w.useState(null),[d,m]=w.useState("skos:exactMatch"),[f,y]=w.useState(((j=e.conceptual)==null?void 0:j.ontology_layer)??"core"),[p,v]=w.useState([]),[x,_]=w.useState("");w.useEffect(()=>{Go().then(C=>v(C.ontologies)).catch(()=>{})},[]),w.useEffect(()=>{const C=setTimeout(()=>{if(!r.trim())return o([]);Bo(r,x||void 0).then(E=>{o(E.results),l(E.loaded_terms)}).catch(()=>o([]))},200);return()=>clearTimeout(C)},[r,x]);const M=()=>{c&&t("set_alignment",{id:e.id,aligns_to:c.prefixed,alignment:d,layer:f,resolved_via:c.source}).then(n)};return h.jsxs(Zt,{title:`Align '${e.name}' to ontology`,onClose:n,wide:!0,children:[p.length>0&&h.jsxs("div",{className:"src-picker",children:[h.jsx("button",{className:"src-chip"+(x===""?" active":""),onClick:()=>_(""),children:"all sources"}),p.map(C=>h.jsx("button",{className:"src-chip"+(x===C.id?" active":""),title:C.count!=null?`${C.count} terms`:"live resolver",onClick:()=>_(C.id),children:C.name},C.id))]}),h.jsx("input",{autoFocus:!0,className:"edit-input modal-search",placeholder:x?`Search within ${x}…`:"Search vocabulary terms…",value:r,onChange:C=>s(C.target.value)}),a===0&&p.length===0&&h.jsx("p",{className:"empty-hint",children:"No vocabulary loaded. Declare one in mdl-project.yaml's ontology_stack (or run `mdl ontology vendor fibo`)."}),h.jsxs("div",{className:"term-results",children:[i.map(C=>h.jsxs("button",{className:"term-card"+((c==null?void 0:c.iri)===C.iri?" picked":""),onClick:()=>u(C),children:[h.jsxs("div",{className:"term-head",children:[h.jsx("span",{className:"term-label",children:C.label}),h.jsxs("span",{className:"term-source",children:[C.source_kind==="glossary-term"&&h.jsx("span",{className:"kind-badge",children:"glossary"}),C.source]})]}),h.jsx("code",{className:"term-iri",children:C.prefixed}),C.definition&&h.jsx("p",{className:"term-def",children:C.definition})]},C.iri)),r&&i.length===0&&a!==0&&h.jsxs("p",{className:"empty-hint",children:["no matches for “",r,"”"]})]}),h.jsxs("div",{className:"modal-footer",children:[h.jsxs("label",{children:["predicate",h.jsx("select",{value:d,onChange:C=>m(C.target.value),children:Jy.map(C=>h.jsx("option",{children:C},C))})]}),h.jsxs("label",{children:["layer",h.jsx("select",{value:f,onChange:C=>y(C.target.value),children:ba.map(C=>h.jsx("option",{children:C},C))})]}),h.jsxs("button",{className:"primary-btn",disabled:!c,onClick:M,children:["Align",c?` to ${c.label}`:""]})]})]})}function tx({entity:e,doc:t,exec:n,onClose:r}){var b,j,C;const[s,i]=w.useState(((b=e.term_map)==null?void 0:b.subject_template)??""),[o,a]=w.useState(((j=e.term_map)==null?void 0:j.class_iri)??""),l=new Set(e.attributes.map(E=>E.name)),u=Array.from(s.matchAll(/\{([^}]+)\}/g)).map(E=>E[1]).filter(E=>!l.has(E)),d=E=>!E||E.startsWith("http://")||E.startsWith("https://")||/^[^\s:]+:[^\s:]+/.test(E),m=u.length===0&&d(o),f=()=>{n("set_term_map",{id:e.id,subject_template:s.trim()||null,class_iri:o.trim()||null}).then(r)},y=(t.project.name||"").replace(/[^0-9a-zA-Z]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"modelith-model",p=t.project.kg_base_iri||`urn:${y}:`,v=(C=(e.key_groups??[]).find(E=>E.type==="pk"))==null?void 0:C.members.map(E=>{var L;return(L=e.attributes.find(S=>S.id===E))==null?void 0:L.name}).filter(Boolean),x=v&&v.length?`${p}${e.id}/${v.map(E=>`{${E}}`).join("_")}`:"(blank-node: entity has no primary key)",_=o.trim()||`${p}${e.id}`,M=s.trim()||x;return h.jsxs(Zt,{title:`Knowledge Graph mapping — ${e.name}`,onClose:r,wide:!0,children:[h.jsx("p",{className:"empty-hint",style:{marginBottom:14},children:"Override the R2RML term-map for this entity. Leave a field blank to use the default (project base IRI + primary key)."}),h.jsxs("div",{className:"form-row",children:[h.jsx("label",{htmlFor:"tm-class",children:"Class IRI"}),h.jsx("input",{id:"tm-class",className:"edit-input",value:o,placeholder:"https://acme.com/Customer or fibo-fnd:Party",onChange:E=>a(E.target.value)}),d(o)?h.jsxs("code",{className:"form-preview",children:["rr:class ",_]}):h.jsx("span",{className:"form-error",children:"not a valid IRI or prefix:local CURIE"})]}),h.jsxs("div",{className:"form-row",children:[h.jsx("label",{htmlFor:"tm-subject",children:"Subject template"}),h.jsx("input",{id:"tm-subject",className:"edit-input",value:s,placeholder:"https://acme.com/id/customer/{customer_id}",onChange:E=>i(E.target.value)}),u.length>0?h.jsxs("span",{className:"form-error",children:["unknown column",u.length>1?"s":"",": ",u.join(", ")]}):h.jsxs("code",{className:"form-preview",children:["rr:template ",M]}),h.jsxs("span",{className:"form-hint",children:["Wrap a column in ","{ }"," to fill it from each row, e.g."," ","{"+((v==null?void 0:v[0])??"id")+"}",". Columns:"," ",e.attributes.map(E=>E.name).join(", ")]})]}),h.jsxs("div",{className:"modal-footer",children:[h.jsx("button",{className:"mini-btn",onClick:r,children:"Cancel"}),h.jsx("button",{className:"primary-btn",disabled:!m,onClick:f,children:"Save mapping"})]})]})}function nx({doc:e,exec:t,onClose:n,onCreated:r}){const[s,i]=w.useState(""),[o,a]=w.useState(""),[l,c]=w.useState(""),[u,d]=w.useState(""),m=()=>{s.trim()&&t("create_entity",{name:s,definition:o||null,subject_area:l||null,layer:u||null}).then(f=>{const y=f==null?void 0:f.created_id;n(),y&&r(y)})};return h.jsxs(Zt,{title:"New entity",onClose:n,children:[h.jsxs("label",{className:"form-row",children:["name",h.jsx("input",{autoFocus:!0,className:"edit-input",placeholder:"e.g. custody_account",value:s,onChange:f=>i(f.target.value),onKeyDown:f=>f.key==="Enter"&&m()})]}),h.jsxs("label",{className:"form-row",children:["definition",h.jsx("textarea",{className:"edit-input",rows:2,placeholder:"business definition…",value:o,onChange:f=>a(f.target.value)})]}),h.jsxs("label",{className:"form-row",children:["subject area",h.jsxs("select",{value:l,onChange:f=>c(f.target.value),children:[h.jsx("option",{value:"",children:"none"}),e.subject_areas.map(f=>h.jsx("option",{value:f.id,children:f.name},f.id))]})]}),h.jsxs("label",{className:"form-row",children:["ontology layer",h.jsxs("select",{value:u,onChange:f=>d(f.target.value),children:[h.jsx("option",{value:"",children:"none"}),ba.map(f=>h.jsx("option",{children:f},f))]})]}),h.jsx("div",{className:"modal-footer",children:h.jsx("button",{className:"primary-btn",disabled:!s.trim(),onClick:m,children:"Create"})})]})}const va=["many_to_one","one_to_many","one_to_one","many_to_many"];function rx({doc:e,fromId:t,toId:n,initialFromAttr:r,initialToAttr:s,exec:i,onClose:o}){const a=e.entities.find(b=>b.id===t),l=e.entities.find(b=>b.id===n),c=w.useMemo(()=>l==null?void 0:l.attributes.find(b=>b.role==="business_key"),[l]),[u,d]=w.useState(r??""),[m,f]=w.useState(s??(c==null?void 0:c.id)??""),[y,p]=w.useState("many_to_one"),[v,x]=w.useState("mandatory");if(!a||!l)return null;const _=u==="__new__",M=()=>i("create_relationship",{from_entity:a.id,to_entity:l.id,from_attribute:_?null:u||null,to_attribute:m||null,create_from_fk:_,cardinality:y,optionality:v}).then(o);return h.jsxs(Zt,{title:`${a.name} → ${l.name}`,onClose:o,children:[h.jsxs("label",{className:"form-row",children:["cardinality (",a.name," : ",l.name,")",h.jsx("select",{value:y,onChange:b=>p(b.target.value),children:va.map(b=>h.jsx("option",{children:b},b))})]}),h.jsxs("label",{className:"form-row",children:["foreign key on ",a.name,h.jsxs("select",{value:u,onChange:b=>d(b.target.value),children:[h.jsx("option",{value:"",children:"(none)"}),h.jsxs("option",{value:"__new__",children:["➕ create column",c?` "${c.name}"`:""]}),a.attributes.map(b=>h.jsx("option",{value:b.id,children:b.name},b.id))]})]}),h.jsxs("label",{className:"form-row",children:["references on ",l.name,h.jsxs("select",{value:m,onChange:b=>f(b.target.value),children:[h.jsx("option",{value:"",children:"(none)"}),l.attributes.map(b=>h.jsxs("option",{value:b.id,children:[b.name,b.role==="business_key"?" 🔑":""]},b.id))]})]}),h.jsxs("label",{className:"form-row",children:["optionality",h.jsxs("select",{value:v,onChange:b=>x(b.target.value),children:[h.jsx("option",{children:"mandatory"}),h.jsx("option",{children:"optional"})]})]}),h.jsx("div",{className:"modal-footer",children:h.jsx("button",{className:"primary-btn",onClick:M,children:"Create relationship"})})]})}function sx({rel:e,doc:t,exec:n,onClose:r}){const s=x=>{var _;return((_=t.entities.find(M=>M.id===x))==null?void 0:_.name)??"?"},[i,o]=w.useState(e.name),[a,l]=w.useState(e.cardinality),[c,u]=w.useState(e.optionality),[d,m]=w.useState(e.identifying),[f,y]=w.useState(!1),p=async()=>{i.trim()&&i.trim()!==e.name&&await n("rename_relationship",{id:e.id,name:i.trim()}),(a!==e.cardinality||c!==e.optionality||d!==e.identifying)&&await n("update_relationship",{id:e.id,cardinality:a,optionality:c,identifying:d}),r()},v=()=>n("delete_relationship",{id:e.id}).then(r);return h.jsxs(Zt,{title:`${s(e.from.entity)} → ${s(e.to.entity)}`,onClose:r,children:[h.jsxs("label",{className:"form-row",children:["relationship name",h.jsx("input",{value:i,onChange:x=>o(x.target.value),autoFocus:!0})]}),h.jsxs("label",{className:"form-row",children:["cardinality",h.jsx("select",{value:a,onChange:x=>l(x.target.value),children:va.map(x=>h.jsx("option",{children:x},x))})]}),h.jsxs("label",{className:"form-row",children:["optionality",h.jsxs("select",{value:c,onChange:x=>u(x.target.value),children:[h.jsx("option",{value:"mandatory",children:"mandatory"}),h.jsx("option",{value:"optional",children:"optional"})]})]}),h.jsxs("label",{className:"form-row",children:["identifying",h.jsxs("select",{value:d?"yes":"no",onChange:x=>m(x.target.value==="yes"),children:[h.jsx("option",{value:"no",children:"no — parent key is a plain reference"}),h.jsx("option",{value:"yes",children:"yes — parent key is part of the child's identity"})]})]}),h.jsxs("div",{className:"modal-footer",style:{justifyContent:"space-between"},children:[f?h.jsx("button",{className:"danger-btn",onClick:v,children:"Confirm delete"}):h.jsx("button",{className:"mini-btn danger",onClick:()=>y(!0),children:"Delete relationship"}),h.jsx("button",{className:"primary-btn",onClick:p,children:"Save"})]})]})}const ix=w.memo(function({id:t,sourceX:n,sourceY:r,targetX:s,targetY:i,sourcePosition:o,targetPosition:a,data:l,selected:c}){const[u]=vn({sourceX:n,sourceY:r,sourcePosition:o,targetX:s,targetY:i,targetPosition:a,borderRadius:10}),d=l==null?void 0:l.relationship,m=(l==null?void 0:l.dimmed)??!1,f=(d==null?void 0:d.cardinality)??"many_to_one",y=(d==null?void 0:d.optionality)==="optional",p=(d==null?void 0:d.identifying)??!1,v=f==="many_to_one"||f==="many_to_many",x=f==="one_to_many"||f==="many_to_many",_="rel-edge"+(c?" selected":"")+(m?" dimmed":""),M=((l==null?void 0:l.memberCount)??0)>1,b=l==null?void 0:l.onHoverEdge;return h.jsxs("g",{className:_,children:[h.jsx("path",{id:t,className:"rel-path",d:u,fill:"none",strokeDasharray:p?void 0:"6 4"}),h.jsx("path",{d:u,fill:"none",strokeWidth:14,stroke:"transparent",onMouseEnter:b?()=>b(d.id):void 0,onMouseLeave:b?()=>b(null):void 0}),h.jsx(li,{x:n,y:r,side:o,many:v,optional:y}),h.jsx(li,{x:s,y:i,side:a,many:x,optional:!1}),(c||M)&&d&&h.jsxs("text",{className:"rel-label",x:(n+s)/2,y:(r+i)/2-8,children:[c?d.verb_phrase||d.name:"",M?`${c?" ":""}(${l.memberCount})`:""]})]})});function li({x:e,y:t,side:n,many:r,optional:s}){const i=n===Z.Left?-1:1,o=7,a=12,l=[];return r?l.push(h.jsx("path",{className:"rel-glyph",d:`M ${e+i*a} ${t} L ${e} ${t-o} M ${e+i*a} ${t} L ${e} ${t} M ${e+i*a} ${t} L ${e} ${t+o}`,fill:"none"},"foot")):l.push(h.jsx("line",{className:"rel-glyph",x1:e+i*(a-3),y1:t-o,x2:e+i*(a-3),y2:t+o},"one")),s?l.push(h.jsx("circle",{className:"rel-glyph ring",cx:e+i*(a+6),cy:t,r:4},"opt")):l.push(h.jsx("line",{className:"rel-glyph",x1:e+i*(a+5),y1:t-o,x2:e+i*(a+5),y2:t+o},"mand")),h.jsx(h.Fragment,{children:l})}const ox={entity:Rm},ax={relationship:ix},ci=["#e0a63a","#e8825a","#d98ba8","#c4a3e0","#7fb0d8","#7fc9a0","#e6c14a"],ui="#8a7d6a";function lx(e,t){const n=(i,o)=>{var a;return!!o&&!!((a=t.get(i))!=null&&a.attributes.some(l=>l.id===o))},r=e.from.attributes[0],s=e.to.attributes[0];return{sourceHandle:n(e.from.entity,r)?r:Dr,targetHandle:n(e.to.entity,s)?s:Lr}}function Dx({doc:e,caps:t,exec:n,selectedId:r,onSelect:s,query:i="",showTypes:o=!0,collapseDetail:a=!1,expandedEntities:l,onToggleExpand:c,activeAreas:u,onError:d,handleRef:m}){const{fitView:f,fitBounds:y,getNodes:p}=Rn(),[v,x]=w.useState([]),[_,M]=w.useState([]),b=w.useRef(!1),[j,C]=w.useState(null),[E,L]=w.useState(null),[S,O]=w.useState(!1),[P,V]=w.useState(null),[F,g]=w.useState(null),[$,N]=w.useState(null),[I,H]=w.useState(null),k=!t.canEdit,R=w.useMemo(()=>{const B=new Map;return e.subject_areas.forEach((q,W)=>B.set(q.id,ci[W%ci.length])),B},[e]),D=w.useMemo(()=>{const B=new Map;return e.entities.forEach(q=>B.set(q.id,q)),B},[e]),z=w.useMemo(()=>{const B=new Map,q=new Map;return e.subject_areas.forEach(W=>{(W.members??[]).forEach(Q=>q.set(Q,{id:W.id,name:W.name}))}),e.entities.forEach(W=>{var T,se;const Q=(T=W.conceptual)!=null&&T.id?q.get(W.conceptual.id):void 0,U=(se=W.conceptual)==null?void 0:se.subject_area,X=Q??(U?{id:U.id,name:U.name??U.id}:void 0);X&&B.set(W.id,X)}),B},[e]),Y=w.useCallback(B=>{var W;if(!u||u.size===0)return!1;const q=(W=z.get(B))==null?void 0:W.id;return!(q&&u.has(q))},[u,z]),G=w.useMemo(()=>{const B=new Map,q=(W,Q)=>{if(!Q.length)return;const U=B.get(W)??new Set;Q.forEach(X=>U.add(X)),B.set(W,U)};for(const W of e.relationships)q(W.from.entity,W.from.attributes),q(W.to.entity,W.to.attributes);return B},[e]);w.useEffect(()=>{var X;const B=i.trim().toLowerCase(),q=new Set;if(B)for(const T of e.entities)(T.name.toLowerCase()+" "+(((X=T.conceptual)==null?void 0:X.name.toLowerCase())??"")+" "+T.attributes.map(ce=>ce.name.toLowerCase()).join(" ")).includes(B)&&q.add(T.id);const W=new Set;if(r){W.add(r);for(const T of e.relationships)T.from.entity===r&&W.add(T.to.entity),T.to.entity===r&&W.add(T.from.entity)}const Q=e.entities.map(T=>{const se=B!==""&&!q.has(T.id),ce=r!==null&&!W.has(T.id);return{id:T.id,type:"entity",position:{x:0,y:0},hidden:Y(T.id),data:{entity:T,color:(()=>{const me=z.get(T.id);return me?R.get(me.id)??ui:ui})(),dimmed:se||ce,highlighted:B!==""&&q.has(T.id),showTypes:o,collapseDetail:a,expanded:(l==null?void 0:l.has(T.id))??!1,onToggleExpand:c,endpointAttrs:G.get(T.id),highlightAttrs:void 0,onHoverAttr:N}}}),U=e.relationships.filter(T=>D.has(T.from.entity)&&D.has(T.to.entity)).map(T=>{const{sourceHandle:se,targetHandle:ce}=lx(T,D),me=r!==null&&T.from.entity!==r&&T.to.entity!==r;return{id:T.id,source:T.from.entity,target:T.to.entity,sourceHandle:se,targetHandle:ce,type:"relationship",data:{relationship:T,dimmed:me,memberCount:Math.max(T.from.attributes.length,T.to.attributes.length),onHoverEdge:H}}});x(T=>{const se=new Map(T.map(oe=>[oe.id,oe.position])),ce=Q.every(oe=>se.has(oe.id)),me=((u==null?void 0:u.size)??0)>0;if(b.current&&ce&&T.length>=Q.length&&!me)return Q.map(oe=>({...oe,position:se.get(oe.id)??oe.position}));const we=me?Q.filter(oe=>!oe.hidden):Q,be=ri(we,U,D,"auto",z),Ee=new Map(be.map(oe=>[oe.id,oe.position])),Ge=Q.map(oe=>Ee.has(oe.id)?{...oe,position:Ee.get(oe.id)}:se.has(oe.id)&&b.current?{...oe,position:se.get(oe.id)}:oe);return b.current=!0,requestAnimationFrame(()=>f({padding:.15,duration:300})),Ge}),M(U)},[e,i,r,o,a,l,c,R,D,z,Y,u,G,f]);const K=w.useMemo(()=>{const B=new Set,q=new Set,W=new Map,Q=(U,X)=>{if(!X.length)return;const T=W.get(U)??new Set;X.forEach(se=>T.add(se)),W.set(U,T)};if($)for(const U of e.relationships)(U.from.attributes.includes($)||U.to.attributes.includes($))&&(B.add(U.id),q.add(U.from.entity),q.add(U.to.entity),Q(U.from.entity,U.from.attributes),Q(U.to.entity,U.to.attributes));if(I){const U=e.relationships.find(X=>X.id===I);U&&(Q(U.from.entity,U.from.attributes),Q(U.to.entity,U.to.attributes))}return{active:$!==null,relsForAttr:B,entsForAttr:q,hitAttrsByEntity:W}},[e,$,I]);w.useEffect(()=>{var Q;const B=i.trim().toLowerCase(),q=new Set;if(B)for(const U of e.entities)(U.name.toLowerCase()+" "+(((Q=U.conceptual)==null?void 0:Q.name.toLowerCase())??"")+" "+U.attributes.map(T=>T.name.toLowerCase()).join(" ")).includes(B)&&q.add(U.id);const W=new Set;if(r){W.add(r);for(const U of e.relationships)U.from.entity===r&&W.add(U.to.entity),U.to.entity===r&&W.add(U.from.entity)}x(U=>U.map(X=>{const T=B!==""&&!q.has(X.id),se=r!==null&&!W.has(X.id),ce=K.active&&!K.entsForAttr.has(X.id),me=T||se||ce,we=B!==""&&q.has(X.id)||K.active&&K.entsForAttr.has(X.id),be=K.hitAttrsByEntity.get(X.id);return X.data.dimmed===me&&X.data.highlighted===we&&X.data.highlightAttrs===be?X:{...X,data:{...X.data,dimmed:me,highlighted:we,highlightAttrs:be}}})),M(U=>U.map(X=>{var we,be;const T=(we=X.data)==null?void 0:we.relationship,se=r!==null&&T!==void 0&&T.from.entity!==r&&T.to.entity!==r,ce=K.active&&!K.relsForAttr.has(X.id),me=se||ce;return((be=X.data)==null?void 0:be.dimmed)===me?X:{...X,data:{...X.data,dimmed:me}}}))},[K,i,r,e]),w.useEffect(()=>{var Q;const B=i.trim().toLowerCase();if(!B)return;const q=new Set;for(const U of e.entities)(U.name.toLowerCase()+" "+(((Q=U.conceptual)==null?void 0:Q.name.toLowerCase())??"")+" "+U.attributes.map(T=>T.name.toLowerCase()).join(" ")).includes(B)&&q.add(U.id);if(!q.size)return;const W=requestAnimationFrame(()=>{const U=p().filter(T=>q.has(T.id));if(!U.length)return;const X=kf(U);y(X,{padding:.35,duration:400})});return()=>cancelAnimationFrame(W)},[i,e,p,y]);const J=w.useCallback((B="auto",q="LR")=>{x(W=>ri(W,_,D,B,z,q)),requestAnimationFrame(()=>f({padding:.15,duration:300}))},[_,D,z,f]),ee=w.useCallback(B=>{s(B),x(q=>(q.find(Q=>Q.id===B)&&requestAnimationFrame(()=>f({nodes:[{id:B}],padding:.4,duration:400})),q))},[f,s]);w.useImperativeHandle(m,()=>({relayout:J,fitView:()=>f({padding:.15,duration:300}),focusEntity:ee,newEntity:()=>O(!0)}),[J,f,ee]);const ie=w.useCallback(B=>{if(k||!B.source||!B.target||B.source===B.target)return;const q=B.sourceHandle&&B.sourceHandle!==Dr?B.sourceHandle:void 0,W=B.targetHandle&&B.targetHandle!==Lr?B.targetHandle:void 0;V({from:B.source,to:B.target,fromAttr:q,toAttr:W})},[k]),te=w.useCallback(async(B,q)=>{try{return await n(B,q)}catch(W){throw d==null||d(W instanceof Error?W.message:String(W)),W}},[n,d]),re=r?D.get(r)??null:null,de=e.relationships.find(B=>B.id===F)??null;return h.jsxs(h.Fragment,{children:[h.jsxs(Do,{nodes:v,edges:_,nodeTypes:ox,edgeTypes:ax,onNodeClick:(B,q)=>s(q.id),onEdgeClick:(B,q)=>!k&&g(q.id),onPaneClick:()=>{s(null),g(null)},onNodeDragStop:(B,q)=>x(W=>W.map(Q=>Q.id===q.id?{...Q,position:q.position}:Q)),onConnect:ie,nodesConnectable:!k,minZoom:.05,onlyRenderVisibleElements:!0,proOptions:{hideAttribution:!0},fitView:!0,children:[h.jsx(xm,{variant:ke.Dots,gap:22,size:1.5,color:"#33291f"}),h.jsx(im,{pannable:!0,zoomable:!0,nodeColor:B=>{var q;return((q=B.data)==null?void 0:q.color)??"#5a4f42"},maskColor:"rgba(20, 17, 15, 0.75)"}),h.jsx(fm,{showInteractive:!1})]}),re&&h.jsx(Om,{entity:re,doc:e,caps:t,exec:te,onClose:()=>s(null),onFocusEntity:ee,onAlign:C,onEditMapping:L}),j&&h.jsx(ex,{entity:j,exec:te,onClose:()=>C(null)}),E&&h.jsx(tx,{entity:E,doc:e,exec:te,onClose:()=>L(null)}),S&&h.jsx(nx,{doc:e,exec:te,onClose:()=>O(!1),onCreated:ee}),P&&h.jsx(rx,{doc:e,fromId:P.from,toId:P.to,initialFromAttr:P.fromAttr,initialToAttr:P.toAttr,exec:te,onClose:()=>V(null)}),de&&h.jsx(sx,{rel:de,doc:e,exec:te,onClose:()=>g(null)})]})}function Lx({tab:e,onClose:t,readOnly:n,refreshKey:r,onModelChanged:s,onFocusEntity:i}){return h.jsxs("aside",{className:"side-panel",children:[h.jsxs("div",{className:"detail-header",children:[h.jsxs("h2",{children:[e==="ontology"&&"Ontology",e==="layers"&&"Ontology layers",e==="changes"&&"Uncommitted changes",e==="decisions"&&"Decision ledger"]}),h.jsx("button",{className:"icon-btn",onClick:t,children:"✕"})]}),e==="ontology"&&h.jsx(cx,{}),e==="layers"&&h.jsx(dx,{refreshKey:r,onFocusEntity:i}),e==="changes"&&h.jsx(fx,{readOnly:n,refreshKey:r,onModelChanged:s}),e==="decisions"&&h.jsx(hx,{readOnly:n})]})}function cx(){const[e,t]=w.useState(""),[n,r]=w.useState([]),[s,i]=w.useState({loaded:0,vocabs:[]}),[o,a]=w.useState(null),[l,c]=w.useState([]),[u,d]=w.useState("");w.useEffect(()=>{Go().then(f=>c(f.ontologies)).catch(()=>{})},[]),w.useEffect(()=>{const f=setTimeout(()=>{Bo(e||"a",u||void 0).then(y=>{r(e?y.results:[]),i({loaded:y.loaded_terms,vocabs:y.vocabularies})}).catch(()=>{})},200);return()=>clearTimeout(f)},[e,u]);const m=w.useCallback(f=>{wm(f).then(a).catch(()=>{})},[]);return o?h.jsxs("div",{className:"panel-body",children:[h.jsx("button",{className:"mini-btn",onClick:()=>a(null),children:"← back"}),h.jsx("h3",{style:{marginTop:12},children:o.label}),h.jsx("code",{className:"term-iri",children:o.prefixed}),o.definition&&h.jsx("p",{className:"term-def",children:o.definition}),h.jsxs("div",{className:"kv",children:[h.jsx("span",{className:"k",children:"source"}),h.jsx("span",{className:"v",children:o.source})]}),o.broader.length>0&&h.jsxs(h.Fragment,{children:[h.jsx("h4",{children:"broader"}),o.broader.map(f=>h.jsxs("button",{className:"rel-link",onClick:()=>m(f.iri),children:["↑ ",f.label]},f.iri))]}),o.narrower.length>0&&h.jsxs(h.Fragment,{children:[h.jsx("h4",{children:"narrower"}),o.narrower.map(f=>h.jsxs("button",{className:"rel-link",onClick:()=>m(f.iri),children:["↓ ",f.label]},f.iri))]})]}):h.jsxs("div",{className:"panel-body",children:[l.length>0&&h.jsxs("div",{className:"src-picker",children:[h.jsx("button",{className:"src-chip"+(u===""?" active":""),onClick:()=>d(""),children:"all sources"}),l.map(f=>h.jsxs("button",{className:"src-chip"+(u===f.id?" active":""),title:(f.description??"")+(f.count!=null?` · ${f.count} terms`:" · live"),onClick:()=>d(f.id),children:[f.name,f.layer&&h.jsx("span",{className:`src-layer layer-${f.layer}`,children:f.layer})]},f.id))]}),h.jsx("input",{className:"edit-input",placeholder:u?`Search within ${u}…`:"Search vocabulary terms…",value:e,onChange:f=>t(f.target.value)}),h.jsx("p",{className:"meta-line",children:l.length>0?`${l.length} source${l.length>1?"s":""}: ${s.vocabs.join(", ")}`+(s.loaded>0?` · ${s.loaded} local terms indexed`:""):"no vocabulary loaded — declare ontology_stack in mdl-project.yaml or run `mdl ontology vendor fibo`"}),h.jsx("div",{className:"term-results",children:n.map(f=>h.jsxs("button",{className:"term-card",onClick:()=>m(f.prefixed),children:[h.jsxs("div",{className:"term-head",children:[h.jsx("span",{className:"term-label",children:f.label}),h.jsxs("span",{className:"term-source",children:[f.source_kind==="glossary-term"&&h.jsx("span",{className:"kind-badge",title:"glossary term",children:"glossary"}),f.source]})]}),h.jsx("code",{className:"term-iri",children:f.prefixed}),f.definition&&h.jsx("p",{className:"term-def",children:f.definition})]},f.iri))})]})}const ux=["industry","core","domain","specialised"];function dx({refreshKey:e,onFocusEntity:t}){const[n,r]=w.useState(null),[s,i]=w.useState(null);if(w.useEffect(()=>{bm().then(r).catch(()=>{}),vm().then(i).catch(()=>{})},[e]),!n)return h.jsx("div",{className:"panel-body",children:"loading…"});const o=new Set((s==null?void 0:s.core_uncovered)??[]);return h.jsxs("div",{className:"panel-body",children:[s&&h.jsxs("div",{className:"coverage-banner"+(s.coverage_pct<100?" warn":""),children:["industry alignment coverage: ",h.jsxs("b",{children:[s.coverage_pct,"%"]})," (",s.core_with_industry,"+",s.core_exempt,"/",s.total_core," core terms)"]}),h.jsxs("div",{className:"layer-band external",children:[h.jsx("h4",{children:"industry (external vocabularies)"}),n.external_terms.length===0&&h.jsx("p",{className:"empty-hint",children:"no aligned terms yet"}),n.external_terms.map(a=>h.jsxs("div",{className:"stack-term external",title:a.definition??void 0,children:[a.label,h.jsx("span",{className:"term-source",children:a.source})]},a.iri))]}),ux.slice(1).map(a=>h.jsxs("div",{className:"layer-band",children:[h.jsx("h4",{children:a}),(n.layers[a]??[]).length===0&&h.jsx("p",{className:"empty-hint",children:"—"}),(n.layers[a]??[]).map(l=>{var c;return h.jsxs("button",{className:"stack-term"+(o.has(l.name)?" uncovered":""),title:l.definition??void 0,onClick:()=>t(l.id),children:[l.name,(l.aligned_refs??(l.aligned_to?[l.aligned_to]:[])).map((u,d)=>h.jsxs("span",{className:"align-arrow"+(u.resolved?"":" unresolved")+(u.status==="proposed"?" proposed":""),title:u.ref+(u.resolved_via?` (via ${u.resolved_via})`:""),children:["↑ ",u.label,u.status==="proposed"?" ·prop":""]},`${u.ref}-${d}`)),!l.aligned_to&&(((c=l.aligned_refs)==null?void 0:c.length)??0)===0&&!l.no_industry_equivalent&&h.jsx("span",{className:"align-arrow missing",children:"unaligned"})]},l.id)})]},a))]})}function fx({readOnly:e,refreshKey:t,onModelChanged:n}){const[r,s]=w.useState(null),[i,o]=w.useState(""),[a,l]=w.useState(""),[c,u]=w.useState(!1),d=w.useCallback(()=>{Em().then(s).catch(()=>s(null)),Nm().then(m=>o([m.diff,...m.untracked].filter(Boolean).join(` + +`))).catch(()=>o(""))},[]);return w.useEffect(d,[d,t]),r!=null&&r.git?r.clean?h.jsx("div",{className:"panel-body ok",children:"✓ working tree clean"}):h.jsxs("div",{className:"panel-body",children:[h.jsx("ul",{className:"dirty-list",children:r.dirty.map(m=>h.jsxs("li",{children:[h.jsx("code",{className:"dirty-state",children:m.state})," ",m.path]},m.path))}),h.jsx("pre",{className:"diff-view",children:i.split(` +`).map((m,f)=>h.jsx("span",{className:m.startsWith("+")&&!m.startsWith("+++")?"diff-add":m.startsWith("-")&&!m.startsWith("---")?"diff-del":m.startsWith("@@")?"diff-hunk":"",children:m+` +`},f))}),!e&&h.jsxs(h.Fragment,{children:[h.jsx("input",{className:"edit-input",placeholder:"commit message…",value:a,onChange:m=>l(m.target.value)}),h.jsxs("div",{className:"modal-footer",children:[h.jsx("button",{className:"mini-btn danger",disabled:c,onClick:()=>{confirm("Discard ALL uncommitted model changes?")&&(u(!0),km().then(()=>{u(!1),d(),n()}))},children:"Discard all"}),h.jsx("button",{className:"primary-btn",disabled:c||!a.trim(),onClick:()=>{u(!0),Sm(a).then(()=>{u(!1),l(""),d()})},children:"Commit"})]})]})]}):h.jsx("div",{className:"panel-body",children:"model directory is not in a git repo"})}function hx({readOnly:e}){const[t,n]=w.useState([]),r=w.useCallback(()=>{jm().then(i=>n(i.decisions)).catch(()=>n([]))},[]);if(w.useEffect(r,[r]),t.length===0)return h.jsx("div",{className:"panel-body",children:"no recorded decisions (run `mdl reverse` to propose)"});const s={accepted:"✓",rejected:"✗",proposed:"?"};return h.jsx("div",{className:"panel-body",children:t.map(i=>h.jsxs("div",{className:"decision "+i.verdict,children:[h.jsxs("div",{className:"decision-head",children:[h.jsx("span",{className:"decision-mark",children:s[i.verdict]}),h.jsx("span",{className:"chip",children:i.confidence}),h.jsx("span",{className:"chip",children:i.signal})]}),h.jsx("p",{className:"decision-subject",children:i.subject}),!e&&i.verdict==="proposed"&&h.jsxs("div",{className:"decision-actions",children:[h.jsx("button",{className:"mini-btn",onClick:()=>Os(i.signal_key,"accepted").then(r),children:"Accept"}),h.jsx("button",{className:"mini-btn danger",onClick:()=>Os(i.signal_key,"rejected").then(r),children:"Reject"})]})]},i.signal_key))})}function Px({exec:e,canEdit:t,onImported:n,submitLabel:r="Import & review",buttonClass:s="erd-action ghost",applyBatch:i,openImport:o=!1}){const[a,l]=w.useState(o&&t?"import":null),[c,u]=w.useState([]),[d,m]=w.useState("postgres"),f=w.useRef(null);w.useEffect(()=>{Cm().then(p=>u(p.formats)).catch(()=>u([]))},[]),w.useEffect(()=>{if(!a)return;const p=v=>{f.current&&!f.current.contains(v.target)&&l(null)};return document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[a]);const y=c.find(p=>p.id==="sql");return h.jsxs("div",{className:"ie-wrap",ref:f,children:[h.jsxs("button",{className:s+(a==="export"?" on":""),onClick:()=>l(a==="export"?null:"export"),children:[h.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"↧"}),"Export ",h.jsx("span",{className:"erd-caret",children:"▾"})]}),t&&h.jsxs("button",{className:s+(a==="import"?" on":""),onClick:()=>l(a==="import"?null:"import"),children:[h.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"↥"}),"Import ",h.jsx("span",{className:"erd-caret",children:"▾"})]}),a==="export"&&h.jsxs("div",{className:"ie-menu",role:"menu",children:[(y==null?void 0:y.dialects)&&h.jsxs("label",{className:"ie-dialect",children:[h.jsx("span",{children:"SQL dialect"}),h.jsx("select",{value:d,onChange:p=>m(p.target.value),children:y.dialects.map(p=>h.jsx("option",{value:p,children:p},p))})]}),c.map(p=>h.jsx("a",{className:"ie-item",href:$m(p.id,p.id==="sql"?d:void 0),download:!0,onClick:()=>l(null),children:p.label},p.id))]}),a==="import"&&h.jsx(mx,{exec:e,submitLabel:r,buttonClass:s,applyBatch:i,onClose:()=>l(null),onImported:p=>{l(null),n==null||n(p)}})]})}const di=[{id:"sql",label:"SQL DDL",hint:"CREATE TABLE … PRIMARY KEY / FOREIGN KEY"},{id:"mermaid",label:"Mermaid erDiagram",hint:"structural: entities, attributes, relationships"},{id:"json-schema",label:"JSON Schema",hint:"each object definition becomes an entity"},{id:"erwin",label:"erwin XML",hint:"entities, keys, relationships, subject areas, subtypes"}];function mx({exec:e,submitLabel:t,buttonClass:n,applyBatch:r,onClose:s,onImported:i}){var b;const[o,a]=w.useState("sql"),[l,c]=w.useState("postgres"),[u,d]=w.useState(""),[m,f]=w.useState(!1),[y,p]=w.useState(null),[v,x]=w.useState([]),_=j=>{j&&j.text().then(d).catch(()=>p("could not read that file"))},M=async()=>{f(!0),p(null),x([]);try{const j=await Mm(o,u,o==="sql"?l:void 0);if(!j.changes.length){p(j.warnings[0]??"nothing to import from that document"),f(!1);return}if(r)await r(j.changes);else for(const C of j.changes)await e(C.op,C.payload);x(j.warnings),i(j.tables)}catch(j){p(j instanceof Error?j.message:String(j))}finally{f(!1)}};return h.jsxs("div",{className:"ie-menu ie-import",role:"dialog",children:[h.jsx("div",{className:"ie-tabs",children:di.map(j=>h.jsx("button",{className:"ie-tab"+(o===j.id?" active":""),onClick:()=>a(j.id),children:j.label},j.id))}),h.jsx("p",{className:"ie-hint",children:(b=di.find(j=>j.id===o))==null?void 0:b.hint}),o==="sql"&&h.jsxs("label",{className:"ie-dialect",children:[h.jsx("span",{children:"dialect"}),h.jsx("select",{value:l,onChange:j=>c(j.target.value),children:["postgres","snowflake","mysql","duckdb"].map(j=>h.jsx("option",{children:j},j))})]}),h.jsx("textarea",{className:"ie-textarea",placeholder:`Paste ${o} here, or choose a file…`,value:u,onChange:j=>d(j.target.value),rows:8}),h.jsx("input",{type:"file",className:"ie-file",accept:".sql,.mmd,.md,.json,.xml,.txt",onChange:j=>{var C;return _(((C=j.target.files)==null?void 0:C[0])??null)}}),o==="mermaid"&&h.jsx("p",{className:"ie-warn",children:"Mermaid is a diagram format: types and keys are approximate and relationships are inferred from the lines."}),v.map((j,C)=>h.jsx("p",{className:"ie-warn",children:j},C)),y&&h.jsx("p",{className:"ie-error",children:y}),h.jsxs("div",{className:"ie-foot",children:[h.jsx("button",{className:n,onClick:s,children:"Cancel"}),h.jsx("button",{className:n,disabled:m||!u.trim(),onClick:M,children:m?"Importing…":t})]})]})}export{Vo as A,xm as B,fm as C,Rm as E,Px as I,dx as L,Dx as M,cx as O,ci as P,To as R,Lx as S,xx as a,Cx as b,kx as c,Mx as d,Ax as e,yx as f,Em as g,Ix as h,jx as i,vx as j,_x as k,Ex as l,Sx as m,Nx as n,Bo as o,$x as p,wx as q,bx as r,_m as s,ri as t,Do as u,ix as v,im as w}; diff --git a/packages/server/src/mdl_server/static/assets/styles-CIm9mWtD.js b/packages/server/src/mdl_server/static/assets/styles-CIm9mWtD.js deleted file mode 100644 index f6d5142..0000000 --- a/packages/server/src/mdl_server/static/assets/styles-CIm9mWtD.js +++ /dev/null @@ -1,23 +0,0 @@ -var qa=Object.defineProperty;var Xa=(e,t,n)=>t in e?qa(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var le=(e,t,n)=>Xa(e,typeof t!="symbol"?t+"":t,n);import{r as w,g as li,R as A,j as f}from"./client-DOmNpTln.js";function pe(e){if(typeof e=="string"||typeof e=="number")return""+e;let t="";if(Array.isArray(e))for(let n=0,r;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?rl:nl;fi.useSyncExternalStore=_t.useSyncExternalStore!==void 0?_t.useSyncExternalStore:sl;di.exports=fi;var il=di.exports;/** - * @license React - * use-sync-external-store-shim/with-selector.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Nn=w,ol=il;function al(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var ll=typeof Object.is=="function"?Object.is:al,cl=ol.useSyncExternalStore,ul=Nn.useRef,dl=Nn.useEffect,fl=Nn.useMemo,hl=Nn.useDebugValue;ui.useSyncExternalStoreWithSelector=function(e,t,n,r,s){var i=ul(null);if(i.current===null){var o={hasValue:!1,value:null};i.current=o}else o=i.current;i=fl(function(){function l(h){if(!c){if(c=!0,u=h,h=r(h),s!==void 0&&o.hasValue){var y=o.value;if(s(y,h))return d=y}return d=h}if(y=d,ll(u,h))return y;var g=r(h);return s!==void 0&&s(y,g)?(u=h,y):(u=h,d=g)}var c=!1,u,d,m=n===void 0?null:n;return[function(){return l(t())},m===null?void 0:function(){return l(m())}]},[t,n,r,s]);var a=cl(e,i[0],i[1]);return dl(function(){o.hasValue=!0,o.value=a},[a]),hl(a),a};ci.exports=ui;var ml=ci.exports;const pl=li(ml),gl={},Wr=e=>{let t;const n=new Set,r=(u,d)=>{const m=typeof u=="function"?u(t):u;if(!Object.is(m,t)){const h=t;t=d??(typeof m!="object"||m===null)?m:Object.assign({},t,m),n.forEach(y=>y(t,h))}},s=()=>t,l={setState:r,getState:s,getInitialState:()=>c,subscribe:u=>(n.add(u),()=>n.delete(u)),destroy:()=>{(gl?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},c=t=e(r,s,l);return l},yl=e=>e?Wr(e):Wr,{useDebugValue:xl}=A,{useSyncExternalStoreWithSelector:wl}=pl,vl=e=>e;function hi(e,t=vl,n){const r=wl(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return xl(r),r}const Ur=(e,t)=>{const n=yl(e),r=(s,i=t)=>hi(n,s,i);return Object.assign(r,n),r},bl=(e,t)=>e?Ur(e,t):Ur;function me(e,t){if(Object.is(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const[r,s]of e)if(!Object.is(s,t.get(r)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const r of e)if(!t.has(r))return!1;return!0}const n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(t,r)||!Object.is(e[r],t[r]))return!1;return!0}var _l={value:()=>{}};function Sn(){for(var e=0,t=arguments.length,n={},r;e=0&&(r=n.slice(s+1),n=n.slice(0,s)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}ln.prototype=Sn.prototype={constructor:ln,on:function(e,t){var n=this._,r=El(e+"",n),s,i=-1,o=r.length;if(arguments.length<2){for(;++i0)for(var n=new Array(s),r=0,s,i;r=0&&(t=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),Xr.hasOwnProperty(t)?{space:Xr[t],local:e}:e}function Sl(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===er&&t.documentElement.namespaceURI===er?t.createElement(e):t.createElementNS(n,e)}}function kl(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function mi(e){var t=kn(e);return(t.local?kl:Sl)(t)}function jl(){}function wr(e){return e==null?jl:function(){return this.querySelector(e)}}function Cl(e){typeof e!="function"&&(e=wr(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s=$&&($=_+1);!(j=b[$])&&++$=0;)(o=r[s])&&(i&&o.compareDocumentPosition(i)^4&&i.parentNode.insertBefore(o,i),i=o);return this}function Jl(e){e||(e=ec);function t(d,m){return d&&m?e(d.__data__,m.__data__):!d-!m}for(var n=this._groups,r=n.length,s=new Array(r),i=0;it?1:e>=t?0:NaN}function tc(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function nc(){return Array.from(this)}function rc(){for(var e=this._groups,t=0,n=e.length;t1?this.each((t==null?mc:typeof t=="function"?gc:pc)(e,t,n??"")):Et(this.node(),e)}function Et(e,t){return e.style.getPropertyValue(t)||wi(e).getComputedStyle(e,null).getPropertyValue(t)}function xc(e){return function(){delete this[e]}}function wc(e,t){return function(){this[e]=t}}function vc(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function bc(e,t){return arguments.length>1?this.each((t==null?xc:typeof t=="function"?vc:wc)(e,t)):this.node()[e]}function vi(e){return e.trim().split(/^|\s+/)}function vr(e){return e.classList||new bi(e)}function bi(e){this._node=e,this._names=vi(e.getAttribute("class")||"")}bi.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function _i(e,t){for(var n=vr(e),r=-1,s=t.length;++r=0&&(n=t.slice(r+1),t=t.slice(0,r)),{type:t,name:n}})}function Xc(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,s=t.length,i;n()=>e;function tr(e,{sourceEvent:t,subject:n,target:r,identifier:s,active:i,x:o,y:a,dx:l,dy:c,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:s,enumerable:!0,configurable:!0},active:{value:i,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:a,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:c,enumerable:!0,configurable:!0},_:{value:u}})}tr.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function iu(e){return!e.ctrlKey&&!e.button}function ou(){return this.parentNode}function au(e,t){return t??{x:e.x,y:e.y}}function lu(){return navigator.maxTouchPoints||"ontouchstart"in this}function cu(){var e=iu,t=ou,n=au,r=lu,s={},i=Sn("start","drag","end"),o=0,a,l,c,u,d=0;function m(v){v.on("mousedown.drag",h).filter(r).on("touchstart.drag",b).on("touchmove.drag",x,su).on("touchend.drag touchcancel.drag",_).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function h(v,j){if(!(u||!e.call(this,v,j))){var C=$(this,t.call(this,v,j),v,j,"mouse");C&&(_e(v.view).on("mousemove.drag",y,Pt).on("mouseup.drag",g,Pt),ki(v.view),Pn(v),c=!1,a=v.clientX,l=v.clientY,C("start",v))}}function y(v){if(wt(v),!c){var j=v.clientX-a,C=v.clientY-l;c=j*j+C*C>d}s.mouse("drag",v)}function g(v){_e(v.view).on("mousemove.drag mouseup.drag",null),ji(v.view,c),wt(v),s.mouse("end",v)}function b(v,j){if(e.call(this,v,j)){var C=v.changedTouches,N=t.call(this,v,j),D=C.length,S,T;for(S=0;S>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?Qt(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?Qt(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=du.exec(e))?new xe(t[1],t[2],t[3],1):(t=fu.exec(e))?new xe(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=hu.exec(e))?Qt(t[1],t[2],t[3],t[4]):(t=mu.exec(e))?Qt(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=pu.exec(e))?ns(t[1],t[2]/100,t[3]/100,1):(t=gu.exec(e))?ns(t[1],t[2]/100,t[3]/100,t[4]):Kr.hasOwnProperty(e)?Jr(Kr[e]):e==="transparent"?new xe(NaN,NaN,NaN,0):null}function Jr(e){return new xe(e>>16&255,e>>8&255,e&255,1)}function Qt(e,t,n,r){return r<=0&&(e=t=n=NaN),new xe(e,t,n,r)}function wu(e){return e instanceof Ut||(e=Ft(e)),e?(e=e.rgb(),new xe(e.r,e.g,e.b,e.opacity)):new xe}function nr(e,t,n,r){return arguments.length===1?wu(e):new xe(e,t,n,r??1)}function xe(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}br(xe,nr,Ci(Ut,{brighter(e){return e=e==null?hn:Math.pow(hn,e),new xe(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?zt:Math.pow(zt,e),new xe(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new xe(ot(this.r),ot(this.g),ot(this.b),mn(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:es,formatHex:es,formatHex8:vu,formatRgb:ts,toString:ts}));function es(){return`#${st(this.r)}${st(this.g)}${st(this.b)}`}function vu(){return`#${st(this.r)}${st(this.g)}${st(this.b)}${st((isNaN(this.opacity)?1:this.opacity)*255)}`}function ts(){const e=mn(this.opacity);return`${e===1?"rgb(":"rgba("}${ot(this.r)}, ${ot(this.g)}, ${ot(this.b)}${e===1?")":`, ${e})`}`}function mn(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function ot(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function st(e){return e=ot(e),(e<16?"0":"")+e.toString(16)}function ns(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Ce(e,t,n,r)}function $i(e){if(e instanceof Ce)return new Ce(e.h,e.s,e.l,e.opacity);if(e instanceof Ut||(e=Ft(e)),!e)return new Ce;if(e instanceof Ce)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,s=Math.min(t,n,r),i=Math.max(t,n,r),o=NaN,a=i-s,l=(i+s)/2;return a?(t===i?o=(n-r)/a+(n0&&l<1?0:o,new Ce(o,a,l,e.opacity)}function bu(e,t,n,r){return arguments.length===1?$i(e):new Ce(e,t,n,r??1)}function Ce(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}br(Ce,bu,Ci(Ut,{brighter(e){return e=e==null?hn:Math.pow(hn,e),new Ce(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?zt:Math.pow(zt,e),new Ce(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,s=2*n-r;return new xe(zn(e>=240?e-240:e+120,s,r),zn(e,s,r),zn(e<120?e+240:e-120,s,r),this.opacity)},clamp(){return new Ce(rs(this.h),Jt(this.s),Jt(this.l),mn(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=mn(this.opacity);return`${e===1?"hsl(":"hsla("}${rs(this.h)}, ${Jt(this.s)*100}%, ${Jt(this.l)*100}%${e===1?")":`, ${e})`}`}}));function rs(e){return e=(e||0)%360,e<0?e+360:e}function Jt(e){return Math.max(0,Math.min(1,e||0))}function zn(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const Mi=e=>()=>e;function _u(e,t){return function(n){return e+n*t}}function Eu(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function Nu(e){return(e=+e)==1?Ai:function(t,n){return n-t?Eu(t,n,e):Mi(isNaN(t)?n:t)}}function Ai(e,t){var n=t-e;return n?_u(e,n):Mi(isNaN(e)?t:e)}const ss=function e(t){var n=Nu(t);function r(s,i){var o=n((s=nr(s)).r,(i=nr(i)).r),a=n(s.g,i.g),l=n(s.b,i.b),c=Ai(s.opacity,i.opacity);return function(u){return s.r=o(u),s.g=a(u),s.b=l(u),s.opacity=c(u),s+""}}return r.gamma=e,r}(1);function Ge(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}var rr=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Hn=new RegExp(rr.source,"g");function Su(e){return function(){return e}}function ku(e){return function(t){return e(t)+""}}function ju(e,t){var n=rr.lastIndex=Hn.lastIndex=0,r,s,i,o=-1,a=[],l=[];for(e=e+"",t=t+"";(r=rr.exec(e))&&(s=Hn.exec(t));)(i=s.index)>n&&(i=t.slice(n,i),a[o]?a[o]+=i:a[++o]=i),(r=r[0])===(s=s[0])?a[o]?a[o]+=s:a[++o]=s:(a[++o]=null,l.push({i:o,x:Ge(r,s)})),n=Hn.lastIndex;return n180?u+=360:u-c>180&&(c+=360),m.push({i:d.push(s(d)+"rotate(",null,r)-2,x:Ge(c,u)})):u&&d.push(s(d)+"rotate("+u+r)}function a(c,u,d,m){c!==u?m.push({i:d.push(s(d)+"skewX(",null,r)-2,x:Ge(c,u)}):u&&d.push(s(d)+"skewX("+u+r)}function l(c,u,d,m,h,y){if(c!==d||u!==m){var g=h.push(s(h)+"scale(",null,",",null,")");y.push({i:g-4,x:Ge(c,d)},{i:g-2,x:Ge(u,m)})}else(d!==1||m!==1)&&h.push(s(h)+"scale("+d+","+m+")")}return function(c,u){var d=[],m=[];return c=e(c),u=e(u),i(c.translateX,c.translateY,u.translateX,u.translateY,d,m),o(c.rotate,u.rotate,d,m),a(c.skewX,u.skewX,d,m),l(c.scaleX,c.scaleY,u.scaleX,u.scaleY,d,m),c=u=null,function(h){for(var y=-1,g=m.length,b;++y=0&&e._call.call(void 0,t),e=e._next;--Nt}function as(){lt=(gn=Vt.now())+jn,Nt=Tt=0;try{Lu()}finally{Nt=0,zu(),lt=0}}function Pu(){var e=Vt.now(),t=e-gn;t>Ti&&(jn-=t,gn=e)}function zu(){for(var e,t=pn,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:pn=n);Ot=e,ir(r)}function ir(e){if(!Nt){Tt&&(Tt=clearTimeout(Tt));var t=e-lt;t>24?(e<1/0&&(Tt=setTimeout(as,e-Vt.now()-jn)),$t&&($t=clearInterval($t))):($t||(gn=Vt.now(),$t=setInterval(Pu,Ti)),Nt=1,Oi(as))}}function ls(e,t,n){var r=new yn;return t=t==null?0:+t,r.restart(s=>{r.stop(),e(s+t)},t,n),r}var Hu=Sn("start","end","cancel","interrupt"),Fu=[],Li=0,cs=1,or=2,cn=3,us=4,ar=5,un=6;function Cn(e,t,n,r,s,i){var o=e.__transition;if(!o)e.__transition={};else if(n in o)return;Vu(e,n,{name:t,index:r,group:s,on:Hu,tween:Fu,time:i.time,delay:i.delay,duration:i.duration,ease:i.ease,timer:null,state:Li})}function Er(e,t){var n=$e(e,t);if(n.state>Li)throw new Error("too late; already scheduled");return n}function Re(e,t){var n=$e(e,t);if(n.state>cn)throw new Error("too late; already running");return n}function $e(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function Vu(e,t,n){var r=e.__transition,s;r[t]=n,n.timer=Di(i,0,n.time);function i(c){n.state=cs,n.timer.restart(o,n.delay,n.time),n.delay<=c&&o(c-n.delay)}function o(c){var u,d,m,h;if(n.state!==cs)return l();for(u in r)if(h=r[u],h.name===n.name){if(h.state===cn)return ls(o);h.state===us?(h.state=un,h.timer.stop(),h.on.call("interrupt",e,e.__data__,h.index,h.group),delete r[u]):+uor&&r.state=0&&(t=t.slice(0,n)),!t||t==="start"})}function xd(e,t,n){var r,s,i=yd(t)?Er:Re;return function(){var o=i(this,e),a=o.on;a!==r&&(s=(r=a).copy()).on(t,n),o.on=s}}function wd(e,t){var n=this._id;return arguments.length<2?$e(this.node(),n).on.on(e):this.each(xd(n,e,t))}function vd(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function bd(){return this.on("end.remove",vd(this._id))}function _d(e){var t=this._name,n=this._id;typeof e!="function"&&(e=wr(e));for(var r=this._groups,s=r.length,i=new Array(s),o=0;o()=>e;function Ud(e,{sourceEvent:t,target:n,transform:r,dispatch:s}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:s}})}function ze(e,t,n){this.k=e,this.x=t,this.y=n}ze.prototype={constructor:ze,scale:function(e){return e===1?this:new ze(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new ze(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var He=new ze(1,0,0);ze.prototype;function Fn(e){e.stopImmediatePropagation()}function Mt(e){e.preventDefault(),e.stopImmediatePropagation()}function qd(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function Xd(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function ds(){return this.__zoom||He}function Kd(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Zd(){return navigator.maxTouchPoints||"ontouchstart"in this}function Qd(e,t,n){var r=e.invertX(t[0][0])-n[0][0],s=e.invertX(t[1][0])-n[1][0],i=e.invertY(t[0][1])-n[0][1],o=e.invertY(t[1][1])-n[1][1];return e.translate(s>r?(r+s)/2:Math.min(0,r)||Math.max(0,s),o>i?(i+o)/2:Math.min(0,i)||Math.max(0,o))}function Fi(){var e=qd,t=Xd,n=Qd,r=Kd,s=Zd,i=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],a=250,l=Ou,c=Sn("start","zoom","end"),u,d,m,h=500,y=150,g=0,b=10;function x(p){p.property("__zoom",ds).on("wheel.zoom",D,{passive:!1}).on("mousedown.zoom",S).on("dblclick.zoom",T).filter(s).on("touchstart.zoom",P).on("touchmove.zoom",V).on("touchend.zoom touchcancel.zoom",F).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}x.transform=function(p,M,E,O){var L=p.selection?p.selection():p;L.property("__zoom",ds),p!==L?j(p,M,E,O):L.interrupt().each(function(){C(this,arguments).event(O).start().zoom(null,typeof M=="function"?M.apply(this,arguments):M).end()})},x.scaleBy=function(p,M,E,O){x.scaleTo(p,function(){var L=this.__zoom.k,k=typeof M=="function"?M.apply(this,arguments):M;return L*k},E,O)},x.scaleTo=function(p,M,E,O){x.transform(p,function(){var L=t.apply(this,arguments),k=this.__zoom,I=E==null?v(L):typeof E=="function"?E.apply(this,arguments):E,z=k.invert(I),H=typeof M=="function"?M.apply(this,arguments):M;return n($(_(k,H),I,z),L,o)},E,O)},x.translateBy=function(p,M,E,O){x.transform(p,function(){return n(this.__zoom.translate(typeof M=="function"?M.apply(this,arguments):M,typeof E=="function"?E.apply(this,arguments):E),t.apply(this,arguments),o)},null,O)},x.translateTo=function(p,M,E,O,L){x.transform(p,function(){var k=t.apply(this,arguments),I=this.__zoom,z=O==null?v(k):typeof O=="function"?O.apply(this,arguments):O;return n(He.translate(z[0],z[1]).scale(I.k).translate(typeof M=="function"?-M.apply(this,arguments):-M,typeof E=="function"?-E.apply(this,arguments):-E),k,o)},O,L)};function _(p,M){return M=Math.max(i[0],Math.min(i[1],M)),M===p.k?p:new ze(M,p.x,p.y)}function $(p,M,E){var O=M[0]-E[0]*p.k,L=M[1]-E[1]*p.k;return O===p.x&&L===p.y?p:new ze(p.k,O,L)}function v(p){return[(+p[0][0]+ +p[1][0])/2,(+p[0][1]+ +p[1][1])/2]}function j(p,M,E,O){p.on("start.zoom",function(){C(this,arguments).event(O).start()}).on("interrupt.zoom end.zoom",function(){C(this,arguments).event(O).end()}).tween("zoom",function(){var L=this,k=arguments,I=C(L,k).event(O),z=t.apply(L,k),H=E==null?v(z):typeof E=="function"?E.apply(L,k):E,G=Math.max(z[1][0]-z[0][0],z[1][1]-z[0][1]),Y=L.__zoom,U=typeof M=="function"?M.apply(L,k):M,K=l(Y.invert(H).concat(G/Y.k),U.invert(H).concat(G/U.k));return function(Z){if(Z===1)Z=U;else{var B=K(Z),W=G/B[2];Z=new ze(W,H[0]-B[0]*W,H[1]-B[1]*W)}I.zoom(null,Z)}})}function C(p,M,E){return!E&&p.__zooming||new N(p,M)}function N(p,M){this.that=p,this.args=M,this.active=0,this.sourceEvent=null,this.extent=t.apply(p,M),this.taps=0}N.prototype={event:function(p){return p&&(this.sourceEvent=p),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(p,M){return this.mouse&&p!=="mouse"&&(this.mouse[1]=M.invert(this.mouse[0])),this.touch0&&p!=="touch"&&(this.touch0[1]=M.invert(this.touch0[0])),this.touch1&&p!=="touch"&&(this.touch1[1]=M.invert(this.touch1[0])),this.that.__zoom=M,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(p){var M=_e(this.that).datum();c.call(p,this.that,new Ud(p,{sourceEvent:this.sourceEvent,target:x,transform:this.that.__zoom,dispatch:c}),M)}};function D(p,...M){if(!e.apply(this,arguments))return;var E=C(this,M).event(p),O=this.__zoom,L=Math.max(i[0],Math.min(i[1],O.k*Math.pow(2,r.apply(this,arguments)))),k=je(p);if(E.wheel)(E.mouse[0][0]!==k[0]||E.mouse[0][1]!==k[1])&&(E.mouse[1]=O.invert(E.mouse[0]=k)),clearTimeout(E.wheel);else{if(O.k===L)return;E.mouse=[k,O.invert(k)],dn(this),E.start()}Mt(p),E.wheel=setTimeout(I,y),E.zoom("mouse",n($(_(O,L),E.mouse[0],E.mouse[1]),E.extent,o));function I(){E.wheel=null,E.end()}}function S(p,...M){if(m||!e.apply(this,arguments))return;var E=p.currentTarget,O=C(this,M,!0).event(p),L=_e(p.view).on("mousemove.zoom",H,!0).on("mouseup.zoom",G,!0),k=je(p,E),I=p.clientX,z=p.clientY;ki(p.view),Fn(p),O.mouse=[k,this.__zoom.invert(k)],dn(this),O.start();function H(Y){if(Mt(Y),!O.moved){var U=Y.clientX-I,K=Y.clientY-z;O.moved=U*U+K*K>g}O.event(Y).zoom("mouse",n($(O.that.__zoom,O.mouse[0]=je(Y,E),O.mouse[1]),O.extent,o))}function G(Y){L.on("mousemove.zoom mouseup.zoom",null),ji(Y.view,O.moved),Mt(Y),O.event(Y).end()}}function T(p,...M){if(e.apply(this,arguments)){var E=this.__zoom,O=je(p.changedTouches?p.changedTouches[0]:p,this),L=E.invert(O),k=E.k*(p.shiftKey?.5:2),I=n($(_(E,k),O,L),t.apply(this,M),o);Mt(p),a>0?_e(this).transition().duration(a).call(j,I,O,p):_e(this).call(x.transform,I,O,p)}}function P(p,...M){if(e.apply(this,arguments)){var E=p.touches,O=E.length,L=C(this,M,p.changedTouches.length===O).event(p),k,I,z,H;for(Fn(p),I=0;I"[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001",error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>"The React Flow parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,t)=>`Couldn't create edge for ${e?"target":"source"} handle id: "${e?t.targetHandle:t.sourceHandle}", edge id: ${t.id}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`},Vi=Ve.error001();function se(e,t){const n=w.useContext($n);if(n===null)throw new Error(Vi);return hi(n,e,t)}const he=()=>{const e=w.useContext($n);if(e===null)throw new Error(Vi);return w.useMemo(()=>({getState:e.getState,setState:e.setState,subscribe:e.subscribe,destroy:e.destroy}),[e])},ef=e=>e.userSelectionActive?"none":"all";function Sr({position:e,children:t,className:n,style:r,...s}){const i=se(ef),o=`${e}`.split("-");return A.createElement("div",{className:pe(["react-flow__panel",n,...o]),style:{...r,pointerEvents:i},...s},t)}function tf({proOptions:e,position:t="bottom-right"}){return e!=null&&e.hideAttribution?null:A.createElement(Sr,{position:t,className:"react-flow__attribution","data-message":"Please only hide this attribution when you are subscribed to React Flow Pro: https://reactflow.dev/pro"},A.createElement("a",{href:"https://reactflow.dev",target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution"},"React Flow"))}const nf=({x:e,y:t,label:n,labelStyle:r={},labelShowBg:s=!0,labelBgStyle:i={},labelBgPadding:o=[2,4],labelBgBorderRadius:a=2,children:l,className:c,...u})=>{const d=w.useRef(null),[m,h]=w.useState({x:0,y:0,width:0,height:0}),y=pe(["react-flow__edge-textwrapper",c]);return w.useEffect(()=>{if(d.current){const g=d.current.getBBox();h({x:g.x,y:g.y,width:g.width,height:g.height})}},[n]),typeof n>"u"||!n?null:A.createElement("g",{transform:`translate(${e-m.width/2} ${t-m.height/2})`,className:y,visibility:m.width?"visible":"hidden",...u},s&&A.createElement("rect",{width:m.width+2*o[0],x:-o[0],y:-o[1],height:m.height+2*o[1],className:"react-flow__edge-textbg",style:i,rx:a,ry:a}),A.createElement("text",{className:"react-flow__edge-text",y:m.height/2,dy:"0.3em",ref:d,style:r},n),l)};var rf=w.memo(nf);const kr=e=>({width:e.offsetWidth,height:e.offsetHeight}),St=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),jr=(e={x:0,y:0},t)=>({x:St(e.x,t[0][0],t[1][0]),y:St(e.y,t[0][1],t[1][1])}),fs=(e,t,n)=>en?-St(Math.abs(e-n),1,50)/50:0,Bi=(e,t)=>{const n=fs(e.x,35,t.width-35)*20,r=fs(e.y,35,t.height-35)*20;return[n,r]},Gi=e=>{var t;return((t=e.getRootNode)==null?void 0:t.call(e))||(window==null?void 0:window.document)},Yi=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),Bt=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),Wi=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),hs=e=>({...e.positionAbsolute||{x:0,y:0},width:e.width||0,height:e.height||0}),sf=(e,t)=>Wi(Yi(Bt(e),Bt(t))),lr=(e,t)=>{const n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},of=e=>Ee(e.width)&&Ee(e.height)&&Ee(e.x)&&Ee(e.y),Ee=e=>!isNaN(e)&&isFinite(e),ae=Symbol.for("internals"),Ui=["Enter"," ","Escape"],af=(e,t)=>{},lf=e=>"nativeEvent"in e;function cr(e){var s,i;const t=lf(e)?e.nativeEvent:e,n=((i=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:i[0])||e.target;return["INPUT","SELECT","TEXTAREA"].includes(n==null?void 0:n.nodeName)||(n==null?void 0:n.hasAttribute("contenteditable"))||!!(n!=null&&n.closest(".nokey"))}const qi=e=>"clientX"in e,qe=(e,t)=>{var i,o;const n=qi(e),r=n?e.clientX:(i=e.touches)==null?void 0:i[0].clientX,s=n?e.clientY:(o=e.touches)==null?void 0:o[0].clientY;return{x:r-((t==null?void 0:t.left)??0),y:s-((t==null?void 0:t.top)??0)}},xn=()=>{var e;return typeof navigator<"u"&&((e=navigator==null?void 0:navigator.userAgent)==null?void 0:e.indexOf("Mac"))>=0},qt=({id:e,path:t,labelX:n,labelY:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:h=20})=>A.createElement(A.Fragment,null,A.createElement("path",{id:e,style:u,d:t,fill:"none",className:"react-flow__edge-path",markerEnd:d,markerStart:m}),h&&A.createElement("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:h,className:"react-flow__edge-interaction"}),s&&Ee(n)&&Ee(r)?A.createElement(rf,{x:n,y:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c}):null);qt.displayName="BaseEdge";function At(e,t,n){return n===void 0?n:r=>{const s=t().edges.find(i=>i.id===e);s&&n(r,{...s})}}function Xi({sourceX:e,sourceY:t,targetX:n,targetY:r}){const s=Math.abs(n-e)/2,i=n{const[b,x,_]=Zi({sourceX:e,sourceY:t,sourcePosition:s,targetX:n,targetY:r,targetPosition:i});return A.createElement(qt,{path:b,labelX:x,labelY:_,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:h,markerStart:y,interactionWidth:g})});Cr.displayName="SimpleBezierEdge";const ps={[X.Left]:{x:-1,y:0},[X.Right]:{x:1,y:0},[X.Top]:{x:0,y:-1},[X.Bottom]:{x:0,y:1}},cf=({source:e,sourcePosition:t=X.Bottom,target:n})=>t===X.Left||t===X.Right?e.xMath.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));function uf({source:e,sourcePosition:t=X.Bottom,target:n,targetPosition:r=X.Top,center:s,offset:i}){const o=ps[t],a=ps[r],l={x:e.x+o.x*i,y:e.y+o.y*i},c={x:n.x+a.x*i,y:n.y+a.y*i},u=cf({source:l,sourcePosition:t,target:c}),d=u.x!==0?"x":"y",m=u[d];let h=[],y,g;const b={x:0,y:0},x={x:0,y:0},[_,$,v,j]=Xi({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(o[d]*a[d]===-1){y=s.x??_,g=s.y??$;const N=[{x:y,y:l.y},{x:y,y:c.y}],D=[{x:l.x,y:g},{x:c.x,y:g}];o[d]===m?h=d==="x"?N:D:h=d==="x"?D:N}else{const N=[{x:l.x,y:c.y}],D=[{x:c.x,y:l.y}];if(d==="x"?h=o.x===m?D:N:h=o.y===m?N:D,t===r){const F=Math.abs(e[d]-n[d]);if(F<=i){const p=Math.min(i-1,i-F);o[d]===m?b[d]=(l[d]>e[d]?-1:1)*p:x[d]=(c[d]>n[d]?-1:1)*p}}if(t!==r){const F=d==="x"?"y":"x",p=o[d]===a[F],M=l[F]>c[F],E=l[F]=V?(y=(S.x+T.x)/2,g=h[0].y):(y=h[0].x,g=(S.y+T.y)/2)}return[[e,{x:l.x+b.x,y:l.y+b.y},...h,{x:c.x+x.x,y:c.y+x.y},n],y,g,v,j]}function df(e,t,n,r){const s=Math.min(gs(e,t)/2,gs(t,n)/2,r),{x:i,y:o}=t;if(e.x===i&&i===n.x||e.y===o&&o===n.y)return`L${i} ${o}`;if(e.y===o){const c=e.x{let $="";return _>0&&_{const[x,_,$]=vn({sourceX:e,sourceY:t,sourcePosition:d,targetX:n,targetY:r,targetPosition:m,borderRadius:g==null?void 0:g.borderRadius,offset:g==null?void 0:g.offset});return A.createElement(qt,{path:x,labelX:_,labelY:$,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:h,markerStart:y,interactionWidth:b})});Mn.displayName="SmoothStepEdge";const $r=w.memo(e=>{var t;return A.createElement(Mn,{...e,pathOptions:w.useMemo(()=>{var n;return{borderRadius:0,offset:(n=e.pathOptions)==null?void 0:n.offset}},[(t=e.pathOptions)==null?void 0:t.offset])})});$r.displayName="StepEdge";function ff({sourceX:e,sourceY:t,targetX:n,targetY:r}){const[s,i,o,a]=Xi({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,s,i,o,a]}const Mr=w.memo(({sourceX:e,sourceY:t,targetX:n,targetY:r,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:h})=>{const[y,g,b]=ff({sourceX:e,sourceY:t,targetX:n,targetY:r});return A.createElement(qt,{path:y,labelX:g,labelY:b,label:s,labelStyle:i,labelShowBg:o,labelBgStyle:a,labelBgPadding:l,labelBgBorderRadius:c,style:u,markerEnd:d,markerStart:m,interactionWidth:h})});Mr.displayName="StraightEdge";function nn(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function ys({pos:e,x1:t,y1:n,x2:r,y2:s,c:i}){switch(e){case X.Left:return[t-nn(t-r,i),n];case X.Right:return[t+nn(r-t,i),n];case X.Top:return[t,n-nn(n-s,i)];case X.Bottom:return[t,n+nn(s-n,i)]}}function Qi({sourceX:e,sourceY:t,sourcePosition:n=X.Bottom,targetX:r,targetY:s,targetPosition:i=X.Top,curvature:o=.25}){const[a,l]=ys({pos:n,x1:e,y1:t,x2:r,y2:s,c:o}),[c,u]=ys({pos:i,x1:r,y1:s,x2:e,y2:t,c:o}),[d,m,h,y]=Ki({sourceX:e,sourceY:t,targetX:r,targetY:s,sourceControlX:a,sourceControlY:l,targetControlX:c,targetControlY:u});return[`M${e},${t} C${a},${l} ${c},${u} ${r},${s}`,d,m,h,y]}const bn=w.memo(({sourceX:e,sourceY:t,targetX:n,targetY:r,sourcePosition:s=X.Bottom,targetPosition:i=X.Top,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:h,markerStart:y,pathOptions:g,interactionWidth:b})=>{const[x,_,$]=Qi({sourceX:e,sourceY:t,sourcePosition:s,targetX:n,targetY:r,targetPosition:i,curvature:g==null?void 0:g.curvature});return A.createElement(qt,{path:x,labelX:_,labelY:$,label:o,labelStyle:a,labelShowBg:l,labelBgStyle:c,labelBgPadding:u,labelBgBorderRadius:d,style:m,markerEnd:h,markerStart:y,interactionWidth:b})});bn.displayName="BezierEdge";const Ar=w.createContext(null),hf=Ar.Provider;Ar.Consumer;const mf=()=>w.useContext(Ar),pf=e=>"id"in e&&"source"in e&&"target"in e,gf=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`reactflow__edge-${e}${t||""}-${n}${r||""}`,ur=(e,t)=>typeof e>"u"?"":typeof e=="string"?e:`${t?`${t}__`:""}${Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("&")}`,yf=(e,t)=>t.some(n=>n.source===e.source&&n.target===e.target&&(n.sourceHandle===e.sourceHandle||!n.sourceHandle&&!e.sourceHandle)&&(n.targetHandle===e.targetHandle||!n.targetHandle&&!e.targetHandle)),xf=(e,t)=>{if(!e.source||!e.target)return t;let n;return pf(e)?n={...e}:n={...e,id:gf(e)},yf(n,t)?t:t.concat(n)},dr=({x:e,y:t},[n,r,s],i,[o,a])=>{const l={x:(e-n)/s,y:(t-r)/s};return i?{x:o*Math.round(l.x/o),y:a*Math.round(l.y/a)}:l},Ji=({x:e,y:t},[n,r,s])=>({x:e*s+n,y:t*s+r}),at=(e,t=[0,0])=>{if(!e)return{x:0,y:0,positionAbsolute:{x:0,y:0}};const n=(e.width??0)*t[0],r=(e.height??0)*t[1],s={x:e.position.x-n,y:e.position.y-r};return{...s,positionAbsolute:e.positionAbsolute?{x:e.positionAbsolute.x-n,y:e.positionAbsolute.y-r}:s}},Xt=(e,t=[0,0])=>{if(e.length===0)return{x:0,y:0,width:0,height:0};const n=e.reduce((r,s)=>{const{x:i,y:o}=at(s,t).positionAbsolute;return Yi(r,Bt({x:i,y:o,width:s.width||0,height:s.height||0}))},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return Wi(n)},wf=(e,t=[0,0])=>(console.warn("[DEPRECATED] `getRectOfNodes` is deprecated. Instead use `getNodesBounds` https://reactflow.dev/api-reference/utils/get-nodes-bounds."),Xt(e,t)),eo=(e,t,[n,r,s]=[0,0,1],i=!1,o=!1,a=[0,0])=>{const l={x:(t.x-n)/s,y:(t.y-r)/s,width:t.width/s,height:t.height/s},c=[];return e.forEach(u=>{const{width:d,height:m,selectable:h=!0,hidden:y=!1}=u;if(o&&!h||y)return!1;const{positionAbsolute:g}=at(u,a),b={x:g.x,y:g.y,width:d||0,height:m||0},x=lr(l,b),_=typeof d>"u"||typeof m>"u"||d===null||m===null,$=i&&x>0,v=(d||0)*(m||0);(_||$||x>=v||u.dragging)&&c.push(u)}),c},to=(e,t)=>{const n=e.map(r=>r.id);return t.filter(r=>n.includes(r.source)||n.includes(r.target))},no=(e,t,n,r,s,i=.1)=>{const o=t/(e.width*(1+i)),a=n/(e.height*(1+i)),l=Math.min(o,a),c=St(l,r,s),u=e.x+e.width/2,d=e.y+e.height/2,m=t/2-u*c,h=n/2-d*c;return{x:m,y:h,zoom:c}},rt=(e,t=0)=>e.transition().duration(t);function xs(e,t,n,r){return(t[n]||[]).reduce((s,i)=>{var o,a;return`${e.id}-${i.id}-${n}`!==r&&s.push({id:i.id||null,type:n,nodeId:e.id,x:(((o=e.positionAbsolute)==null?void 0:o.x)??0)+i.x+i.width/2,y:(((a=e.positionAbsolute)==null?void 0:a.y)??0)+i.y+i.height/2}),s},[])}function vf(e,t,n,r,s,i){const{x:o,y:a}=qe(e),c=t.elementsFromPoint(o,a).find(y=>y.classList.contains("react-flow__handle"));if(c){const y=c.getAttribute("data-nodeid");if(y){const g=Ir(void 0,c),b=c.getAttribute("data-handleid"),x=i({nodeId:y,id:b,type:g});if(x){const _=s.find($=>$.nodeId===y&&$.type===g&&$.id===b);return{handle:{id:b,type:g,nodeId:y,x:(_==null?void 0:_.x)||n.x,y:(_==null?void 0:_.y)||n.y},validHandleResult:x}}}}let u=[],d=1/0;if(s.forEach(y=>{const g=Math.sqrt((y.x-n.x)**2+(y.y-n.y)**2);if(g<=r){const b=i(y);g<=d&&(gy.isValid),h=u.some(({handle:y})=>y.type==="target");return u.find(({handle:y,validHandleResult:g})=>h?y.type==="target":m?g.isValid:!0)||u[0]}const bf={source:null,target:null,sourceHandle:null,targetHandle:null},ro=()=>({handleDomNode:null,isValid:!1,connection:bf,endHandle:null});function so(e,t,n,r,s,i,o){const a=s==="target",l=o.querySelector(`.react-flow__handle[data-id="${e==null?void 0:e.nodeId}-${e==null?void 0:e.id}-${e==null?void 0:e.type}"]`),c={...ro(),handleDomNode:l};if(l){const u=Ir(void 0,l),d=l.getAttribute("data-nodeid"),m=l.getAttribute("data-handleid"),h=l.classList.contains("connectable"),y=l.classList.contains("connectableend"),g={source:a?d:n,sourceHandle:a?m:r,target:a?n:d,targetHandle:a?r:m};c.connection=g,h&&y&&(t===ct.Strict?a&&u==="source"||!a&&u==="target":d!==n||m!==r)&&(c.endHandle={nodeId:d,handleId:m,type:u},c.isValid=i(g))}return c}function _f({nodes:e,nodeId:t,handleId:n,handleType:r}){return e.reduce((s,i)=>{if(i[ae]){const{handleBounds:o}=i[ae];let a=[],l=[];o&&(a=xs(i,o,"source",`${t}-${n}-${r}`),l=xs(i,o,"target",`${t}-${n}-${r}`)),s.push(...a,...l)}return s},[])}function Ir(e,t){return e||(t!=null&&t.classList.contains("target")?"target":t!=null&&t.classList.contains("source")?"source":null)}function Vn(e){e==null||e.classList.remove("valid","connecting","react-flow__handle-valid","react-flow__handle-connecting")}function Ef(e,t){let n=null;return t?n="valid":e&&!t&&(n="invalid"),n}function io({event:e,handleId:t,nodeId:n,onConnect:r,isTarget:s,getState:i,setState:o,isValidConnection:a,edgeUpdaterType:l,onReconnectEnd:c}){const u=Gi(e.target),{connectionMode:d,domNode:m,autoPanOnConnect:h,connectionRadius:y,onConnectStart:g,panBy:b,getNodes:x,cancelConnection:_}=i();let $=0,v;const{x:j,y:C}=qe(e),N=u==null?void 0:u.elementFromPoint(j,C),D=Ir(l,N),S=m==null?void 0:m.getBoundingClientRect();if(!S||!D)return;let T,P=qe(e,S),V=!1,F=null,p=!1,M=null;const E=_f({nodes:x(),nodeId:n,handleId:t,handleType:D}),O=()=>{if(!h)return;const[I,z]=Bi(P,S);b({x:I,y:z}),$=requestAnimationFrame(O)};o({connectionPosition:P,connectionStatus:null,connectionNodeId:n,connectionHandleId:t,connectionHandleType:D,connectionStartHandle:{nodeId:n,handleId:t,type:D},connectionEndHandle:null}),g==null||g(e,{nodeId:n,handleId:t,handleType:D});function L(I){const{transform:z}=i();P=qe(I,S);const{handle:H,validHandleResult:G}=vf(I,u,dr(P,z,!1,[1,1]),y,E,Y=>so(Y,d,n,t,s?"target":"source",a,u));if(v=H,V||(O(),V=!0),M=G.handleDomNode,F=G.connection,p=G.isValid,o({connectionPosition:v&&p?Ji({x:v.x,y:v.y},z):P,connectionStatus:Ef(!!v,p),connectionEndHandle:G.endHandle}),!v&&!p&&!M)return Vn(T);F.source!==F.target&&M&&(Vn(T),T=M,M.classList.add("connecting","react-flow__handle-connecting"),M.classList.toggle("valid",p),M.classList.toggle("react-flow__handle-valid",p))}function k(I){var z,H;(v||M)&&F&&p&&(r==null||r(F)),(H=(z=i()).onConnectEnd)==null||H.call(z,I),l&&(c==null||c(I)),Vn(T),_(),cancelAnimationFrame($),V=!1,p=!1,F=null,M=null,u.removeEventListener("mousemove",L),u.removeEventListener("mouseup",k),u.removeEventListener("touchmove",L),u.removeEventListener("touchend",k)}u.addEventListener("mousemove",L),u.addEventListener("mouseup",k),u.addEventListener("touchmove",L),u.addEventListener("touchend",k)}const ws=()=>!0,Nf=e=>({connectionStartHandle:e.connectionStartHandle,connectOnClick:e.connectOnClick,noPanClassName:e.noPanClassName}),Sf=(e,t,n)=>r=>{const{connectionStartHandle:s,connectionEndHandle:i,connectionClickStartHandle:o}=r;return{connecting:(s==null?void 0:s.nodeId)===e&&(s==null?void 0:s.handleId)===t&&(s==null?void 0:s.type)===n||(i==null?void 0:i.nodeId)===e&&(i==null?void 0:i.handleId)===t&&(i==null?void 0:i.type)===n,clickConnecting:(o==null?void 0:o.nodeId)===e&&(o==null?void 0:o.handleId)===t&&(o==null?void 0:o.type)===n}},oo=w.forwardRef(({type:e="source",position:t=X.Top,isValidConnection:n,isConnectable:r=!0,isConnectableStart:s=!0,isConnectableEnd:i=!0,id:o,onConnect:a,children:l,className:c,onMouseDown:u,onTouchStart:d,...m},h)=>{var S,T;const y=o||null,g=e==="target",b=he(),x=mf(),{connectOnClick:_,noPanClassName:$}=se(Nf,me),{connecting:v,clickConnecting:j}=se(Sf(x,y,e),me);x||(T=(S=b.getState()).onError)==null||T.call(S,"010",Ve.error010());const C=P=>{const{defaultEdgeOptions:V,onConnect:F,hasDefaultEdges:p}=b.getState(),M={...V,...P};if(p){const{edges:E,setEdges:O}=b.getState();O(xf(M,E))}F==null||F(M),a==null||a(M)},N=P=>{if(!x)return;const V=qi(P);s&&(V&&P.button===0||!V)&&io({event:P,handleId:y,nodeId:x,onConnect:C,isTarget:g,getState:b.getState,setState:b.setState,isValidConnection:n||b.getState().isValidConnection||ws}),V?u==null||u(P):d==null||d(P)},D=P=>{const{onClickConnectStart:V,onClickConnectEnd:F,connectionClickStartHandle:p,connectionMode:M,isValidConnection:E}=b.getState();if(!x||!p&&!s)return;if(!p){V==null||V(P,{nodeId:x,handleId:y,handleType:e}),b.setState({connectionClickStartHandle:{nodeId:x,type:e,handleId:y}});return}const O=Gi(P.target),L=n||E||ws,{connection:k,isValid:I}=so({nodeId:x,id:y,type:e},M,p.nodeId,p.handleId||null,p.type,L,O);I&&C(k),F==null||F(P),b.setState({connectionClickStartHandle:null})};return A.createElement("div",{"data-handleid":y,"data-nodeid":x,"data-handlepos":t,"data-id":`${x}-${y}-${e}`,className:pe(["react-flow__handle",`react-flow__handle-${t}`,"nodrag",$,c,{source:!g,target:g,connectable:r,connectablestart:s,connectableend:i,connecting:j,connectionindicator:r&&(s&&!v||i&&v)}]),onMouseDown:N,onTouchStart:N,onClick:_?D:void 0,ref:h,...m},l)});oo.displayName="Handle";var Ue=w.memo(oo);const ao=({data:e,isConnectable:t,targetPosition:n=X.Top,sourcePosition:r=X.Bottom})=>A.createElement(A.Fragment,null,A.createElement(Ue,{type:"target",position:n,isConnectable:t}),e==null?void 0:e.label,A.createElement(Ue,{type:"source",position:r,isConnectable:t}));ao.displayName="DefaultNode";var fr=w.memo(ao);const lo=({data:e,isConnectable:t,sourcePosition:n=X.Bottom})=>A.createElement(A.Fragment,null,e==null?void 0:e.label,A.createElement(Ue,{type:"source",position:n,isConnectable:t}));lo.displayName="InputNode";var co=w.memo(lo);const uo=({data:e,isConnectable:t,targetPosition:n=X.Top})=>A.createElement(A.Fragment,null,A.createElement(Ue,{type:"target",position:n,isConnectable:t}),e==null?void 0:e.label);uo.displayName="OutputNode";var fo=w.memo(uo);const Rr=()=>null;Rr.displayName="GroupNode";const kf=e=>({selectedNodes:e.getNodes().filter(t=>t.selected),selectedEdges:e.edges.filter(t=>t.selected).map(t=>({...t}))}),rn=e=>e.id;function jf(e,t){return me(e.selectedNodes.map(rn),t.selectedNodes.map(rn))&&me(e.selectedEdges.map(rn),t.selectedEdges.map(rn))}const ho=w.memo(({onSelectionChange:e})=>{const t=he(),{selectedNodes:n,selectedEdges:r}=se(kf,jf);return w.useEffect(()=>{const s={nodes:n,edges:r};e==null||e(s),t.getState().onSelectionChange.forEach(i=>i(s))},[n,r,e]),null});ho.displayName="SelectionListener";const Cf=e=>!!e.onSelectionChange;function $f({onSelectionChange:e}){const t=se(Cf);return e||t?A.createElement(ho,{onSelectionChange:e}):null}const Mf=e=>({setNodes:e.setNodes,setEdges:e.setEdges,setDefaultNodesAndEdges:e.setDefaultNodesAndEdges,setMinZoom:e.setMinZoom,setMaxZoom:e.setMaxZoom,setTranslateExtent:e.setTranslateExtent,setNodeExtent:e.setNodeExtent,reset:e.reset});function mt(e,t){w.useEffect(()=>{typeof e<"u"&&t(e)},[e])}function Q(e,t,n){w.useEffect(()=>{typeof t<"u"&&n({[e]:t})},[t])}const Af=({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,onConnect:s,onConnectStart:i,onConnectEnd:o,onClickConnectStart:a,onClickConnectEnd:l,nodesDraggable:c,nodesConnectable:u,nodesFocusable:d,edgesFocusable:m,edgesUpdatable:h,elevateNodesOnSelect:y,minZoom:g,maxZoom:b,nodeExtent:x,onNodesChange:_,onEdgesChange:$,elementsSelectable:v,connectionMode:j,snapGrid:C,snapToGrid:N,translateExtent:D,connectOnClick:S,defaultEdgeOptions:T,fitView:P,fitViewOptions:V,onNodesDelete:F,onEdgesDelete:p,onNodeDrag:M,onNodeDragStart:E,onNodeDragStop:O,onSelectionDrag:L,onSelectionDragStart:k,onSelectionDragStop:I,noPanClassName:z,nodeOrigin:H,rfId:G,autoPanOnConnect:Y,autoPanOnNodeDrag:U,onError:K,connectionRadius:Z,isValidConnection:B,nodeDragThreshold:W})=>{const{setNodes:q,setEdges:ee,setDefaultNodesAndEdges:J,setMinZoom:oe,setMaxZoom:ie,setTranslateExtent:re,setNodeExtent:ge,reset:te}=se(Mf,me),R=he();return w.useEffect(()=>{const ne=r==null?void 0:r.map(ce=>({...ce,...T}));return J(n,ne),()=>{te()}},[]),Q("defaultEdgeOptions",T,R.setState),Q("connectionMode",j,R.setState),Q("onConnect",s,R.setState),Q("onConnectStart",i,R.setState),Q("onConnectEnd",o,R.setState),Q("onClickConnectStart",a,R.setState),Q("onClickConnectEnd",l,R.setState),Q("nodesDraggable",c,R.setState),Q("nodesConnectable",u,R.setState),Q("nodesFocusable",d,R.setState),Q("edgesFocusable",m,R.setState),Q("edgesUpdatable",h,R.setState),Q("elementsSelectable",v,R.setState),Q("elevateNodesOnSelect",y,R.setState),Q("snapToGrid",N,R.setState),Q("snapGrid",C,R.setState),Q("onNodesChange",_,R.setState),Q("onEdgesChange",$,R.setState),Q("connectOnClick",S,R.setState),Q("fitViewOnInit",P,R.setState),Q("fitViewOnInitOptions",V,R.setState),Q("onNodesDelete",F,R.setState),Q("onEdgesDelete",p,R.setState),Q("onNodeDrag",M,R.setState),Q("onNodeDragStart",E,R.setState),Q("onNodeDragStop",O,R.setState),Q("onSelectionDrag",L,R.setState),Q("onSelectionDragStart",k,R.setState),Q("onSelectionDragStop",I,R.setState),Q("noPanClassName",z,R.setState),Q("nodeOrigin",H,R.setState),Q("rfId",G,R.setState),Q("autoPanOnConnect",Y,R.setState),Q("autoPanOnNodeDrag",U,R.setState),Q("onError",K,R.setState),Q("connectionRadius",Z,R.setState),Q("isValidConnection",B,R.setState),Q("nodeDragThreshold",W,R.setState),mt(e,q),mt(t,ee),mt(g,oe),mt(b,ie),mt(D,re),mt(x,ge),null},vs={display:"none"},If={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},mo="react-flow__node-desc",po="react-flow__edge-desc",Rf="react-flow__aria-live",Tf=e=>e.ariaLiveMessage;function Of({rfId:e}){const t=se(Tf);return A.createElement("div",{id:`${Rf}-${e}`,"aria-live":"assertive","aria-atomic":"true",style:If},t)}function Df({rfId:e,disableKeyboardA11y:t}){return A.createElement(A.Fragment,null,A.createElement("div",{id:`${mo}-${e}`,style:vs},"Press enter or space to select a node.",!t&&"You can then use the arrow keys to move the node around."," Press delete to remove it and escape to cancel."," "),A.createElement("div",{id:`${po}-${e}`,style:vs},"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel."),!t&&A.createElement(Of,{rfId:e}))}var Yt=(e=null,t={actInsideInputWithModifier:!0})=>{const[n,r]=w.useState(!1),s=w.useRef(!1),i=w.useRef(new Set([])),[o,a]=w.useMemo(()=>{if(e!==null){const c=(Array.isArray(e)?e:[e]).filter(d=>typeof d=="string").map(d=>d.split("+")),u=c.reduce((d,m)=>d.concat(...m),[]);return[c,u]}return[[],[]]},[e]);return w.useEffect(()=>{const l=typeof document<"u"?document:null,c=(t==null?void 0:t.target)||l;if(e!==null){const u=h=>{if(s.current=h.ctrlKey||h.metaKey||h.shiftKey,(!s.current||s.current&&!t.actInsideInputWithModifier)&&cr(h))return!1;const g=_s(h.code,a);i.current.add(h[g]),bs(o,i.current,!1)&&(h.preventDefault(),r(!0))},d=h=>{if((!s.current||s.current&&!t.actInsideInputWithModifier)&&cr(h))return!1;const g=_s(h.code,a);bs(o,i.current,!0)?(r(!1),i.current.clear()):i.current.delete(h[g]),h.key==="Meta"&&i.current.clear(),s.current=!1},m=()=>{i.current.clear(),r(!1)};return c==null||c.addEventListener("keydown",u),c==null||c.addEventListener("keyup",d),window.addEventListener("blur",m),()=>{c==null||c.removeEventListener("keydown",u),c==null||c.removeEventListener("keyup",d),window.removeEventListener("blur",m)}}},[e,r]),n};function bs(e,t,n){return e.filter(r=>n||r.length===t.size).some(r=>r.every(s=>t.has(s)))}function _s(e,t){return t.includes(e)?"code":"key"}function go(e,t,n,r){var a,l;const s=e.parentNode||e.parentId;if(!s)return n;const i=t.get(s),o=at(i,r);return go(i,t,{x:(n.x??0)+o.x,y:(n.y??0)+o.y,z:(((a=i[ae])==null?void 0:a.z)??0)>(n.z??0)?((l=i[ae])==null?void 0:l.z)??0:n.z??0},r)}function yo(e,t,n){e.forEach(r=>{var i;const s=r.parentNode||r.parentId;if(s&&!e.has(s))throw new Error(`Parent node ${s} not found`);if(s||n!=null&&n[r.id]){const{x:o,y:a,z:l}=go(r,e,{...r.position,z:((i=r[ae])==null?void 0:i.z)??0},t);r.positionAbsolute={x:o,y:a},r[ae].z=l,n!=null&&n[r.id]&&(r[ae].isParent=!0)}})}function Bn(e,t,n,r){const s=new Map,i={},o=r?1e3:0;return e.forEach(a=>{var h;const l=(Ee(a.zIndex)?a.zIndex:0)+(a.selected?o:0),c=t.get(a.id),u={...a,positionAbsolute:{x:a.position.x,y:a.position.y}},d=a.parentNode||a.parentId;d&&(i[d]=!0);const m=(c==null?void 0:c.type)&&(c==null?void 0:c.type)!==a.type;Object.defineProperty(u,ae,{enumerable:!1,value:{handleBounds:m||(h=c==null?void 0:c[ae])==null?void 0:h.handleBounds,z:l}}),s.set(a.id,u)}),yo(s,n,i),s}function xo(e,t={}){const{getNodes:n,width:r,height:s,minZoom:i,maxZoom:o,d3Zoom:a,d3Selection:l,fitViewOnInitDone:c,fitViewOnInit:u,nodeOrigin:d}=e(),m=t.initial&&!c&&u;if(a&&l&&(m||!t.initial)){const y=n().filter(b=>{var _;const x=t.includeHiddenNodes?b.width&&b.height:!b.hidden;return(_=t.nodes)!=null&&_.length?x&&t.nodes.some($=>$.id===b.id):x}),g=y.every(b=>b.width&&b.height);if(y.length>0&&g){const b=Xt(y,d),{x,y:_,zoom:$}=no(b,r,s,t.minZoom??i,t.maxZoom??o,t.padding??.1),v=He.translate(x,_).scale($);return typeof t.duration=="number"&&t.duration>0?a.transform(rt(l,t.duration),v):a.transform(l,v),!0}}return!1}function Lf(e,t){return e.forEach(n=>{const r=t.get(n.id);r&&t.set(r.id,{...r,[ae]:r[ae],selected:n.selected})}),new Map(t)}function Pf(e,t){return t.map(n=>{const r=e.find(s=>s.id===n.id);return r&&(n.selected=r.selected),n})}function sn({changedNodes:e,changedEdges:t,get:n,set:r}){const{nodeInternals:s,edges:i,onNodesChange:o,onEdgesChange:a,hasDefaultNodes:l,hasDefaultEdges:c}=n();e!=null&&e.length&&(l&&r({nodeInternals:Lf(e,s)}),o==null||o(e)),t!=null&&t.length&&(c&&r({edges:Pf(t,i)}),a==null||a(t))}const pt=()=>{},zf={zoomIn:pt,zoomOut:pt,zoomTo:pt,getZoom:()=>1,setViewport:pt,getViewport:()=>({x:0,y:0,zoom:1}),fitView:()=>!1,setCenter:pt,fitBounds:pt,project:e=>e,screenToFlowPosition:e=>e,flowToScreenPosition:e=>e,viewportInitialized:!1},Hf=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection}),Ff=()=>{const e=he(),{d3Zoom:t,d3Selection:n}=se(Hf,me);return w.useMemo(()=>n&&t?{zoomIn:s=>t.scaleBy(rt(n,s==null?void 0:s.duration),1.2),zoomOut:s=>t.scaleBy(rt(n,s==null?void 0:s.duration),1/1.2),zoomTo:(s,i)=>t.scaleTo(rt(n,i==null?void 0:i.duration),s),getZoom:()=>e.getState().transform[2],setViewport:(s,i)=>{const[o,a,l]=e.getState().transform,c=He.translate(s.x??o,s.y??a).scale(s.zoom??l);t.transform(rt(n,i==null?void 0:i.duration),c)},getViewport:()=>{const[s,i,o]=e.getState().transform;return{x:s,y:i,zoom:o}},fitView:s=>xo(e.getState,s),setCenter:(s,i,o)=>{const{width:a,height:l,maxZoom:c}=e.getState(),u=typeof(o==null?void 0:o.zoom)<"u"?o.zoom:c,d=a/2-s*u,m=l/2-i*u,h=He.translate(d,m).scale(u);t.transform(rt(n,o==null?void 0:o.duration),h)},fitBounds:(s,i)=>{const{width:o,height:a,minZoom:l,maxZoom:c}=e.getState(),{x:u,y:d,zoom:m}=no(s,o,a,l,c,(i==null?void 0:i.padding)??.1),h=He.translate(u,d).scale(m);t.transform(rt(n,i==null?void 0:i.duration),h)},project:s=>{const{transform:i,snapToGrid:o,snapGrid:a}=e.getState();return console.warn("[DEPRECATED] `project` is deprecated. Instead use `screenToFlowPosition`. There is no need to subtract the react flow bounds anymore! https://reactflow.dev/api-reference/types/react-flow-instance#screen-to-flow-position"),dr(s,i,o,a)},screenToFlowPosition:s=>{const{transform:i,snapToGrid:o,snapGrid:a,domNode:l}=e.getState();if(!l)return s;const{x:c,y:u}=l.getBoundingClientRect(),d={x:s.x-c,y:s.y-u};return dr(d,i,o,a)},flowToScreenPosition:s=>{const{transform:i,domNode:o}=e.getState();if(!o)return s;const{x:a,y:l}=o.getBoundingClientRect(),c=Ji(s,i);return{x:c.x+a,y:c.y+l}},viewportInitialized:!0}:zf,[t,n])};function An(){const e=Ff(),t=he(),n=w.useCallback(()=>t.getState().getNodes().map(g=>({...g})),[]),r=w.useCallback(g=>t.getState().nodeInternals.get(g),[]),s=w.useCallback(()=>{const{edges:g=[]}=t.getState();return g.map(b=>({...b}))},[]),i=w.useCallback(g=>{const{edges:b=[]}=t.getState();return b.find(x=>x.id===g)},[]),o=w.useCallback(g=>{const{getNodes:b,setNodes:x,hasDefaultNodes:_,onNodesChange:$}=t.getState(),v=b(),j=typeof g=="function"?g(v):g;if(_)x(j);else if($){const C=j.length===0?v.map(N=>({type:"remove",id:N.id})):j.map(N=>({item:N,type:"reset"}));$(C)}},[]),a=w.useCallback(g=>{const{edges:b=[],setEdges:x,hasDefaultEdges:_,onEdgesChange:$}=t.getState(),v=typeof g=="function"?g(b):g;if(_)x(v);else if($){const j=v.length===0?b.map(C=>({type:"remove",id:C.id})):v.map(C=>({item:C,type:"reset"}));$(j)}},[]),l=w.useCallback(g=>{const b=Array.isArray(g)?g:[g],{getNodes:x,setNodes:_,hasDefaultNodes:$,onNodesChange:v}=t.getState();if($){const C=[...x(),...b];_(C)}else if(v){const j=b.map(C=>({item:C,type:"add"}));v(j)}},[]),c=w.useCallback(g=>{const b=Array.isArray(g)?g:[g],{edges:x=[],setEdges:_,hasDefaultEdges:$,onEdgesChange:v}=t.getState();if($)_([...x,...b]);else if(v){const j=b.map(C=>({item:C,type:"add"}));v(j)}},[]),u=w.useCallback(()=>{const{getNodes:g,edges:b=[],transform:x}=t.getState(),[_,$,v]=x;return{nodes:g().map(j=>({...j})),edges:b.map(j=>({...j})),viewport:{x:_,y:$,zoom:v}}},[]),d=w.useCallback(({nodes:g,edges:b})=>{const{nodeInternals:x,getNodes:_,edges:$,hasDefaultNodes:v,hasDefaultEdges:j,onNodesDelete:C,onEdgesDelete:N,onNodesChange:D,onEdgesChange:S}=t.getState(),T=(g||[]).map(M=>M.id),P=(b||[]).map(M=>M.id),V=_().reduce((M,E)=>{const O=E.parentNode||E.parentId,L=!T.includes(E.id)&&O&&M.find(I=>I.id===O);return(typeof E.deletable=="boolean"?E.deletable:!0)&&(T.includes(E.id)||L)&&M.push(E),M},[]),F=$.filter(M=>typeof M.deletable=="boolean"?M.deletable:!0),p=F.filter(M=>P.includes(M.id));if(V||p){const M=to(V,F),E=[...p,...M],O=E.reduce((L,k)=>(L.includes(k.id)||L.push(k.id),L),[]);if((j||v)&&(j&&t.setState({edges:$.filter(L=>!O.includes(L.id))}),v&&(V.forEach(L=>{x.delete(L.id)}),t.setState({nodeInternals:new Map(x)}))),O.length>0&&(N==null||N(E),S&&S(O.map(L=>({id:L,type:"remove"})))),V.length>0&&(C==null||C(V),D)){const L=V.map(k=>({id:k.id,type:"remove"}));D(L)}}},[]),m=w.useCallback(g=>{const b=of(g),x=b?null:t.getState().nodeInternals.get(g.id);return!b&&!x?[null,null,b]:[b?g:hs(x),x,b]},[]),h=w.useCallback((g,b=!0,x)=>{const[_,$,v]=m(g);return _?(x||t.getState().getNodes()).filter(j=>{if(!v&&(j.id===$.id||!j.positionAbsolute))return!1;const C=hs(j),N=lr(C,_);return b&&N>0||N>=_.width*_.height}):[]},[]),y=w.useCallback((g,b,x=!0)=>{const[_]=m(g);if(!_)return!1;const $=lr(_,b);return x&&$>0||$>=_.width*_.height},[]);return w.useMemo(()=>({...e,getNodes:n,getNode:r,getEdges:s,getEdge:i,setNodes:o,setEdges:a,addNodes:l,addEdges:c,toObject:u,deleteElements:d,getIntersectingNodes:h,isNodeIntersecting:y}),[e,n,r,s,i,o,a,l,c,u,d,h,y])}const Vf={actInsideInputWithModifier:!1};var Bf=({deleteKeyCode:e,multiSelectionKeyCode:t})=>{const n=he(),{deleteElements:r}=An(),s=Yt(e,Vf),i=Yt(t);w.useEffect(()=>{if(s){const{edges:o,getNodes:a}=n.getState(),l=a().filter(u=>u.selected),c=o.filter(u=>u.selected);r({nodes:l,edges:c}),n.setState({nodesSelectionActive:!1})}},[s]),w.useEffect(()=>{n.setState({multiSelectionActive:i})},[i])};function Gf(e){const t=he();w.useEffect(()=>{let n;const r=()=>{var i,o;if(!e.current)return;const s=kr(e.current);(s.height===0||s.width===0)&&((o=(i=t.getState()).onError)==null||o.call(i,"004",Ve.error004())),t.setState({width:s.width||500,height:s.height||500})};return r(),window.addEventListener("resize",r),e.current&&(n=new ResizeObserver(()=>r()),n.observe(e.current)),()=>{window.removeEventListener("resize",r),n&&e.current&&n.unobserve(e.current)}},[])}const Tr={position:"absolute",width:"100%",height:"100%",top:0,left:0},Yf=(e,t)=>e.x!==t.x||e.y!==t.y||e.zoom!==t.k,on=e=>({x:e.x,y:e.y,zoom:e.k}),gt=(e,t)=>e.target.closest(`.${t}`),Es=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),Ns=e=>{const t=e.ctrlKey&&xn()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t},Wf=e=>({d3Zoom:e.d3Zoom,d3Selection:e.d3Selection,d3ZoomHandler:e.d3ZoomHandler,userSelectionActive:e.userSelectionActive}),Uf=({onMove:e,onMoveStart:t,onMoveEnd:n,onPaneContextMenu:r,zoomOnScroll:s=!0,zoomOnPinch:i=!0,panOnScroll:o=!1,panOnScrollSpeed:a=.5,panOnScrollMode:l=it.Free,zoomOnDoubleClick:c=!0,elementsSelectable:u,panOnDrag:d=!0,defaultViewport:m,translateExtent:h,minZoom:y,maxZoom:g,zoomActivationKeyCode:b,preventScrolling:x=!0,children:_,noWheelClassName:$,noPanClassName:v})=>{const j=w.useRef(),C=he(),N=w.useRef(!1),D=w.useRef(!1),S=w.useRef(null),T=w.useRef({x:0,y:0,zoom:0}),{d3Zoom:P,d3Selection:V,d3ZoomHandler:F,userSelectionActive:p}=se(Wf,me),M=Yt(b),E=w.useRef(0),O=w.useRef(!1),L=w.useRef();return Gf(S),w.useEffect(()=>{if(S.current){const k=S.current.getBoundingClientRect(),I=Fi().scaleExtent([y,g]).translateExtent(h),z=_e(S.current).call(I),H=He.translate(m.x,m.y).scale(St(m.zoom,y,g)),G=[[0,0],[k.width,k.height]],Y=I.constrain()(H,G,h);I.transform(z,Y),I.wheelDelta(Ns),C.setState({d3Zoom:I,d3Selection:z,d3ZoomHandler:z.on("wheel.zoom"),transform:[Y.x,Y.y,Y.k],domNode:S.current.closest(".react-flow")})}},[]),w.useEffect(()=>{V&&P&&(o&&!M&&!p?V.on("wheel.zoom",k=>{if(gt(k,$))return!1;k.preventDefault(),k.stopImmediatePropagation();const I=V.property("__zoom").k||1;if(k.ctrlKey&&i){const B=je(k),W=Ns(k),q=I*Math.pow(2,W);P.scaleTo(V,q,B,k);return}const z=k.deltaMode===1?20:1;let H=l===it.Vertical?0:k.deltaX*z,G=l===it.Horizontal?0:k.deltaY*z;!xn()&&k.shiftKey&&l!==it.Vertical&&(H=k.deltaY*z,G=0),P.translateBy(V,-(H/I)*a,-(G/I)*a,{internal:!0});const Y=on(V.property("__zoom")),{onViewportChangeStart:U,onViewportChange:K,onViewportChangeEnd:Z}=C.getState();clearTimeout(L.current),O.current||(O.current=!0,t==null||t(k,Y),U==null||U(Y)),O.current&&(e==null||e(k,Y),K==null||K(Y),L.current=setTimeout(()=>{n==null||n(k,Y),Z==null||Z(Y),O.current=!1},150))},{passive:!1}):typeof F<"u"&&V.on("wheel.zoom",function(k,I){if(!x&&k.type==="wheel"&&!k.ctrlKey||gt(k,$))return null;k.preventDefault(),F.call(this,k,I)},{passive:!1}))},[p,o,l,V,P,F,M,i,x,$,t,e,n]),w.useEffect(()=>{P&&P.on("start",k=>{var H,G;if(!k.sourceEvent||k.sourceEvent.internal)return null;E.current=(H=k.sourceEvent)==null?void 0:H.button;const{onViewportChangeStart:I}=C.getState(),z=on(k.transform);N.current=!0,T.current=z,((G=k.sourceEvent)==null?void 0:G.type)==="mousedown"&&C.setState({paneDragging:!0}),I==null||I(z),t==null||t(k.sourceEvent,z)})},[P,t]),w.useEffect(()=>{P&&(p&&!N.current?P.on("zoom",null):p||P.on("zoom",k=>{var z;const{onViewportChange:I}=C.getState();if(C.setState({transform:[k.transform.x,k.transform.y,k.transform.k]}),D.current=!!(r&&Es(d,E.current??0)),(e||I)&&!((z=k.sourceEvent)!=null&&z.internal)){const H=on(k.transform);I==null||I(H),e==null||e(k.sourceEvent,H)}}))},[p,P,e,d,r]),w.useEffect(()=>{P&&P.on("end",k=>{if(!k.sourceEvent||k.sourceEvent.internal)return null;const{onViewportChangeEnd:I}=C.getState();if(N.current=!1,C.setState({paneDragging:!1}),r&&Es(d,E.current??0)&&!D.current&&r(k.sourceEvent),D.current=!1,(n||I)&&Yf(T.current,k.transform)){const z=on(k.transform);T.current=z,clearTimeout(j.current),j.current=setTimeout(()=>{I==null||I(z),n==null||n(k.sourceEvent,z)},o?150:0)}})},[P,o,d,n,r]),w.useEffect(()=>{P&&P.filter(k=>{const I=M||s,z=i&&k.ctrlKey;if((d===!0||Array.isArray(d)&&d.includes(1))&&k.button===1&&k.type==="mousedown"&&(gt(k,"react-flow__node")||gt(k,"react-flow__edge")))return!0;if(!d&&!I&&!o&&!c&&!i||p||!c&&k.type==="dblclick"||gt(k,$)&&k.type==="wheel"||gt(k,v)&&(k.type!=="wheel"||o&&k.type==="wheel"&&!M)||!i&&k.ctrlKey&&k.type==="wheel"||!I&&!o&&!z&&k.type==="wheel"||!d&&(k.type==="mousedown"||k.type==="touchstart")||Array.isArray(d)&&!d.includes(k.button)&&k.type==="mousedown")return!1;const H=Array.isArray(d)&&d.includes(k.button)||!k.button||k.button<=1;return(!k.ctrlKey||k.type==="wheel")&&H})},[p,P,s,i,o,c,d,u,M]),A.createElement("div",{className:"react-flow__renderer",ref:S,style:Tr},_)},qf=e=>({userSelectionActive:e.userSelectionActive,userSelectionRect:e.userSelectionRect});function Xf(){const{userSelectionActive:e,userSelectionRect:t}=se(qf,me);return e&&t?A.createElement("div",{className:"react-flow__selection react-flow__container",style:{width:t.width,height:t.height,transform:`translate(${t.x}px, ${t.y}px)`}}):null}function Ss(e,t){const n=t.parentNode||t.parentId,r=e.find(s=>s.id===n);if(r){const s=t.position.x+t.width-r.width,i=t.position.y+t.height-r.height;if(s>0||i>0||t.position.x<0||t.position.y<0){if(r.style={...r.style},r.style.width=r.style.width??r.width,r.style.height=r.style.height??r.height,s>0&&(r.style.width+=s),i>0&&(r.style.height+=i),t.position.x<0){const o=Math.abs(t.position.x);r.position.x=r.position.x-o,r.style.width+=o,t.position.x=0}if(t.position.y<0){const o=Math.abs(t.position.y);r.position.y=r.position.y-o,r.style.height+=o,t.position.y=0}r.width=r.style.width,r.height=r.style.height}}}function Kf(e,t){if(e.some(r=>r.type==="reset"))return e.filter(r=>r.type==="reset").map(r=>r.item);const n=e.filter(r=>r.type==="add").map(r=>r.item);return t.reduce((r,s)=>{const i=e.filter(a=>a.id===s.id);if(i.length===0)return r.push(s),r;const o={...s};for(const a of i)if(a)switch(a.type){case"select":{o.selected=a.selected;break}case"position":{typeof a.position<"u"&&(o.position=a.position),typeof a.positionAbsolute<"u"&&(o.positionAbsolute=a.positionAbsolute),typeof a.dragging<"u"&&(o.dragging=a.dragging),o.expandParent&&Ss(r,o);break}case"dimensions":{typeof a.dimensions<"u"&&(o.width=a.dimensions.width,o.height=a.dimensions.height),typeof a.updateStyle<"u"&&(o.style={...o.style||{},...a.dimensions}),typeof a.resizing=="boolean"&&(o.resizing=a.resizing),o.expandParent&&Ss(r,o);break}case"remove":return r}return r.push(o),r},n)}function Zf(e,t){return Kf(e,t)}const Ye=(e,t)=>({id:e,type:"select",selected:t});function xt(e,t){return e.reduce((n,r)=>{const s=t.includes(r.id);return!r.selected&&s?(r.selected=!0,n.push(Ye(r.id,!0))):r.selected&&!s&&(r.selected=!1,n.push(Ye(r.id,!1))),n},[])}const Gn=(e,t)=>n=>{n.target===t.current&&(e==null||e(n))},Qf=e=>({userSelectionActive:e.userSelectionActive,elementsSelectable:e.elementsSelectable,dragging:e.paneDragging}),wo=w.memo(({isSelecting:e,selectionMode:t=Gt.Full,panOnDrag:n,onSelectionStart:r,onSelectionEnd:s,onPaneClick:i,onPaneContextMenu:o,onPaneScroll:a,onPaneMouseEnter:l,onPaneMouseMove:c,onPaneMouseLeave:u,children:d})=>{const m=w.useRef(null),h=he(),y=w.useRef(0),g=w.useRef(0),b=w.useRef(),{userSelectionActive:x,elementsSelectable:_,dragging:$}=se(Qf,me),v=()=>{h.setState({userSelectionActive:!1,userSelectionRect:null}),y.current=0,g.current=0},j=F=>{i==null||i(F),h.getState().resetSelectedElements(),h.setState({nodesSelectionActive:!1})},C=F=>{if(Array.isArray(n)&&(n!=null&&n.includes(2))){F.preventDefault();return}o==null||o(F)},N=a?F=>a(F):void 0,D=F=>{const{resetSelectedElements:p,domNode:M}=h.getState();if(b.current=M==null?void 0:M.getBoundingClientRect(),!_||!e||F.button!==0||F.target!==m.current||!b.current)return;const{x:E,y:O}=qe(F,b.current);p(),h.setState({userSelectionRect:{width:0,height:0,startX:E,startY:O,x:E,y:O}}),r==null||r(F)},S=F=>{const{userSelectionRect:p,nodeInternals:M,edges:E,transform:O,onNodesChange:L,onEdgesChange:k,nodeOrigin:I,getNodes:z}=h.getState();if(!e||!b.current||!p)return;h.setState({userSelectionActive:!0,nodesSelectionActive:!1});const H=qe(F,b.current),G=p.startX??0,Y=p.startY??0,U={...p,x:H.xq.id),W=Z.map(q=>q.id);if(y.current!==W.length){y.current=W.length;const q=xt(K,W);q.length&&(L==null||L(q))}if(g.current!==B.length){g.current=B.length;const q=xt(E,B);q.length&&(k==null||k(q))}h.setState({userSelectionRect:U})},T=F=>{if(F.button!==0)return;const{userSelectionRect:p}=h.getState();!x&&p&&F.target===m.current&&(j==null||j(F)),h.setState({nodesSelectionActive:y.current>0}),v(),s==null||s(F)},P=F=>{x&&(h.setState({nodesSelectionActive:y.current>0}),s==null||s(F)),v()},V=_&&(e||x);return A.createElement("div",{className:pe(["react-flow__pane",{dragging:$,selection:e}]),onClick:V?void 0:Gn(j,m),onContextMenu:Gn(C,m),onWheel:Gn(N,m),onMouseEnter:V?void 0:l,onMouseDown:V?D:void 0,onMouseMove:V?S:c,onMouseUp:V?T:void 0,onMouseLeave:V?P:u,ref:m,style:Tr},d,A.createElement(Xf,null))});wo.displayName="Pane";function vo(e,t){const n=e.parentNode||e.parentId;if(!n)return!1;const r=t.get(n);return r?r.selected?!0:vo(r,t):!1}function ks(e,t,n){let r=e;do{if(r!=null&&r.matches(t))return!0;if(r===n.current)return!1;r=r.parentElement}while(r);return!1}function Jf(e,t,n,r){return Array.from(e.values()).filter(s=>(s.selected||s.id===r)&&(!s.parentNode||s.parentId||!vo(s,e))&&(s.draggable||t&&typeof s.draggable>"u")).map(s=>{var i,o;return{id:s.id,position:s.position||{x:0,y:0},positionAbsolute:s.positionAbsolute||{x:0,y:0},distance:{x:n.x-(((i=s.positionAbsolute)==null?void 0:i.x)??0),y:n.y-(((o=s.positionAbsolute)==null?void 0:o.y)??0)},delta:{x:0,y:0},extent:s.extent,parentNode:s.parentNode||s.parentId,parentId:s.parentNode||s.parentId,width:s.width,height:s.height,expandParent:s.expandParent}})}function eh(e,t){return!t||t==="parent"?t:[t[0],[t[1][0]-(e.width||0),t[1][1]-(e.height||0)]]}function bo(e,t,n,r,s=[0,0],i){const o=eh(e,e.extent||r);let a=o;const l=e.parentNode||e.parentId;if(e.extent==="parent"&&!e.expandParent)if(l&&e.width&&e.height){const d=n.get(l),{x:m,y:h}=at(d,s).positionAbsolute;a=d&&Ee(m)&&Ee(h)&&Ee(d.width)&&Ee(d.height)?[[m+e.width*s[0],h+e.height*s[1]],[m+d.width-e.width+e.width*s[0],h+d.height-e.height+e.height*s[1]]]:a}else i==null||i("005",Ve.error005()),a=o;else if(e.extent&&l&&e.extent!=="parent"){const d=n.get(l),{x:m,y:h}=at(d,s).positionAbsolute;a=[[e.extent[0][0]+m,e.extent[0][1]+h],[e.extent[1][0]+m,e.extent[1][1]+h]]}let c={x:0,y:0};if(l){const d=n.get(l);c=at(d,s).positionAbsolute}const u=a&&a!=="parent"?jr(t,a):t;return{position:{x:u.x-c.x,y:u.y-c.y},positionAbsolute:u}}function Yn({nodeId:e,dragItems:t,nodeInternals:n}){const r=t.map(s=>({...n.get(s.id),position:s.position,positionAbsolute:s.positionAbsolute}));return[e?r.find(s=>s.id===e):r[0],r]}const js=(e,t,n,r)=>{const s=t.querySelectorAll(e);if(!s||!s.length)return null;const i=Array.from(s),o=t.getBoundingClientRect(),a={x:o.width*r[0],y:o.height*r[1]};return i.map(l=>{const c=l.getBoundingClientRect();return{id:l.getAttribute("data-handleid"),position:l.getAttribute("data-handlepos"),x:(c.left-o.left-a.x)/n,y:(c.top-o.top-a.y)/n,...kr(l)}})};function It(e,t,n){return n===void 0?n:r=>{const s=t().nodeInternals.get(e);s&&n(r,{...s})}}function hr({id:e,store:t,unselect:n=!1,nodeRef:r}){const{addSelectedNodes:s,unselectNodesAndEdges:i,multiSelectionActive:o,nodeInternals:a,onError:l}=t.getState(),c=a.get(e);if(!c){l==null||l("012",Ve.error012(e));return}t.setState({nodesSelectionActive:!1}),c.selected?(n||c.selected&&o)&&(i({nodes:[c],edges:[]}),requestAnimationFrame(()=>{var u;return(u=r==null?void 0:r.current)==null?void 0:u.blur()})):s([e])}function th(){const e=he();return w.useCallback(({sourceEvent:n})=>{const{transform:r,snapGrid:s,snapToGrid:i}=e.getState(),o=n.touches?n.touches[0].clientX:n.clientX,a=n.touches?n.touches[0].clientY:n.clientY,l={x:(o-r[0])/r[2],y:(a-r[1])/r[2]};return{xSnapped:i?s[0]*Math.round(l.x/s[0]):l.x,ySnapped:i?s[1]*Math.round(l.y/s[1]):l.y,...l}},[])}function Wn(e){return(t,n,r)=>e==null?void 0:e(t,r)}function _o({nodeRef:e,disabled:t=!1,noDragClassName:n,handleSelector:r,nodeId:s,isSelectable:i,selectNodesOnDrag:o}){const a=he(),[l,c]=w.useState(!1),u=w.useRef([]),d=w.useRef({x:null,y:null}),m=w.useRef(0),h=w.useRef(null),y=w.useRef({x:0,y:0}),g=w.useRef(null),b=w.useRef(!1),x=w.useRef(!1),_=w.useRef(!1),$=th();return w.useEffect(()=>{if(e!=null&&e.current){const v=_e(e.current),j=({x:D,y:S})=>{const{nodeInternals:T,onNodeDrag:P,onSelectionDrag:V,updateNodePositions:F,nodeExtent:p,snapGrid:M,snapToGrid:E,nodeOrigin:O,onError:L}=a.getState();d.current={x:D,y:S};let k=!1,I={x:0,y:0,x2:0,y2:0};if(u.current.length>1&&p){const H=Xt(u.current,O);I=Bt(H)}if(u.current=u.current.map(H=>{const G={x:D-H.distance.x,y:S-H.distance.y};E&&(G.x=M[0]*Math.round(G.x/M[0]),G.y=M[1]*Math.round(G.y/M[1]));const Y=[[p[0][0],p[0][1]],[p[1][0],p[1][1]]];u.current.length>1&&p&&!H.extent&&(Y[0][0]=H.positionAbsolute.x-I.x+p[0][0],Y[1][0]=H.positionAbsolute.x+(H.width??0)-I.x2+p[1][0],Y[0][1]=H.positionAbsolute.y-I.y+p[0][1],Y[1][1]=H.positionAbsolute.y+(H.height??0)-I.y2+p[1][1]);const U=bo(H,G,T,Y,O,L);return k=k||H.position.x!==U.position.x||H.position.y!==U.position.y,H.position=U.position,H.positionAbsolute=U.positionAbsolute,H}),!k)return;F(u.current,!0,!0),c(!0);const z=s?P:Wn(V);if(z&&g.current){const[H,G]=Yn({nodeId:s,dragItems:u.current,nodeInternals:T});z(g.current,H,G)}},C=()=>{if(!h.current)return;const[D,S]=Bi(y.current,h.current);if(D!==0||S!==0){const{transform:T,panBy:P}=a.getState();d.current.x=(d.current.x??0)-D/T[2],d.current.y=(d.current.y??0)-S/T[2],P({x:D,y:S})&&j(d.current)}m.current=requestAnimationFrame(C)},N=D=>{var O;const{nodeInternals:S,multiSelectionActive:T,nodesDraggable:P,unselectNodesAndEdges:V,onNodeDragStart:F,onSelectionDragStart:p}=a.getState();x.current=!0;const M=s?F:Wn(p);(!o||!i)&&!T&&s&&((O=S.get(s))!=null&&O.selected||V()),s&&i&&o&&hr({id:s,store:a,nodeRef:e});const E=$(D);if(d.current=E,u.current=Jf(S,P,E,s),M&&u.current){const[L,k]=Yn({nodeId:s,dragItems:u.current,nodeInternals:S});M(D.sourceEvent,L,k)}};if(t)v.on(".drag",null);else{const D=cu().on("start",S=>{const{domNode:T,nodeDragThreshold:P}=a.getState();P===0&&N(S),_.current=!1;const V=$(S);d.current=V,h.current=(T==null?void 0:T.getBoundingClientRect())||null,y.current=qe(S.sourceEvent,h.current)}).on("drag",S=>{var F,p;const T=$(S),{autoPanOnNodeDrag:P,nodeDragThreshold:V}=a.getState();if(S.sourceEvent.type==="touchmove"&&S.sourceEvent.touches.length>1&&(_.current=!0),!_.current){if(!b.current&&x.current&&P&&(b.current=!0,C()),!x.current){const M=T.xSnapped-(((F=d==null?void 0:d.current)==null?void 0:F.x)??0),E=T.ySnapped-(((p=d==null?void 0:d.current)==null?void 0:p.y)??0);Math.sqrt(M*M+E*E)>V&&N(S)}(d.current.x!==T.xSnapped||d.current.y!==T.ySnapped)&&u.current&&x.current&&(g.current=S.sourceEvent,y.current=qe(S.sourceEvent,h.current),j(T))}}).on("end",S=>{if(!(!x.current||_.current)&&(c(!1),b.current=!1,x.current=!1,cancelAnimationFrame(m.current),u.current)){const{updateNodePositions:T,nodeInternals:P,onNodeDragStop:V,onSelectionDragStop:F}=a.getState(),p=s?V:Wn(F);if(T(u.current,!1,!1),p){const[M,E]=Yn({nodeId:s,dragItems:u.current,nodeInternals:P});p(S.sourceEvent,M,E)}}}).filter(S=>{const T=S.target;return!S.button&&(!n||!ks(T,`.${n}`,e))&&(!r||ks(T,r,e))});return v.call(D),()=>{v.on(".drag",null)}}}},[e,t,n,r,i,a,s,o,$]),l}function Eo(){const e=he();return w.useCallback(n=>{const{nodeInternals:r,nodeExtent:s,updateNodePositions:i,getNodes:o,snapToGrid:a,snapGrid:l,onError:c,nodesDraggable:u}=e.getState(),d=o().filter(_=>_.selected&&(_.draggable||u&&typeof _.draggable>"u")),m=a?l[0]:5,h=a?l[1]:5,y=n.isShiftPressed?4:1,g=n.x*m*y,b=n.y*h*y,x=d.map(_=>{if(_.positionAbsolute){const $={x:_.positionAbsolute.x+g,y:_.positionAbsolute.y+b};a&&($.x=l[0]*Math.round($.x/l[0]),$.y=l[1]*Math.round($.y/l[1]));const{positionAbsolute:v,position:j}=bo(_,$,r,s,void 0,c);_.position=j,_.positionAbsolute=v}return _});i(x,!0,!1)},[])}const bt={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}};var Rt=e=>{const t=({id:n,type:r,data:s,xPos:i,yPos:o,xPosOrigin:a,yPosOrigin:l,selected:c,onClick:u,onMouseEnter:d,onMouseMove:m,onMouseLeave:h,onContextMenu:y,onDoubleClick:g,style:b,className:x,isDraggable:_,isSelectable:$,isConnectable:v,isFocusable:j,selectNodesOnDrag:C,sourcePosition:N,targetPosition:D,hidden:S,resizeObserver:T,dragHandle:P,zIndex:V,isParent:F,noDragClassName:p,noPanClassName:M,initialized:E,disableKeyboardA11y:O,ariaLabel:L,rfId:k,hasHandleBounds:I})=>{const z=he(),H=w.useRef(null),G=w.useRef(null),Y=w.useRef(N),U=w.useRef(D),K=w.useRef(r),Z=$||_||u||d||m||h,B=Eo(),W=It(n,z.getState,d),q=It(n,z.getState,m),ee=It(n,z.getState,h),J=It(n,z.getState,y),oe=It(n,z.getState,g),ie=te=>{const{nodeDragThreshold:R}=z.getState();if($&&(!C||!_||R>0)&&hr({id:n,store:z,nodeRef:H}),u){const ne=z.getState().nodeInternals.get(n);ne&&u(te,{...ne})}},re=te=>{if(!cr(te)&&!O)if(Ui.includes(te.key)&&$){const R=te.key==="Escape";hr({id:n,store:z,unselect:R,nodeRef:H})}else _&&c&&Object.prototype.hasOwnProperty.call(bt,te.key)&&(z.setState({ariaLiveMessage:`Moved selected node ${te.key.replace("Arrow","").toLowerCase()}. New position, x: ${~~i}, y: ${~~o}`}),B({x:bt[te.key].x,y:bt[te.key].y,isShiftPressed:te.shiftKey}))};w.useEffect(()=>()=>{G.current&&(T==null||T.unobserve(G.current),G.current=null)},[]),w.useEffect(()=>{if(H.current&&!S){const te=H.current;(!E||!I||G.current!==te)&&(G.current&&(T==null||T.unobserve(G.current)),T==null||T.observe(te),G.current=te)}},[S,E,I]),w.useEffect(()=>{const te=K.current!==r,R=Y.current!==N,ne=U.current!==D;H.current&&(te||R||ne)&&(te&&(K.current=r),R&&(Y.current=N),ne&&(U.current=D),z.getState().updateNodeDimensions([{id:n,nodeElement:H.current,forceUpdate:!0}]))},[n,r,N,D]);const ge=_o({nodeRef:H,disabled:S||!_,noDragClassName:p,handleSelector:P,nodeId:n,isSelectable:$,selectNodesOnDrag:C});return S?null:A.createElement("div",{className:pe(["react-flow__node",`react-flow__node-${r}`,{[M]:_},x,{selected:c,selectable:$,parent:F,dragging:ge}]),ref:H,style:{zIndex:V,transform:`translate(${a}px,${l}px)`,pointerEvents:Z?"all":"none",visibility:E?"visible":"hidden",...b},"data-id":n,"data-testid":`rf__node-${n}`,onMouseEnter:W,onMouseMove:q,onMouseLeave:ee,onContextMenu:J,onClick:ie,onDoubleClick:oe,onKeyDown:j?re:void 0,tabIndex:j?0:void 0,role:j?"button":void 0,"aria-describedby":O?void 0:`${mo}-${k}`,"aria-label":L},A.createElement(hf,{value:n},A.createElement(e,{id:n,data:s,type:r,xPos:i,yPos:o,selected:c,isConnectable:v,sourcePosition:N,targetPosition:D,dragging:ge,dragHandle:P,zIndex:V})))};return t.displayName="NodeWrapper",w.memo(t)};const nh=e=>{const t=e.getNodes().filter(n=>n.selected);return{...Xt(t,e.nodeOrigin),transformString:`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`,userSelectionActive:e.userSelectionActive}};function rh({onSelectionContextMenu:e,noPanClassName:t,disableKeyboardA11y:n}){const r=he(),{width:s,height:i,x:o,y:a,transformString:l,userSelectionActive:c}=se(nh,me),u=Eo(),d=w.useRef(null);if(w.useEffect(()=>{var y;n||(y=d.current)==null||y.focus({preventScroll:!0})},[n]),_o({nodeRef:d}),c||!s||!i)return null;const m=e?y=>{const g=r.getState().getNodes().filter(b=>b.selected);e(y,g)}:void 0,h=y=>{Object.prototype.hasOwnProperty.call(bt,y.key)&&u({x:bt[y.key].x,y:bt[y.key].y,isShiftPressed:y.shiftKey})};return A.createElement("div",{className:pe(["react-flow__nodesselection","react-flow__container",t]),style:{transform:l}},A.createElement("div",{ref:d,className:"react-flow__nodesselection-rect",onContextMenu:m,tabIndex:n?void 0:-1,onKeyDown:n?void 0:h,style:{width:s,height:i,top:a,left:o}}))}var sh=w.memo(rh);const ih=e=>e.nodesSelectionActive,No=({children:e,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:s,onPaneContextMenu:i,onPaneScroll:o,deleteKeyCode:a,onMove:l,onMoveStart:c,onMoveEnd:u,selectionKeyCode:d,selectionOnDrag:m,selectionMode:h,onSelectionStart:y,onSelectionEnd:g,multiSelectionKeyCode:b,panActivationKeyCode:x,zoomActivationKeyCode:_,elementsSelectable:$,zoomOnScroll:v,zoomOnPinch:j,panOnScroll:C,panOnScrollSpeed:N,panOnScrollMode:D,zoomOnDoubleClick:S,panOnDrag:T,defaultViewport:P,translateExtent:V,minZoom:F,maxZoom:p,preventScrolling:M,onSelectionContextMenu:E,noWheelClassName:O,noPanClassName:L,disableKeyboardA11y:k})=>{const I=se(ih),z=Yt(d),H=Yt(x),G=H||T,Y=H||C,U=z||m&&G!==!0;return Bf({deleteKeyCode:a,multiSelectionKeyCode:b}),A.createElement(Uf,{onMove:l,onMoveStart:c,onMoveEnd:u,onPaneContextMenu:i,elementsSelectable:$,zoomOnScroll:v,zoomOnPinch:j,panOnScroll:Y,panOnScrollSpeed:N,panOnScrollMode:D,zoomOnDoubleClick:S,panOnDrag:!z&&G,defaultViewport:P,translateExtent:V,minZoom:F,maxZoom:p,zoomActivationKeyCode:_,preventScrolling:M,noWheelClassName:O,noPanClassName:L},A.createElement(wo,{onSelectionStart:y,onSelectionEnd:g,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:s,onPaneContextMenu:i,onPaneScroll:o,panOnDrag:G,isSelecting:!!U,selectionMode:h},e,I&&A.createElement(sh,{onSelectionContextMenu:E,noPanClassName:L,disableKeyboardA11y:k})))};No.displayName="FlowRenderer";var oh=w.memo(No);function ah(e){return se(w.useCallback(n=>e?eo(n.nodeInternals,{x:0,y:0,width:n.width,height:n.height},n.transform,!0):n.getNodes(),[e]))}function lh(e){const t={input:Rt(e.input||co),default:Rt(e.default||fr),output:Rt(e.output||fo),group:Rt(e.group||Rr)},n={},r=Object.keys(e).filter(s=>!["input","default","output","group"].includes(s)).reduce((s,i)=>(s[i]=Rt(e[i]||fr),s),n);return{...t,...r}}const ch=({x:e,y:t,width:n,height:r,origin:s})=>!n||!r?{x:e,y:t}:s[0]<0||s[1]<0||s[0]>1||s[1]>1?{x:e,y:t}:{x:e-n*s[0],y:t-r*s[1]},uh=e=>({nodesDraggable:e.nodesDraggable,nodesConnectable:e.nodesConnectable,nodesFocusable:e.nodesFocusable,elementsSelectable:e.elementsSelectable,updateNodeDimensions:e.updateNodeDimensions,onError:e.onError}),So=e=>{const{nodesDraggable:t,nodesConnectable:n,nodesFocusable:r,elementsSelectable:s,updateNodeDimensions:i,onError:o}=se(uh,me),a=ah(e.onlyRenderVisibleElements),l=w.useRef(),c=w.useMemo(()=>{if(typeof ResizeObserver>"u")return null;const u=new ResizeObserver(d=>{const m=d.map(h=>({id:h.target.getAttribute("data-id"),nodeElement:h.target,forceUpdate:!0}));i(m)});return l.current=u,u},[]);return w.useEffect(()=>()=>{var u;(u=l==null?void 0:l.current)==null||u.disconnect()},[]),A.createElement("div",{className:"react-flow__nodes",style:Tr},a.map(u=>{var j,C,N;let d=u.type||"default";e.nodeTypes[d]||(o==null||o("003",Ve.error003(d)),d="default");const m=e.nodeTypes[d]||e.nodeTypes.default,h=!!(u.draggable||t&&typeof u.draggable>"u"),y=!!(u.selectable||s&&typeof u.selectable>"u"),g=!!(u.connectable||n&&typeof u.connectable>"u"),b=!!(u.focusable||r&&typeof u.focusable>"u"),x=e.nodeExtent?jr(u.positionAbsolute,e.nodeExtent):u.positionAbsolute,_=(x==null?void 0:x.x)??0,$=(x==null?void 0:x.y)??0,v=ch({x:_,y:$,width:u.width??0,height:u.height??0,origin:e.nodeOrigin});return A.createElement(m,{key:u.id,id:u.id,className:u.className,style:u.style,type:d,data:u.data,sourcePosition:u.sourcePosition||X.Bottom,targetPosition:u.targetPosition||X.Top,hidden:u.hidden,xPos:_,yPos:$,xPosOrigin:v.x,yPosOrigin:v.y,selectNodesOnDrag:e.selectNodesOnDrag,onClick:e.onNodeClick,onMouseEnter:e.onNodeMouseEnter,onMouseMove:e.onNodeMouseMove,onMouseLeave:e.onNodeMouseLeave,onContextMenu:e.onNodeContextMenu,onDoubleClick:e.onNodeDoubleClick,selected:!!u.selected,isDraggable:h,isSelectable:y,isConnectable:g,isFocusable:b,resizeObserver:c,dragHandle:u.dragHandle,zIndex:((j=u[ae])==null?void 0:j.z)??0,isParent:!!((C=u[ae])!=null&&C.isParent),noDragClassName:e.noDragClassName,noPanClassName:e.noPanClassName,initialized:!!u.width&&!!u.height,rfId:e.rfId,disableKeyboardA11y:e.disableKeyboardA11y,ariaLabel:u.ariaLabel,hasHandleBounds:!!((N=u[ae])!=null&&N.handleBounds)})}))};So.displayName="NodeRenderer";var dh=w.memo(So);const fh=(e,t,n)=>n===X.Left?e-t:n===X.Right?e+t:e,hh=(e,t,n)=>n===X.Top?e-t:n===X.Bottom?e+t:e,Cs="react-flow__edgeupdater",$s=({position:e,centerX:t,centerY:n,radius:r=10,onMouseDown:s,onMouseEnter:i,onMouseOut:o,type:a})=>A.createElement("circle",{onMouseDown:s,onMouseEnter:i,onMouseOut:o,className:pe([Cs,`${Cs}-${a}`]),cx:fh(t,r,e),cy:hh(n,r,e),r,stroke:"transparent",fill:"transparent"}),mh=()=>!0;var yt=e=>{const t=({id:n,className:r,type:s,data:i,onClick:o,onEdgeDoubleClick:a,selected:l,animated:c,label:u,labelStyle:d,labelShowBg:m,labelBgStyle:h,labelBgPadding:y,labelBgBorderRadius:g,style:b,source:x,target:_,sourceX:$,sourceY:v,targetX:j,targetY:C,sourcePosition:N,targetPosition:D,elementsSelectable:S,hidden:T,sourceHandleId:P,targetHandleId:V,onContextMenu:F,onMouseEnter:p,onMouseMove:M,onMouseLeave:E,reconnectRadius:O,onReconnect:L,onReconnectStart:k,onReconnectEnd:I,markerEnd:z,markerStart:H,rfId:G,ariaLabel:Y,isFocusable:U,isReconnectable:K,pathOptions:Z,interactionWidth:B,disableKeyboardA11y:W})=>{const q=w.useRef(null),[ee,J]=w.useState(!1),[oe,ie]=w.useState(!1),re=he(),ge=w.useMemo(()=>`url('#${ur(H,G)}')`,[H,G]),te=w.useMemo(()=>`url('#${ur(z,G)}')`,[z,G]);if(T)return null;const R=ye=>{var Ae;const{edges:ke,addSelectedEdges:Qe,unselectNodesAndEdges:Je,multiSelectionActive:et}=re.getState(),Oe=ke.find(jt=>jt.id===n);Oe&&(S&&(re.setState({nodesSelectionActive:!1}),Oe.selected&&et?(Je({nodes:[],edges:[Oe]}),(Ae=q.current)==null||Ae.blur()):Qe([n])),o&&o(ye,Oe))},ne=At(n,re.getState,a),ce=At(n,re.getState,F),be=At(n,re.getState,p),we=At(n,re.getState,M),ue=At(n,re.getState,E),Te=(ye,ke)=>{if(ye.button!==0)return;const{edges:Qe,isValidConnection:Je}=re.getState(),et=ke?_:x,Oe=(ke?V:P)||null,Ae=ke?"target":"source",jt=Je||mh,Tn=ke,Ct=Qe.find(tt=>tt.id===n);ie(!0),k==null||k(ye,Ct,Ae);const On=tt=>{ie(!1),I==null||I(tt,Ct,Ae)};io({event:ye,handleId:Oe,nodeId:et,onConnect:tt=>L==null?void 0:L(Ct,tt),isTarget:Tn,getState:re.getState,setState:re.setState,isValidConnection:jt,edgeUpdaterType:Ae,onReconnectEnd:On})},dt=ye=>Te(ye,!0),Ke=ye=>Te(ye,!1),Ze=()=>J(!0),ft=()=>J(!1),ht=!S&&!o,kt=ye=>{var ke;if(!W&&Ui.includes(ye.key)&&S){const{unselectNodesAndEdges:Qe,addSelectedEdges:Je,edges:et}=re.getState();ye.key==="Escape"?((ke=q.current)==null||ke.blur(),Qe({edges:[et.find(Ae=>Ae.id===n)]})):Je([n])}};return A.createElement("g",{className:pe(["react-flow__edge",`react-flow__edge-${s}`,r,{selected:l,animated:c,inactive:ht,updating:ee}]),onClick:R,onDoubleClick:ne,onContextMenu:ce,onMouseEnter:be,onMouseMove:we,onMouseLeave:ue,onKeyDown:U?kt:void 0,tabIndex:U?0:void 0,role:U?"button":"img","data-testid":`rf__edge-${n}`,"aria-label":Y===null?void 0:Y||`Edge from ${x} to ${_}`,"aria-describedby":U?`${po}-${G}`:void 0,ref:q},!oe&&A.createElement(e,{id:n,source:x,target:_,selected:l,animated:c,label:u,labelStyle:d,labelShowBg:m,labelBgStyle:h,labelBgPadding:y,labelBgBorderRadius:g,data:i,style:b,sourceX:$,sourceY:v,targetX:j,targetY:C,sourcePosition:N,targetPosition:D,sourceHandleId:P,targetHandleId:V,markerStart:ge,markerEnd:te,pathOptions:Z,interactionWidth:B}),K&&A.createElement(A.Fragment,null,(K==="source"||K===!0)&&A.createElement($s,{position:N,centerX:$,centerY:v,radius:O,onMouseDown:dt,onMouseEnter:Ze,onMouseOut:ft,type:"source"}),(K==="target"||K===!0)&&A.createElement($s,{position:D,centerX:j,centerY:C,radius:O,onMouseDown:Ke,onMouseEnter:Ze,onMouseOut:ft,type:"target"})))};return t.displayName="EdgeWrapper",w.memo(t)};function ph(e){const t={default:yt(e.default||bn),straight:yt(e.bezier||Mr),step:yt(e.step||$r),smoothstep:yt(e.step||Mn),simplebezier:yt(e.simplebezier||Cr)},n={},r=Object.keys(e).filter(s=>!["default","bezier"].includes(s)).reduce((s,i)=>(s[i]=yt(e[i]||bn),s),n);return{...t,...r}}function Ms(e,t,n=null){const r=((n==null?void 0:n.x)||0)+t.x,s=((n==null?void 0:n.y)||0)+t.y,i=(n==null?void 0:n.width)||t.width,o=(n==null?void 0:n.height)||t.height;switch(e){case X.Top:return{x:r+i/2,y:s};case X.Right:return{x:r+i,y:s+o/2};case X.Bottom:return{x:r+i/2,y:s+o};case X.Left:return{x:r,y:s+o/2}}}function As(e,t){return e?e.length===1||!t?e[0]:t&&e.find(n=>n.id===t)||null:null}const gh=(e,t,n,r,s,i)=>{const o=Ms(n,e,t),a=Ms(i,r,s);return{sourceX:o.x,sourceY:o.y,targetX:a.x,targetY:a.y}};function yh({sourcePos:e,targetPos:t,sourceWidth:n,sourceHeight:r,targetWidth:s,targetHeight:i,width:o,height:a,transform:l}){const c={x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x+n,t.x+s),y2:Math.max(e.y+r,t.y+i)};c.x===c.x2&&(c.x2+=1),c.y===c.y2&&(c.y2+=1);const u=Bt({x:(0-l[0])/l[2],y:(0-l[1])/l[2],width:o/l[2],height:a/l[2]}),d=Math.max(0,Math.min(u.x2,c.x2)-Math.max(u.x,c.x)),m=Math.max(0,Math.min(u.y2,c.y2)-Math.max(u.y,c.y));return Math.ceil(d*m)>0}function Is(e){var r,s,i,o,a;const t=((r=e==null?void 0:e[ae])==null?void 0:r.handleBounds)||null,n=t&&(e==null?void 0:e.width)&&(e==null?void 0:e.height)&&typeof((s=e==null?void 0:e.positionAbsolute)==null?void 0:s.x)<"u"&&typeof((i=e==null?void 0:e.positionAbsolute)==null?void 0:i.y)<"u";return[{x:((o=e==null?void 0:e.positionAbsolute)==null?void 0:o.x)||0,y:((a=e==null?void 0:e.positionAbsolute)==null?void 0:a.y)||0,width:(e==null?void 0:e.width)||0,height:(e==null?void 0:e.height)||0},t,!!n]}const xh=[{level:0,isMaxLevel:!0,edges:[]}];function wh(e,t,n=!1){let r=-1;const s=e.reduce((o,a)=>{var u,d;const l=Ee(a.zIndex);let c=l?a.zIndex:0;if(n){const m=t.get(a.target),h=t.get(a.source),y=a.selected||(m==null?void 0:m.selected)||(h==null?void 0:h.selected),g=Math.max(((u=h==null?void 0:h[ae])==null?void 0:u.z)||0,((d=m==null?void 0:m[ae])==null?void 0:d.z)||0,1e3);c=(l?a.zIndex:0)+(y?g:0)}return o[c]?o[c].push(a):o[c]=[a],r=c>r?c:r,o},{}),i=Object.entries(s).map(([o,a])=>{const l=+o;return{edges:a,level:l,isMaxLevel:l===r}});return i.length===0?xh:i}function vh(e,t,n){const r=se(w.useCallback(s=>e?s.edges.filter(i=>{const o=t.get(i.source),a=t.get(i.target);return(o==null?void 0:o.width)&&(o==null?void 0:o.height)&&(a==null?void 0:a.width)&&(a==null?void 0:a.height)&&yh({sourcePos:o.positionAbsolute||{x:0,y:0},targetPos:a.positionAbsolute||{x:0,y:0},sourceWidth:o.width,sourceHeight:o.height,targetWidth:a.width,targetHeight:a.height,width:s.width,height:s.height,transform:s.transform})}):s.edges,[e,t]));return wh(r,t,n)}const bh=({color:e="none",strokeWidth:t=1})=>A.createElement("polyline",{style:{stroke:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",fill:"none",points:"-5,-4 0,0 -5,4"}),_h=({color:e="none",strokeWidth:t=1})=>A.createElement("polyline",{style:{stroke:e,fill:e,strokeWidth:t},strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"}),Rs={[wn.Arrow]:bh,[wn.ArrowClosed]:_h};function Eh(e){const t=he();return w.useMemo(()=>{var s,i;return Object.prototype.hasOwnProperty.call(Rs,e)?Rs[e]:((i=(s=t.getState()).onError)==null||i.call(s,"009",Ve.error009(e)),null)},[e])}const Nh=({id:e,type:t,color:n,width:r=12.5,height:s=12.5,markerUnits:i="strokeWidth",strokeWidth:o,orient:a="auto-start-reverse"})=>{const l=Eh(t);return l?A.createElement("marker",{className:"react-flow__arrowhead",id:e,markerWidth:`${r}`,markerHeight:`${s}`,viewBox:"-10 -10 20 20",markerUnits:i,orient:a,refX:"0",refY:"0"},A.createElement(l,{color:n,strokeWidth:o})):null},Sh=({defaultColor:e,rfId:t})=>n=>{const r=[];return n.edges.reduce((s,i)=>([i.markerStart,i.markerEnd].forEach(o=>{if(o&&typeof o=="object"){const a=ur(o,t);r.includes(a)||(s.push({id:a,color:o.color||e,...o}),r.push(a))}}),s),[]).sort((s,i)=>s.id.localeCompare(i.id))},ko=({defaultColor:e,rfId:t})=>{const n=se(w.useCallback(Sh({defaultColor:e,rfId:t}),[e,t]),(r,s)=>!(r.length!==s.length||r.some((i,o)=>i.id!==s[o].id)));return A.createElement("defs",null,n.map(r=>A.createElement(Nh,{id:r.id,key:r.id,type:r.type,color:r.color,width:r.width,height:r.height,markerUnits:r.markerUnits,strokeWidth:r.strokeWidth,orient:r.orient})))};ko.displayName="MarkerDefinitions";var kh=w.memo(ko);const jh=e=>({nodesConnectable:e.nodesConnectable,edgesFocusable:e.edgesFocusable,edgesUpdatable:e.edgesUpdatable,elementsSelectable:e.elementsSelectable,width:e.width,height:e.height,connectionMode:e.connectionMode,nodeInternals:e.nodeInternals,onError:e.onError}),jo=({defaultMarkerColor:e,onlyRenderVisibleElements:t,elevateEdgesOnSelect:n,rfId:r,edgeTypes:s,noPanClassName:i,onEdgeContextMenu:o,onEdgeMouseEnter:a,onEdgeMouseMove:l,onEdgeMouseLeave:c,onEdgeClick:u,onEdgeDoubleClick:d,onReconnect:m,onReconnectStart:h,onReconnectEnd:y,reconnectRadius:g,children:b,disableKeyboardA11y:x})=>{const{edgesFocusable:_,edgesUpdatable:$,elementsSelectable:v,width:j,height:C,connectionMode:N,nodeInternals:D,onError:S}=se(jh,me),T=vh(t,D,n);return j?A.createElement(A.Fragment,null,T.map(({level:P,edges:V,isMaxLevel:F})=>A.createElement("svg",{key:P,style:{zIndex:P},width:j,height:C,className:"react-flow__edges react-flow__container"},F&&A.createElement(kh,{defaultColor:e,rfId:r}),A.createElement("g",null,V.map(p=>{const[M,E,O]=Is(D.get(p.source)),[L,k,I]=Is(D.get(p.target));if(!O||!I)return null;let z=p.type||"default";s[z]||(S==null||S("011",Ve.error011(z)),z="default");const H=s[z]||s.default,G=N===ct.Strict?k.target:(k.target??[]).concat(k.source??[]),Y=As(E.source,p.sourceHandle),U=As(G,p.targetHandle),K=(Y==null?void 0:Y.position)||X.Bottom,Z=(U==null?void 0:U.position)||X.Top,B=!!(p.focusable||_&&typeof p.focusable>"u"),W=p.reconnectable||p.updatable,q=typeof m<"u"&&(W||$&&typeof W>"u");if(!Y||!U)return S==null||S("008",Ve.error008(Y,p)),null;const{sourceX:ee,sourceY:J,targetX:oe,targetY:ie}=gh(M,Y,K,L,U,Z);return A.createElement(H,{key:p.id,id:p.id,className:pe([p.className,i]),type:z,data:p.data,selected:!!p.selected,animated:!!p.animated,hidden:!!p.hidden,label:p.label,labelStyle:p.labelStyle,labelShowBg:p.labelShowBg,labelBgStyle:p.labelBgStyle,labelBgPadding:p.labelBgPadding,labelBgBorderRadius:p.labelBgBorderRadius,style:p.style,source:p.source,target:p.target,sourceHandleId:p.sourceHandle,targetHandleId:p.targetHandle,markerEnd:p.markerEnd,markerStart:p.markerStart,sourceX:ee,sourceY:J,targetX:oe,targetY:ie,sourcePosition:K,targetPosition:Z,elementsSelectable:v,onContextMenu:o,onMouseEnter:a,onMouseMove:l,onMouseLeave:c,onClick:u,onEdgeDoubleClick:d,onReconnect:m,onReconnectStart:h,onReconnectEnd:y,reconnectRadius:g,rfId:r,ariaLabel:p.ariaLabel,isFocusable:B,isReconnectable:q,pathOptions:"pathOptions"in p?p.pathOptions:void 0,interactionWidth:p.interactionWidth,disableKeyboardA11y:x})})))),b):null};jo.displayName="EdgeRenderer";var Ch=w.memo(jo);const $h=e=>`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]})`;function Mh({children:e}){const t=se($h);return A.createElement("div",{className:"react-flow__viewport react-flow__container",style:{transform:t}},e)}function Ah(e){const t=An(),n=w.useRef(!1);w.useEffect(()=>{!n.current&&t.viewportInitialized&&e&&(setTimeout(()=>e(t),1),n.current=!0)},[e,t.viewportInitialized])}const Ih={[X.Left]:X.Right,[X.Right]:X.Left,[X.Top]:X.Bottom,[X.Bottom]:X.Top},Co=({nodeId:e,handleType:t,style:n,type:r=We.Bezier,CustomComponent:s,connectionStatus:i})=>{var C,N,D;const{fromNode:o,handleId:a,toX:l,toY:c,connectionMode:u}=se(w.useCallback(S=>({fromNode:S.nodeInternals.get(e),handleId:S.connectionHandleId,toX:(S.connectionPosition.x-S.transform[0])/S.transform[2],toY:(S.connectionPosition.y-S.transform[1])/S.transform[2],connectionMode:S.connectionMode}),[e]),me),d=(C=o==null?void 0:o[ae])==null?void 0:C.handleBounds;let m=d==null?void 0:d[t];if(u===ct.Loose&&(m=m||(d==null?void 0:d[t==="source"?"target":"source"])),!o||!m)return null;const h=a?m.find(S=>S.id===a):m[0],y=h?h.x+h.width/2:(o.width??0)/2,g=h?h.y+h.height/2:o.height??0,b=(((N=o.positionAbsolute)==null?void 0:N.x)??0)+y,x=(((D=o.positionAbsolute)==null?void 0:D.y)??0)+g,_=h==null?void 0:h.position,$=_?Ih[_]:null;if(!_||!$)return null;if(s)return A.createElement(s,{connectionLineType:r,connectionLineStyle:n,fromNode:o,fromHandle:h,fromX:b,fromY:x,toX:l,toY:c,fromPosition:_,toPosition:$,connectionStatus:i});let v="";const j={sourceX:b,sourceY:x,sourcePosition:_,targetX:l,targetY:c,targetPosition:$};return r===We.Bezier?[v]=Qi(j):r===We.Step?[v]=vn({...j,borderRadius:0}):r===We.SmoothStep?[v]=vn(j):r===We.SimpleBezier?[v]=Zi(j):v=`M${b},${x} ${l},${c}`,A.createElement("path",{d:v,fill:"none",className:"react-flow__connection-path",style:n})};Co.displayName="ConnectionLine";const Rh=e=>({nodeId:e.connectionNodeId,handleType:e.connectionHandleType,nodesConnectable:e.nodesConnectable,connectionStatus:e.connectionStatus,width:e.width,height:e.height});function Th({containerStyle:e,style:t,type:n,component:r}){const{nodeId:s,handleType:i,nodesConnectable:o,width:a,height:l,connectionStatus:c}=se(Rh,me);return!(s&&i&&a&&o)?null:A.createElement("svg",{style:e,width:a,height:l,className:"react-flow__edges react-flow__connectionline react-flow__container"},A.createElement("g",{className:pe(["react-flow__connection",c])},A.createElement(Co,{nodeId:s,handleType:i,style:t,type:n,CustomComponent:r,connectionStatus:c})))}function Ts(e,t){return w.useRef(null),he(),w.useMemo(()=>t(e),[e])}const $o=({nodeTypes:e,edgeTypes:t,onMove:n,onMoveStart:r,onMoveEnd:s,onInit:i,onNodeClick:o,onEdgeClick:a,onNodeDoubleClick:l,onEdgeDoubleClick:c,onNodeMouseEnter:u,onNodeMouseMove:d,onNodeMouseLeave:m,onNodeContextMenu:h,onSelectionContextMenu:y,onSelectionStart:g,onSelectionEnd:b,connectionLineType:x,connectionLineStyle:_,connectionLineComponent:$,connectionLineContainerStyle:v,selectionKeyCode:j,selectionOnDrag:C,selectionMode:N,multiSelectionKeyCode:D,panActivationKeyCode:S,zoomActivationKeyCode:T,deleteKeyCode:P,onlyRenderVisibleElements:V,elementsSelectable:F,selectNodesOnDrag:p,defaultViewport:M,translateExtent:E,minZoom:O,maxZoom:L,preventScrolling:k,defaultMarkerColor:I,zoomOnScroll:z,zoomOnPinch:H,panOnScroll:G,panOnScrollSpeed:Y,panOnScrollMode:U,zoomOnDoubleClick:K,panOnDrag:Z,onPaneClick:B,onPaneMouseEnter:W,onPaneMouseMove:q,onPaneMouseLeave:ee,onPaneScroll:J,onPaneContextMenu:oe,onEdgeContextMenu:ie,onEdgeMouseEnter:re,onEdgeMouseMove:ge,onEdgeMouseLeave:te,onReconnect:R,onReconnectStart:ne,onReconnectEnd:ce,reconnectRadius:be,noDragClassName:we,noWheelClassName:ue,noPanClassName:Te,elevateEdgesOnSelect:dt,disableKeyboardA11y:Ke,nodeOrigin:Ze,nodeExtent:ft,rfId:ht})=>{const kt=Ts(e,lh),ye=Ts(t,ph);return Ah(i),A.createElement(oh,{onPaneClick:B,onPaneMouseEnter:W,onPaneMouseMove:q,onPaneMouseLeave:ee,onPaneContextMenu:oe,onPaneScroll:J,deleteKeyCode:P,selectionKeyCode:j,selectionOnDrag:C,selectionMode:N,onSelectionStart:g,onSelectionEnd:b,multiSelectionKeyCode:D,panActivationKeyCode:S,zoomActivationKeyCode:T,elementsSelectable:F,onMove:n,onMoveStart:r,onMoveEnd:s,zoomOnScroll:z,zoomOnPinch:H,zoomOnDoubleClick:K,panOnScroll:G,panOnScrollSpeed:Y,panOnScrollMode:U,panOnDrag:Z,defaultViewport:M,translateExtent:E,minZoom:O,maxZoom:L,onSelectionContextMenu:y,preventScrolling:k,noDragClassName:we,noWheelClassName:ue,noPanClassName:Te,disableKeyboardA11y:Ke},A.createElement(Mh,null,A.createElement(Ch,{edgeTypes:ye,onEdgeClick:a,onEdgeDoubleClick:c,onlyRenderVisibleElements:V,onEdgeContextMenu:ie,onEdgeMouseEnter:re,onEdgeMouseMove:ge,onEdgeMouseLeave:te,onReconnect:R,onReconnectStart:ne,onReconnectEnd:ce,reconnectRadius:be,defaultMarkerColor:I,noPanClassName:Te,elevateEdgesOnSelect:!!dt,disableKeyboardA11y:Ke,rfId:ht},A.createElement(Th,{style:_,type:x,component:$,containerStyle:v})),A.createElement("div",{className:"react-flow__edgelabel-renderer"}),A.createElement(dh,{nodeTypes:kt,onNodeClick:o,onNodeDoubleClick:l,onNodeMouseEnter:u,onNodeMouseMove:d,onNodeMouseLeave:m,onNodeContextMenu:h,selectNodesOnDrag:p,onlyRenderVisibleElements:V,noPanClassName:Te,noDragClassName:we,disableKeyboardA11y:Ke,nodeOrigin:Ze,nodeExtent:ft,rfId:ht})))};$o.displayName="GraphView";var Oh=w.memo($o);const mr=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],Be={rfId:"1",width:0,height:0,transform:[0,0,1],nodeInternals:new Map,edges:[],onNodesChange:null,onEdgesChange:null,hasDefaultNodes:!1,hasDefaultEdges:!1,d3Zoom:null,d3Selection:null,d3ZoomHandler:void 0,minZoom:.5,maxZoom:2,translateExtent:mr,nodeExtent:mr,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionNodeId:null,connectionHandleId:null,connectionHandleType:"source",connectionPosition:{x:0,y:0},connectionStatus:null,connectionMode:ct.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:[0,0],nodeDragThreshold:0,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesUpdatable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,fitViewOnInit:!1,fitViewOnInitDone:!1,fitViewOnInitOptions:void 0,onSelectionChange:[],multiSelectionActive:!1,connectionStartHandle:null,connectionEndHandle:null,connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,connectionRadius:20,onError:af,isValidConnection:void 0},Dh=()=>bl((e,t)=>({...Be,setNodes:n=>{const{nodeInternals:r,nodeOrigin:s,elevateNodesOnSelect:i}=t();e({nodeInternals:Bn(n,r,s,i)})},getNodes:()=>Array.from(t().nodeInternals.values()),setEdges:n=>{const{defaultEdgeOptions:r={}}=t();e({edges:n.map(s=>({...r,...s}))})},setDefaultNodesAndEdges:(n,r)=>{const s=typeof n<"u",i=typeof r<"u",o=s?Bn(n,new Map,t().nodeOrigin,t().elevateNodesOnSelect):new Map;e({nodeInternals:o,edges:i?r:[],hasDefaultNodes:s,hasDefaultEdges:i})},updateNodeDimensions:n=>{const{onNodesChange:r,nodeInternals:s,fitViewOnInit:i,fitViewOnInitDone:o,fitViewOnInitOptions:a,domNode:l,nodeOrigin:c}=t(),u=l==null?void 0:l.querySelector(".react-flow__viewport");if(!u)return;const d=window.getComputedStyle(u),{m22:m}=new window.DOMMatrixReadOnly(d.transform),h=n.reduce((g,b)=>{const x=s.get(b.id);if(x!=null&&x.hidden)s.set(x.id,{...x,[ae]:{...x[ae],handleBounds:void 0}});else if(x){const _=kr(b.nodeElement);!!(_.width&&_.height&&(x.width!==_.width||x.height!==_.height||b.forceUpdate))&&(s.set(x.id,{...x,[ae]:{...x[ae],handleBounds:{source:js(".source",b.nodeElement,m,c),target:js(".target",b.nodeElement,m,c)}},..._}),g.push({id:x.id,type:"dimensions",dimensions:_}))}return g},[]);yo(s,c);const y=o||i&&!o&&xo(t,{initial:!0,...a});e({nodeInternals:new Map(s),fitViewOnInitDone:y}),(h==null?void 0:h.length)>0&&(r==null||r(h))},updateNodePositions:(n,r=!0,s=!1)=>{const{triggerNodeChanges:i}=t(),o=n.map(a=>{const l={id:a.id,type:"position",dragging:s};return r&&(l.positionAbsolute=a.positionAbsolute,l.position=a.position),l});i(o)},triggerNodeChanges:n=>{const{onNodesChange:r,nodeInternals:s,hasDefaultNodes:i,nodeOrigin:o,getNodes:a,elevateNodesOnSelect:l}=t();if(n!=null&&n.length){if(i){const c=Zf(n,a()),u=Bn(c,s,o,l);e({nodeInternals:u})}r==null||r(n)}},addSelectedNodes:n=>{const{multiSelectionActive:r,edges:s,getNodes:i}=t();let o,a=null;r?o=n.map(l=>Ye(l,!0)):(o=xt(i(),n),a=xt(s,[])),sn({changedNodes:o,changedEdges:a,get:t,set:e})},addSelectedEdges:n=>{const{multiSelectionActive:r,edges:s,getNodes:i}=t();let o,a=null;r?o=n.map(l=>Ye(l,!0)):(o=xt(s,n),a=xt(i(),[])),sn({changedNodes:a,changedEdges:o,get:t,set:e})},unselectNodesAndEdges:({nodes:n,edges:r}={})=>{const{edges:s,getNodes:i}=t(),o=n||i(),a=r||s,l=o.map(u=>(u.selected=!1,Ye(u.id,!1))),c=a.map(u=>Ye(u.id,!1));sn({changedNodes:l,changedEdges:c,get:t,set:e})},setMinZoom:n=>{const{d3Zoom:r,maxZoom:s}=t();r==null||r.scaleExtent([n,s]),e({minZoom:n})},setMaxZoom:n=>{const{d3Zoom:r,minZoom:s}=t();r==null||r.scaleExtent([s,n]),e({maxZoom:n})},setTranslateExtent:n=>{var r;(r=t().d3Zoom)==null||r.translateExtent(n),e({translateExtent:n})},resetSelectedElements:()=>{const{edges:n,getNodes:r}=t(),i=r().filter(a=>a.selected).map(a=>Ye(a.id,!1)),o=n.filter(a=>a.selected).map(a=>Ye(a.id,!1));sn({changedNodes:i,changedEdges:o,get:t,set:e})},setNodeExtent:n=>{const{nodeInternals:r}=t();r.forEach(s=>{s.positionAbsolute=jr(s.position,n)}),e({nodeExtent:n,nodeInternals:new Map(r)})},panBy:n=>{const{transform:r,width:s,height:i,d3Zoom:o,d3Selection:a,translateExtent:l}=t();if(!o||!a||!n.x&&!n.y)return!1;const c=He.translate(r[0]+n.x,r[1]+n.y).scale(r[2]),u=[[0,0],[s,i]],d=o==null?void 0:o.constrain()(c,u,l);return o.transform(a,d),r[0]!==d.x||r[1]!==d.y||r[2]!==d.k},cancelConnection:()=>e({connectionNodeId:Be.connectionNodeId,connectionHandleId:Be.connectionHandleId,connectionHandleType:Be.connectionHandleType,connectionStatus:Be.connectionStatus,connectionStartHandle:Be.connectionStartHandle,connectionEndHandle:Be.connectionEndHandle}),reset:()=>e({...Be})}),Object.is),Mo=({children:e})=>{const t=w.useRef(null);return t.current||(t.current=Dh()),A.createElement(Jd,{value:t.current},e)};Mo.displayName="ReactFlowProvider";const Ao=({children:e})=>w.useContext($n)?A.createElement(A.Fragment,null,e):A.createElement(Mo,null,e);Ao.displayName="ReactFlowWrapper";const Lh={input:co,default:fr,output:fo,group:Rr},Ph={default:bn,straight:Mr,step:$r,smoothstep:Mn,simplebezier:Cr},zh=[0,0],Hh=[15,15],Fh={x:0,y:0,zoom:1},Vh={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},Io=w.forwardRef(({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,className:s,nodeTypes:i=Lh,edgeTypes:o=Ph,onNodeClick:a,onEdgeClick:l,onInit:c,onMove:u,onMoveStart:d,onMoveEnd:m,onConnect:h,onConnectStart:y,onConnectEnd:g,onClickConnectStart:b,onClickConnectEnd:x,onNodeMouseEnter:_,onNodeMouseMove:$,onNodeMouseLeave:v,onNodeContextMenu:j,onNodeDoubleClick:C,onNodeDragStart:N,onNodeDrag:D,onNodeDragStop:S,onNodesDelete:T,onEdgesDelete:P,onSelectionChange:V,onSelectionDragStart:F,onSelectionDrag:p,onSelectionDragStop:M,onSelectionContextMenu:E,onSelectionStart:O,onSelectionEnd:L,connectionMode:k=ct.Strict,connectionLineType:I=We.Bezier,connectionLineStyle:z,connectionLineComponent:H,connectionLineContainerStyle:G,deleteKeyCode:Y="Backspace",selectionKeyCode:U="Shift",selectionOnDrag:K=!1,selectionMode:Z=Gt.Full,panActivationKeyCode:B="Space",multiSelectionKeyCode:W=xn()?"Meta":"Control",zoomActivationKeyCode:q=xn()?"Meta":"Control",snapToGrid:ee=!1,snapGrid:J=Hh,onlyRenderVisibleElements:oe=!1,selectNodesOnDrag:ie=!0,nodesDraggable:re,nodesConnectable:ge,nodesFocusable:te,nodeOrigin:R=zh,edgesFocusable:ne,edgesUpdatable:ce,elementsSelectable:be,defaultViewport:we=Fh,minZoom:ue=.5,maxZoom:Te=2,translateExtent:dt=mr,preventScrolling:Ke=!0,nodeExtent:Ze,defaultMarkerColor:ft="#b1b1b7",zoomOnScroll:ht=!0,zoomOnPinch:kt=!0,panOnScroll:ye=!1,panOnScrollSpeed:ke=.5,panOnScrollMode:Qe=it.Free,zoomOnDoubleClick:Je=!0,panOnDrag:et=!0,onPaneClick:Oe,onPaneMouseEnter:Ae,onPaneMouseMove:jt,onPaneMouseLeave:Tn,onPaneScroll:Ct,onPaneContextMenu:On,children:Vr,onEdgeContextMenu:tt,onEdgeDoubleClick:pa,onEdgeMouseEnter:ga,onEdgeMouseMove:ya,onEdgeMouseLeave:xa,onEdgeUpdate:wa,onEdgeUpdateStart:va,onEdgeUpdateEnd:ba,onReconnect:_a,onReconnectStart:Ea,onReconnectEnd:Na,reconnectRadius:Sa=10,edgeUpdaterRadius:ka=10,onNodesChange:ja,onEdgesChange:Ca,noDragClassName:$a="nodrag",noWheelClassName:Ma="nowheel",noPanClassName:Br="nopan",fitView:Aa=!1,fitViewOptions:Ia,connectOnClick:Ra=!0,attributionPosition:Ta,proOptions:Oa,defaultEdgeOptions:Da,elevateNodesOnSelect:La=!0,elevateEdgesOnSelect:Pa=!1,disableKeyboardA11y:Gr=!1,autoPanOnConnect:za=!0,autoPanOnNodeDrag:Ha=!0,connectionRadius:Fa=20,isValidConnection:Va,onError:Ba,style:Ga,id:Yr,nodeDragThreshold:Ya,...Wa},Ua)=>{const Dn=Yr||"1";return A.createElement("div",{...Wa,style:{...Ga,...Vh},ref:Ua,className:pe(["react-flow",s]),"data-testid":"rf__wrapper",id:Yr},A.createElement(Ao,null,A.createElement(Oh,{onInit:c,onMove:u,onMoveStart:d,onMoveEnd:m,onNodeClick:a,onEdgeClick:l,onNodeMouseEnter:_,onNodeMouseMove:$,onNodeMouseLeave:v,onNodeContextMenu:j,onNodeDoubleClick:C,nodeTypes:i,edgeTypes:o,connectionLineType:I,connectionLineStyle:z,connectionLineComponent:H,connectionLineContainerStyle:G,selectionKeyCode:U,selectionOnDrag:K,selectionMode:Z,deleteKeyCode:Y,multiSelectionKeyCode:W,panActivationKeyCode:B,zoomActivationKeyCode:q,onlyRenderVisibleElements:oe,selectNodesOnDrag:ie,defaultViewport:we,translateExtent:dt,minZoom:ue,maxZoom:Te,preventScrolling:Ke,zoomOnScroll:ht,zoomOnPinch:kt,zoomOnDoubleClick:Je,panOnScroll:ye,panOnScrollSpeed:ke,panOnScrollMode:Qe,panOnDrag:et,onPaneClick:Oe,onPaneMouseEnter:Ae,onPaneMouseMove:jt,onPaneMouseLeave:Tn,onPaneScroll:Ct,onPaneContextMenu:On,onSelectionContextMenu:E,onSelectionStart:O,onSelectionEnd:L,onEdgeContextMenu:tt,onEdgeDoubleClick:pa,onEdgeMouseEnter:ga,onEdgeMouseMove:ya,onEdgeMouseLeave:xa,onReconnect:_a??wa,onReconnectStart:Ea??va,onReconnectEnd:Na??ba,reconnectRadius:Sa??ka,defaultMarkerColor:ft,noDragClassName:$a,noWheelClassName:Ma,noPanClassName:Br,elevateEdgesOnSelect:Pa,rfId:Dn,disableKeyboardA11y:Gr,nodeOrigin:R,nodeExtent:Ze}),A.createElement(Af,{nodes:e,edges:t,defaultNodes:n,defaultEdges:r,onConnect:h,onConnectStart:y,onConnectEnd:g,onClickConnectStart:b,onClickConnectEnd:x,nodesDraggable:re,nodesConnectable:ge,nodesFocusable:te,edgesFocusable:ne,edgesUpdatable:ce,elementsSelectable:be,elevateNodesOnSelect:La,minZoom:ue,maxZoom:Te,nodeExtent:Ze,onNodesChange:ja,onEdgesChange:Ca,snapToGrid:ee,snapGrid:J,connectionMode:k,translateExtent:dt,connectOnClick:Ra,defaultEdgeOptions:Da,fitView:Aa,fitViewOptions:Ia,onNodesDelete:T,onEdgesDelete:P,onNodeDragStart:N,onNodeDrag:D,onNodeDragStop:S,onSelectionDrag:p,onSelectionDragStart:F,onSelectionDragStop:M,noPanClassName:Br,nodeOrigin:R,rfId:Dn,autoPanOnConnect:za,autoPanOnNodeDrag:Ha,onError:Ba,connectionRadius:Fa,isValidConnection:Va,nodeDragThreshold:Ya}),A.createElement($f,{onSelectionChange:V}),Vr,A.createElement(tf,{proOptions:Oa,position:Ta}),A.createElement(Df,{rfId:Dn,disableKeyboardA11y:Gr})))});Io.displayName="ReactFlow";const Ro=({id:e,x:t,y:n,width:r,height:s,style:i,color:o,strokeColor:a,strokeWidth:l,className:c,borderRadius:u,shapeRendering:d,onClick:m,selected:h})=>{const{background:y,backgroundColor:g}=i||{},b=o||y||g;return A.createElement("rect",{className:pe(["react-flow__minimap-node",{selected:h},c]),x:t,y:n,rx:u,ry:u,width:r,height:s,fill:b,stroke:a,strokeWidth:l,shapeRendering:d,onClick:m?x=>m(x,e):void 0})};Ro.displayName="MiniMapNode";var Bh=w.memo(Ro);const Gh=e=>e.nodeOrigin,Yh=e=>e.getNodes().filter(t=>!t.hidden&&t.width&&t.height),Un=e=>e instanceof Function?e:()=>e;function Wh({nodeStrokeColor:e="transparent",nodeColor:t="#e2e2e2",nodeClassName:n="",nodeBorderRadius:r=5,nodeStrokeWidth:s=2,nodeComponent:i=Bh,onClick:o}){const a=se(Yh,me),l=se(Gh),c=Un(t),u=Un(e),d=Un(n),m=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return A.createElement(A.Fragment,null,a.map(h=>{const{x:y,y:g}=at(h,l).positionAbsolute;return A.createElement(i,{key:h.id,x:y,y:g,width:h.width,height:h.height,style:h.style,selected:h.selected,className:d(h),color:c(h),borderRadius:r,strokeColor:u(h),strokeWidth:s,shapeRendering:m,onClick:o,id:h.id})}))}var Uh=w.memo(Wh);const qh=200,Xh=150,Kh=e=>{const t=e.getNodes(),n={x:-e.transform[0]/e.transform[2],y:-e.transform[1]/e.transform[2],width:e.width/e.transform[2],height:e.height/e.transform[2]};return{viewBB:n,boundingRect:t.length>0?sf(Xt(t,e.nodeOrigin),n):n,rfId:e.rfId}},Zh="react-flow__minimap-desc";function To({style:e,className:t,nodeStrokeColor:n="transparent",nodeColor:r="#e2e2e2",nodeClassName:s="",nodeBorderRadius:i=5,nodeStrokeWidth:o=2,nodeComponent:a,maskColor:l="rgb(240, 240, 240, 0.6)",maskStrokeColor:c="none",maskStrokeWidth:u=1,position:d="bottom-right",onClick:m,onNodeClick:h,pannable:y=!1,zoomable:g=!1,ariaLabel:b="React Flow mini map",inversePan:x=!1,zoomStep:_=10,offsetScale:$=5}){const v=he(),j=w.useRef(null),{boundingRect:C,viewBB:N,rfId:D}=se(Kh,me),S=(e==null?void 0:e.width)??qh,T=(e==null?void 0:e.height)??Xh,P=C.width/S,V=C.height/T,F=Math.max(P,V),p=F*S,M=F*T,E=$*F,O=C.x-(p-C.width)/2-E,L=C.y-(M-C.height)/2-E,k=p+E*2,I=M+E*2,z=`${Zh}-${D}`,H=w.useRef(0);H.current=F,w.useEffect(()=>{if(j.current){const U=_e(j.current),K=W=>{const{transform:q,d3Selection:ee,d3Zoom:J}=v.getState();if(W.sourceEvent.type!=="wheel"||!ee||!J)return;const oe=-W.sourceEvent.deltaY*(W.sourceEvent.deltaMode===1?.05:W.sourceEvent.deltaMode?1:.002)*_,ie=q[2]*Math.pow(2,oe);J.scaleTo(ee,ie)},Z=W=>{const{transform:q,d3Selection:ee,d3Zoom:J,translateExtent:oe,width:ie,height:re}=v.getState();if(W.sourceEvent.type!=="mousemove"||!ee||!J)return;const ge=H.current*Math.max(1,q[2])*(x?-1:1),te={x:q[0]-W.sourceEvent.movementX*ge,y:q[1]-W.sourceEvent.movementY*ge},R=[[0,0],[ie,re]],ne=He.translate(te.x,te.y).scale(q[2]),ce=J.constrain()(ne,R,oe);J.transform(ee,ce)},B=Fi().on("zoom",y?Z:null).on("zoom.wheel",g?K:null);return U.call(B),()=>{U.on("zoom",null)}}},[y,g,x,_]);const G=m?U=>{const K=je(U);m(U,{x:K[0],y:K[1]})}:void 0,Y=h?(U,K)=>{const Z=v.getState().nodeInternals.get(K);h(U,Z)}:void 0;return A.createElement(Sr,{position:d,style:e,className:pe(["react-flow__minimap",t]),"data-testid":"rf__minimap"},A.createElement("svg",{width:S,height:T,viewBox:`${O} ${L} ${k} ${I}`,role:"img","aria-labelledby":z,ref:j,onClick:G},b&&A.createElement("title",{id:z},b),A.createElement(Uh,{onClick:Y,nodeColor:r,nodeStrokeColor:n,nodeBorderRadius:i,nodeClassName:s,nodeStrokeWidth:o,nodeComponent:a}),A.createElement("path",{className:"react-flow__minimap-mask",d:`M${O-E},${L-E}h${k+E*2}v${I+E*2}h${-k-E*2}z - M${N.x},${N.y}h${N.width}v${N.height}h${-N.width}z`,fill:l,fillRule:"evenodd",stroke:c,strokeWidth:u,pointerEvents:"none"})))}To.displayName="MiniMap";var Qh=w.memo(To);function Jh(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32"},A.createElement("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"}))}function em(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5"},A.createElement("path",{d:"M0 0h32v4.2H0z"}))}function tm(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30"},A.createElement("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"}))}function nm(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},A.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"}))}function rm(){return A.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32"},A.createElement("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"}))}const Dt=({children:e,className:t,...n})=>A.createElement("button",{type:"button",className:pe(["react-flow__controls-button",t]),...n},e);Dt.displayName="ControlButton";const sm=e=>({isInteractive:e.nodesDraggable||e.nodesConnectable||e.elementsSelectable,minZoomReached:e.transform[2]<=e.minZoom,maxZoomReached:e.transform[2]>=e.maxZoom}),Oo=({style:e,showZoom:t=!0,showFitView:n=!0,showInteractive:r=!0,fitViewOptions:s,onZoomIn:i,onZoomOut:o,onFitView:a,onInteractiveChange:l,className:c,children:u,position:d="bottom-left"})=>{const m=he(),[h,y]=w.useState(!1),{isInteractive:g,minZoomReached:b,maxZoomReached:x}=se(sm,me),{zoomIn:_,zoomOut:$,fitView:v}=An();if(w.useEffect(()=>{y(!0)},[]),!h)return null;const j=()=>{_(),i==null||i()},C=()=>{$(),o==null||o()},N=()=>{v(s),a==null||a()},D=()=>{m.setState({nodesDraggable:!g,nodesConnectable:!g,elementsSelectable:!g}),l==null||l(!g)};return A.createElement(Sr,{className:pe(["react-flow__controls",c]),position:d,style:e,"data-testid":"rf__controls"},t&&A.createElement(A.Fragment,null,A.createElement(Dt,{onClick:j,className:"react-flow__controls-zoomin",title:"zoom in","aria-label":"zoom in",disabled:x},A.createElement(Jh,null)),A.createElement(Dt,{onClick:C,className:"react-flow__controls-zoomout",title:"zoom out","aria-label":"zoom out",disabled:b},A.createElement(em,null))),n&&A.createElement(Dt,{className:"react-flow__controls-fitview",onClick:N,title:"fit view","aria-label":"fit view"},A.createElement(tm,null)),r&&A.createElement(Dt,{className:"react-flow__controls-interactive",onClick:D,title:"toggle interactivity","aria-label":"toggle interactivity"},g?A.createElement(rm,null):A.createElement(nm,null)),u)};Oo.displayName="Controls";var im=w.memo(Oo),Ne;(function(e){e.Lines="lines",e.Dots="dots",e.Cross="cross"})(Ne||(Ne={}));function om({color:e,dimensions:t,lineWidth:n}){return A.createElement("path",{stroke:e,strokeWidth:n,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`})}function am({color:e,radius:t}){return A.createElement("circle",{cx:t,cy:t,r:t,fill:e})}const lm={[Ne.Dots]:"#91919a",[Ne.Lines]:"#eee",[Ne.Cross]:"#e2e2e2"},cm={[Ne.Dots]:1,[Ne.Lines]:1,[Ne.Cross]:6},um=e=>({transform:e.transform,patternId:`pattern-${e.rfId}`});function Do({id:e,variant:t=Ne.Dots,gap:n=20,size:r,lineWidth:s=1,offset:i=2,color:o,style:a,className:l}){const c=w.useRef(null),{transform:u,patternId:d}=se(um,me),m=o||lm[t],h=r||cm[t],y=t===Ne.Dots,g=t===Ne.Cross,b=Array.isArray(n)?n:[n,n],x=[b[0]*u[2]||1,b[1]*u[2]||1],_=h*u[2],$=g?[_,_]:x,v=y?[_/i,_/i]:[$[0]/i,$[1]/i];return A.createElement("svg",{className:pe(["react-flow__background",l]),style:{...a,position:"absolute",width:"100%",height:"100%",top:0,left:0},ref:c,"data-testid":"rf__background"},A.createElement("pattern",{id:d+e,x:u[0]%x[0],y:u[1]%x[1],width:x[0],height:x[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${v[0]},-${v[1]})`},y?A.createElement(am,{color:m,radius:_/i}):A.createElement(om,{dimensions:$,color:m,lineWidth:s})),A.createElement("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${d+e})`}))}Do.displayName="Background";var dm=w.memo(Do);const Or=(()=>{const e=window.location.pathname.match(/^(\/view\/[^/]+)(?:\/|$)/);return e?e[1]:""})();function Lo(e){return Or+e}async function fe(e){const t=await fetch(Lo(e));if(!t.ok)throw new Error(`${e}: ${t.status} ${await t.text()}`);return await t.json()}async function Xe(e,t){const n=await fetch(Lo(e),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),r=await n.json();if(!n.ok)throw new Po(r.error??`${e}: ${n.status}`,n.status);return r}class Po extends Error{constructor(n,r){super(n);le(this,"status");this.status=r}}const fx=e=>fe(e?`/api/model?subject_area=${encodeURIComponent(e)}`:"/api/model"),hx=()=>fe("/api/diagnostics"),zo=(e,t)=>fe(`/api/ontology/search?q=${encodeURIComponent(e)}`+(t?`&within=${encodeURIComponent(t)}`:"")),Ho=()=>fe("/api/ontology/ontologies"),fm=e=>fe(`/api/ontology/term?ref=${encodeURIComponent(e)}`),hm=()=>fe("/api/ontology/stack"),mm=()=>fe("/api/ontology/coverage"),pm=(e,t,n)=>Xe("/api/command",{op:e,payload:t,fingerprint:n??""}),gm=()=>fe("/api/git/status"),ym=()=>fe("/api/git/diff"),xm=e=>Xe("/api/git/commit",{message:e}),wm=()=>Xe("/api/git/discard",{}),vm=()=>fe("/api/decisions"),Os=(e,t)=>Xe(`/api/decisions/${e}/verdict`,{verdict:t}),mx=(e={})=>{const t=new URLSearchParams;return e.subject_area&&t.set("subject_area",e.subject_area),e.q&&t.set("q",e.q),fe(`/api/glossary/terms?${t.toString()}`)},px=()=>fe("/api/glossary/config"),gx=e=>Xe("/api/git/propose",e),yx=(e="HEAD")=>fe(`/api/git/diff/model?base=${encodeURIComponent(e)}`),xx=(e="HEAD")=>fe(`/api/git/classify?base=${encodeURIComponent(e)}`),wx=e=>Xe("/api/git/classify",{changes:e}),vx=e=>fe(`/api/git/conflicts?base=${encodeURIComponent(e)}`),bx=(e="")=>fe(`/api/git/context?user=${encodeURIComponent(e)}`),_x=(e="")=>fe(`/api/git/proposals?user=${encodeURIComponent(e)}`),bm=()=>fe("/api/export"),_m=(e,t)=>{const n=t?`?dialect=${encodeURIComponent(t)}`:"";return`${Or}/api/export/${encodeURIComponent(e)}${n}`},Em=(e,t,n)=>Xe("/api/import",{format:e,content:t,dialect:n}),Ex=async e=>{for(const t of e)await pm(t.op,t.payload)},Nx=(e,t,n)=>fetch(`${Or}/api/preview`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({changes:e,subject_area:t??""}),signal:n}).then(async r=>{if(!r.ok)throw new Po(await r.text(),r.status);return await r.json()}),Sx=()=>fe("/api/glossary/subject-areas"),kx=e=>fe(`/api/glossary/subject-area/${e}`),jx=(e,t)=>Xe(`/api/glossary/subject-area/${e}/expand`,t),Nm={business_key:"🔑",surrogate_key:"#",measure:"Σ",attribute:""};function Sm(e){return e??""}const Dr="__entity_source",Lr="__entity_target",km=w.memo(function({data:t,selected:n}){var C;const{entity:r,color:s,dimmed:i,highlighted:o,showTypes:a,collapseDetail:l,expanded:c,onToggleExpand:u,endpointAttrs:d,highlightAttrs:m,dimAttrs:h,onHoverAttr:y}=t,g=N=>N.role==="business_key"?0:d!=null&&d.has(N.id)?1:2,b=[...r.attributes].map((N,D)=>({a:N,i:D})).sort((N,D)=>g(N.a)-g(D.a)||N.i-D.i).map(N=>N.a),x=b.filter(N=>N.role==="business_key");let _=b.filter(N=>N.role!=="business_key");const $=!!l&&!c;let v=0;if($){const N=_.filter(D=>d==null?void 0:d.has(D.id));v=_.length-N.length,_=N}const j=(N,D)=>{const S="attr-row"+(m!=null&&m.has(N.id)?" rel-hit":"")+(h!=null&&h.has(N.id)?" rel-dim":"")+(d!=null&&d.has(N.id)?" endpoint":"");return f.jsxs("div",{className:S,onMouseEnter:y?()=>y(N.id):void 0,onMouseLeave:y?()=>y(null):void 0,children:[f.jsx(Ue,{id:N.id,type:"target",position:X.Left,className:"port attr-port"}),f.jsx(Ue,{id:N.id,type:"source",position:X.Right,className:"port attr-port"}),f.jsx("span",{className:"attr-icon",children:Nm[N.role]}),f.jsx("span",{className:"attr-name"+(D?" pk":""),children:N.name}),a&&f.jsx("span",{className:"attr-type",children:Sm(N.domain)}),!N.nullable&&f.jsx("span",{className:"attr-notnull",title:"not null",children:"●"})]},N.id)};return f.jsxs("div",{className:"entity-node"+(n?" selected":"")+(i?" dimmed":"")+(o?" highlighted":""),style:{borderTopColor:s},children:[f.jsx(Ue,{id:Lr,type:"target",position:X.Left,className:"port"}),f.jsx(Ue,{id:Dr,type:"source",position:X.Right,className:"port"}),f.jsxs("div",{className:"entity-header",children:[f.jsx("span",{className:"entity-name",title:((C=r.conceptual)==null?void 0:C.definition)??void 0,children:r.name}),f.jsxs("span",{className:"entity-badges",children:[r.pattern&&f.jsx("span",{className:"badge pattern",children:r.pattern}),(()=>{var S;const N=(((S=r.conceptual)==null?void 0:S.ontology_refs)??[]).filter(T=>T.uri);if(N.length===0)return null;const D=N.map(T=>T.uri).join(` -`);return f.jsxs("span",{className:"badge ontology",title:D,children:["⚙",N.length>1?` ${N.length}`:""]})})()]})]}),x.length>0&&f.jsx("div",{className:"attr-section keys",children:x.map(N=>j(N,!0))}),f.jsxs("div",{className:"attr-section",children:[_.map(N=>j(N,!1)),r.attributes.length===0&&f.jsx("div",{className:"attr-row empty",children:"no attributes"}),v>0&&f.jsx("div",{className:"attr-row more",title:"Show all columns",onClick:u?()=>u(r.id):void 0,children:`+${v} more`}),c&&!!l&&f.jsx("div",{className:"attr-row more",title:"Collapse to keys",onClick:u?()=>u(r.id):void 0,children:"− collapse"})]})]})}),jm=["string","integer","bigint","decimal","boolean","date","timestamp"];function Cm({entity:e,doc:t,caps:n,exec:r,onClose:s,onFocusEntity:i,onAlign:o,onEditMapping:a}){var m,h,y,g,b,x,_,$,v,j,C,N,D;const l=!n.canEdit,c=e.conceptual,u=t.relationships.filter(S=>S.from.entity===e.id||S.to.entity===e.id),d=S=>{var T;return((T=t.entities.find(P=>P.id===S))==null?void 0:T.name)??S};return f.jsxs("aside",{className:"detail-panel",children:[f.jsxs("div",{className:"detail-header",children:[f.jsxs("div",{style:{flex:1},children:[f.jsx(Le,{value:e.name,className:"entity-title-input",readOnly:l,onCommit:S=>r("rename_entity",{id:e.id,name:S})}),(e.physical_name||!l)&&f.jsxs("div",{className:"physical-name-row",title:"Physical table name (erwin Physical_Name)",children:[f.jsx("span",{className:"physical-label",children:"physical"}),f.jsx(Le,{value:e.physical_name??"",className:"physical-name-input",placeholder:l?"—":"physical table name…",readOnly:l,onCommit:S=>r("rename_entity",{id:e.id,physical_name:S})})]}),f.jsxs("div",{children:[f.jsx(Mm,{entity:e,doc:t,readOnly:l,exec:r}),f.jsx(Im,{entity:e,readOnly:l,exec:r}),e.category&&f.jsx("span",{className:"cat-badge "+e.category.role,title:e.category.role==="supertype"?`Supertype of category "${e.category.category}"`:`Subtype in "${e.category.category}" (${e.category.materialization})`,children:e.category.role==="supertype"?"◆ supertype":"◇ subtype"})]})]}),f.jsx("button",{className:"icon-btn",onClick:s,title:"Close",children:"✕"})]}),f.jsxs("section",{children:[f.jsx("h3",{children:"Definition"}),f.jsx(Le,{value:((m=c==null?void 0:c.definition)==null?void 0:m.trim())??"",multiline:!0,placeholder:l?"—":"add a business definition…",className:"definition-input",readOnly:l,onCommit:S=>r("set_definition",{id:e.id,definition:S})})]}),f.jsxs("section",{children:[f.jsxs("h3",{children:["Ontology",!l&&f.jsxs("span",{className:"h3-actions",children:[f.jsx("button",{className:"mini-btn",onClick:()=>o(e),children:(((h=c==null?void 0:c.ontology_refs)==null?void 0:h.length)??0)>0?"Add / re-align…":"Align…"}),(((y=c==null?void 0:c.ontology_refs)==null?void 0:y.length)??0)>0&&f.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_alignment",{id:e.id}),title:"Clear every alignment on this object",children:"Clear all"})]})]}),(c==null?void 0:c.ontology_layer)&&f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"layer"}),f.jsx("span",{className:`chip layer-${c.ontology_layer}`,children:c.ontology_layer}),c.no_industry_equivalent&&f.jsx("span",{className:"chip",title:"reviewed: no industry equivalent",children:"no industry equivalent"})]}),f.jsx($m,{entityId:e.id,refs:(c==null?void 0:c.ontology_refs)??[],caps:n,exec:r})]}),f.jsxs("section",{children:[f.jsxs("h3",{children:["Knowledge Graph mapping",!l&&f.jsxs("span",{className:"h3-actions",children:[f.jsx("button",{className:"mini-btn",onClick:()=>a(e),children:(g=e.term_map)!=null&&g.subject_template||(b=e.term_map)!=null&&b.class_iri?"Edit mapping…":"Map…"}),(((x=e.term_map)==null?void 0:x.subject_template)||((_=e.term_map)==null?void 0:_.class_iri))&&f.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_term_map",{id:e.id}),children:"Clear"})]})]}),($=e.term_map)!=null&&$.subject_template||(v=e.term_map)!=null&&v.class_iri?f.jsxs(f.Fragment,{children:[((j=e.term_map)==null?void 0:j.class_iri)&&f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"class IRI"}),f.jsx("code",{className:"v",children:e.term_map.class_iri})]}),((C=e.term_map)==null?void 0:C.subject_template)&&f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"subject"}),f.jsx("code",{className:"v",children:e.term_map.subject_template})]})]}):f.jsxs("p",{className:"empty-hint",children:["uses the default R2RML term-map (base IRI",t.project.kg_base_iri?` ${t.project.kg_base_iri}`:""," + primary key)"]})]}),f.jsxs("section",{children:[f.jsx("h3",{children:"Stewardship"}),f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"owner"}),f.jsx(Le,{value:((N=c==null?void 0:c.stewardship)==null?void 0:N.owner)??"",placeholder:"—",readOnly:l,onCommit:S=>{var T;return r("set_stewardship",{id:e.id,owner:S,steward:((T=c==null?void 0:c.stewardship)==null?void 0:T.steward)??null})}})]}),f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"steward"}),f.jsx(Le,{value:((D=c==null?void 0:c.stewardship)==null?void 0:D.steward)??"",placeholder:"—",readOnly:l,onCommit:S=>{var T;return r("set_stewardship",{id:e.id,owner:((T=c==null?void 0:c.stewardship)==null?void 0:T.owner)??null,steward:S})}})]})]}),f.jsxs("section",{children:[f.jsxs("h3",{children:["Attributes (",e.attributes.length,")"]}),f.jsx("table",{className:"attr-table",children:f.jsx("tbody",{children:e.attributes.map(S=>f.jsx(Tm,{a:S,entity:e,doc:t,readOnly:l,exec:r},S.id))})}),!l&&f.jsx(Om,{entity:e,exec:r})]}),e.key_groups&&e.key_groups.length>0&&f.jsxs("section",{children:[f.jsxs("h3",{children:["Keys (",e.key_groups.length,")"]}),e.key_groups.map(S=>{const T=S.members.map(P=>{var V;return((V=e.attributes.find(F=>F.id===P))==null?void 0:V.name)??"?"}).join(", ");return f.jsxs("div",{className:"key-row",children:[f.jsx("span",{className:"key-badge "+S.type,children:S.type.toUpperCase()}),f.jsx("span",{className:"key-name",children:S.name}),f.jsx("span",{className:"key-cols",children:T})]},S.id)})]}),e.udp&&Object.keys(e.udp).length>0&&f.jsxs("section",{children:[f.jsx("h3",{children:"Properties (UDP)"}),f.jsx("table",{className:"attr-table",children:f.jsx("tbody",{children:Object.entries(e.udp).map(([S,T])=>f.jsxs("tr",{className:"udp-row",children:[f.jsx("td",{className:"udp-key",children:S}),f.jsx("td",{className:"udp-val",children:String(T)})]},S))})})]}),u.length>0&&f.jsxs("section",{children:[f.jsxs("h3",{children:["Relationships (",u.length,")"]}),u.map(S=>{const T=S.from.entity===e.id?S.to.entity:S.from.entity;return f.jsxs("div",{className:"rel-row",children:[f.jsxs("div",{className:"rel-main",children:[f.jsxs("button",{className:"rel-link",onClick:()=>i(T),children:[f.jsx("span",{className:"rel-card",children:Dm(S,e.id)}),d(T)]}),(S.verb_phrase||S.inverse_verb_phrase||!l)&&f.jsxs("div",{className:"verb-phrases",title:"erwin verb phrases (parent → child, and inverse)",children:[f.jsx(Le,{value:S.verb_phrase??"",className:"verb-input",placeholder:l?"":"verb phrase…",readOnly:l,onCommit:P=>r("update_relationship",{id:S.id,verb_phrase:P})}),f.jsx("span",{className:"verb-sep",children:"/"}),f.jsx(Le,{value:S.inverse_verb_phrase??"",className:"verb-input",placeholder:l?"":"inverse…",readOnly:l,onCommit:P=>r("update_relationship",{id:S.id,inverse_verb_phrase:P})})]})]}),!l&&f.jsx("button",{className:"mini-btn danger",title:`delete ${S.name}`,onClick:()=>r("delete_relationship",{id:S.id}),children:"✕"})]},S.id)})]}),f.jsxs("section",{children:[f.jsx("h3",{children:"Identity"}),f.jsx("code",{className:"ulid",title:"Immutable ULID — click to copy",onClick:()=>{var S;return(S=navigator.clipboard)==null?void 0:S.writeText(e.id)},children:e.id}),!l&&f.jsx("div",{style:{marginTop:12},children:f.jsx("button",{className:"mini-btn danger",onClick:()=>{confirm(`Delete entity '${e.name}' (and its relationships)?`)&&r("delete_entity",{id:e.id,cascade:!0}).then(s)},children:"Delete entity…"})})]})]})}function $m({entityId:e,refs:t,caps:n,exec:r}){const s=!n.canEdit,i=t.filter(o=>o.uri);return i.length===0?f.jsx("p",{className:"empty-hint",children:"not aligned to any ontology term"}):f.jsx("div",{className:"ref-list",children:i.map((o,a)=>{const l=o.status==="proposed";return f.jsxs("div",{className:"ref-card"+(l?" proposed":""),children:[f.jsxs("div",{className:"ref-head",children:[f.jsx("code",{className:"ref-uri",title:o.uri??void 0,children:o.uri}),f.jsx("span",{className:"ref-status "+(l?"proposed":"accepted"),children:l?"proposed":"accepted"})]}),f.jsxs("div",{className:"ref-meta",children:[o.predicate&&f.jsx("span",{className:"ref-pill",children:o.predicate}),o.layer&&f.jsx("span",{className:`chip layer-${o.layer}`,children:o.layer}),o.resolved_via&&f.jsxs("span",{className:"ref-via",title:"resolver that found this term",children:["via ",o.resolved_via]}),typeof o.confidence=="number"&&f.jsxs("span",{className:"ref-via",children:["conf ",Math.round(o.confidence*100),"%"]})]}),!s&&f.jsxs("div",{className:"ref-actions",children:[l&&n.canArbitrate&&f.jsx("button",{className:"mini-btn",onClick:()=>r("promote_alignment",{id:e,uri:o.uri}),title:"Accept this proposed alignment (architect action)",children:"Promote"}),f.jsx("button",{className:"mini-btn danger",onClick:()=>r("clear_alignment",{id:e,uri:o.uri}),title:"Remove this alignment",children:"Remove"})]})]},`${o.uri}-${a}`)})})}function Le({value:e,onCommit:t,readOnly:n,multiline:r=!1,placeholder:s="",className:i=""}){const[o,a]=w.useState(e);w.useEffect(()=>a(e),[e]);const l=()=>{o.trim()!==e.trim()&&t(o.trim())};return n?f.jsx("span",{className:i,children:e||s}):r?f.jsx("textarea",{className:`edit-input ${i}`,value:o,placeholder:s,rows:3,onChange:c=>a(c.target.value),onBlur:l}):f.jsx("input",{className:`edit-input ${i}`,value:o,placeholder:s,onChange:c=>a(c.target.value),onBlur:l,onKeyDown:c=>c.key==="Enter"&&c.target.blur()})}function Mm({entity:e,doc:t,readOnly:n,exec:r}){var i,o,a;const s=((o=(i=e.conceptual)==null?void 0:i.subject_area)==null?void 0:o.id)??"";return n?(a=e.conceptual)!=null&&a.subject_area?f.jsx("span",{className:"chip",children:e.conceptual.subject_area.name}):null:f.jsxs("select",{className:"chip-select",value:s,onChange:l=>r("set_subject_area",{id:e.id,subject_area:l.target.value||null}),children:[f.jsx("option",{value:"",children:"no subject area"}),t.subject_areas.map(l=>f.jsx("option",{value:l.id,children:l.name},l.id))]})}const Am=["","scd2","hub","link","satellite","bridge"];function Im({entity:e,readOnly:t,exec:n}){return t?e.pattern?f.jsx("span",{className:"chip pattern",children:e.pattern}):null:f.jsx("select",{className:"chip-select",value:e.pattern??"",onChange:r=>n("set_pattern",{id:e.id,pattern:r.target.value||null}),children:Am.map(r=>f.jsx("option",{value:r,children:r||"no pattern"},r))})}const Rm=["attribute","business_key","measure","surrogate_key"];function Tm({a:e,entity:t,doc:n,readOnly:r,exec:s}){if(r)return f.jsxs("tr",{children:[f.jsxs("td",{className:e.role==="business_key"?"pk":"",children:[e.name,e.physical_name&&e.physical_name!==e.name&&f.jsx("span",{className:"physical-col",title:"Physical column name",children:e.physical_name}),e.enum_values&&e.enum_values.length>0&&f.jsx("span",{className:"enum-badge",title:`Allowed: ${e.enum_values.join(", ")}`,children:"enum"})]}),f.jsx("td",{className:"type",children:e.domain??""}),f.jsx("td",{className:"null",children:e.nullable?"":"NN"})]});const i=o=>s("update_attribute",{entity_id:t.id,attribute_id:e.id,...o});return f.jsxs("tr",{children:[f.jsxs("td",{className:e.role==="business_key"?"pk":"",children:[f.jsx(Le,{value:e.name,readOnly:!1,onCommit:o=>i({name:o})}),(e.physical_name||!1)&&f.jsx(Le,{value:e.physical_name??"",className:"physical-col-input",placeholder:"physical…",readOnly:!1,onCommit:o=>i({physical_name:o})}),e.enum_values&&e.enum_values.length>0&&f.jsx("span",{className:"enum-badge",title:`Allowed: ${e.enum_values.join(", ")}`,children:"enum"})]}),f.jsx("td",{className:"type",children:f.jsx("select",{className:"cell-select",value:e.domain??"string",onChange:o=>i({domain:o.target.value}),children:[...new Set([...jm,...n.domains??[],e.domain??"string"])].sort().map(o=>f.jsx("option",{value:o,children:o},o))})}),f.jsx("td",{children:f.jsx("select",{className:"cell-select",value:e.role,onChange:o=>i({role:o.target.value}),title:"role",children:Rm.map(o=>f.jsx("option",{value:o,children:o==="business_key"?"🔑 key":o==="measure"?"Σ measure":o},o))})}),f.jsx("td",{className:"null",children:f.jsx("input",{type:"checkbox",checked:!e.nullable,title:"not null",onChange:o=>i({nullable:!o.target.checked})})}),f.jsx("td",{children:f.jsx("button",{className:"mini-btn danger",title:"delete attribute",onClick:()=>s("delete_attribute",{entity_id:t.id,attribute_id:e.id}),children:"✕"})})]})}function Om({entity:e,exec:t}){const[n,r]=w.useState(""),s=()=>{n.trim()&&t("add_attribute",{entity_id:e.id,name:n,domain:"string"}).then(()=>r(""))};return f.jsxs("div",{className:"add-attr",children:[f.jsx("input",{className:"edit-input",placeholder:"+ add attribute…",value:n,onChange:i=>r(i.target.value),onKeyDown:i=>i.key==="Enter"&&s()}),n&&f.jsx("button",{className:"mini-btn",onClick:s,children:"Add"})]})}function Dm(e,t){const n=e.from.entity===t;switch(e.cardinality){case"many_to_one":return n?"N:1 →":"1:N ←";case"one_to_many":return n?"1:N →":"N:1 ←";case"one_to_one":return"1:1";default:return"N:M"}}var Lm="\0",nt="\0",Ds="";let Pm=class{constructor(t){le(this,"_isDirected",!0);le(this,"_isMultigraph",!1);le(this,"_isCompound",!1);le(this,"_label");le(this,"_defaultNodeLabelFn",()=>{});le(this,"_defaultEdgeLabelFn",()=>{});le(this,"_nodes",{});le(this,"_in",{});le(this,"_preds",{});le(this,"_out",{});le(this,"_sucs",{});le(this,"_edgeObjs",{});le(this,"_edgeLabels",{});le(this,"_nodeCount",0);le(this,"_edgeCount",0);le(this,"_parent");le(this,"_children");t&&(this._isDirected=Object.hasOwn(t,"directed")?t.directed:!0,this._isMultigraph=Object.hasOwn(t,"multigraph")?t.multigraph:!1,this._isCompound=Object.hasOwn(t,"compound")?t.compound:!1),this._isCompound&&(this._parent={},this._children={},this._children[nt]={})}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return this._defaultNodeLabelFn=t,typeof t!="function"&&(this._defaultNodeLabelFn=()=>t),this}nodeCount(){return this._nodeCount}nodes(){return Object.keys(this._nodes)}sources(){var t=this;return this.nodes().filter(n=>Object.keys(t._in[n]).length===0)}sinks(){var t=this;return this.nodes().filter(n=>Object.keys(t._out[n]).length===0)}setNodes(t,n){var r=arguments,s=this;return t.forEach(function(i){r.length>1?s.setNode(i,n):s.setNode(i)}),this}setNode(t,n){return Object.hasOwn(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=n),this):(this._nodes[t]=arguments.length>1?n:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=nt,this._children[t]={},this._children[nt][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return Object.hasOwn(this._nodes,t)}removeNode(t){var n=this;if(Object.hasOwn(this._nodes,t)){var r=s=>n.removeEdge(n._edgeObjs[s]);delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],this.children(t).forEach(function(s){n.setParent(s)}),delete this._children[t]),Object.keys(this._in[t]).forEach(r),delete this._in[t],delete this._preds[t],Object.keys(this._out[t]).forEach(r),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(n===void 0)n=nt;else{n+="";for(var r=n;r!==void 0;r=this.parent(r))if(r===t)throw new Error("Setting "+n+" as parent of "+t+" would create a cycle");this.setNode(n)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=n,this._children[n][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var n=this._parent[t];if(n!==nt)return n}}children(t=nt){if(this._isCompound){var n=this._children[t];if(n)return Object.keys(n)}else{if(t===nt)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var n=this._preds[t];if(n)return Object.keys(n)}successors(t){var n=this._sucs[t];if(n)return Object.keys(n)}neighbors(t){var n=this.predecessors(t);if(n){const s=new Set(n);for(var r of this.successors(t))s.add(r);return Array.from(s.values())}}isLeaf(t){var n;return this.isDirected()?n=this.successors(t):n=this.neighbors(t),n.length===0}filterNodes(t){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var r=this;Object.entries(this._nodes).forEach(function([o,a]){t(o)&&n.setNode(o,a)}),Object.values(this._edgeObjs).forEach(function(o){n.hasNode(o.v)&&n.hasNode(o.w)&&n.setEdge(o,r.edge(o))});var s={};function i(o){var a=r.parent(o);return a===void 0||n.hasNode(a)?(s[o]=a,a):a in s?s[a]:i(a)}return this._isCompound&&n.nodes().forEach(o=>n.setParent(o,i(o))),n}setDefaultEdgeLabel(t){return this._defaultEdgeLabelFn=t,typeof t!="function"&&(this._defaultEdgeLabelFn=()=>t),this}edgeCount(){return this._edgeCount}edges(){return Object.values(this._edgeObjs)}setPath(t,n){var r=this,s=arguments;return t.reduce(function(i,o){return s.length>1?r.setEdge(i,o,n):r.setEdge(i,o),o}),this}setEdge(){var t,n,r,s,i=!1,o=arguments[0];typeof o=="object"&&o!==null&&"v"in o?(t=o.v,n=o.w,r=o.name,arguments.length===2&&(s=arguments[1],i=!0)):(t=o,n=arguments[1],r=arguments[3],arguments.length>2&&(s=arguments[2],i=!0)),t=""+t,n=""+n,r!==void 0&&(r=""+r);var a=Lt(this._isDirected,t,n,r);if(Object.hasOwn(this._edgeLabels,a))return i&&(this._edgeLabels[a]=s),this;if(r!==void 0&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(n),this._edgeLabels[a]=i?s:this._defaultEdgeLabelFn(t,n,r);var l=zm(this._isDirected,t,n,r);return t=l.v,n=l.w,Object.freeze(l),this._edgeObjs[a]=l,Ls(this._preds[n],t),Ls(this._sucs[t],n),this._in[n][a]=l,this._out[t][a]=l,this._edgeCount++,this}edge(t,n,r){var s=arguments.length===1?qn(this._isDirected,arguments[0]):Lt(this._isDirected,t,n,r);return this._edgeLabels[s]}edgeAsObj(){const t=this.edge(...arguments);return typeof t!="object"?{label:t}:t}hasEdge(t,n,r){var s=arguments.length===1?qn(this._isDirected,arguments[0]):Lt(this._isDirected,t,n,r);return Object.hasOwn(this._edgeLabels,s)}removeEdge(t,n,r){var s=arguments.length===1?qn(this._isDirected,arguments[0]):Lt(this._isDirected,t,n,r),i=this._edgeObjs[s];return i&&(t=i.v,n=i.w,delete this._edgeLabels[s],delete this._edgeObjs[s],Ps(this._preds[n],t),Ps(this._sucs[t],n),delete this._in[n][s],delete this._out[t][s],this._edgeCount--),this}inEdges(t,n){var r=this._in[t];if(r){var s=Object.values(r);return n?s.filter(i=>i.v===n):s}}outEdges(t,n){var r=this._out[t];if(r){var s=Object.values(r);return n?s.filter(i=>i.w===n):s}}nodeEdges(t,n){var r=this.inEdges(t,n);if(r)return r.concat(this.outEdges(t,n))}};function Ls(e,t){e[t]?e[t]++:e[t]=1}function Ps(e,t){--e[t]||delete e[t]}function Lt(e,t,n,r){var s=""+t,i=""+n;if(!e&&s>i){var o=s;s=i,i=o}return s+Ds+i+Ds+(r===void 0?Lm:r)}function zm(e,t,n,r){var s=""+t,i=""+n;if(!e&&s>i){var o=s;s=i,i=o}var a={v:s,w:i};return r&&(a.name=r),a}function qn(e,t){return Lt(e,t.v,t.w,t.name)}var Pr=Pm,Hm="2.2.4",Fm={Graph:Pr,version:Hm},Vm=Pr,Bm={write:Gm,read:Um};function Gm(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:Ym(e),edges:Wm(e)};return e.graph()!==void 0&&(t.value=structuredClone(e.graph())),t}function Ym(e){return e.nodes().map(function(t){var n=e.node(t),r=e.parent(t),s={v:t};return n!==void 0&&(s.value=n),r!==void 0&&(s.parent=r),s})}function Wm(e){return e.edges().map(function(t){var n=e.edge(t),r={v:t.v,w:t.w};return t.name!==void 0&&(r.name=t.name),n!==void 0&&(r.value=n),r})}function Um(e){var t=new Vm(e.options).setGraph(e.value);return e.nodes.forEach(function(n){t.setNode(n.v,n.value),n.parent&&t.setParent(n.v,n.parent)}),e.edges.forEach(function(n){t.setEdge({v:n.v,w:n.w,name:n.name},n.value)}),t}var qm=Xm;function Xm(e){var t={},n=[],r;function s(i){Object.hasOwn(t,i)||(t[i]=!0,r.push(i),e.successors(i).forEach(s),e.predecessors(i).forEach(s))}return e.nodes().forEach(function(i){r=[],s(i),r.length&&n.push(r)}),n}let Km=class{constructor(){le(this,"_arr",[]);le(this,"_keyIndices",{})}size(){return this._arr.length}keys(){return this._arr.map(function(t){return t.key})}has(t){return Object.hasOwn(this._keyIndices,t)}priority(t){var n=this._keyIndices[t];if(n!==void 0)return this._arr[n].priority}min(){if(this.size()===0)throw new Error("Queue underflow");return this._arr[0].key}add(t,n){var r=this._keyIndices;if(t=String(t),!Object.hasOwn(r,t)){var s=this._arr,i=s.length;return r[t]=i,s.push({key:t,priority:n}),this._decrease(i),!0}return!1}removeMin(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key}decrease(t,n){var r=this._keyIndices[t];if(n>this._arr[r].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[r].priority+" New: "+n);this._arr[r].priority=n,this._decrease(r)}_heapify(t){var n=this._arr,r=2*t,s=r+1,i=t;r>1,!(n[s].priority1;function Jm(e,t,n,r){return ep(e,String(t),n||Qm,r||function(s){return e.outEdges(s)})}function ep(e,t,n,r){var s={},i=new Zm,o,a,l=function(c){var u=c.v!==o?c.v:c.w,d=s[u],m=n(c),h=a.distance+m;if(m<0)throw new Error("dijkstra does not allow negative edge weights. Bad edge: "+c+" Weight: "+m);h0&&(o=i.removeMin(),a=s[o],a.distance!==Number.POSITIVE_INFINITY);)r(o).forEach(l);return s}var tp=Vo,np=rp;function rp(e,t,n){return e.nodes().reduce(function(r,s){return r[s]=tp(e,s,t,n),r},{})}var Bo=sp;function sp(e){var t=0,n=[],r={},s=[];function i(o){var a=r[o]={onStack:!0,lowlink:t,index:t++};if(n.push(o),e.successors(o).forEach(function(u){Object.hasOwn(r,u)?r[u].onStack&&(a.lowlink=Math.min(a.lowlink,r[u].index)):(i(u),a.lowlink=Math.min(a.lowlink,r[u].lowlink))}),a.lowlink===a.index){var l=[],c;do c=n.pop(),r[c].onStack=!1,l.push(c);while(o!==c);s.push(l)}}return e.nodes().forEach(function(o){Object.hasOwn(r,o)||i(o)}),s}var ip=Bo,op=ap;function ap(e){return ip(e).filter(function(t){return t.length>1||t.length===1&&e.hasEdge(t[0],t[0])})}var lp=up,cp=()=>1;function up(e,t,n){return dp(e,t||cp,n||function(r){return e.outEdges(r)})}function dp(e,t,n){var r={},s=e.nodes();return s.forEach(function(i){r[i]={},r[i][i]={distance:0},s.forEach(function(o){i!==o&&(r[i][o]={distance:Number.POSITIVE_INFINITY})}),n(i).forEach(function(o){var a=o.v===i?o.w:o.v,l=t(o);r[i][a]={distance:l,predecessor:i}})}),s.forEach(function(i){var o=r[i];s.forEach(function(a){var l=r[a];s.forEach(function(c){var u=l[i],d=o[c],m=l[c],h=u.distance+d.distance;he.successors(a):a=>e.neighbors(a),s=n==="post"?pp:gp,i=[],o={};return t.forEach(a=>{if(!e.hasNode(a))throw new Error("Graph does not have node: "+a);s(a,r,o,i)}),i}function pp(e,t,n,r){for(var s=[[e,!1]];s.length>0;){var i=s.pop();i[1]?r.push(i[0]):Object.hasOwn(n,i[0])||(n[i[0]]=!0,s.push([i[0],!0]),Uo(t(i[0]),o=>s.push([o,!1])))}}function gp(e,t,n,r){for(var s=[e];s.length>0;){var i=s.pop();Object.hasOwn(n,i)||(n[i]=!0,r.push(i),Uo(t(i),o=>s.push(o)))}}function Uo(e,t){for(var n=e.length;n--;)t(e[n],n,e);return e}var yp=Wo,xp=wp;function wp(e,t){return yp(e,t,"post")}var vp=Wo,bp=_p;function _p(e,t){return vp(e,t,"pre")}var Ep=Pr,Np=Fo,Sp=kp;function kp(e,t){var n=new Ep,r={},s=new Np,i;function o(l){var c=l.v===i?l.w:l.v,u=s.priority(c);if(u!==void 0){var d=t(l);d0;){if(i=s.removeMin(),Object.hasOwn(r,i))n.setEdge(i,r[i]);else{if(a)throw new Error("Input graph is not connected: "+e);a=!0}e.nodeEdges(i).forEach(o)}return n}var jp={components:qm,dijkstra:Vo,dijkstraAll:np,findCycles:op,floydWarshall:lp,isAcyclic:fp,postorder:xp,preorder:bp,prim:Sp,tarjan:Bo,topsort:Yo},Hs=Fm,Me={Graph:Hs.Graph,json:Bm,alg:jp,version:Hs.version};let Cp=class{constructor(){let t={};t._next=t._prev=t,this._sentinel=t}dequeue(){let t=this._sentinel,n=t._prev;if(n!==t)return Fs(n),n}enqueue(t){let n=this._sentinel;t._prev&&t._next&&Fs(t),t._next=n._next,n._next._prev=t,n._next=t,t._prev=n}toString(){let t=[],n=this._sentinel,r=n._prev;for(;r!==n;)t.push(JSON.stringify(r,$p)),r=r._prev;return"["+t.join(", ")+"]"}};function Fs(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function $p(e,t){if(e!=="_next"&&e!=="_prev")return t}var Mp=Cp;let Ap=Me.Graph,Ip=Mp;var Rp=Op;let Tp=()=>1;function Op(e,t){if(e.nodeCount()<=1)return[];let n=Lp(e,t||Tp);return Dp(n.graph,n.buckets,n.zeroIdx).flatMap(s=>e.outEdges(s.v,s.w))}function Dp(e,t,n){let r=[],s=t[t.length-1],i=t[0],o;for(;e.nodeCount();){for(;o=i.dequeue();)Xn(e,t,n,o);for(;o=s.dequeue();)Xn(e,t,n,o);if(e.nodeCount()){for(let a=t.length-2;a>0;--a)if(o=t[a].dequeue(),o){r=r.concat(Xn(e,t,n,o,!0));break}}}return r}function Xn(e,t,n,r,s){let i=s?[]:void 0;return e.inEdges(r.v).forEach(o=>{let a=e.edge(o),l=e.node(o.v);s&&i.push({v:o.v,w:o.w}),l.out-=a,gr(t,n,l)}),e.outEdges(r.v).forEach(o=>{let a=e.edge(o),l=o.w,c=e.node(l);c.in-=a,gr(t,n,c)}),e.removeNode(r.v),i}function Lp(e,t){let n=new Ap,r=0,s=0;e.nodes().forEach(a=>{n.setNode(a,{v:a,in:0,out:0})}),e.edges().forEach(a=>{let l=n.edge(a.v,a.w)||0,c=t(a),u=l+c;n.setEdge(a.v,a.w,u),s=Math.max(s,n.node(a.v).out+=c),r=Math.max(r,n.node(a.w).in+=c)});let i=Pp(s+r+3).map(()=>new Ip),o=r+1;return n.nodes().forEach(a=>{gr(i,o,n.node(a))}),{graph:n,buckets:i,zeroIdx:o}}function gr(e,t,n){n.out?n.in?e[n.out-n.in+t].enqueue(n):e[e.length-1].enqueue(n):e[0].enqueue(n)}function Pp(e){const t=[];for(let n=0;nt.setNode(n,e.node(n))),e.edges().forEach(n=>{let r=t.edge(n.v,n.w)||{weight:0,minlen:1},s=e.edge(n);t.setEdge(n.v,n.w,{weight:r.weight+s.weight,minlen:Math.max(r.minlen,s.minlen)})}),t}function Hp(e){let t=new qo({multigraph:e.isMultigraph()}).setGraph(e.graph());return e.nodes().forEach(n=>{e.children(n).length||t.setNode(n,e.node(n))}),e.edges().forEach(n=>{t.setEdge(n,e.edge(n))}),t}function Fp(e){let t=e.nodes().map(n=>{let r={};return e.outEdges(n).forEach(s=>{r[s.w]=(r[s.w]||0)+e.edge(s).weight}),r});return zr(e.nodes(),t)}function Vp(e){let t=e.nodes().map(n=>{let r={};return e.inEdges(n).forEach(s=>{r[s.v]=(r[s.v]||0)+e.edge(s).weight}),r});return zr(e.nodes(),t)}function Bp(e,t){let n=e.x,r=e.y,s=t.x-n,i=t.y-r,o=e.width/2,a=e.height/2;if(!s&&!i)throw new Error("Not possible to find intersection inside of the rectangle");let l,c;return Math.abs(i)*o>Math.abs(s)*a?(i<0&&(a=-a),l=a*s/i,c=a):(s<0&&(o=-o),l=o,c=o*i/s),{x:n+l,y:r+c}}function Gp(e){let t=Jo(Zo(e)+1).map(()=>[]);return e.nodes().forEach(n=>{let r=e.node(n),s=r.rank;s!==void 0&&(t[s][r.order]=n)}),t}function Yp(e){let t=e.nodes().map(r=>{let s=e.node(r).rank;return s===void 0?Number.MAX_VALUE:s}),n=In(Math.min,t);e.nodes().forEach(r=>{let s=e.node(r);Object.hasOwn(s,"rank")&&(s.rank-=n)})}function Wp(e){let t=e.nodes().map(o=>e.node(o).rank),n=In(Math.min,t),r=[];e.nodes().forEach(o=>{let a=e.node(o).rank-n;r[a]||(r[a]=[]),r[a].push(o)});let s=0,i=e.graph().nodeRankFactor;Array.from(r).forEach((o,a)=>{o===void 0&&a%i!==0?--s:o!==void 0&&s&&o.forEach(l=>e.node(l).rank+=s)})}function Up(e,t,n,r){let s={width:0,height:0};return arguments.length>=4&&(s.rank=n,s.order=r),Xo(e,"border",s,t)}function qp(e,t=Ko){const n=[];for(let r=0;rKo){const n=qp(t);return e.apply(null,n.map(r=>e.apply(null,r)))}else return e.apply(null,t)}function Zo(e){const n=e.nodes().map(r=>{let s=e.node(r).rank;return s===void 0?Number.MIN_VALUE:s});return In(Math.max,n)}function Xp(e,t){let n={lhs:[],rhs:[]};return e.forEach(r=>{t(r)?n.lhs.push(r):n.rhs.push(r)}),n}function Kp(e,t){let n=Date.now();try{return t()}finally{console.log(e+" time: "+(Date.now()-n)+"ms")}}function Zp(e,t){return t()}let Qp=0;function Qo(e){var t=++Qp;return e+(""+t)}function Jo(e,t,n=1){t==null&&(t=e,e=0);let r=i=>itr[t]),Object.entries(e).reduce((r,[s,i])=>(r[s]=n(i,s),r),{})}function zr(e,t){return e.reduce((n,r,s)=>(n[r]=t[s],n),{})}let tg=Rp,ng=de.uniqueId;var rg={run:sg,undo:og};function sg(e){(e.graph().acyclicer==="greedy"?tg(e,n(e)):ig(e)).forEach(r=>{let s=e.edge(r);e.removeEdge(r),s.forwardName=r.name,s.reversed=!0,e.setEdge(r.w,r.v,s,ng("rev"))});function n(r){return s=>r.edge(s).weight}}function ig(e){let t=[],n={},r={};function s(i){Object.hasOwn(r,i)||(r[i]=!0,n[i]=!0,e.outEdges(i).forEach(o=>{Object.hasOwn(n,o.w)?t.push(o):s(o.w)}),delete n[i])}return e.nodes().forEach(s),t}function og(e){e.edges().forEach(t=>{let n=e.edge(t);if(n.reversed){e.removeEdge(t);let r=n.forwardName;delete n.reversed,delete n.forwardName,e.setEdge(t.w,t.v,n,r)}})}let ag=de;var lg={run:cg,undo:dg};function cg(e){e.graph().dummyChains=[],e.edges().forEach(t=>ug(e,t))}function ug(e,t){let n=t.v,r=e.node(n).rank,s=t.w,i=e.node(s).rank,o=t.name,a=e.edge(t),l=a.labelRank;if(i===r+1)return;e.removeEdge(t);let c,u,d;for(d=0,++r;r{let n=e.node(t),r=n.edgeLabel,s;for(e.setEdge(n.edgeObj,r);n.dummy;)s=e.successors(t)[0],e.removeNode(t),r.points.push({x:n.x,y:n.y}),n.dummy==="edge-label"&&(r.x=n.x,r.y=n.y,r.width=n.width,r.height=n.height),t=s,n=e.node(t)})}const{applyWithChunking:fg}=de;var Rn={longestPath:hg,slack:mg};function hg(e){var t={};function n(r){var s=e.node(r);if(Object.hasOwn(t,r))return s.rank;t[r]=!0;let i=e.outEdges(r).map(a=>a==null?Number.POSITIVE_INFINITY:n(a.w)-e.edge(a).minlen);var o=fg(Math.min,i);return o===Number.POSITIVE_INFINITY&&(o=0),s.rank=o}e.sources().forEach(n)}function mg(e,t){return e.node(t.w).rank-e.node(t.v).rank-e.edge(t).minlen}var pg=Me.Graph,_n=Rn.slack,ea=gg;function gg(e){var t=new pg({directed:!1}),n=e.nodes()[0],r=e.nodeCount();t.setNode(n,{});for(var s,i;yg(t,e){var i=s.v,o=r===i?s.w:i;!e.hasNode(o)&&!_n(t,s)&&(e.setNode(o,{}),e.setEdge(r,o,{}),n(o))})}return e.nodes().forEach(n),e.nodeCount()}function xg(e,t){return t.edges().reduce((r,s)=>{let i=Number.POSITIVE_INFINITY;return e.hasNode(s.v)!==e.hasNode(s.w)&&(i=_n(t,s)),it.node(r).rank+=n)}var vg=ea,Vs=Rn.slack,bg=Rn.longestPath,_g=Me.alg.preorder,Eg=Me.alg.postorder,Ng=de.simplify,Sg=ut;ut.initLowLimValues=Fr;ut.initCutValues=Hr;ut.calcCutValue=ta;ut.leaveEdge=ra;ut.enterEdge=sa;ut.exchangeEdges=ia;function ut(e){e=Ng(e),bg(e);var t=vg(e);Fr(t),Hr(t,e);for(var n,r;n=ra(t);)r=sa(t,e,n),ia(t,e,n,r)}function Hr(e,t){var n=Eg(e,e.nodes());n=n.slice(0,n.length-1),n.forEach(r=>kg(e,t,r))}function kg(e,t,n){var r=e.node(n),s=r.parent;e.edge(n,s).cutvalue=ta(e,t,n)}function ta(e,t,n){var r=e.node(n),s=r.parent,i=!0,o=t.edge(n,s),a=0;return o||(i=!1,o=t.edge(s,n)),a=o.weight,t.nodeEdges(n).forEach(l=>{var c=l.v===n,u=c?l.w:l.v;if(u!==s){var d=c===i,m=t.edge(l).weight;if(a+=d?m:-m,Cg(e,n,u)){var h=e.edge(n,u).cutvalue;a+=d?-h:h}}}),a}function Fr(e,t){arguments.length<2&&(t=e.nodes()[0]),na(e,{},1,t)}function na(e,t,n,r,s){var i=n,o=e.node(r);return t[r]=!0,e.neighbors(r).forEach(a=>{Object.hasOwn(t,a)||(n=na(e,t,n,a,r))}),o.low=i,o.lim=n++,s?o.parent=s:delete o.parent,n}function ra(e){return e.edges().find(t=>e.edge(t).cutvalue<0)}function sa(e,t,n){var r=n.v,s=n.w;t.hasEdge(r,s)||(r=n.w,s=n.v);var i=e.node(r),o=e.node(s),a=i,l=!1;i.lim>o.lim&&(a=o,l=!0);var c=t.edges().filter(u=>l===Bs(e,e.node(u.v),a)&&l!==Bs(e,e.node(u.w),a));return c.reduce((u,d)=>Vs(t,d)!t.node(s).parent),r=_g(e,n);r=r.slice(1),r.forEach(s=>{var i=e.node(s).parent,o=t.edge(s,i),a=!1;o||(o=t.edge(i,s),a=!0),t.node(s).rank=t.node(i).rank+(a?o.minlen:-o.minlen)})}function Cg(e,t,n){return e.hasEdge(t,n)}function Bs(e,t,n){return n.low<=t.lim&&t.lim<=n.lim}var $g=Rn,oa=$g.longestPath,Mg=ea,Ag=Sg,Ig=Rg;function Rg(e){var t=e.graph().ranker;if(t instanceof Function)return t(e);switch(e.graph().ranker){case"network-simplex":Gs(e);break;case"tight-tree":Og(e);break;case"longest-path":Tg(e);break;case"none":break;default:Gs(e)}}var Tg=oa;function Og(e){oa(e),Mg(e)}function Gs(e){Ag(e)}var Dg=Lg;function Lg(e){let t=zg(e);e.graph().dummyChains.forEach(n=>{let r=e.node(n),s=r.edgeObj,i=Pg(e,t,s.v,s.w),o=i.path,a=i.lca,l=0,c=o[l],u=!0;for(;n!==s.w;){if(r=e.node(n),u){for(;(c=o[l])!==a&&e.node(c).maxRanko||a>t[l].lim));for(c=l,l=r;(l=e.parent(l))!==c;)i.push(l);return{path:s.concat(i.reverse()),lca:c}}function zg(e){let t={},n=0;function r(s){let i=n;e.children(s).forEach(r),t[s]={low:i,lim:n++}}return e.children().forEach(r),t}let En=de;var Hg={run:Fg,cleanup:Gg};function Fg(e){let t=En.addDummyNode(e,"root",{},"_root"),n=Vg(e),r=Object.values(n),s=En.applyWithChunking(Math.max,r)-1,i=2*s+1;e.graph().nestingRoot=t,e.edges().forEach(a=>e.edge(a).minlen*=i);let o=Bg(e)+1;e.children().forEach(a=>aa(e,t,i,o,s,n,a)),e.graph().nodeRankFactor=i}function aa(e,t,n,r,s,i,o){let a=e.children(o);if(!a.length){o!==t&&e.setEdge(t,o,{weight:0,minlen:n});return}let l=En.addBorderNode(e,"_bt"),c=En.addBorderNode(e,"_bb"),u=e.node(o);e.setParent(l,o),u.borderTop=l,e.setParent(c,o),u.borderBottom=c,a.forEach(d=>{aa(e,t,n,r,s,i,d);let m=e.node(d),h=m.borderTop?m.borderTop:d,y=m.borderBottom?m.borderBottom:d,g=m.borderTop?r:2*r,b=h!==y?1:s-i[o]+1;e.setEdge(l,h,{weight:g,minlen:b,nestingEdge:!0}),e.setEdge(y,c,{weight:g,minlen:b,nestingEdge:!0})}),e.parent(o)||e.setEdge(t,l,{weight:0,minlen:s+i[o]})}function Vg(e){var t={};function n(r,s){var i=e.children(r);i&&i.length&&i.forEach(o=>n(o,s+1)),t[r]=s}return e.children().forEach(r=>n(r,1)),t}function Bg(e){return e.edges().reduce((t,n)=>t+e.edge(n).weight,0)}function Gg(e){var t=e.graph();e.removeNode(t.nestingRoot),delete t.nestingRoot,e.edges().forEach(n=>{var r=e.edge(n);r.nestingEdge&&e.removeEdge(n)})}let Yg=de;var Wg=Ug;function Ug(e){function t(n){let r=e.children(n),s=e.node(n);if(r.length&&r.forEach(t),Object.hasOwn(s,"minRank")){s.borderLeft=[],s.borderRight=[];for(let i=s.minRank,o=s.maxRank+1;iWs(e.node(t))),e.edges().forEach(t=>Ws(e.edge(t)))}function Ws(e){let t=e.width;e.width=e.height,e.height=t}function Zg(e){e.nodes().forEach(t=>Kn(e.node(t))),e.edges().forEach(t=>{let n=e.edge(t);n.points.forEach(Kn),Object.hasOwn(n,"y")&&Kn(n)})}function Kn(e){e.y=-e.y}function Qg(e){e.nodes().forEach(t=>Zn(e.node(t))),e.edges().forEach(t=>{let n=e.edge(t);n.points.forEach(Zn),Object.hasOwn(n,"x")&&Zn(n)})}function Zn(e){let t=e.x;e.x=e.y,e.y=t}let Us=de;var Jg=e0;function e0(e){let t={},n=e.nodes().filter(l=>!e.children(l).length),r=n.map(l=>e.node(l).rank),s=Us.applyWithChunking(Math.max,r),i=Us.range(s+1).map(()=>[]);function o(l){if(t[l])return;t[l]=!0;let c=e.node(l);i[c.rank].push(l),e.successors(l).forEach(o)}return n.sort((l,c)=>e.node(l).rank-e.node(c).rank).forEach(o),i}let t0=de.zipObject;var n0=r0;function r0(e,t){let n=0;for(let r=1;ru)),s=t.flatMap(c=>e.outEdges(c).map(u=>({pos:r[u.w],weight:e.edge(u).weight})).sort((u,d)=>u.pos-d.pos)),i=1;for(;i{let u=c.pos+i;a[u]+=c.weight;let d=0;for(;u>0;)u%2&&(d+=a[u+1]),u=u-1>>1,a[u]+=c.weight;l+=c.weight*d}),l}var i0=o0;function o0(e,t=[]){return t.map(n=>{let r=e.inEdges(n);if(r.length){let s=r.reduce((i,o)=>{let a=e.edge(o),l=e.node(o.v);return{sum:i.sum+a.weight*l.order,weight:i.weight+a.weight}},{sum:0,weight:0});return{v:n,barycenter:s.sum/s.weight,weight:s.weight}}else return{v:n}})}let a0=de;var l0=c0;function c0(e,t){let n={};e.forEach((s,i)=>{let o=n[s.v]={indegree:0,in:[],out:[],vs:[s.v],i};s.barycenter!==void 0&&(o.barycenter=s.barycenter,o.weight=s.weight)}),t.edges().forEach(s=>{let i=n[s.v],o=n[s.w];i!==void 0&&o!==void 0&&(o.indegree++,i.out.push(n[s.w]))});let r=Object.values(n).filter(s=>!s.indegree);return u0(r)}function u0(e){let t=[];function n(s){return i=>{i.merged||(i.barycenter===void 0||s.barycenter===void 0||i.barycenter>=s.barycenter)&&d0(s,i)}}function r(s){return i=>{i.in.push(s),--i.indegree===0&&e.push(i)}}for(;e.length;){let s=e.pop();t.push(s),s.in.reverse().forEach(n(s)),s.out.forEach(r(s))}return t.filter(s=>!s.merged).map(s=>a0.pick(s,["vs","i","barycenter","weight"]))}function d0(e,t){let n=0,r=0;e.weight&&(n+=e.barycenter*e.weight,r+=e.weight),t.weight&&(n+=t.barycenter*t.weight,r+=t.weight),e.vs=t.vs.concat(e.vs),e.barycenter=n/r,e.weight=r,e.i=Math.min(t.i,e.i),t.merged=!0}let f0=de;var h0=m0;function m0(e,t){let n=f0.partition(e,u=>Object.hasOwn(u,"barycenter")),r=n.lhs,s=n.rhs.sort((u,d)=>d.i-u.i),i=[],o=0,a=0,l=0;r.sort(p0(!!t)),l=qs(i,s,l),r.forEach(u=>{l+=u.vs.length,i.push(u.vs),o+=u.barycenter*u.weight,a+=u.weight,l=qs(i,s,l)});let c={vs:i.flat(!0)};return a&&(c.barycenter=o/a,c.weight=a),c}function qs(e,t,n){let r;for(;t.length&&(r=t[t.length-1]).i<=n;)t.pop(),e.push(r.vs),n++;return n}function p0(e){return(t,n)=>t.barycentern.barycenter?1:e?n.i-t.i:t.i-n.i}let g0=i0,y0=l0,x0=h0;var w0=ca;function ca(e,t,n,r){let s=e.children(t),i=e.node(t),o=i?i.borderLeft:void 0,a=i?i.borderRight:void 0,l={};o&&(s=s.filter(m=>m!==o&&m!==a));let c=g0(e,s);c.forEach(m=>{if(e.children(m.v).length){let h=ca(e,m.v,n,r);l[m.v]=h,Object.hasOwn(h,"barycenter")&&b0(m,h)}});let u=y0(c,n);v0(u,l);let d=x0(u,r);if(o&&(d.vs=[o,d.vs,a].flat(!0),e.predecessors(o).length)){let m=e.node(e.predecessors(o)[0]),h=e.node(e.predecessors(a)[0]);Object.hasOwn(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+m.order+h.order)/(d.weight+2),d.weight+=2}return d}function v0(e,t){e.forEach(n=>{n.vs=n.vs.flatMap(r=>t[r]?t[r].vs:r)})}function b0(e,t){e.barycenter!==void 0?(e.barycenter=(e.barycenter*e.weight+t.barycenter*t.weight)/(e.weight+t.weight),e.weight+=t.weight):(e.barycenter=t.barycenter,e.weight=t.weight)}let _0=Me.Graph,E0=de;var N0=S0;function S0(e,t,n,r){r||(r=e.nodes());let s=k0(e),i=new _0({compound:!0}).setGraph({root:s}).setDefaultNodeLabel(o=>e.node(o));return r.forEach(o=>{let a=e.node(o),l=e.parent(o);(a.rank===t||a.minRank<=t&&t<=a.maxRank)&&(i.setNode(o),i.setParent(o,l||s),e[n](o).forEach(c=>{let u=c.v===o?c.w:c.v,d=i.edge(u,o),m=d!==void 0?d.weight:0;i.setEdge(u,o,{weight:e.edge(c).weight+m})}),Object.hasOwn(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[t],borderRight:a.borderRight[t]}))}),i}function k0(e){for(var t;e.hasNode(t=E0.uniqueId("_root")););return t}var j0=C0;function C0(e,t,n){let r={},s;n.forEach(i=>{let o=e.parent(i),a,l;for(;o;){if(a=e.parent(o),a?(l=r[a],r[a]=o):(l=s,s=o),l&&l!==o){t.setEdge(l,o);return}o=a}})}let $0=Jg,M0=n0,A0=w0,I0=N0,R0=j0,T0=Me.Graph,an=de;var O0=ua;function ua(e,t){if(t&&typeof t.customOrder=="function"){t.customOrder(e,ua);return}let n=an.maxRank(e),r=Xs(e,an.range(1,n+1),"inEdges"),s=Xs(e,an.range(n-1,-1,-1),"outEdges"),i=$0(e);if(Ks(e,i),t&&t.disableOptimalOrderHeuristic)return;let o=Number.POSITIVE_INFINITY,a;for(let l=0,c=0;c<4;++l,++c){D0(l%2?r:s,l%4>=2),i=an.buildLayerMatrix(e);let u=M0(e,i);u{r.has(i)||r.set(i,[]),r.get(i).push(o)};for(const i of e.nodes()){const o=e.node(i);if(typeof o.rank=="number"&&s(o.rank,i),typeof o.minRank=="number"&&typeof o.maxRank=="number")for(let a=o.minRank;a<=o.maxRank;a++)a!==o.rank&&s(a,i)}return t.map(function(i){return I0(e,i,n,r.get(i)||[])})}function D0(e,t){let n=new T0;e.forEach(function(r){let s=r.graph().root,i=A0(r,s,n,t);i.vs.forEach((o,a)=>r.node(o).order=a),R0(r,n,i.vs)})}function Ks(e,t){Object.values(t).forEach(n=>n.forEach((r,s)=>e.node(r).order=s))}let L0=Me.Graph,Pe=de;var P0={positionX:X0};function z0(e,t){let n={};function r(s,i){let o=0,a=0,l=s.length,c=i[i.length-1];return i.forEach((u,d)=>{let m=F0(e,u),h=m?e.node(m).order:l;(m||u===c)&&(i.slice(a,d+1).forEach(y=>{e.predecessors(y).forEach(g=>{let b=e.node(g),x=b.order;(x{u=i[d],e.node(u).dummy&&e.predecessors(u).forEach(m=>{let h=e.node(m);h.dummy&&(h.orderc)&&da(n,m,u)})})}function s(i,o){let a=-1,l,c=0;return o.forEach((u,d)=>{if(e.node(u).dummy==="border"){let m=e.predecessors(u);m.length&&(l=e.node(m[0]).order,r(o,c,d,a,l),c=d,a=l)}r(o,c,o.length,l,i.length)}),o}return t.length&&t.reduce(s),n}function F0(e,t){if(e.node(t).dummy)return e.predecessors(t).find(n=>e.node(n).dummy)}function da(e,t,n){if(t>n){let s=t;t=n,n=s}let r=e[t];r||(e[t]=r={}),r[n]=!0}function V0(e,t,n){if(t>n){let r=t;t=n,n=r}return!!e[t]&&Object.hasOwn(e[t],n)}function B0(e,t,n,r){let s={},i={},o={};return t.forEach(a=>{a.forEach((l,c)=>{s[l]=l,i[l]=l,o[l]=c})}),t.forEach(a=>{let l=-1;a.forEach(c=>{let u=r(c);if(u.length){u=u.sort((m,h)=>o[m]-o[h]);let d=(u.length-1)/2;for(let m=Math.floor(d),h=Math.ceil(d);m<=h;++m){let y=u[m];i[c]===c&&lMath.max(m,i[h.v]+o.edge(h)),0)}function u(d){let m=o.outEdges(d).reduce((y,g)=>Math.min(y,i[g.w]-o.edge(g)),Number.POSITIVE_INFINITY),h=e.node(d);m!==Number.POSITIVE_INFINITY&&h.borderType!==a&&(i[d]=Math.max(i[d],m))}return l(c,o.predecessors.bind(o)),l(u,o.successors.bind(o)),Object.keys(r).forEach(d=>i[d]=i[n[d]]),i}function Y0(e,t,n,r){let s=new L0,i=e.graph(),o=K0(i.nodesep,i.edgesep,r);return t.forEach(a=>{let l;a.forEach(c=>{let u=n[c];if(s.setNode(u),l){var d=n[l],m=s.edge(d,u);s.setEdge(d,u,Math.max(o(e,c,l),m||0))}l=c})}),s}function W0(e,t){return Object.values(t).reduce((n,r)=>{let s=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;Object.entries(r).forEach(([a,l])=>{let c=Z0(e,a)/2;s=Math.max(l+c,s),i=Math.min(l-c,i)});const o=s-i;return o{["l","r"].forEach(o=>{let a=i+o,l=e[a];if(l===t)return;let c=Object.values(l),u=r-Pe.applyWithChunking(Math.min,c);o!=="l"&&(u=s-Pe.applyWithChunking(Math.max,c)),u&&(e[a]=Pe.mapValues(l,d=>d+u))})})}function q0(e,t){return Pe.mapValues(e.ul,(n,r)=>{if(t)return e[t.toLowerCase()][r];{let s=Object.values(e).map(i=>i[r]).sort((i,o)=>i-o);return(s[1]+s[2])/2}})}function X0(e){let t=Pe.buildLayerMatrix(e),n=Object.assign(z0(e,t),H0(e,t)),r={},s;["u","d"].forEach(o=>{s=o==="u"?t:Object.values(t).reverse(),["l","r"].forEach(a=>{a==="r"&&(s=s.map(d=>Object.values(d).reverse()));let l=(o==="u"?e.predecessors:e.successors).bind(e),c=B0(e,s,n,l),u=G0(e,s,c.root,c.align,a==="r");a==="r"&&(u=Pe.mapValues(u,d=>-d)),r[o+a]=u})});let i=W0(e,r);return U0(r,i),q0(r,e.graph().align)}function K0(e,t,n){return(r,s,i)=>{let o=r.node(s),a=r.node(i),l=0,c;if(l+=o.width/2,Object.hasOwn(o,"labelpos"))switch(o.labelpos.toLowerCase()){case"l":c=-o.width/2;break;case"r":c=o.width/2;break}if(c&&(l+=n?c:-c),c=0,l+=(o.dummy?t:e)/2,l+=(a.dummy?t:e)/2,l+=a.width/2,Object.hasOwn(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":c=a.width/2;break;case"r":c=-a.width/2;break}return c&&(l+=n?c:-c),c=0,l}}function Z0(e,t){return e.node(t).width}let fa=de,Q0=P0.positionX;var J0=ey;function ey(e){e=fa.asNonCompoundGraph(e),ty(e),Object.entries(Q0(e)).forEach(([t,n])=>e.node(t).x=n)}function ty(e){let t=fa.buildLayerMatrix(e),n=e.graph().ranksep,r=0;t.forEach(s=>{const i=s.reduce((o,a)=>{const l=e.node(a).height;return o>l?o:l},0);s.forEach(o=>e.node(o).y=r+i/2),r+=i+n})}let Zs=rg,Qs=lg,ny=Ig,ry=de.normalizeRanks,sy=Dg,iy=de.removeEmptyRanks,Js=Hg,oy=Wg,ei=qg,ay=O0,ly=J0,Se=de,cy=Me.Graph;var uy=dy;function dy(e,t){let n=t&&t.debugTiming?Se.time:Se.notime;n("layout",()=>{let r=n(" buildLayoutGraph",()=>by(e));n(" runLayout",()=>fy(r,n,t)),n(" updateInputGraph",()=>hy(e,r))})}function fy(e,t,n){t(" makeSpaceForEdgeLabels",()=>_y(e)),t(" removeSelfEdges",()=>Ay(e)),t(" acyclic",()=>Zs.run(e)),t(" nestingGraph.run",()=>Js.run(e)),t(" rank",()=>ny(Se.asNonCompoundGraph(e))),t(" injectEdgeLabelProxies",()=>Ey(e)),t(" removeEmptyRanks",()=>iy(e)),t(" nestingGraph.cleanup",()=>Js.cleanup(e)),t(" normalizeRanks",()=>ry(e)),t(" assignRankMinMax",()=>Ny(e)),t(" removeEdgeLabelProxies",()=>Sy(e)),t(" normalize.run",()=>Qs.run(e)),t(" parentDummyChains",()=>sy(e)),t(" addBorderSegments",()=>oy(e)),t(" order",()=>ay(e,n)),t(" insertSelfEdges",()=>Iy(e)),t(" adjustCoordinateSystem",()=>ei.adjust(e)),t(" position",()=>ly(e)),t(" positionSelfEdges",()=>Ry(e)),t(" removeBorderNodes",()=>My(e)),t(" normalize.undo",()=>Qs.undo(e)),t(" fixupEdgeLabelCoords",()=>Cy(e)),t(" undoCoordinateSystem",()=>ei.undo(e)),t(" translateGraph",()=>ky(e)),t(" assignNodeIntersects",()=>jy(e)),t(" reversePoints",()=>$y(e)),t(" acyclic.undo",()=>Zs.undo(e))}function hy(e,t){e.nodes().forEach(n=>{let r=e.node(n),s=t.node(n);r&&(r.x=s.x,r.y=s.y,r.rank=s.rank,t.children(n).length&&(r.width=s.width,r.height=s.height))}),e.edges().forEach(n=>{let r=e.edge(n),s=t.edge(n);r.points=s.points,Object.hasOwn(s,"x")&&(r.x=s.x,r.y=s.y)}),e.graph().width=t.graph().width,e.graph().height=t.graph().height}let my=["nodesep","edgesep","ranksep","marginx","marginy"],py={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},gy=["acyclicer","ranker","rankdir","align"],yy=["width","height","rank"],ti={width:0,height:0},xy=["minlen","weight","width","height","labeloffset"],wy={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},vy=["labelpos"];function by(e){let t=new cy({multigraph:!0,compound:!0}),n=Jn(e.graph());return t.setGraph(Object.assign({},py,Qn(n,my),Se.pick(n,gy))),e.nodes().forEach(r=>{let s=Jn(e.node(r));const i=Qn(s,yy);Object.keys(ti).forEach(o=>{i[o]===void 0&&(i[o]=ti[o])}),t.setNode(r,i),t.setParent(r,e.parent(r))}),e.edges().forEach(r=>{let s=Jn(e.edge(r));t.setEdge(r,Object.assign({},wy,Qn(s,xy),Se.pick(s,vy)))}),t}function _y(e){let t=e.graph();t.ranksep/=2,e.edges().forEach(n=>{let r=e.edge(n);r.minlen*=2,r.labelpos.toLowerCase()!=="c"&&(t.rankdir==="TB"||t.rankdir==="BT"?r.width+=r.labeloffset:r.height+=r.labeloffset)})}function Ey(e){e.edges().forEach(t=>{let n=e.edge(t);if(n.width&&n.height){let r=e.node(t.v),i={rank:(e.node(t.w).rank-r.rank)/2+r.rank,e:t};Se.addDummyNode(e,"edge-proxy",i,"_ep")}})}function Ny(e){let t=0;e.nodes().forEach(n=>{let r=e.node(n);r.borderTop&&(r.minRank=e.node(r.borderTop).rank,r.maxRank=e.node(r.borderBottom).rank,t=Math.max(t,r.maxRank))}),e.graph().maxRank=t}function Sy(e){e.nodes().forEach(t=>{let n=e.node(t);n.dummy==="edge-proxy"&&(e.edge(n.e).labelRank=n.rank,e.removeNode(t))})}function ky(e){let t=Number.POSITIVE_INFINITY,n=0,r=Number.POSITIVE_INFINITY,s=0,i=e.graph(),o=i.marginx||0,a=i.marginy||0;function l(c){let u=c.x,d=c.y,m=c.width,h=c.height;t=Math.min(t,u-m/2),n=Math.max(n,u+m/2),r=Math.min(r,d-h/2),s=Math.max(s,d+h/2)}e.nodes().forEach(c=>l(e.node(c))),e.edges().forEach(c=>{let u=e.edge(c);Object.hasOwn(u,"x")&&l(u)}),t-=o,r-=a,e.nodes().forEach(c=>{let u=e.node(c);u.x-=t,u.y-=r}),e.edges().forEach(c=>{let u=e.edge(c);u.points.forEach(d=>{d.x-=t,d.y-=r}),Object.hasOwn(u,"x")&&(u.x-=t),Object.hasOwn(u,"y")&&(u.y-=r)}),i.width=n-t+o,i.height=s-r+a}function jy(e){e.edges().forEach(t=>{let n=e.edge(t),r=e.node(t.v),s=e.node(t.w),i,o;n.points?(i=n.points[0],o=n.points[n.points.length-1]):(n.points=[],i=s,o=r),n.points.unshift(Se.intersectRect(r,i)),n.points.push(Se.intersectRect(s,o))})}function Cy(e){e.edges().forEach(t=>{let n=e.edge(t);if(Object.hasOwn(n,"x"))switch((n.labelpos==="l"||n.labelpos==="r")&&(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset;break}})}function $y(e){e.edges().forEach(t=>{let n=e.edge(t);n.reversed&&n.points.reverse()})}function My(e){e.nodes().forEach(t=>{if(e.children(t).length){let n=e.node(t),r=e.node(n.borderTop),s=e.node(n.borderBottom),i=e.node(n.borderLeft[n.borderLeft.length-1]),o=e.node(n.borderRight[n.borderRight.length-1]);n.width=Math.abs(o.x-i.x),n.height=Math.abs(s.y-r.y),n.x=i.x+n.width/2,n.y=r.y+n.height/2}}),e.nodes().forEach(t=>{e.node(t).dummy==="border"&&e.removeNode(t)})}function Ay(e){e.edges().forEach(t=>{if(t.v===t.w){var n=e.node(t.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:t,label:e.edge(t)}),e.removeEdge(t)}})}function Iy(e){var t=Se.buildLayerMatrix(e);t.forEach(n=>{var r=0;n.forEach((s,i)=>{var o=e.node(s);o.order=i+r,(o.selfEdges||[]).forEach(a=>{Se.addDummyNode(e,"selfedge",{width:a.label.width,height:a.label.height,rank:o.rank,order:i+ ++r,e:a.e,label:a.label},"_se")}),delete o.selfEdges})})}function Ry(e){e.nodes().forEach(t=>{var n=e.node(t);if(n.dummy==="selfedge"){var r=e.node(n.e.v),s=r.x+r.width/2,i=r.y,o=n.x-s,a=r.height/2;e.setEdge(n.e,n.label),e.removeNode(t),n.label.points=[{x:s+2*o/3,y:i-a},{x:s+5*o/6,y:i-a},{x:s+o,y:i},{x:s+5*o/6,y:i+a},{x:s+2*o/3,y:i+a}],n.label.x=n.x,n.label.y=n.y}})}function Qn(e,t){return Se.mapValues(Se.pick(e,t),Number)}function Jn(e){var t={};return e&&Object.entries(e).forEach(([n,r])=>{typeof n=="string"&&(n=n.toLowerCase()),t[n]=r}),t}let Ty=de,Oy=Me.Graph;var Dy={debugOrdering:Ly};function Ly(e){let t=Ty.buildLayerMatrix(e),n=new Oy({compound:!0,multigraph:!0}).setGraph({});return e.nodes().forEach(r=>{n.setNode(r,{label:r}),n.setParent(r,"layer"+e.node(r).rank)}),e.edges().forEach(r=>n.setEdge(r.v,r.w,{},r.name)),t.forEach((r,s)=>{let i="layer"+s;n.setNode(i,{rank:"same"}),r.reduce((o,a)=>(n.setEdge(o,a,{style:"invis"}),a))}),n}var Py="1.1.8",zy={graphlib:Me,layout:uy,debug:Dy,util:{time:de.time,notime:de.notime},version:Py};const ni=li(zy),yr=264,Hy=44,Fy=26,Vy=14;function xr(e){const t=Math.max(e.attributes.length,1);return Hy+t*Fy+Vy}const By=40;function ri(e,t,n,r="auto"){return r==="grid"||r==="auto"&&e.length>By?Uy(e,n):Gy(e,t,n)}function Gy(e,t,n){const r=new ni.graphlib.Graph;r.setGraph({rankdir:"LR",nodesep:70,ranksep:150,edgesep:30,marginx:48,marginy:48,ranker:"network-simplex"}),r.setDefaultEdgeLabel(()=>({}));for(const s of e){const i=n.get(s.id);r.setNode(s.id,{width:yr,height:i?xr(i):120})}for(const s of t)r.setEdge(s.source,s.target,{minlen:1,weight:2});return ni.layout(r),e.map(s=>{const i=r.node(s.id),o=n.get(s.id),a=o?xr(o):120;return{...s,position:{x:i.x-yr/2,y:i.y-a/2}}})}const Yy=40,Wy=40;function Uy(e,t){const n=c=>{const u=t.get(c);return u?xr(u):120},r=c=>{var u,d,m;return((m=(d=(u=t.get(c))==null?void 0:u.conceptual)==null?void 0:d.subject_area)==null?void 0:m.name)??""},s=[...e].sort((c,u)=>{var g,b;const d=r(c.id),m=r(u.id);if(d!==m)return d.localeCompare(m);const h=((g=t.get(c.id))==null?void 0:g.name)??c.id,y=((b=t.get(u.id))==null?void 0:b.name)??u.id;return h.localeCompare(y)}),i=Math.max(1,Math.round(Math.sqrt(s.length))),o=Array.from({length:i},(c,u)=>u*(yr+Yy)),a=new Map;let l=0;for(let c=0;ca.set(m.id,{x:o[h],y:l}));const d=Math.max(...u.map(m=>n(m.id)));l+=d+Wy}return e.map(c=>({...c,position:a.get(c.id)??c.position}))}function Kt({title:e,onClose:t,children:n,wide:r}){return f.jsx("div",{className:"modal-backdrop",onClick:t,children:f.jsxs("div",{className:"modal"+(r?" wide":""),onClick:s=>s.stopPropagation(),children:[f.jsxs("div",{className:"modal-header",children:[f.jsx("h2",{children:e}),f.jsx("button",{className:"icon-btn",onClick:t,children:"✕"})]}),n]})})}const qy=["skos:exactMatch","skos:closeMatch","skos:broadMatch","skos:narrowMatch","skos:relatedMatch"],ha=["industry","core","domain","specialised"];function Xy({entity:e,exec:t,onClose:n}){var v,j;const[r,s]=w.useState(((v=e.conceptual)==null?void 0:v.name)??e.name),[i,o]=w.useState([]),[a,l]=w.useState(null),[c,u]=w.useState(null),[d,m]=w.useState("skos:exactMatch"),[h,y]=w.useState(((j=e.conceptual)==null?void 0:j.ontology_layer)??"core"),[g,b]=w.useState([]),[x,_]=w.useState("");w.useEffect(()=>{Ho().then(C=>b(C.ontologies)).catch(()=>{})},[]),w.useEffect(()=>{const C=setTimeout(()=>{if(!r.trim())return o([]);zo(r,x||void 0).then(N=>{o(N.results),l(N.loaded_terms)}).catch(()=>o([]))},200);return()=>clearTimeout(C)},[r,x]);const $=()=>{c&&t("set_alignment",{id:e.id,aligns_to:c.prefixed,alignment:d,layer:h,resolved_via:c.source}).then(n)};return f.jsxs(Kt,{title:`Align '${e.name}' to ontology`,onClose:n,wide:!0,children:[g.length>0&&f.jsxs("div",{className:"src-picker",children:[f.jsx("button",{className:"src-chip"+(x===""?" active":""),onClick:()=>_(""),children:"all sources"}),g.map(C=>f.jsx("button",{className:"src-chip"+(x===C.id?" active":""),title:C.count!=null?`${C.count} terms`:"live resolver",onClick:()=>_(C.id),children:C.name},C.id))]}),f.jsx("input",{autoFocus:!0,className:"edit-input modal-search",placeholder:x?`Search within ${x}…`:"Search vocabulary terms…",value:r,onChange:C=>s(C.target.value)}),a===0&&g.length===0&&f.jsx("p",{className:"empty-hint",children:"No vocabulary loaded. Declare one in mdl-project.yaml's ontology_stack (or run `mdl ontology vendor fibo`)."}),f.jsxs("div",{className:"term-results",children:[i.map(C=>f.jsxs("button",{className:"term-card"+((c==null?void 0:c.iri)===C.iri?" picked":""),onClick:()=>u(C),children:[f.jsxs("div",{className:"term-head",children:[f.jsx("span",{className:"term-label",children:C.label}),f.jsxs("span",{className:"term-source",children:[C.source_kind==="glossary-term"&&f.jsx("span",{className:"kind-badge",children:"glossary"}),C.source]})]}),f.jsx("code",{className:"term-iri",children:C.prefixed}),C.definition&&f.jsx("p",{className:"term-def",children:C.definition})]},C.iri)),r&&i.length===0&&a!==0&&f.jsxs("p",{className:"empty-hint",children:["no matches for “",r,"”"]})]}),f.jsxs("div",{className:"modal-footer",children:[f.jsxs("label",{children:["predicate",f.jsx("select",{value:d,onChange:C=>m(C.target.value),children:qy.map(C=>f.jsx("option",{children:C},C))})]}),f.jsxs("label",{children:["layer",f.jsx("select",{value:h,onChange:C=>y(C.target.value),children:ha.map(C=>f.jsx("option",{children:C},C))})]}),f.jsxs("button",{className:"primary-btn",disabled:!c,onClick:$,children:["Align",c?` to ${c.label}`:""]})]})]})}function Ky({entity:e,doc:t,exec:n,onClose:r}){var v,j,C;const[s,i]=w.useState(((v=e.term_map)==null?void 0:v.subject_template)??""),[o,a]=w.useState(((j=e.term_map)==null?void 0:j.class_iri)??""),l=new Set(e.attributes.map(N=>N.name)),u=Array.from(s.matchAll(/\{([^}]+)\}/g)).map(N=>N[1]).filter(N=>!l.has(N)),d=N=>!N||N.startsWith("http://")||N.startsWith("https://")||/^[^\s:]+:[^\s:]+/.test(N),m=u.length===0&&d(o),h=()=>{n("set_term_map",{id:e.id,subject_template:s.trim()||null,class_iri:o.trim()||null}).then(r)},y=(t.project.name||"").replace(/[^0-9a-zA-Z]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"modelith-model",g=t.project.kg_base_iri||`urn:${y}:`,b=(C=(e.key_groups??[]).find(N=>N.type==="pk"))==null?void 0:C.members.map(N=>{var D;return(D=e.attributes.find(S=>S.id===N))==null?void 0:D.name}).filter(Boolean),x=b&&b.length?`${g}${e.id}/${b.map(N=>`{${N}}`).join("_")}`:"(blank-node: entity has no primary key)",_=o.trim()||`${g}${e.id}`,$=s.trim()||x;return f.jsxs(Kt,{title:`Knowledge Graph mapping — ${e.name}`,onClose:r,wide:!0,children:[f.jsx("p",{className:"empty-hint",style:{marginBottom:14},children:"Override the R2RML term-map for this entity. Leave a field blank to use the default (project base IRI + primary key)."}),f.jsxs("div",{className:"form-row",children:[f.jsx("label",{htmlFor:"tm-class",children:"Class IRI"}),f.jsx("input",{id:"tm-class",className:"edit-input",value:o,placeholder:"https://acme.com/Customer or fibo-fnd:Party",onChange:N=>a(N.target.value)}),d(o)?f.jsxs("code",{className:"form-preview",children:["rr:class ",_]}):f.jsx("span",{className:"form-error",children:"not a valid IRI or prefix:local CURIE"})]}),f.jsxs("div",{className:"form-row",children:[f.jsx("label",{htmlFor:"tm-subject",children:"Subject template"}),f.jsx("input",{id:"tm-subject",className:"edit-input",value:s,placeholder:"https://acme.com/id/customer/{customer_id}",onChange:N=>i(N.target.value)}),u.length>0?f.jsxs("span",{className:"form-error",children:["unknown column",u.length>1?"s":"",": ",u.join(", ")]}):f.jsxs("code",{className:"form-preview",children:["rr:template ",$]}),f.jsxs("span",{className:"form-hint",children:["Wrap a column in ","{ }"," to fill it from each row, e.g."," ","{"+((b==null?void 0:b[0])??"id")+"}",". Columns:"," ",e.attributes.map(N=>N.name).join(", ")]})]}),f.jsxs("div",{className:"modal-footer",children:[f.jsx("button",{className:"mini-btn",onClick:r,children:"Cancel"}),f.jsx("button",{className:"primary-btn",disabled:!m,onClick:h,children:"Save mapping"})]})]})}function Zy({doc:e,exec:t,onClose:n,onCreated:r}){const[s,i]=w.useState(""),[o,a]=w.useState(""),[l,c]=w.useState(""),[u,d]=w.useState(""),m=()=>{s.trim()&&t("create_entity",{name:s,definition:o||null,subject_area:l||null,layer:u||null}).then(h=>{const y=h==null?void 0:h.created_id;n(),y&&r(y)})};return f.jsxs(Kt,{title:"New entity",onClose:n,children:[f.jsxs("label",{className:"form-row",children:["name",f.jsx("input",{autoFocus:!0,className:"edit-input",placeholder:"e.g. custody_account",value:s,onChange:h=>i(h.target.value),onKeyDown:h=>h.key==="Enter"&&m()})]}),f.jsxs("label",{className:"form-row",children:["definition",f.jsx("textarea",{className:"edit-input",rows:2,placeholder:"business definition…",value:o,onChange:h=>a(h.target.value)})]}),f.jsxs("label",{className:"form-row",children:["subject area",f.jsxs("select",{value:l,onChange:h=>c(h.target.value),children:[f.jsx("option",{value:"",children:"none"}),e.subject_areas.map(h=>f.jsx("option",{value:h.id,children:h.name},h.id))]})]}),f.jsxs("label",{className:"form-row",children:["ontology layer",f.jsxs("select",{value:u,onChange:h=>d(h.target.value),children:[f.jsx("option",{value:"",children:"none"}),ha.map(h=>f.jsx("option",{children:h},h))]})]}),f.jsx("div",{className:"modal-footer",children:f.jsx("button",{className:"primary-btn",disabled:!s.trim(),onClick:m,children:"Create"})})]})}const ma=["many_to_one","one_to_many","one_to_one","many_to_many"];function Qy({doc:e,fromId:t,toId:n,initialFromAttr:r,initialToAttr:s,exec:i,onClose:o}){const a=e.entities.find(v=>v.id===t),l=e.entities.find(v=>v.id===n),c=w.useMemo(()=>l==null?void 0:l.attributes.find(v=>v.role==="business_key"),[l]),[u,d]=w.useState(r??""),[m,h]=w.useState(s??(c==null?void 0:c.id)??""),[y,g]=w.useState("many_to_one"),[b,x]=w.useState("mandatory");if(!a||!l)return null;const _=u==="__new__",$=()=>i("create_relationship",{from_entity:a.id,to_entity:l.id,from_attribute:_?null:u||null,to_attribute:m||null,create_from_fk:_,cardinality:y,optionality:b}).then(o);return f.jsxs(Kt,{title:`${a.name} → ${l.name}`,onClose:o,children:[f.jsxs("label",{className:"form-row",children:["cardinality (",a.name," : ",l.name,")",f.jsx("select",{value:y,onChange:v=>g(v.target.value),children:ma.map(v=>f.jsx("option",{children:v},v))})]}),f.jsxs("label",{className:"form-row",children:["foreign key on ",a.name,f.jsxs("select",{value:u,onChange:v=>d(v.target.value),children:[f.jsx("option",{value:"",children:"(none)"}),f.jsxs("option",{value:"__new__",children:["➕ create column",c?` "${c.name}"`:""]}),a.attributes.map(v=>f.jsx("option",{value:v.id,children:v.name},v.id))]})]}),f.jsxs("label",{className:"form-row",children:["references on ",l.name,f.jsxs("select",{value:m,onChange:v=>h(v.target.value),children:[f.jsx("option",{value:"",children:"(none)"}),l.attributes.map(v=>f.jsxs("option",{value:v.id,children:[v.name,v.role==="business_key"?" 🔑":""]},v.id))]})]}),f.jsxs("label",{className:"form-row",children:["optionality",f.jsxs("select",{value:b,onChange:v=>x(v.target.value),children:[f.jsx("option",{children:"mandatory"}),f.jsx("option",{children:"optional"})]})]}),f.jsx("div",{className:"modal-footer",children:f.jsx("button",{className:"primary-btn",onClick:$,children:"Create relationship"})})]})}function Jy({rel:e,doc:t,exec:n,onClose:r}){const s=x=>{var _;return((_=t.entities.find($=>$.id===x))==null?void 0:_.name)??"?"},[i,o]=w.useState(e.name),[a,l]=w.useState(e.cardinality),[c,u]=w.useState(e.optionality),[d,m]=w.useState(e.identifying),[h,y]=w.useState(!1),g=async()=>{i.trim()&&i.trim()!==e.name&&await n("rename_relationship",{id:e.id,name:i.trim()}),(a!==e.cardinality||c!==e.optionality||d!==e.identifying)&&await n("update_relationship",{id:e.id,cardinality:a,optionality:c,identifying:d}),r()},b=()=>n("delete_relationship",{id:e.id}).then(r);return f.jsxs(Kt,{title:`${s(e.from.entity)} → ${s(e.to.entity)}`,onClose:r,children:[f.jsxs("label",{className:"form-row",children:["relationship name",f.jsx("input",{value:i,onChange:x=>o(x.target.value),autoFocus:!0})]}),f.jsxs("label",{className:"form-row",children:["cardinality",f.jsx("select",{value:a,onChange:x=>l(x.target.value),children:ma.map(x=>f.jsx("option",{children:x},x))})]}),f.jsxs("label",{className:"form-row",children:["optionality",f.jsxs("select",{value:c,onChange:x=>u(x.target.value),children:[f.jsx("option",{value:"mandatory",children:"mandatory"}),f.jsx("option",{value:"optional",children:"optional"})]})]}),f.jsxs("label",{className:"form-row",children:["identifying",f.jsxs("select",{value:d?"yes":"no",onChange:x=>m(x.target.value==="yes"),children:[f.jsx("option",{value:"no",children:"no — parent key is a plain reference"}),f.jsx("option",{value:"yes",children:"yes — parent key is part of the child's identity"})]})]}),f.jsxs("div",{className:"modal-footer",style:{justifyContent:"space-between"},children:[h?f.jsx("button",{className:"danger-btn",onClick:b,children:"Confirm delete"}):f.jsx("button",{className:"mini-btn danger",onClick:()=>y(!0),children:"Delete relationship"}),f.jsx("button",{className:"primary-btn",onClick:g,children:"Save"})]})]})}const ex=w.memo(function({id:t,sourceX:n,sourceY:r,targetX:s,targetY:i,sourcePosition:o,targetPosition:a,data:l,selected:c}){const[u]=vn({sourceX:n,sourceY:r,sourcePosition:o,targetX:s,targetY:i,targetPosition:a,borderRadius:10}),d=l==null?void 0:l.relationship,m=(l==null?void 0:l.dimmed)??!1,h=(d==null?void 0:d.cardinality)??"many_to_one",y=(d==null?void 0:d.optionality)==="optional",g=(d==null?void 0:d.identifying)??!1,b=h==="many_to_one"||h==="many_to_many",x=h==="one_to_many"||h==="many_to_many",_="rel-edge"+(c?" selected":"")+(m?" dimmed":""),$=((l==null?void 0:l.memberCount)??0)>1,v=l==null?void 0:l.onHoverEdge;return f.jsxs("g",{className:_,children:[f.jsx("path",{id:t,className:"rel-path",d:u,fill:"none",strokeDasharray:g?void 0:"6 4"}),f.jsx("path",{d:u,fill:"none",strokeWidth:14,stroke:"transparent",onMouseEnter:v?()=>v(d.id):void 0,onMouseLeave:v?()=>v(null):void 0}),f.jsx(si,{x:n,y:r,side:o,many:b,optional:y}),f.jsx(si,{x:s,y:i,side:a,many:x,optional:!1}),(c||$)&&d&&f.jsxs("text",{className:"rel-label",x:(n+s)/2,y:(r+i)/2-8,children:[c?d.verb_phrase||d.name:"",$?`${c?" ":""}(${l.memberCount})`:""]})]})});function si({x:e,y:t,side:n,many:r,optional:s}){const i=n===X.Left?-1:1,o=7,a=12,l=[];return r?l.push(f.jsx("path",{className:"rel-glyph",d:`M ${e+i*a} ${t} L ${e} ${t-o} M ${e+i*a} ${t} L ${e} ${t} M ${e+i*a} ${t} L ${e} ${t+o}`,fill:"none"},"foot")):l.push(f.jsx("line",{className:"rel-glyph",x1:e+i*(a-3),y1:t-o,x2:e+i*(a-3),y2:t+o},"one")),s?l.push(f.jsx("circle",{className:"rel-glyph ring",cx:e+i*(a+6),cy:t,r:4},"opt")):l.push(f.jsx("line",{className:"rel-glyph",x1:e+i*(a+5),y1:t-o,x2:e+i*(a+5),y2:t+o},"mand")),f.jsx(f.Fragment,{children:l})}const tx={entity:km},nx={relationship:ex},ii=["#e0a63a","#e8825a","#d98ba8","#c4a3e0","#7fb0d8","#7fc9a0","#e6c14a"],oi="#8a7d6a";function rx(e,t){const n=(i,o)=>{var a;return!!o&&!!((a=t.get(i))!=null&&a.attributes.some(l=>l.id===o))},r=e.from.attributes[0],s=e.to.attributes[0];return{sourceHandle:n(e.from.entity,r)?r:Dr,targetHandle:n(e.to.entity,s)?s:Lr}}function Ax({doc:e,caps:t,exec:n,selectedId:r,onSelect:s,query:i="",showTypes:o=!0,collapseDetail:a=!1,expandedEntities:l,onToggleExpand:c,onError:u,handleRef:d}){const{fitView:m,fitBounds:h,getNodes:y}=An(),[g,b]=w.useState([]),[x,_]=w.useState([]),$=w.useRef(!1),[v,j]=w.useState(null),[C,N]=w.useState(null),[D,S]=w.useState(!1),[T,P]=w.useState(null),[V,F]=w.useState(null),[p,M]=w.useState(null),[E,O]=w.useState(null),L=!t.canEdit,k=w.useMemo(()=>{const B=new Map;return e.subject_areas.forEach((W,q)=>B.set(W.id,ii[q%ii.length])),B},[e]),I=w.useMemo(()=>{const B=new Map;return e.entities.forEach(W=>B.set(W.id,W)),B},[e]),z=w.useMemo(()=>{const B=new Map,W=(q,ee)=>{if(!ee.length)return;const J=B.get(q)??new Set;ee.forEach(oe=>J.add(oe)),B.set(q,J)};for(const q of e.relationships)W(q.from.entity,q.from.attributes),W(q.to.entity,q.to.attributes);return B},[e]);w.useEffect(()=>{var te;const B=i.trim().toLowerCase(),W=new Set;if(B)for(const R of e.entities)(R.name.toLowerCase()+" "+(((te=R.conceptual)==null?void 0:te.name.toLowerCase())??"")+" "+R.attributes.map(ce=>ce.name.toLowerCase()).join(" ")).includes(B)&&W.add(R.id);const q=new Set;if(r){q.add(r);for(const R of e.relationships)R.from.entity===r&&q.add(R.to.entity),R.to.entity===r&&q.add(R.from.entity)}const ee=new Set,J=new Set,oe=new Map,ie=(R,ne)=>{if(!ne.length)return;const ce=oe.get(R)??new Set;ne.forEach(be=>ce.add(be)),oe.set(R,ce)};if(p)for(const R of e.relationships)(R.from.attributes.includes(p)||R.to.attributes.includes(p))&&(ee.add(R.id),J.add(R.from.entity),J.add(R.to.entity),ie(R.from.entity,R.from.attributes),ie(R.to.entity,R.to.attributes));if(E){const R=e.relationships.find(ne=>ne.id===E);R&&(ie(R.from.entity,R.from.attributes),ie(R.to.entity,R.to.attributes))}const re=e.entities.map(R=>{var we;const ne=B!==""&&!W.has(R.id),ce=r!==null&&!q.has(R.id),be=p!==null&&!J.has(R.id);return{id:R.id,type:"entity",position:{x:0,y:0},data:{entity:R,color:(we=R.conceptual)!=null&&we.subject_area?k.get(R.conceptual.subject_area.id)??oi:oi,dimmed:ne||ce||be,highlighted:B!==""&&W.has(R.id)||p!==null&&J.has(R.id),showTypes:o,collapseDetail:a,expanded:(l==null?void 0:l.has(R.id))??!1,onToggleExpand:c,endpointAttrs:z.get(R.id),highlightAttrs:oe.get(R.id),onHoverAttr:M}}}),ge=e.relationships.filter(R=>I.has(R.from.entity)&&I.has(R.to.entity)).map(R=>{const{sourceHandle:ne,targetHandle:ce}=rx(R,I),be=r!==null&&R.from.entity!==r&&R.to.entity!==r,we=p!==null&&!ee.has(R.id);return{id:R.id,source:R.from.entity,target:R.to.entity,sourceHandle:ne,targetHandle:ce,type:"relationship",data:{relationship:R,dimmed:be||we,memberCount:Math.max(R.from.attributes.length,R.to.attributes.length),onHoverEdge:O}}});b(R=>{const ne=new Map(R.map(ue=>[ue.id,ue.position])),ce=re.every(ue=>ne.has(ue.id));if($.current&&ce&&R.length>=re.length)return re.map(ue=>({...ue,position:ne.get(ue.id)??ue.position}));const we=ri(re,ge,I).map(ue=>ne.has(ue.id)&&$.current?{...ue,position:ne.get(ue.id)}:ue);return $.current=!0,requestAnimationFrame(()=>m({padding:.15,duration:300})),we}),_(ge)},[e,i,r,o,a,l,c,k,I,z,p,E,m]),w.useEffect(()=>{var ee;const B=i.trim().toLowerCase();if(!B)return;const W=new Set;for(const J of e.entities)(J.name.toLowerCase()+" "+(((ee=J.conceptual)==null?void 0:ee.name.toLowerCase())??"")+" "+J.attributes.map(ie=>ie.name.toLowerCase()).join(" ")).includes(B)&&W.add(J.id);if(!W.size)return;const q=requestAnimationFrame(()=>{const J=y().filter(ie=>W.has(ie.id));if(!J.length)return;const oe=wf(J);h(oe,{padding:.35,duration:400})});return()=>cancelAnimationFrame(q)},[i,e,y,h]);const H=w.useCallback((B="auto")=>{b(W=>ri(W,x,I,B)),requestAnimationFrame(()=>m({padding:.15,duration:300}))},[x,I,m]),G=w.useCallback(B=>{s(B),b(W=>(W.find(ee=>ee.id===B)&&requestAnimationFrame(()=>m({nodes:[{id:B}],padding:.4,duration:400})),W))},[m,s]);w.useImperativeHandle(d,()=>({relayout:H,fitView:()=>m({padding:.15,duration:300}),focusEntity:G,newEntity:()=>S(!0)}),[H,m,G]);const Y=w.useCallback(B=>{if(L||!B.source||!B.target||B.source===B.target)return;const W=B.sourceHandle&&B.sourceHandle!==Dr?B.sourceHandle:void 0,q=B.targetHandle&&B.targetHandle!==Lr?B.targetHandle:void 0;P({from:B.source,to:B.target,fromAttr:W,toAttr:q})},[L]),U=w.useCallback(async(B,W)=>{try{return await n(B,W)}catch(q){throw u==null||u(q instanceof Error?q.message:String(q)),q}},[n,u]),K=r?I.get(r)??null:null,Z=e.relationships.find(B=>B.id===V)??null;return f.jsxs(f.Fragment,{children:[f.jsxs(Io,{nodes:g,edges:x,nodeTypes:tx,edgeTypes:nx,onNodeClick:(B,W)=>s(W.id),onEdgeClick:(B,W)=>!L&&F(W.id),onPaneClick:()=>{s(null),F(null)},onNodeDragStop:(B,W)=>b(q=>q.map(ee=>ee.id===W.id?{...ee,position:W.position}:ee)),onConnect:Y,nodesConnectable:!L,minZoom:.05,onlyRenderVisibleElements:!0,proOptions:{hideAttribution:!0},fitView:!0,children:[f.jsx(dm,{variant:Ne.Dots,gap:22,size:1.5,color:"#33291f"}),f.jsx(Qh,{pannable:!0,zoomable:!0,nodeColor:B=>{var W;return((W=B.data)==null?void 0:W.color)??"#5a4f42"},maskColor:"rgba(20, 17, 15, 0.75)"}),f.jsx(im,{showInteractive:!1})]}),K&&f.jsx(Cm,{entity:K,doc:e,caps:t,exec:U,onClose:()=>s(null),onFocusEntity:G,onAlign:j,onEditMapping:N}),v&&f.jsx(Xy,{entity:v,exec:U,onClose:()=>j(null)}),C&&f.jsx(Ky,{entity:C,doc:e,exec:U,onClose:()=>N(null)}),D&&f.jsx(Zy,{doc:e,exec:U,onClose:()=>S(!1),onCreated:G}),T&&f.jsx(Qy,{doc:e,fromId:T.from,toId:T.to,initialFromAttr:T.fromAttr,initialToAttr:T.toAttr,exec:U,onClose:()=>P(null)}),Z&&f.jsx(Jy,{rel:Z,doc:e,exec:U,onClose:()=>F(null)})]})}function Ix({tab:e,onClose:t,readOnly:n,refreshKey:r,onModelChanged:s,onFocusEntity:i}){return f.jsxs("aside",{className:"side-panel",children:[f.jsxs("div",{className:"detail-header",children:[f.jsxs("h2",{children:[e==="ontology"&&"Ontology",e==="layers"&&"Ontology layers",e==="changes"&&"Uncommitted changes",e==="decisions"&&"Decision ledger"]}),f.jsx("button",{className:"icon-btn",onClick:t,children:"✕"})]}),e==="ontology"&&f.jsx(sx,{}),e==="layers"&&f.jsx(ox,{refreshKey:r,onFocusEntity:i}),e==="changes"&&f.jsx(ax,{readOnly:n,refreshKey:r,onModelChanged:s}),e==="decisions"&&f.jsx(lx,{readOnly:n})]})}function sx(){const[e,t]=w.useState(""),[n,r]=w.useState([]),[s,i]=w.useState({loaded:0,vocabs:[]}),[o,a]=w.useState(null),[l,c]=w.useState([]),[u,d]=w.useState("");w.useEffect(()=>{Ho().then(h=>c(h.ontologies)).catch(()=>{})},[]),w.useEffect(()=>{const h=setTimeout(()=>{zo(e||"a",u||void 0).then(y=>{r(e?y.results:[]),i({loaded:y.loaded_terms,vocabs:y.vocabularies})}).catch(()=>{})},200);return()=>clearTimeout(h)},[e,u]);const m=w.useCallback(h=>{fm(h).then(a).catch(()=>{})},[]);return o?f.jsxs("div",{className:"panel-body",children:[f.jsx("button",{className:"mini-btn",onClick:()=>a(null),children:"← back"}),f.jsx("h3",{style:{marginTop:12},children:o.label}),f.jsx("code",{className:"term-iri",children:o.prefixed}),o.definition&&f.jsx("p",{className:"term-def",children:o.definition}),f.jsxs("div",{className:"kv",children:[f.jsx("span",{className:"k",children:"source"}),f.jsx("span",{className:"v",children:o.source})]}),o.broader.length>0&&f.jsxs(f.Fragment,{children:[f.jsx("h4",{children:"broader"}),o.broader.map(h=>f.jsxs("button",{className:"rel-link",onClick:()=>m(h.iri),children:["↑ ",h.label]},h.iri))]}),o.narrower.length>0&&f.jsxs(f.Fragment,{children:[f.jsx("h4",{children:"narrower"}),o.narrower.map(h=>f.jsxs("button",{className:"rel-link",onClick:()=>m(h.iri),children:["↓ ",h.label]},h.iri))]})]}):f.jsxs("div",{className:"panel-body",children:[l.length>0&&f.jsxs("div",{className:"src-picker",children:[f.jsx("button",{className:"src-chip"+(u===""?" active":""),onClick:()=>d(""),children:"all sources"}),l.map(h=>f.jsxs("button",{className:"src-chip"+(u===h.id?" active":""),title:(h.description??"")+(h.count!=null?` · ${h.count} terms`:" · live"),onClick:()=>d(h.id),children:[h.name,h.layer&&f.jsx("span",{className:`src-layer layer-${h.layer}`,children:h.layer})]},h.id))]}),f.jsx("input",{className:"edit-input",placeholder:u?`Search within ${u}…`:"Search vocabulary terms…",value:e,onChange:h=>t(h.target.value)}),f.jsx("p",{className:"meta-line",children:l.length>0?`${l.length} source${l.length>1?"s":""}: ${s.vocabs.join(", ")}`+(s.loaded>0?` · ${s.loaded} local terms indexed`:""):"no vocabulary loaded — declare ontology_stack in mdl-project.yaml or run `mdl ontology vendor fibo`"}),f.jsx("div",{className:"term-results",children:n.map(h=>f.jsxs("button",{className:"term-card",onClick:()=>m(h.prefixed),children:[f.jsxs("div",{className:"term-head",children:[f.jsx("span",{className:"term-label",children:h.label}),f.jsxs("span",{className:"term-source",children:[h.source_kind==="glossary-term"&&f.jsx("span",{className:"kind-badge",title:"glossary term",children:"glossary"}),h.source]})]}),f.jsx("code",{className:"term-iri",children:h.prefixed}),h.definition&&f.jsx("p",{className:"term-def",children:h.definition})]},h.iri))})]})}const ix=["industry","core","domain","specialised"];function ox({refreshKey:e,onFocusEntity:t}){const[n,r]=w.useState(null),[s,i]=w.useState(null);if(w.useEffect(()=>{hm().then(r).catch(()=>{}),mm().then(i).catch(()=>{})},[e]),!n)return f.jsx("div",{className:"panel-body",children:"loading…"});const o=new Set((s==null?void 0:s.core_uncovered)??[]);return f.jsxs("div",{className:"panel-body",children:[s&&f.jsxs("div",{className:"coverage-banner"+(s.coverage_pct<100?" warn":""),children:["industry alignment coverage: ",f.jsxs("b",{children:[s.coverage_pct,"%"]})," (",s.core_with_industry,"+",s.core_exempt,"/",s.total_core," core terms)"]}),f.jsxs("div",{className:"layer-band external",children:[f.jsx("h4",{children:"industry (external vocabularies)"}),n.external_terms.length===0&&f.jsx("p",{className:"empty-hint",children:"no aligned terms yet"}),n.external_terms.map(a=>f.jsxs("div",{className:"stack-term external",title:a.definition??void 0,children:[a.label,f.jsx("span",{className:"term-source",children:a.source})]},a.iri))]}),ix.slice(1).map(a=>f.jsxs("div",{className:"layer-band",children:[f.jsx("h4",{children:a}),(n.layers[a]??[]).length===0&&f.jsx("p",{className:"empty-hint",children:"—"}),(n.layers[a]??[]).map(l=>{var c;return f.jsxs("button",{className:"stack-term"+(o.has(l.name)?" uncovered":""),title:l.definition??void 0,onClick:()=>t(l.id),children:[l.name,(l.aligned_refs??(l.aligned_to?[l.aligned_to]:[])).map((u,d)=>f.jsxs("span",{className:"align-arrow"+(u.resolved?"":" unresolved")+(u.status==="proposed"?" proposed":""),title:u.ref+(u.resolved_via?` (via ${u.resolved_via})`:""),children:["↑ ",u.label,u.status==="proposed"?" ·prop":""]},`${u.ref}-${d}`)),!l.aligned_to&&(((c=l.aligned_refs)==null?void 0:c.length)??0)===0&&!l.no_industry_equivalent&&f.jsx("span",{className:"align-arrow missing",children:"unaligned"})]},l.id)})]},a))]})}function ax({readOnly:e,refreshKey:t,onModelChanged:n}){const[r,s]=w.useState(null),[i,o]=w.useState(""),[a,l]=w.useState(""),[c,u]=w.useState(!1),d=w.useCallback(()=>{gm().then(s).catch(()=>s(null)),ym().then(m=>o([m.diff,...m.untracked].filter(Boolean).join(` - -`))).catch(()=>o(""))},[]);return w.useEffect(d,[d,t]),r!=null&&r.git?r.clean?f.jsx("div",{className:"panel-body ok",children:"✓ working tree clean"}):f.jsxs("div",{className:"panel-body",children:[f.jsx("ul",{className:"dirty-list",children:r.dirty.map(m=>f.jsxs("li",{children:[f.jsx("code",{className:"dirty-state",children:m.state})," ",m.path]},m.path))}),f.jsx("pre",{className:"diff-view",children:i.split(` -`).map((m,h)=>f.jsx("span",{className:m.startsWith("+")&&!m.startsWith("+++")?"diff-add":m.startsWith("-")&&!m.startsWith("---")?"diff-del":m.startsWith("@@")?"diff-hunk":"",children:m+` -`},h))}),!e&&f.jsxs(f.Fragment,{children:[f.jsx("input",{className:"edit-input",placeholder:"commit message…",value:a,onChange:m=>l(m.target.value)}),f.jsxs("div",{className:"modal-footer",children:[f.jsx("button",{className:"mini-btn danger",disabled:c,onClick:()=>{confirm("Discard ALL uncommitted model changes?")&&(u(!0),wm().then(()=>{u(!1),d(),n()}))},children:"Discard all"}),f.jsx("button",{className:"primary-btn",disabled:c||!a.trim(),onClick:()=>{u(!0),xm(a).then(()=>{u(!1),l(""),d()})},children:"Commit"})]})]})]}):f.jsx("div",{className:"panel-body",children:"model directory is not in a git repo"})}function lx({readOnly:e}){const[t,n]=w.useState([]),r=w.useCallback(()=>{vm().then(i=>n(i.decisions)).catch(()=>n([]))},[]);if(w.useEffect(r,[r]),t.length===0)return f.jsx("div",{className:"panel-body",children:"no recorded decisions (run `mdl reverse` to propose)"});const s={accepted:"✓",rejected:"✗",proposed:"?"};return f.jsx("div",{className:"panel-body",children:t.map(i=>f.jsxs("div",{className:"decision "+i.verdict,children:[f.jsxs("div",{className:"decision-head",children:[f.jsx("span",{className:"decision-mark",children:s[i.verdict]}),f.jsx("span",{className:"chip",children:i.confidence}),f.jsx("span",{className:"chip",children:i.signal})]}),f.jsx("p",{className:"decision-subject",children:i.subject}),!e&&i.verdict==="proposed"&&f.jsxs("div",{className:"decision-actions",children:[f.jsx("button",{className:"mini-btn",onClick:()=>Os(i.signal_key,"accepted").then(r),children:"Accept"}),f.jsx("button",{className:"mini-btn danger",onClick:()=>Os(i.signal_key,"rejected").then(r),children:"Reject"})]})]},i.signal_key))})}function Rx({exec:e,canEdit:t,onImported:n,submitLabel:r="Import & review",buttonClass:s="erd-action ghost",applyBatch:i,openImport:o=!1}){const[a,l]=w.useState(o&&t?"import":null),[c,u]=w.useState([]),[d,m]=w.useState("postgres"),h=w.useRef(null);w.useEffect(()=>{bm().then(g=>u(g.formats)).catch(()=>u([]))},[]),w.useEffect(()=>{if(!a)return;const g=b=>{h.current&&!h.current.contains(b.target)&&l(null)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[a]);const y=c.find(g=>g.id==="sql");return f.jsxs("div",{className:"ie-wrap",ref:h,children:[f.jsxs("button",{className:s+(a==="export"?" on":""),onClick:()=>l(a==="export"?null:"export"),children:[f.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"↧"}),"Export ",f.jsx("span",{className:"erd-caret",children:"▾"})]}),t&&f.jsxs("button",{className:s+(a==="import"?" on":""),onClick:()=>l(a==="import"?null:"import"),children:[f.jsx("span",{className:"erd-ico","aria-hidden":"true",children:"↥"}),"Import ",f.jsx("span",{className:"erd-caret",children:"▾"})]}),a==="export"&&f.jsxs("div",{className:"ie-menu",role:"menu",children:[(y==null?void 0:y.dialects)&&f.jsxs("label",{className:"ie-dialect",children:[f.jsx("span",{children:"SQL dialect"}),f.jsx("select",{value:d,onChange:g=>m(g.target.value),children:y.dialects.map(g=>f.jsx("option",{value:g,children:g},g))})]}),c.map(g=>f.jsx("a",{className:"ie-item",href:_m(g.id,g.id==="sql"?d:void 0),download:!0,onClick:()=>l(null),children:g.label},g.id))]}),a==="import"&&f.jsx(cx,{exec:e,submitLabel:r,buttonClass:s,applyBatch:i,onClose:()=>l(null),onImported:g=>{l(null),n==null||n(g)}})]})}const ai=[{id:"sql",label:"SQL DDL",hint:"CREATE TABLE … PRIMARY KEY / FOREIGN KEY"},{id:"mermaid",label:"Mermaid erDiagram",hint:"structural: entities, attributes, relationships"},{id:"json-schema",label:"JSON Schema",hint:"each object definition becomes an entity"},{id:"erwin",label:"erwin XML",hint:"entities, keys, relationships, subject areas, subtypes"}];function cx({exec:e,submitLabel:t,buttonClass:n,applyBatch:r,onClose:s,onImported:i}){var v;const[o,a]=w.useState("sql"),[l,c]=w.useState("postgres"),[u,d]=w.useState(""),[m,h]=w.useState(!1),[y,g]=w.useState(null),[b,x]=w.useState([]),_=j=>{j&&j.text().then(d).catch(()=>g("could not read that file"))},$=async()=>{h(!0),g(null),x([]);try{const j=await Em(o,u,o==="sql"?l:void 0);if(!j.changes.length){g(j.warnings[0]??"nothing to import from that document"),h(!1);return}if(r)await r(j.changes);else for(const C of j.changes)await e(C.op,C.payload);x(j.warnings),i(j.tables)}catch(j){g(j instanceof Error?j.message:String(j))}finally{h(!1)}};return f.jsxs("div",{className:"ie-menu ie-import",role:"dialog",children:[f.jsx("div",{className:"ie-tabs",children:ai.map(j=>f.jsx("button",{className:"ie-tab"+(o===j.id?" active":""),onClick:()=>a(j.id),children:j.label},j.id))}),f.jsx("p",{className:"ie-hint",children:(v=ai.find(j=>j.id===o))==null?void 0:v.hint}),o==="sql"&&f.jsxs("label",{className:"ie-dialect",children:[f.jsx("span",{children:"dialect"}),f.jsx("select",{value:l,onChange:j=>c(j.target.value),children:["postgres","snowflake","mysql","duckdb"].map(j=>f.jsx("option",{children:j},j))})]}),f.jsx("textarea",{className:"ie-textarea",placeholder:`Paste ${o} here, or choose a file…`,value:u,onChange:j=>d(j.target.value),rows:8}),f.jsx("input",{type:"file",className:"ie-file",accept:".sql,.mmd,.md,.json,.xml,.txt",onChange:j=>{var C;return _(((C=j.target.files)==null?void 0:C[0])??null)}}),o==="mermaid"&&f.jsx("p",{className:"ie-warn",children:"Mermaid is a diagram format: types and keys are approximate and relationships are inferred from the lines."}),b.map((j,C)=>f.jsx("p",{className:"ie-warn",children:j},C)),y&&f.jsx("p",{className:"ie-error",children:y}),f.jsxs("div",{className:"ie-foot",children:[f.jsx("button",{className:n,onClick:s,children:"Cancel"}),f.jsx("button",{className:n,disabled:m||!u.trim(),onClick:$,children:m?"Importing…":t})]})]})}export{Po as A,dm as B,im as C,km as E,Rx as I,ox as L,Ax as M,sx as O,ii as P,Mo as R,Ix as S,hx as a,Ex as b,bx as c,Sx as d,kx as e,fx as f,gm as g,jx as h,_x as i,gx as j,yx as k,xx as l,vx as m,wx as n,zo as o,Nx as p,mx as q,px as r,pm as s,ri as t,Io as u,ex as v,Qh as w}; diff --git a/packages/server/src/mdl_server/static/assets/styles-DxhL4SV-.css b/packages/server/src/mdl_server/static/assets/styles-DxhL4SV-.css new file mode 100644 index 0000000..442fd83 --- /dev/null +++ b/packages/server/src/mdl_server/static/assets/styles-DxhL4SV-.css @@ -0,0 +1 @@ +.react-flow{direction:ltr}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;cursor:-webkit-grab;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;-webkit-animation:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:-webkit-grab;cursor:grab}.react-flow__node.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:-webkit-grab;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background:#1a192b;border:1px solid white;border-radius:100%}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:-4px;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{font-size:10px;background:#ffffff80;padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@-webkit-keyframes dashdraw{0%{stroke-dashoffset:10}}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:3px;width:150px;font-size:12px;color:#222;text-align:center;border-width:1px;border-style:solid;border-color:#1a192b;background-color:#fff}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{border:none;background:#fefefe;border-bottom:1px solid #eee;box-sizing:content-box;display:flex;justify-content:center;align-items:center;width:16px;height:16px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:5px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:#3367d9;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:#3367d9;border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.ie-wrap{position:relative;display:inline-flex;gap:6px}.erd-ico{font-size:13px;line-height:1;opacity:.85;margin-right:1px}.ie-wrap button:hover .erd-ico,.ie-wrap button.on .erd-ico,.ie-wrap button.active .erd-ico{opacity:1}.erd-caret{opacity:.55;margin-left:1px}.ie-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:30;min-width:220px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:6px;box-shadow:0 12px 32px #00000073;display:flex;flex-direction:column;gap:2px}.ie-item{display:block;padding:8px 10px;border-radius:6px;color:var(--text);text-decoration:none;font-size:13px;cursor:pointer}.ie-item:hover{background:#5eead424;color:var(--accent)}.ie-dialect{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px 8px;margin-bottom:4px;border-bottom:1px solid var(--border);font-size:12px;color:var(--text-dim)}.ie-dialect select{background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:3px 6px;font-size:12px}.ie-import{width:380px;padding:12px;gap:8px}.ie-tabs{display:flex;gap:4px}.ie-tab{flex:1;padding:6px 8px;border-radius:6px;font-size:12px;cursor:pointer;background:none;border:1px solid var(--border);color:var(--text-dim)}.ie-tab.active{border-color:var(--accent);color:var(--accent);background:#5eead41a}.ie-hint{font-size:11px;color:var(--text-dim);margin:0}.ie-textarea{width:100%;font-family:var(--mono);font-size:12px;resize:vertical;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px;box-sizing:border-box}.ie-textarea:focus{border-color:var(--accent);outline:none}.ie-file{font-size:11px;color:var(--text-dim)}.ie-warn{font-size:11px;color:var(--pk);margin:0}.ie-error{font-size:12px;color:var(--err);margin:0}.ie-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}:root{--bg: #14110f;--bg-raised: #1c1815;--bg-card: #221d19;--border: #33291f;--border-strong: #4a3c2c;--text: #ece6dd;--text-dim: #a89a86;--accent: #e0a63a;--accent-soft: rgba(224, 166, 58, .15);--accent-ink: #241a08;--pk: #f2c14e;--err: #f0857a;--warn: #e6a94a;--ok: #6cbf73;--font: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;--mono: "SF Mono", ui-monospace, "Cascadia Code", Menlo, monospace}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:var(--font);background:var(--bg);color:var(--text)}.app{display:flex;flex-direction:column;height:100%}.canvas-wrap{flex:1;position:relative;min-height:0}.react-flow{background:var(--bg)}.topbar{display:flex;flex-direction:column;padding:8px 16px 0;background:var(--bg-raised);border-bottom:1px solid var(--border);z-index:10}.topbar-row{display:flex;align-items:center;gap:14px}.topbar-row.context{padding-bottom:8px}.topbar-row.actions{gap:10px;padding-bottom:8px;flex-wrap:wrap}.brand{display:flex;align-items:baseline;gap:8px;white-space:nowrap}.logo{color:var(--accent);font-size:18px}.brand-name{font-weight:700;letter-spacing:.02em}.project-name{color:var(--text-dim);font-size:13px}.search{flex:0 1 300px;margin-left:auto;padding:7px 12px;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);font-size:13px;outline:none}.search:focus{border-color:var(--accent)}.stats{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--text-dim)}.stat-item{display:inline-flex;align-items:center;gap:5px}.stat-item svg{color:var(--text-dim)}.diag-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:99px;font-weight:600}.diag-chip.ok{background:#34d39926;color:var(--ok)}.diag-chip.warn{background:#fbbf2426;color:var(--warn)}.diag-chip.err{background:#f8717126;color:var(--err)}.hamburger{position:relative;display:inline-flex;align-items:center;justify-content:center;padding:6px;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim);cursor:pointer}.hamburger:hover{color:var(--text);border-color:var(--border-strong)}.hamburger.active{color:var(--accent);border-color:var(--accent)}.hamburger-badge{position:absolute;top:-6px;right:-6px;min-width:15px;height:15px;padding:0 3px;border-radius:99px;background:var(--accent);color:var(--accent-ink);font-size:10px;font-weight:700;line-height:15px;text-align:center}.btn-group{display:inline-flex;align-items:center;gap:2px;background:var(--bg-card);border:1px solid var(--border);border-radius:9px;padding:2px}.grp-tag{font-size:10px;color:var(--text-dim);opacity:.75;padding:0 6px 0 4px;letter-spacing:.03em;text-transform:none;white-space:nowrap}.grp-btn{display:inline-flex;align-items:center;gap:5px;padding:5px 9px;border-radius:6px;border:none;background:transparent;color:var(--text-dim);cursor:pointer;font-size:12px;white-space:nowrap}.grp-btn.icon-only{padding:5px 7px}.grp-btn:hover{color:var(--text);background:#ffffff0d}.grp-btn.active{color:var(--accent)}.grp-btn.active svg{color:var(--accent)}.grp-badge{width:6px;height:6px;border-radius:50%;background:var(--warn);display:inline-block;margin-left:1px}.dir-arrow{display:inline-flex;transition:transform .15s ease}.tool-btn{display:inline-flex;align-items:center;gap:5px;padding:6px 11px;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim);cursor:pointer;font-size:12px}.tool-btn:hover{color:var(--text);border-color:var(--border-strong)}.tool-btn.active{color:var(--accent);border-color:var(--accent)}.tool-btn.primary{color:var(--accent);border-color:#e0a63a66;font-weight:600}.layout-picker{position:relative;display:inline-flex;gap:2px}.layout-picker .caret{font-size:10px}.layout-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:20;background:var(--bg-raised);border:1px solid var(--border-strong);border-radius:8px;padding:4px;min-width:150px;box-shadow:0 8px 24px #0006}.layout-menu button{display:block;width:100%;text-align:left;padding:7px 10px;border:0;border-radius:6px;background:transparent;color:var(--text-dim);cursor:pointer;font-size:13px}.layout-menu button:hover{background:var(--bg-card);color:var(--text)}.canvas-drawer{position:absolute;top:12px;left:12px;bottom:12px;width:300px;background:var(--bg-raised);border:1px solid var(--border);border-radius:14px;padding:16px;overflow-y:auto;z-index:9;box-shadow:0 12px 40px #00000080;display:flex;flex-direction:column;gap:10px;transform:translate(calc(-100% - 16px));opacity:0;pointer-events:none;transition:transform .2s ease,opacity .2s ease}.canvas-drawer.open{transform:translate(0);opacity:1;pointer-events:auto}.drawer-header{display:flex;align-items:center;justify-content:space-between}.drawer-header h2{margin:0;font-size:15px;display:inline-flex;align-items:center;gap:7px}.drawer-header h2 svg{color:var(--accent)}.drawer-hint{font-size:11px;color:var(--text-dim);line-height:1.4}.sa-all{align-self:flex-start;padding:4px 10px;border-radius:7px;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim);cursor:pointer;font-size:12px}.sa-all:hover:not(:disabled){color:var(--text);border-color:var(--border-strong)}.sa-all.active{color:var(--accent);border-color:var(--accent)}.sa-all:disabled{opacity:.5;cursor:default}.sa-list{display:flex;flex-direction:column;gap:3px;margin-top:2px}.sa-row{display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:8px;cursor:pointer;border:1px solid transparent;-webkit-user-select:none;user-select:none}.sa-row:hover{background:var(--bg-card)}.sa-row.active{background:var(--accent-soft);border-color:#e0a63a66}.sa-row.muted{cursor:default;opacity:.7}.sa-row.muted:hover{background:transparent}.sa-row input[type=checkbox]{accent-color:var(--accent);cursor:pointer}.sa-chip{width:12px;height:12px;border-radius:3px;flex:0 0 auto}.sa-chip.none{background:repeating-linear-gradient(45deg,#4a3c2c,#4a3c2c 2px,transparent 2px,transparent 4px)}.sa-name{flex:1;font-size:13px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sa-row.muted .sa-name{color:var(--text-dim)}.sa-count{font-size:11px;color:var(--text-dim);background:var(--bg-card);padding:1px 7px;border-radius:99px;flex:0 0 auto}.entity-node{width:264px;background:var(--bg-card);border:1px solid var(--border);border-top:3px solid var(--accent);border-radius:10px;overflow:hidden;box-shadow:0 4px 18px #00000059;font-size:12px;transition:opacity .15s,box-shadow .15s,border-color .15s}.entity-node.selected{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent),0 8px 24px #00000080}.entity-node.highlighted{box-shadow:0 0 0 2px var(--pk),0 8px 24px #00000080}.entity-node.dimmed{opacity:.18}.entity-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:#ffffff08;border-bottom:1px solid var(--border)}.entity-name{font-weight:700;font-size:13px;letter-spacing:.01em}.entity-badges{display:flex;gap:4px}.badge{font-size:10px;padding:1px 6px;border-radius:99px;background:var(--accent-soft);color:var(--accent);text-transform:uppercase;letter-spacing:.05em}.badge.ontology{background:#93c5fd1f;color:#93c5fd}.attr-section{padding:4px 0}.attr-section.keys{border-bottom:1px solid var(--border);background:#fcd34d0a}.attr-row{display:flex;align-items:center;gap:6px;padding:3px 12px;height:26px;line-height:20px;position:relative}.attr-row.empty{color:var(--text-dim);font-style:italic}.attr-row.more{color:var(--text-dim);font-style:italic;cursor:pointer;justify-content:center;height:22px;font-size:11px}.attr-row.more:hover{color:var(--accent);background:var(--accent-soft)}.attr-row.rel-hit{background:var(--accent-soft);box-shadow:inset 2px 0 0 var(--accent)}.attr-row.rel-hit .attr-name{color:var(--accent);font-weight:600}.attr-row.rel-dim{opacity:.35}.attr-row.endpoint .attr-name{font-style:normal}.attr-port{width:8px!important;height:8px!important;opacity:0;top:50%!important}.attr-port.react-flow__handle-left{left:-5px!important}.attr-port.react-flow__handle-right{right:-5px!important}.entity-node:hover .attr-port{opacity:.5}.attr-row:hover .attr-port{opacity:1!important;background:var(--accent)!important}.attr-icon{width:14px;text-align:center;font-size:10px;flex:none}.attr-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attr-name.pk{color:var(--pk);font-weight:600}.attr-type{color:var(--text-dim);font-family:var(--mono);font-size:10px;flex:none}.attr-notnull{color:var(--text-dim);font-size:8px;flex:none}.port{width:11px!important;height:11px!important;background:var(--border-strong)!important;border:2px solid var(--bg)!important;opacity:.55;transition:transform .12s ease,background .12s ease,opacity .12s ease}.entity-node:hover .port{opacity:1;background:var(--accent)!important;transform:scale(1.25);box-shadow:0 0 0 4px var(--accent-soft);cursor:crosshair}.port:hover{transform:scale(1.6)!important;cursor:crosshair}.entity-node:hover{border-color:var(--accent);box-shadow:0 0 0 1px #e0a63a40}.react-flow__connectionline .react-flow__edge-path,.react-flow__connection-path{stroke:var(--accent)!important;stroke-width:2!important}.rel-path{stroke:var(--border-strong);stroke-width:1.6}.rel-edge{cursor:pointer}.rel-glyph{stroke:var(--border-strong);stroke-width:1.6;fill:none}.rel-glyph.ring{fill:var(--bg)}.rel-edge:hover .rel-path,.rel-edge.selected .rel-path,.rel-edge:hover .rel-glyph,.rel-edge.selected .rel-glyph{stroke:var(--accent)}.rel-edge.dimmed{opacity:.12}.rel-label{fill:var(--text);font-size:11px;text-anchor:middle;paint-order:stroke;stroke:var(--bg);stroke-width:4px}.detail-panel{position:absolute;top:12px;right:12px;bottom:12px;width:340px;background:var(--bg-raised);border:1px solid var(--border);border-radius:14px;padding:18px;overflow-y:auto;z-index:9;box-shadow:0 12px 40px #00000080}.detail-header{display:flex;justify-content:space-between;align-items:flex-start}.detail-header h2{margin:0 0 6px;font-size:18px}.icon-btn{background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:14px}.icon-btn:hover{color:var(--text)}.definition{color:var(--text-dim);font-size:13px;line-height:1.5}.detail-panel section{margin-top:18px}.detail-panel h3{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim)}.kv{display:flex;gap:8px;margin:4px 0;font-size:12px;align-items:baseline}.kv .k{color:var(--text-dim);min-width:72px}.kv .v{word-break:break-all}.chip{display:inline-block;font-size:11px;padding:2px 8px;margin:2px 4px 2px 0;border-radius:99px;background:#94a3b81f;color:var(--text-dim)}.chip.pattern{background:var(--accent-soft);color:var(--accent)}.chip.layer-industry{background:#93c5fd26;color:#93c5fd}.chip.layer-core{background:var(--accent-soft);color:var(--accent)}.chip.layer-domain{background:#f0abfc26;color:#f0abfc}.chip.layer-specialised{background:#fcd34d26;color:var(--pk)}.cat-badge{font-size:10px;font-weight:700;margin-left:6px;padding:2px 8px;border-radius:5px;cursor:help}.cat-badge.supertype{background:#a78bfa2e;color:#a78bfa}.cat-badge.subtype{background:var(--accent-soft);color:var(--accent)}.udp-row td{padding:3px 6px;border-bottom:1px solid var(--border);font-size:12px}.udp-key{color:var(--text-dim);font-family:var(--mono);font-size:11px}.udp-val{color:var(--text)}.enum-badge{font-size:8px;font-weight:700;margin-left:6px;padding:1px 5px;border-radius:4px;background:#a78bfa2e;color:#a78bfa;vertical-align:middle;cursor:help}.key-row{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px}.key-badge{font-size:9px;font-weight:700;padding:2px 6px;border-radius:5px;background:#94a3b826;color:var(--text-dim);flex:none}.key-badge.pk{background:#fcd34d2e;color:var(--pk)}.key-badge.unique,.key-badge.alternate{background:var(--accent-soft);color:var(--accent)}.key-name{font-weight:600}.key-cols{color:var(--text-dim);font-family:var(--mono);font-size:11px}.attr-table{width:100%;border-collapse:collapse;font-size:12px;table-layout:auto}.attr-table td{padding:4px 6px;border-bottom:1px solid var(--border)}.attr-table td:first-child{width:100%}.attr-table td:first-child .edit-input{min-width:120px}.attr-table td.pk{color:var(--pk);font-weight:600}.attr-table td.type{color:var(--text-dim);font-family:var(--mono);font-size:11px}.attr-table td.null{color:var(--text-dim);font-size:10px;text-align:right}.rel-link{display:flex;gap:8px;align-items:center;width:100%;background:var(--bg-card);border:1px solid var(--border);border-radius:8px;color:var(--text);padding:7px 10px;margin:4px 0;cursor:pointer;font-size:12px;text-align:left}.rel-link:hover{border-color:var(--accent)}.rel-card{color:var(--text-dim);font-family:var(--mono);font-size:11px}.ulid{font-family:var(--mono);font-size:11px;color:var(--text-dim);cursor:copy;word-break:break-all}.ulid:hover{color:var(--accent)}.splash{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:var(--text-dim)}.splash.error pre{background:var(--bg-card);padding:12px 16px;border-radius:8px;max-width:640px;overflow:auto;color:var(--err);font-size:12px}.react-flow__minimap{background:var(--bg-raised)!important;border-radius:10px}.react-flow__controls{border-radius:10px;overflow:hidden;box-shadow:none!important}.react-flow__controls-button{background:var(--bg-raised)!important;border-bottom:1px solid var(--border)!important;fill:var(--text-dim)!important}.react-flow__controls-button:hover{fill:var(--text)!important}.edit-input{width:100%;padding:6px 9px;border-radius:7px;font-size:12px;border:1px solid var(--border);background:var(--bg-card);color:var(--text);font-family:var(--font);outline:none}.edit-input:focus{border-color:var(--accent)}.entity-title-input{font-size:17px;font-weight:700;background:transparent;border-color:transparent;padding-left:0}.entity-title-input:hover,.entity-title-input:focus{border-color:var(--border);background:var(--bg-card);padding-left:9px}.definition-input{color:var(--text-dim);line-height:1.5;resize:vertical}.chip-select,.cell-select{font-size:11px;padding:2px 6px;margin:2px 6px 2px 0;border-radius:99px;background:#94a3b81f;color:var(--text-dim);border:1px solid transparent;outline:none}.chip-select:hover,.cell-select:hover{border-color:var(--border-strong);color:var(--text)}.cell-select{border-radius:6px;background:transparent;max-width:110px}.mini-btn{font-size:11px;padding:3px 9px;border-radius:7px;cursor:pointer;border:1px solid var(--border);background:var(--bg-card);color:var(--text-dim)}.mini-btn:hover{color:var(--accent);border-color:var(--accent)}.mini-btn.danger:hover{color:var(--err);border-color:var(--err)}.h3-actions{float:right;display:inline-flex;gap:6px}.empty-hint{color:var(--text-dim);font-size:12px;font-style:italic}.add-attr{display:flex;gap:6px;margin-top:8px}.rel-row{display:flex;gap:6px;align-items:flex-start}.rel-row .rel-main{flex:1}.verb-phrases{display:flex;align-items:center;gap:4px;margin-top:2px;padding-left:4px}.verb-phrases .verb-input{font-size:11px;font-style:italic;color:var(--text-dim);min-width:40px}.verb-phrases .verb-sep{color:var(--text-dim);font-size:11px}.physical-name-row{display:flex;align-items:center;gap:6px;margin-top:2px}.physical-name-row .physical-label{font-size:9px;text-transform:uppercase;color:var(--text-dim);letter-spacing:.04em}.physical-name-input{font-size:12px;color:var(--text-dim)}.physical-col{display:block;font-size:10px;color:var(--text-dim);font-family:var(--mono, monospace)}.physical-col-input{display:block;font-size:10px;color:var(--text-dim)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#05080db3;z-index:50;display:flex;align-items:center;justify-content:center}.modal{width:440px;max-height:80vh;overflow-y:auto;background:var(--bg-raised);border:1px solid var(--border-strong);border-radius:14px;padding:20px;box-shadow:0 24px 80px #0009}.modal.wide{width:600px}.modal-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}.modal-header h2{margin:0;font-size:16px}.modal-search{margin-bottom:10px}.modal-footer{display:flex;gap:10px;justify-content:flex-end;align-items:center;margin-top:14px}.modal-footer label{font-size:11px;color:var(--text-dim);display:flex;flex-direction:column;gap:3px}.modal-footer select,.form-row select{background:var(--bg-card);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:5px 8px;font-size:12px}.primary-btn{padding:8px 16px;border-radius:8px;border:none;cursor:pointer;background:var(--accent);color:var(--accent-ink);font-weight:700;font-size:13px}.primary-btn:disabled{opacity:.4;cursor:default}.danger-btn{padding:8px 16px;border-radius:8px;border:1px solid var(--err);cursor:pointer;background:#f8717124;color:var(--err);font-weight:700;font-size:13px}.form-row{display:flex;flex-direction:column;gap:4px;margin-bottom:14px;font-size:12px;color:var(--text-dim)}.form-row>label{font-weight:600;letter-spacing:.02em;text-transform:uppercase;font-size:10px}.form-error{color:var(--err);font-size:11px}.form-preview{color:var(--text-dim);font-size:11px;word-break:break-all;opacity:.85}.form-preview:before{content:""}.form-hint{color:var(--text-dim);font-size:11px;font-style:italic;opacity:.75;word-break:break-word}.term-results{display:flex;flex-direction:column;gap:8px;max-height:44vh;overflow-y:auto}.term-card{text-align:left;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:10px 12px;cursor:pointer;color:var(--text)}.term-card:hover{border-color:var(--border-strong)}.term-card.picked{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.term-head{display:flex;justify-content:space-between;align-items:baseline}.term-label{font-weight:600;font-size:13px}.term-source{font-size:10px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.06em}.term-iri{font-size:10px;color:var(--accent);display:block;margin:2px 0;word-break:break-all}.term-def{font-size:11px;color:var(--text-dim);margin:4px 0 0;line-height:1.45}.kind-badge{font-size:8px;padding:1px 5px;margin-right:6px;border-radius:999px;background:#f0abfc26;color:#f0abfc;letter-spacing:.04em}.src-picker{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}.src-chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:3px 9px;border-radius:999px;background:var(--bg);border:1px solid var(--border);color:var(--text-dim);cursor:pointer}.src-chip:hover{border-color:var(--border-strong);color:var(--text)}.src-chip.active{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}.src-layer{font-size:8px;padding:0 5px;border-radius:999px;text-transform:uppercase;letter-spacing:.04em}.side-panel{position:absolute;top:12px;right:12px;bottom:12px;width:380px;background:var(--bg-raised);border:1px solid var(--border);border-radius:14px;padding:18px;overflow-y:auto;z-index:9;box-shadow:0 12px 40px #00000080}.side-panel h2{margin:0;font-size:16px}.side-panel h4{margin:10px 0 6px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim)}.panel-body{margin-top:12px}.panel-body.ok{color:var(--ok)}.meta-line{font-size:10px;color:var(--text-dim);margin:6px 0 10px}.coverage-banner{font-size:12px;padding:8px 12px;border-radius:9px;margin-bottom:12px;background:#34d3991a;color:var(--ok)}.coverage-banner.warn{background:#fbbf241a;color:var(--warn)}.layer-band{border:1px dashed var(--border);border-radius:10px;padding:8px 12px 10px;margin-bottom:10px}.layer-band.external{border-style:solid;background:#93c5fd0a}.stack-term{display:flex;justify-content:space-between;align-items:baseline;gap:8px;width:100%;background:var(--bg-card);border:1px solid var(--border);color:var(--text);border-radius:7px;padding:5px 10px;margin:4px 0;font-size:12px;cursor:pointer;text-align:left}div.stack-term{cursor:default}.stack-term:hover{border-color:var(--border-strong)}.stack-term.uncovered{border-color:var(--err)}.align-arrow{font-size:10px;color:var(--accent);white-space:nowrap}.align-arrow.unresolved{color:var(--warn)}.align-arrow.missing{color:var(--err);font-style:italic}.align-arrow.proposed{color:var(--warn);font-style:italic}.ref-list{display:flex;flex-direction:column;gap:6px;margin-top:4px}.ref-card{border:1px solid var(--border);border-radius:8px;padding:6px 8px;background:var(--bg)}.ref-card.proposed{border-color:var(--warn)}.ref-head{display:flex;align-items:baseline;gap:8px;justify-content:space-between}.ref-uri{font-family:var(--mono);font-size:12px;word-break:break-all}.ref-status{font-size:9px;text-transform:uppercase;letter-spacing:.04em}.ref-status.accepted{color:var(--accent)}.ref-status.proposed{color:var(--warn)}.ref-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:5px}.ref-pill{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--accent-soft);color:var(--accent)}.ref-via{font-size:10px;color:var(--text-dim)}.ref-actions{display:flex;gap:6px;margin-top:6px}.dirty-list{list-style:none;padding:0;margin:0 0 10px;font-size:12px}.dirty-list li{padding:2px 0}.dirty-state{color:var(--warn);margin-right:6px;font-family:var(--mono)}.diff-view{background:var(--bg);border:1px solid var(--border);border-radius:9px;padding:10px;font-size:10.5px;line-height:1.5;overflow:auto;max-height:42vh;font-family:var(--mono);white-space:pre;margin-bottom:10px}.diff-add{color:var(--ok)}.diff-del{color:var(--err)}.diff-hunk{color:#93c5fd}.decision{border:1px solid var(--border);border-radius:9px;padding:8px 12px;margin-bottom:8px}.decision.accepted{opacity:.65}.decision.rejected{opacity:.45}.decision-head{display:flex;gap:6px;align-items:center}.decision-mark{font-weight:700}.decision-subject{font-size:12px;margin:6px 0}.decision-actions{display:flex;gap:6px}.toast{position:absolute;bottom:20px;left:50%;transform:translate(-50%);background:var(--bg-raised);border:1px solid var(--warn);color:var(--text);border-radius:10px;padding:10px 18px;font-size:12px;z-index:60;box-shadow:0 10px 30px #00000080} diff --git a/packages/server/src/mdl_server/static/index.html b/packages/server/src/mdl_server/static/index.html index 2cf9518..47f766d 100644 --- a/packages/server/src/mdl_server/static/index.html +++ b/packages/server/src/mdl_server/static/index.html @@ -4,10 +4,10 @@ Modelith - + - - + +
diff --git a/packages/server/src/mdl_server/static/sme.html b/packages/server/src/mdl_server/static/sme.html index 27e4cfe..85a3038 100644 --- a/packages/server/src/mdl_server/static/sme.html +++ b/packages/server/src/mdl_server/static/sme.html @@ -4,10 +4,10 @@ Modelith Glossary - + - - + + diff --git a/specs/modelith-canvas-redesign-spec.md b/specs/modelith-canvas-redesign-spec.md new file mode 100644 index 0000000..8087935 --- /dev/null +++ b/specs/modelith-canvas-redesign-spec.md @@ -0,0 +1,162 @@ +# Studio Canvas: toolbar redesign + subject-area filter drawer + +## Context + +The Studio Canvas toolbar (branch `canvas-ux`) is a single non-wrapping flex row cramming +brand + search + a subject-area color **legend** + stats + ~11 cryptic Unicode glyph buttons +(`⬡ ≣ ± ⚖ {T} ⇕ ⟳ ⌗ ▾ ← ⛶`). The legend (`TopBar.tsx` `.legend`, `styles.css:47`) has +`flex-wrap: wrap` on its items but lives in a `nowrap` row, so with several subject areas it +squeezes, stacks into multiple lines, and shoves the whole bar taller — the "renders horribly" +the user saw. Worse, subject areas are a **static color key with no interaction**: there is no +way to focus/visualise a single domain, which is the entire point of subject areas on a large +(46-entity) model. + +Two things already exist and must be reused, not reinvented: +1. **A better toolbar already lives on `feat-semantic-compare-merge`**: a two-row layout + (row 1 = brand/search/status, row 2 = grouped, *labelled* action buttons), an inline-SVG + icon library `canvas/src/icons.tsx` (17 icons, no font dependency, crisp on every OS), and + grouped-button CSS (`.topbar-row`, `.btn-group`, `.grp-btn`, `.grp-tag`, `.sa-legend`). That + branch still leaves subject areas as a static `.sa-legend` strip with no filtering. +2. **`areaByEntity`** (`ModelCanvas.tsx:154`, `Map`) already resolves every + entity → its subject area from both the direct pointer and the inverted `members` list. It is + the ready-made filter key. + +**Intended outcome:** adopt the `feat` branch's grouped two-row toolbar as the base (reconciling +the two divergent toolbars), keep the layout-picker + the new flow-direction toggle already on +`canvas-ux`, and add a **left slide-out drawer** (hamburger, top-left) that lists subject areas +as an *interactive filter* — click a domain to show ONLY it (hide the rest), multi-select via +checkboxes, with color chips + entity counts — plus the layout/direction controls. Filtering +hides non-selected entities (React Flow `hidden`) and auto-fits to the visible set. + +User decisions (locked): **adopt `feat` toolbar + extend**; **hide** non-selected on filter; +**left slide-out drawer** holding both the domain filter and the layout controls. + +## Deliverables + +### A. Adopt the grouped two-row toolbar (port from `feat-semantic-compare-merge`) +- Bring `canvas/src/icons.tsx` onto `canvas-ux` verbatim (17 inline-SVG icons), plus a few new + icons this feature needs: **IconMenu** (hamburger), **IconFilter/IconDomains**, and direction + arrows (or reuse `IconLayout` + a rotating glyph). Keep the `Svg` wrapper + `currentColor`/size + convention. +- Restructure `TopBar.tsx` into the two rows and grouped `.btn-group`s exactly as the `feat` + branch does (`context` row: brand, search, `.stats` with `IconEntity`/`IconRelationship`/diag + chip; `actions` row: `+ Entity`, **Panels** group, **View** group, **Data** group). Replace + every Unicode glyph with its SVG icon + (where the `feat` branch does) a text label. +- Port the toolbar CSS blocks (`.topbar-row`, `.btn-group`, `.grp-btn`, `.grp-tag`, + `.grp-badge`, `.stat-item`) into `canvas/src/styles.css`, replacing the old single-row + `.topbar`/`.legend`/`.actions` rules. +- **Merge, don't overwrite, the LayoutPicker**: the `feat` picker has NO direction toggle; the + `canvas-ux` picker (current `TopBar.tsx:173`) has the `LayoutDir` cycle (→ ↓ ← ↑) I just added. + Keep the direction toggle and render it inside the ported **View** group next to the picker. +- **Remove the `.sa-legend` strip entirely** — subject areas move into the drawer (§C). This is + what fixes the wrapping. + +### B. Subject-area filter state + canvas hide (the engine) +- Add filter state in `App.tsx` (the owner of `doc`, `selectedId`, panel state): a + `Set` of **active subject-area ids** (`activeAreas`), empty = show all. Pass it + + `areaByEntity`-derived membership down to `ModelCanvas`. + - `areaByEntity` currently lives inside `ModelCanvas`; either lift a small + `entityArea: Map` derivation to `App` (so both the drawer counts and the + canvas filter share one source) or pass `activeAreas` into `ModelCanvas` and filter there + using the existing internal `areaByEntity`. Prefer passing `activeAreas` down and filtering + inside `ModelCanvas` — keeps `areaByEntity` where it is. +- **Hide, not dim** (per decision). In `ModelCanvas.tsx`: + - Heavy derivation effect (`:212-239`): set `hidden: activeAreas.size > 0 && + !activeAreas.has(areaByEntity.get(e.id)?.id ?? "")` on each node. React Flow auto-hides edges + whose endpoint node is hidden, so no edge bookkeeping needed (confirmed: no manual edge-hide + required beyond the existing endpoint-existence filter at `:241`). + - **Mirror the same `hidden` rule in the lightweight hover effect** (`:355-374`) or the hover + re-derivation will un-hide filtered nodes on mouseover — this is the same reason that effect + already re-derives `searchDim`/`neighbourDim`. This is the one required consistency point. + - After a filter change, **auto-fit to the visible set and relayout**: call `fitView` + (existing) and re-run `layoutGraph` over the visible nodes so the focused domain uses the + whole canvas. Reuse the `relayout` path (`:423`) which already fits. +- `onlyRenderVisibleElements` is already on (`:510`) and the search-fit reads node rects + (`:399-421`); `hidden: true` keeps nodes in the array (unlike array-filtering), so fit/layout + logic keeps working. Confirmed safe by exploration. + +### C. Left slide-out drawer — `canvas/src/CanvasDrawer.tsx` (new) +- A new component mirroring the `.side-panel` convention (absolute card inside `.canvas-wrap`) + but anchored **left** and **animated** (this introduces the first slide transition in the + codebase — `transform: translateX(-100%)` → `0`, `transition: transform .18s ease`). +- **Hamburger toggle** (`IconMenu`) at the top-left of the toolbar's row-1 (or floating top-left + of `.canvas-wrap`), using the same single-state toggle pattern as `panelTab` + (`App.tsx:243`) — a new `drawerOpen` boolean in `App`. +- Drawer contents, top to bottom: + 1. **Subject areas** — one row per `doc.subject_areas`: a color chip (`saColors.get(sa.id)`), + the name, an entity **count** (from `areaByEntity` / `sa.member_count`), and a checkbox. + Clicking a row = focus that domain (set `activeAreas` to just it); checkboxes = multi-select + add/remove. An "All / Clear" affordance resets `activeAreas` to empty (show all). The active + rows get an `.active` accent. This replaces the dead legend with the filter the user asked + for. + 2. **Layout** — move the layout picker + direction toggle here too (per decision: drawer holds + both filter and layout controls), OR keep them in the toolbar View group and only surface a + compact mirror. Recommend: keep the primary controls in the toolbar (discoverable) and put + the domain filter as the drawer's main job; add layout controls to the drawer only if it + reads cleanly. (Confirm during build; low risk either way.) +- Gate the drawer + hamburger behind `!minimal` (the VS Code preview pane hides the toolbar; + `App.tsx:225`), since it's a toolbar-adjacent control. + +### D. CSS +- New `.canvas-drawer` (left, absolute, `top/bottom:12px; left:12px; width:300px`, + `var(--bg-raised)`, radius 14px, `z-index:9`, slide transition) + `.drawer-open` modifier. +- `.sa-row` (chip + name + count + checkbox, `.active` state), reusing tokens + (`--accent`, `--accent-soft`, `--text-dim`, swatch style at `styles.css:49`). +- Port the `feat` toolbar CSS (§A). No new color tokens — palette is complete (`:root`). + +### E. Verify + test +- `cd canvas && npm run build` (Node 20 via nvm) — typecheck + bundle. Rebuilt static bundle + lands under `packages/server/src/mdl_server/static` (committed as today). +- Live-verify on the 46-entity / 5-domain fund fixture (served on :4811 via a temporary `fund` + launch config, reverted before commit): (1) toolbar is two-row, grouped, no wrapping legend; + (2) hamburger opens the left drawer with 5 domains, chips + counts; (3) clicking a domain hides + the other 4 and fits to it; (4) multi-select shows the union; (5) Clear restores all; (6) hover + over a PK/FK does NOT un-hide filtered nodes (the consistency point); (7) minimap reflects the + hidden set; (8) coloring + clustering still hold. +- Add a canvas Vitest for the filter predicate if a clean unit boundary exists (e.g. a pure + `visibleUnder(activeAreas, areaByEntity)` helper) — mirrors the Vitest already added on + `canvas-ux`. Not required if the logic stays inline. + +## Critical files +- `canvas/src/icons.tsx` — **new on canvas-ux** (port from `feat-semantic-compare-merge`), + a + few new icons (menu, filter, direction). +- `canvas/src/TopBar.tsx` — restructure to two-row grouped layout; merge the ported toolbar with + the existing direction-toggle LayoutPicker; add the hamburger; drop `.sa-legend`. +- `canvas/src/CanvasDrawer.tsx` — **new**: left slide-out with the subject-area filter (+ layout + controls). +- `canvas/src/App.tsx` — `drawerOpen` + `activeAreas` state; wire drawer + pass filter to canvas; + `!minimal` gating. +- `canvas/src/ModelCanvas.tsx` — apply the `hidden` filter in BOTH the heavy effect (`:212`) and + the hover effect (`:355`); fit + relayout on filter change. +- `canvas/src/styles.css` — port toolbar CSS from `feat`; add `.canvas-drawer` / `.sa-row`; + remove old `.legend`/single-row `.topbar`. + +## Reuse (do not reinvent — from exploration) +- `icons.tsx` (17 SVG icons) + toolbar CSS (`.topbar-row/.btn-group/.grp-btn/.grp-tag`) — + `git show feat-semantic-compare-merge:canvas/src/{icons.tsx,TopBar.tsx,styles.css}`. +- `areaByEntity` (`ModelCanvas.tsx:154`) — the entity→area filter key, already dual-sourced. +- `saColors` (`ModelCanvas.tsx:136`) — area id → color, for the drawer chips + minimap. +- `.side-panel` card pattern (`SidePanel.tsx` + `styles.css:373`) — mirror for the left drawer. +- LayoutPicker outside-click-to-close pattern (`TopBar.tsx:176-183`) — for any drawer popovers. +- `panelTab` single-state toggle (`App.tsx:243`) — the pattern for `drawerOpen`. +- `relayout` / `fitView` (`ModelCanvas.tsx:423`) — fit-to-visible after a filter change. + +## Risk posture +- **Toolbar port is the biggest surface** but it's a known-good design already shipped on another + branch — a port + merge with the direction toggle, not a fresh invention. Reconciles the two + divergent toolbars (net simplification for the eventual `feat-semantic-compare-merge` merge: + both branches converge on the same toolbar). +- **The one correctness trap** is the hover effect re-un-hiding filtered nodes; the plan calls it + out explicitly and it has a clear precedent (search dimming is already mirrored there). +- **Hide via `hidden: true`** (not array-filter) keeps fit/layout/minimap working with no extra + edge bookkeeping — the lowest-risk hide mechanism per exploration. +- The slide animation is the first in the codebase but is cosmetic and isolated to one new CSS + block; if it misbehaves, the drawer still works as an instant show/hide like `.side-panel`. +- All additive/branch-local on `canvas-ux`; nothing touches the server/API. + +## Verification +- `cd canvas && npm run build` (Node 20) — clean typecheck + bundle. +- Manual on the fund fixture (:4811), the 8 checks in §E — especially the hover-vs-hide + consistency check and fit-to-domain. +- Revert the temporary `fund` launch config before committing; commit on `canvas-ux` (no push / + PR without explicit go-ahead, per standing instruction). \ No newline at end of file diff --git a/vscode/package.json b/vscode/package.json index 0a9d05f..88a0ddc 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -2,7 +2,7 @@ "name": "modelith-vscode", "displayName": "Modelith", "description": "Ontology-anchored, git-native data modeling for dbt — validate, generate, drift, and the Modelith canvas inside VS Code.", - "version": "0.3.17", + "version": "0.3.18", "publisher": "BosonResearch", "license": "Apache-2.0", "icon": "icon.png", diff --git a/vscode/src/mdl.ts b/vscode/src/mdl.ts index b890fac..766b3ea 100644 --- a/vscode/src/mdl.ts +++ b/vscode/src/mdl.ts @@ -65,7 +65,15 @@ const REAL_FSX: Fsx = { * Runs in the extension host, which in a devcontainer is *inside* the container * (extensionKind: workspace), so detection sees the container's toolchain. */ export async function findMdl(root: string): Promise { - if (cached) return cached; + // Trust the cache only if it still points at a real file. An absolute path can go + // stale when the CLI is upgraded/reinstalled elsewhere (the Windows AppData→new-path + // case); a bare PATH name or ` -m mdl_cli` can't be existence-checked, so it + // is trusted as before (spawn ENOENT there resets the cache — see runMdl). + if (cached) { + const abs = cached.args.length === 0 && path.isAbsolute(cached.cmd); + if (!abs || fs.existsSync(cached.cmd)) return cached; + resetMdlCache(); + } const cfg = vscode.workspace.getConfiguration("modelith"); const explicit = cfg.get("mdlPath")?.trim(); const candidates: MdlBin[] = []; @@ -293,29 +301,59 @@ export interface RunResult { stderr: string; } -export function runMdl( +/** One spawn attempt. Resolves with the result, or with `enoent: true` when the command + * could not be launched (the binary is missing/unspawnable — a broken Windows console + * shim raises this even though the .exe exists and runs from a shell). */ +function spawnOnce( bin: MdlBin, args: string[], cwd: string, - out?: vscode.OutputChannel, - timeoutMs = 120000, -): Promise { - // Echo the exact CLI invocation before running, so every model UI action is - // transparent in the Modelith output (matching the `[canvas] mdl serve …` line). - out?.appendLine(`[run] ${bin.label} ${args.join(" ")} (cwd ${cwd})`); + timeoutMs: number, +): Promise { return new Promise((res) => { - // Default 120s; a live-DB reverse (`--connect` runs dbt debug + introspection over a - // possibly-cold warehouse) passes a longer timeout. const p = cp.spawn(bin.cmd, [...bin.args, ...args], { cwd, timeout: timeoutMs }); let stdout = ""; let stderr = ""; p.stdout.on("data", (d) => (stdout += d)); p.stderr.on("data", (d) => (stderr += d)); - p.on("error", (e) => res({ code: -1, stdout, stderr: String(e) })); + p.on("error", (e) => { + const enoent = (e as NodeJS.ErrnoException).code === "ENOENT"; + res({ code: -1, stdout, stderr: String(e), enoent }); + }); p.on("exit", (code) => res({ code: code ?? -1, stdout, stderr })); }); } +export async function runMdl( + bin: MdlBin, + args: string[], + cwd: string, + out?: vscode.OutputChannel, + timeoutMs = 120000, +): Promise { + // Echo the exact CLI invocation before running, so every model UI action is + // transparent in the Modelith output (matching the `[canvas] mdl serve …` line). + out?.appendLine(`[run] ${bin.label} ${args.join(" ")} (cwd ${cwd})`); + // Default 120s; a live-DB reverse (`--connect` runs dbt debug + introspection over a + // possibly-cold warehouse) passes a longer timeout. + const first = await spawnOnce(bin, args, cwd, timeoutMs); + if (!first.enoent) return first; + + // The resolved command could not be launched. On Windows this is the classic broken + // console-shim case: `pip install --upgrade` can leave an mdl.exe whose embedded + // interpreter path no longer resolves under spawn (it still runs from a shell, which + // is why `where mdl` / a manual `mdl --version` work, but the extension gets ENOENT). + // ` -m mdl_cli` needs no shim, so retry through the interpreter; and drop the + // cache so the next findMdl re-resolves. + resetMdlCache(); + const fresh = await findMdl(cwd).catch(() => null); + if (fresh && (fresh.cmd !== bin.cmd || fresh.args.join(" ") !== bin.args.join(" "))) { + out?.appendLine(`[run] retry via ${fresh.label} (the previous binary would not launch)`); + return spawnOnce(fresh, args, cwd, timeoutMs); + } + return first; +} + // --- CLI capability handshake (version skew) ----------------------------------- /** Suggest the upgrade command that matches HOW this `mdl` was installed. The