@eventcatalog/visualiser 5.0.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/NodeGraph.tsx","../src/nodes/note/NoteNode.tsx","../src/nodes/shared-styles.ts","../src/nodes/service/ServiceNode.tsx","../src/utils/custom-icon.tsx","../src/utils/url-builder.ts","../src/nodes/OwnerIndicator.tsx","../src/utils/node-connections.ts","../src/nodes/NotesIndicator.tsx","../src/context/PortalContainerContext.tsx","../src/nodes/TruncatedResourceName.tsx","../src/nodes/FocusedResourceIndicator.tsx","../src/nodes/Agent.tsx","../src/nodes/AgentTool.tsx","../src/icons/protocols/mcp-dark.svg","../src/icons/protocols/mcp-light.svg","../src/nodes/event/EventNode.tsx","../src/nodes/ApiInfo.tsx","../src/nodes/event/config.ts","../src/nodes/query/QueryNode.tsx","../src/nodes/command/CommandNode.tsx","../src/nodes/channel/ChannelNode.tsx","../src/nodes/data/DataNode.tsx","../src/nodes/data/config.ts","../src/nodes/view/ViewNode.tsx","../src/nodes/actor/ActorNode.tsx","../src/nodes/actor/config.ts","../src/nodes/field/FieldNode.tsx","../src/nodes/field/config.ts","../src/nodes/external-system/ExternalSystem.tsx","../src/nodes/external-system/config.ts","../src/nodes/ContextActor.tsx","../src/nodes/SystemGroupNode.tsx","../src/nodes/DomainCard.tsx","../src/nodes/Flow.tsx","../src/utils/badges.tsx","../src/utils/protocols.tsx","../src/nodes/FlowExpandedNode.tsx","../src/nodes/Entity.tsx","../src/nodes/User.tsx","../src/nodes/Step.tsx","../src/nodes/Domain.tsx","../src/nodes/System.tsx","../src/nodes/GroupNode.tsx","../src/nodes/Custom.tsx","../src/nodes/ExternalSystem2.tsx","../src/nodes/DataProduct.tsx","../src/nodes/SwimlaneNode.tsx","../src/nodes/message-group/MessageGroupNode.tsx","../src/nodes/message-group/MessageGroupExpandedNode.tsx","../src/nodes/diagram-nodes.ts","../src/edges/AnimatedMessageEdge.tsx","../src/utils/flow-portals.tsx","../src/edges/use-cross-domain.ts","../src/edges/EdgeLabel.tsx","../src/edges/route.ts","../src/edges/DomainEdgeEnds.tsx","../src/edges/MultilineEdgeLabel.tsx","../src/edges/FlowEdge.tsx","../src/edges/LabelledEdge.tsx","../src/components/VisualiserSearch.tsx","../src/components/StepWalkthrough.tsx","../src/utils/keyboard.ts","../src/components/FocusMode/utils.ts","../src/components/WalkthroughBadges.tsx","../src/components/CanvasToolbar.tsx","../src/components/Tip.tsx","../src/components/SwimlanePicker.tsx","../src/components/FocusModeModal.tsx","../src/components/FocusMode/FocusModeContent.tsx","../src/components/FocusMode/FocusModeNodeActions.tsx","../src/components/FocusMode/FocusModePlaceholder.tsx","../src/components/DiagramBackground.tsx","../src/components/DiagramMiniMap.tsx","../src/utils/minimap.ts","../src/components/Legend.tsx","../src/utils/fit-view.ts","../src/components/MermaidView.tsx","../src/utils/clipboard.ts","../src/hooks/use-pan-zoom.ts","../src/components/ExportModal.tsx","../src/hooks/use-node-visibility.ts","../src/utils/animate-layout.ts","../src/utils/message-animation.ts","../src/components/VisualizerDropdownContent.tsx","../src/components/diagram-menu.ts","../src/components/NodeContextMenu.tsx","../src/utils/node-memo.ts","../src/utils/edge-animations.ts","../src/utils/export-image.ts","../src/studio/eventcatalog-logo.svg","../src/utils/layout.ts","../src/utils/local-packing.ts","../src/utils/message-group-expansion.ts","../src/components/NotesToolbarButton.tsx","../src/nodes/index.ts","../src/edges/index.ts","../src/utils/export-node-graph.ts"],"sourcesContent":["import {\n useEffect,\n useMemo,\n useState,\n useCallback,\n useRef,\n memo,\n type RefObject,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n ReactFlow,\n ConnectionLineType,\n Controls,\n Panel,\n ReactFlowProvider,\n useNodesState,\n useEdgesState,\n type Edge,\n type Node,\n type NodeChange,\n useReactFlow,\n useStoreApi,\n useNodesInitialized,\n getNodesBounds,\n getViewportForBounds,\n type NodeTypes,\n MarkerType,\n} from \"@xyflow/react\";\n// Styles are provided via styles.css / styles-core.css entry points.\n// Do NOT import CSS here — it breaks SSR (Node cannot load .css files).\nimport {\n ExternalLink,\n HistoryIcon,\n CheckIcon,\n ClipboardIcon,\n MoreVertical,\n Waypoints,\n} from \"lucide-react\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { toPng } from \"html-to-image\";\n// Nodes and edges\nimport { Note as NoteNode } from \"../nodes/note\";\nimport {\n diagramNodeComponents,\n RESOURCE_NODE_TYPES,\n} from \"../nodes/diagram-nodes\";\n// Edges\nimport AnimatedMessageEdge from \"../edges/AnimatedMessageEdge\";\nimport MultilineEdgeLabel from \"../edges/MultilineEdgeLabel\";\nimport FlowEdge from \"../edges/FlowEdge\";\nimport {\n LabelledDefaultEdge,\n LabelledSmoothStepEdge,\n LabelledStepEdge,\n} from \"../edges/LabelledEdge\";\nimport VisualiserSearch, { type VisualiserSearchRef } from \"./VisualiserSearch\";\nimport StepWalkthrough from \"./StepWalkthrough\";\nimport WalkthroughBadges from \"./WalkthroughBadges\";\nimport CanvasToolbar from \"./CanvasToolbar\";\nimport SwimlanePicker from \"./SwimlanePicker\";\nimport FocusModeModal from \"./FocusModeModal\";\nimport DiagramBackground from \"./DiagramBackground\";\nimport DiagramMiniMap from \"./DiagramMiniMap\";\nimport { getStoredShowMinimap, storeShowMinimap } from \"../utils/minimap\";\nimport { getLegend, LegendPanel, type LegendEntry } from \"./Legend\";\nimport { DIAGRAM_FIT_VIEW_OPTIONS } from \"../utils/fit-view\";\nimport MermaidView from \"./MermaidView\";\nimport ExportModal from \"./ExportModal\";\nimport { setLevelInUrl, useNodeVisibility } from \"../hooks/use-node-visibility\";\nimport type { GraphTransition } from \"../utils/animate-layout\";\nimport {\n getNodeSize,\n layoutWithElk,\n type CopiedEdgeRoute,\n type EdgeRoute,\n} from \"../utils/elk-layout\";\nimport {\n FLOW_GROUP_BYS,\n getGrouping,\n groupIntoBoxes,\n countGroups,\n hasSwimlanes,\n isFlowGroupBy,\n isFlowGroupStyle,\n isSwimlaneNode,\n layoutSwimlanes,\n removeSwimlanes,\n type FlowGroupBy,\n type FlowGroupStyle,\n} from \"../utils/swimlanes\";\nimport {\n ANIMATE_MESSAGES_STORAGE_KEY,\n applyMessageAnimation,\n shouldAnimateMessages,\n} from \"../utils/message-animation\";\nimport {\n hideMessageNodes,\n isCarrier,\n isMessageNode,\n} from \"../utils/hide-messages\";\nimport VisualizerDropdownContent from \"./VisualizerDropdownContent\";\nimport {\n DIAGRAM_MENU,\n DIAGRAM_MENU_BUTTON,\n DIAGRAM_MENU_BUTTON_COMPACT,\n DIAGRAM_MENU_BUTTON_ICON,\n DIAGRAM_MENU_BUTTON_ICON_COMPACT,\n DIAGRAM_MENU_TITLE,\n} from \"./diagram-menu\";\nimport NodeContextMenu from \"./NodeContextMenu\";\nimport { memoNode } from \"../utils/node-memo\";\nimport { pauseEdgeAnimations } from \"../utils/edge-animations\";\nimport { convertToMermaid } from \"../utils/export-mermaid\";\nimport {\n addExportBranding,\n EXPORT_PADDING,\n getExportImageDimensions,\n injectExportStyles,\n} from \"../utils/export-image\";\nimport { copyToClipboard } from \"../utils/clipboard\";\nimport { layoutGraph } from \"../utils/layout\";\nimport { packNodesAroundBounds } from \"../utils/local-packing\";\nimport {\n buildMessageGroupExpansionNodes,\n getExpandedMessageGroupNode,\n} from \"../utils/message-group-expansion\";\nimport { AllNotesModal, getNotesFromNode } from \"./NotesToolbarButton\";\nimport { setBuildUrlFn } from \"../utils/url-builder\";\nimport { PortalContainerProvider } from \"../context/PortalContainerContext\";\nimport type { DslGraph } from \"../types\";\n\n// Minimum pixel change to detect layout modifications (avoids floating point comparison issues)\nconst POSITION_CHANGE_THRESHOLD = 1;\n\n// Static props for ReactFlow - defined outside component to avoid new references on every render\nconst NODE_ORIGIN: [number, number] = [0.1, 0.1];\n\n// Nodes levels 2 and 3 are about: services, data stores, messages and channels\nconst LEVEL_NODE_TYPES = [\n \"services\",\n \"service\",\n \"agents\",\n \"agent\",\n \"externalSystem\",\n \"data\",\n \"data-products\",\n \"events\",\n \"event\",\n \"commands\",\n \"command\",\n \"queries\",\n \"query\",\n \"messageGroup\",\n \"messageGroupExpanded\",\n \"channels\",\n \"channel\",\n];\n\n// Nodes a level 1 (context) graph has, besides notes\nconst CONTEXT_NODE_TYPES = [\n \"domains\",\n \"domain\",\n \"domain-group\",\n \"context-domain\",\n \"systems\",\n \"system\",\n \"external-system\",\n \"externalSystem\",\n \"context-actor\",\n \"actor\",\n \"actors\",\n \"note\",\n \"notes\",\n];\nconst INITIAL_FIT_VIEW_OPTIONS = {\n ...DIAGRAM_FIT_VIEW_OPTIONS,\n duration: 0,\n} as const;\nconst HIDE_ATTRIBUTION = { hideAttribution: true };\n\n/** Shows the diagram as Mermaid, in the URL (`?render=mermaid`), as `?level=` keeps its level */\nconst RENDER_PARAM = \"render\";\nconst isMermaidInUrl = () =>\n new URLSearchParams(window.location.search).get(RENDER_PARAM) === \"mermaid\";\n/** A link (relative or absolute) that opens in the Mermaid view */\nconst withMermaidInUrl = (link: string) => {\n const url = new URL(link, window.location.href);\n url.searchParams.set(RENDER_PARAM, \"mermaid\");\n return /^[a-z]+:/i.test(link)\n ? url.href\n : `${url.pathname}${url.search}${url.hash}`;\n};\nconst setMermaidInUrl = (isMermaid: boolean) => {\n const url = new URL(window.location.href);\n if (isMermaid) url.searchParams.set(RENDER_PARAM, \"mermaid\");\n else url.searchParams.delete(RENDER_PARAM);\n window.history.replaceState(window.history.state, \"\", url);\n};\n// Exported images are drawn at twice their size, as Studio's are, so they stay sharp\nconst EXPORT_PIXEL_RATIO = 2;\n// Nothing to show yet (e.g. a graph still being laid out): the same arrays every render, or the graph is set again\nconst NO_NODES: Node[] = [];\nconst NO_EDGES: Edge[] = [];\n\nconst LAYOUT_CHANGE_PANEL_STYLE_WITH_WALKTHROUGH = {\n marginBottom: \"20px\",\n marginLeft: \"420px\",\n} as const;\nconst LAYOUT_CHANGE_PANEL_STYLE_DEFAULT = { marginLeft: \"60px\" } as const;\n\n// Expanded wrapper containers are structural only — they host grouped/inlined\n// child nodes and never represent a business step themselves. Centralised so\n// the walkthrough, click handler, and collapse handler agree on the set.\nconst EXPANDED_WRAPPER_TYPES = new Set([\n \"flowExpanded\",\n \"messageGroupExpanded\",\n]);\nconst isExpandedWrapper = (type: string | undefined) =>\n type != null && EXPANDED_WRAPPER_TYPES.has(type);\n\n// The step the flow walkthrough is on is ringed and glowing (see styles)\nconst WALKTHROUGH_CURRENT_CLASS = \"ec-walkthrough-current\";\nconst withWalkthroughCurrent = (node: Node, current: boolean) => {\n const classes = (node.className ?? \"\")\n .split(\" \")\n .filter((name) => name && name !== WALKTHROUGH_CURRENT_CLASS);\n if (current) classes.push(WALKTHROUGH_CURRENT_CLASS);\n return classes.length > 0 ? classes.join(\" \") : undefined;\n};\n\nconst isOpaque = (style?: { opacity?: unknown }) =>\n style?.opacity === undefined || style.opacity === 1;\n\n/** A node as it's shown with nothing picked out: the node itself when it already is (so it doesn't re-render) */\nconst unpickedNode = (node: Node): Node => {\n const className = withWalkthroughCurrent(node, false);\n if (!node.selected && className === node.className && isOpaque(node.style))\n return node;\n return {\n ...node,\n style: { ...node.style, opacity: 1 },\n className,\n selected: false,\n };\n};\n\n/**\n * An edge as it's shown with nothing picked out, animated as Simulate messages is set (only message edges\n * animate: see applyMessageAnimation). The edge itself when it already is.\n */\nconst unpickedEdge = (edge: Edge, animateMessages: boolean): Edge => {\n const animated = edge.data?.canAnimate === false ? false : animateMessages;\n if (\n isOpaque(edge.style) &&\n isOpaque(edge.labelStyle) &&\n isOpaque(edge.data as { opacity?: unknown } | undefined) &&\n !!edge.animated === animated &&\n !!edge.data?.animated === animated\n )\n return edge;\n return {\n ...edge,\n style: { ...edge.style, opacity: 1 },\n labelStyle: { ...edge.labelStyle, opacity: 1 },\n data: { ...edge.data, opacity: 1, animated },\n animated,\n };\n};\n\n/** Items mapped, or the same array when none changed */\nconst mapChanged = <T,>(items: T[], map: (item: T) => T): T[] => {\n let changed = false;\n const next = items.map((item) => {\n const mapped = map(item);\n if (mapped !== item) changed = true;\n return mapped;\n });\n return changed ? next : items;\n};\n\n// Room the flow walkthrough's card takes along the bottom of the canvas,\n// kept clear when showing a step. Follows the card's height in\n// StepWalkthrough.tsx (about 100px, plus its margin): change them together.\nconst WALKTHROUGH_CARD_SPACE = 170;\n\n// How a flow is grouped is kept in the URL, so links open grouped the same way\nconst GROUP_URL_PARAM = \"group\";\nconst GROUP_STYLE_URL_PARAM = \"groupStyle\";\nconst setGroupInUrl = (groupBy: FlowGroupBy | null, style: FlowGroupStyle) => {\n try {\n const url = new URL(window.location.href);\n if (groupBy) {\n url.searchParams.set(GROUP_URL_PARAM, groupBy);\n url.searchParams.set(GROUP_STYLE_URL_PARAM, style);\n } else {\n url.searchParams.delete(GROUP_URL_PARAM);\n url.searchParams.delete(GROUP_STYLE_URL_PARAM);\n }\n window.history.replaceState(window.history.state, \"\", url);\n } catch {\n // The choice just isn't shareable\n }\n};\nconst readGroupFromUrl = () => {\n try {\n const params = new URL(window.location.href).searchParams;\n return {\n groupBy: params.get(GROUP_URL_PARAM),\n style: params.get(GROUP_STYLE_URL_PARAM),\n };\n } catch {\n return { groupBy: null, style: null };\n }\n};\n\n// Room for the search box above the grouping picker, when it's shown\nconst SWIMLANE_PICKER_PANEL_STYLE_UNDER_SEARCH = { marginTop: 64 } as const;\n\n/**\n * What a diagram shows, to start a Studio canvas from: its full graph (level 3, whatever level is shown, as Studio\n * shows the other levels itself), its nodes where they are (as on screen when level 3 is shown), and the\n * connections between them\n */\nexport type VisualiserSnapshot = {\n title?: string;\n /** The level of detail shown (1 to 3), for Studio to open at. Studio gets the full graph (level 3) whatever it is. */\n level: 1 | 2 | 3;\n nodes: {\n id: string;\n type?: string;\n data: Record<string, unknown>;\n /** The container it's shown in */\n parentId?: string;\n /** Its centre on the diagram (not relative to its container) */\n center: { x: number; y: number };\n /** Its size as shown */\n width: number;\n height: number;\n }[];\n edges: {\n source: string;\n target: string;\n label?: string;\n /**\n * How it's drawn: the points it goes through on the diagram, where its label is, and how tall its nodes were\n * (from the layout)\n */\n route?: CopiedEdgeRoute;\n }[];\n /**\n * Levels 1 and 2 as the diagram shows them (laid out, positions relative to their parents), for Studio to show\n * them the same. Level 1 only when the diagram has an overview.\n */\n levels: { 1?: LevelGraph; 2?: LevelGraph };\n /** Levels 1 and 2 the diagram doesn't have, and why (as it says on them) */\n unavailableLevels: { 1?: string; 2?: string };\n};\n\ntype LevelGraph = { nodes: Node[]; edges: Edge[] };\n\n/** Opening a diagram in Studio: its title, and what it shows (taken when asked for, e.g. once the canvas is named) */\nexport type OpenInStudioRequest = {\n title?: string;\n getSnapshot: () => Promise<VisualiserSnapshot>;\n};\n\n/** The graphs a diagram shows at each level (the detail graph is level 3), for Studio */\ntype StudioGraphs = {\n detail: LevelGraph;\n overview?: LevelGraph;\n hiddenMessages?: LevelGraph;\n};\n\ninterface Props {\n nodes: any;\n edges: any;\n title?: string;\n subtitle?: string;\n includeBackground?: boolean;\n includeControls?: boolean;\n linkTo?: \"docs\" | \"visualiser\";\n includeKey?: boolean;\n linksToVisualiser?: boolean;\n links?: { label: string; url: string }[];\n mode?: \"full\" | \"simple\";\n showFlowWalkthrough?: boolean;\n showSearch?: boolean;\n /** Show the settings menu (top left). Defaults to true. */\n showMenu?: boolean;\n /** Use a narrower search box, for small spaces. */\n compactSearch?: boolean;\n /** Hide the React Flow attribution (bottom right). */\n hideAttribution?: boolean;\n zoomOnScroll?: boolean;\n designId?: string;\n isChatEnabled?: boolean;\n maxTextSize?: number;\n isDevMode?: boolean;\n resourceKey?: string;\n /** Controls whether message flow animation is enabled. When set, overrides URL params and localStorage. */\n animated?: boolean;\n /**\n * When true, message-flow animation is unsupported for this graph: it is forced\n * off (ignoring the `animated` prop, URL params and localStorage) and the\n * \"Simulate Messages\" toggle is hidden. Used by graphs that aren't message\n * flows, e.g. the System Diagram.\n */\n disableMessageAnimation?: boolean;\n /** Description of the overview graph shown as level 1 (see `overviewGraph`) */\n overviewLabel?: string;\n /** True while the overview graph is shown */\n isOverview?: boolean;\n /**\n * Switches between the overview graph and this graph, passing this graph's\n * current state for the next one to animate from\n */\n onShowOverview?: (show: boolean, from: GraphTransition) => void;\n /** The graph switched away from to show this one, to animate from */\n transitionFrom?: GraphTransition;\n /** This graph laid out with its messages and channels hidden, if precomputed */\n hiddenMessagesGraph?: { nodes: Node[]; edges: Edge[] };\n /** Legend entries hidden to start with (kept when switching graphs) */\n initialHiddenLegendKeys?: string[];\n /** Group a flow's steps to start with (the `group` URL parameter wins) */\n swimlanes?: FlowGroupBy;\n onHiddenLegendKeysChange?: (keys: string[]) => void;\n /** The level of detail to open at (2 or 3), rather than the URL's or the saved one */\n initialLevel?: 2 | 3;\n /** Show the Mermaid view to start with (kept when switching graphs, e.g. to level 1) */\n initialMermaidView?: boolean;\n onMermaidViewChange?: (isMermaidView: boolean) => void;\n /** The kind of diagram, so the level is remembered for each kind */\n preferenceScope?: string;\n /** When set, the graph will zoom to this node id. */\n focusNodeId?: string;\n /** Optional token to force repeated focus for the same node id. */\n focusRequestId?: number;\n /** Optional token to trigger fit-to-screen behavior. */\n fitRequestId?: number;\n\n // Callback API for framework integration\n /** Called when a node is clicked */\n onNodeClick?: (node: Node) => void;\n /** Called to build URLs for navigation (used in links dropdown) */\n onBuildUrl?: (path: string) => string;\n /** Called when navigation should occur */\n onNavigate?: (url: string) => void;\n /** Called to save layout positions (dev mode only) */\n onSaveLayout?: (\n resourceKey: string,\n positions: Record<string, { x: number; y: number }>,\n ) => Promise<boolean>;\n /** Called to reset layout positions (dev mode only) */\n onResetLayout?: (resourceKey: string) => Promise<boolean>;\n /** Starts a Studio canvas from what the diagram shows (the menu has \"Open in Studio\" when set) */\n onOpenInStudio?: (request: OpenInStudioRequest) => void;\n /** The graphs shown at each level, for Studio */\n studioGraphs?: StudioGraphs;\n}\n\n// The diagram's nodes and connections as Studio gets them, placed by `place` (where each is, and its size)\nconst toSnapshot = (\n nodes: Node[],\n edges: Edge[],\n place: (node: Node) => {\n position: { x: number; y: number };\n width: number;\n height: number;\n },\n): Pick<VisualiserSnapshot, \"nodes\" | \"edges\"> => {\n const shown = nodes.filter((node) => !node.hidden);\n const ids = new Set(shown.map((node) => node.id));\n return {\n nodes: shown.map((node) => {\n const { position, width, height } = place(node);\n return {\n id: node.id,\n type: node.type,\n data: node.data,\n ...(node.parentId && { parentId: node.parentId }),\n center: { x: position.x + width / 2, y: position.y + height / 2 },\n width,\n height,\n };\n }),\n edges: edges\n .filter(\n (edge) => !edge.hidden && ids.has(edge.source) && ids.has(edge.target),\n )\n .map((edge) => {\n const route = (edge.data as { route?: EdgeRoute } | undefined)?.route;\n return {\n source: edge.source,\n target: edge.target,\n ...(typeof edge.label === \"string\" && { label: edge.label }),\n ...(route && {\n route: {\n points: route.points,\n label: route.label,\n sourceHeight: route.source?.height,\n targetHeight: route.target?.height,\n },\n }),\n };\n }),\n };\n};\n\n// A node's size as laid out (nodes not rendered yet haven't been measured)\nconst laidOutSize = (node: Node) => ({\n width:\n node.measured?.width ??\n node.width ??\n (typeof node.style?.width === \"number\" ? node.style.width : 0),\n height:\n node.measured?.height ??\n node.height ??\n (typeof node.style?.height === \"number\" ? node.style.height : 0),\n});\n\n// --- Shared edge style for group expand edges ---\nconst GROUP_EDGE_STYLE = {\n strokeWidth: 1,\n stroke: \"var(--ec-edge-stroke, #6b7280)\",\n};\nconst GROUP_EDGE_MARKER = {\n type: MarkerType.ArrowClosed,\n width: 20,\n height: 20,\n};\n\n/** Label for the edge connecting the service to a message, based on direction and collection type. */\nconst getChildEdgeLabel = (\n direction: \"sends\" | \"receives\",\n collection: string,\n) => {\n if (direction === \"sends\") {\n if (collection === \"commands\") return \"invokes\";\n if (collection === \"queries\") return \"requests\";\n return \"publishes \\nevent\";\n }\n if (collection === \"commands\" || collection === \"queries\") return \"accepts\";\n return \"subscribed by\";\n};\n\n/**\n * Check if a message can reach the service through downstream edges (i.e. via channels).\n * Uses BFS over the pre-computed edge graph. If reachable, no direct child→service edge is needed.\n */\nconst canReachService = (\n msgId: string,\n serviceNodeId: string,\n expandedEdges: any[],\n): boolean => {\n // Build adjacency list once for efficient traversal\n const adj = new Map<string, string[]>();\n for (const e of expandedEdges) {\n if (!adj.has(e.source)) adj.set(e.source, []);\n adj.get(e.source)!.push(e.target);\n }\n const visited = new Set<string>([msgId]);\n const queue = [msgId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const next of adj.get(current) || []) {\n if (next === serviceNodeId) return true;\n if (!visited.has(next)) {\n visited.add(next);\n queue.push(next);\n }\n }\n }\n return false;\n};\n\n/**\n * Build edges connecting the service to child message nodes inside an expanded group.\n * - For sends: always creates service → child edge.\n * - For receives: only creates child → service edge when no channel path exists.\n */\nconst buildChildEdges = (\n groupData: any,\n groupNodeId: string,\n serviceNodeId: string,\n msgIdToChildId: Map<string, string>,\n): Edge[] => {\n const expandedEdges = groupData.expandedEdges || [];\n\n return (groupData.messages || [])\n .map((item: any) => {\n const msg = item.message;\n const msgId = `${msg.data.id}-${msg.data.version}`;\n const childId = msgIdToChildId.get(msgId)!;\n const collection = msg.collection || \"events\";\n const label = getChildEdgeLabel(groupData.direction, collection);\n\n if (groupData.direction === \"sends\") {\n return {\n id: `${serviceNodeId}-to-${childId}`,\n source: serviceNodeId,\n target: childId,\n label,\n type: \"animated\",\n style: GROUP_EDGE_STYLE,\n markerEnd: GROUP_EDGE_MARKER,\n } as Edge;\n }\n\n // Receives: skip if a channel path already connects this message to the service\n if (canReachService(msgId, serviceNodeId, expandedEdges)) return null;\n\n return {\n id: `${childId}-to-${serviceNodeId}`,\n source: childId,\n target: serviceNodeId,\n label,\n type: \"animated\",\n style: GROUP_EDGE_STYLE,\n markerEnd: GROUP_EDGE_MARKER,\n } as Edge;\n })\n .filter(Boolean) as Edge[];\n};\n\nconst NodeGraphBuilder = ({\n nodes: initialNodes,\n edges: initialEdges,\n title,\n includeBackground = true,\n linkTo: _linkTo = \"docs\",\n includeKey = true,\n linksToVisualiser = false,\n links = [],\n mode = \"full\",\n showFlowWalkthrough = true,\n showSearch = true,\n showMenu = true,\n compactSearch = false,\n hideAttribution = false,\n zoomOnScroll = false,\n isChatEnabled = false,\n maxTextSize,\n isDevMode = false,\n resourceKey,\n animated,\n disableMessageAnimation = false,\n overviewLabel,\n isOverview = false,\n onShowOverview,\n transitionFrom,\n hiddenMessagesGraph,\n initialHiddenLegendKeys,\n onHiddenLegendKeysChange,\n initialMermaidView = false,\n onMermaidViewChange,\n initialLevel,\n preferenceScope,\n swimlanes: initialSwimlanes,\n focusNodeId,\n focusRequestId,\n fitRequestId,\n onNodeClick,\n onBuildUrl,\n onNavigate,\n onSaveLayout,\n onResetLayout,\n onOpenInStudio,\n studioGraphs,\n}: Props) => {\n // Wire up the URL builder so all nodes can use buildUrl() with the correct base path\n useEffect(() => {\n if (onBuildUrl) {\n setBuildUrlFn(onBuildUrl);\n }\n }, []);\n\n const nodeTypes = useMemo(() => {\n const wrapWithContextMenu = (Component: React.ComponentType<any>) => {\n const Wrapped = (props: any) => {\n const items = props.data?.contextMenu;\n if (!items?.length) return <Component {...props} />;\n return (\n <NodeContextMenu items={items}>\n <Component {...props} />\n </NodeContextMenu>\n );\n };\n Wrapped.displayName = `WithContextMenu(${Component.displayName || Component.name || \"Component\"})`;\n return Wrapped;\n };\n\n const ReadOnlyNoteNode = (props: any) => (\n <NoteNode {...props} readOnly={true} />\n );\n ReadOnlyNoteNode.displayName = \"ReadOnlyNoteNode\";\n\n const types: Record<string, React.ComponentType<any>> = {\n ...Object.fromEntries(\n Object.entries(diagramNodeComponents).map(([type, Component]) => [\n type,\n RESOURCE_NODE_TYPES.has(type)\n ? wrapWithContextMenu(Component)\n : Component,\n ]),\n ),\n note: ReadOnlyNoteNode,\n };\n\n // Nodes render again only when something besides their position changes, so\n // animating a layout (e.g. switching levels) moves them without re-rendering\n return Object.fromEntries(\n Object.entries(types).map(([type, Component]) => [\n type,\n memoNode(Component),\n ]),\n ) as unknown as NodeTypes;\n }, []);\n const edgeTypes = useMemo(\n () =>\n ({\n animated: AnimatedMessageEdge,\n multiline: MultilineEdgeLabel,\n \"flow-edge\": FlowEdge,\n default: LabelledDefaultEdge,\n smoothstep: LabelledSmoothStepEdge,\n step: LabelledStepEdge,\n }) as Record<string, any>,\n [],\n );\n // Decided before the first render: edges that start animated and then aren't are all mounted twice\n const [animateMessages, setAnimateMessages] = useState(() =>\n shouldAnimateMessages({\n disabled: disableMessageAnimation,\n animated,\n nodeCount: initialNodes.length,\n }),\n );\n // New edges (the graph's, or ones shown when nodes are shown or expanded) animate as the rest do\n const prepareEdges = useCallback(\n (eds: Edge[]) => applyMessageAnimation(eds, animateMessages),\n [animateMessages],\n );\n const [firstEdges] = useState(() => prepareEdges(initialEdges));\n const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);\n const [edges, setEdges, onEdgesChange] = useEdgesState(firstEdges);\n const {\n fitView,\n getNodes,\n getIntersectingNodes,\n getZoom,\n setCenter,\n getEdges,\n getViewport,\n setViewport,\n getInternalNode,\n } = useReactFlow();\n const storeApi = useStoreApi();\n const previousGraphInputRef = useRef({\n nodes: initialNodes,\n edges: initialEdges,\n });\n\n // Sync when parent passes new nodes/edges (e.g. playground re-parse)\n useEffect(() => {\n const previousGraphInput = previousGraphInputRef.current;\n previousGraphInputRef.current = {\n nodes: initialNodes,\n edges: initialEdges,\n };\n\n // React Flow's fitView prop handles the initial viewport after measuring\n // the nodes. Avoid scheduling a second animated fit on mount.\n if (\n previousGraphInput.nodes === initialNodes &&\n previousGraphInput.edges === initialEdges\n ) {\n return;\n }\n\n setNodes(initialNodes);\n setEdges(prepareEdges(initialEdges));\n // fitView after React Flow processes the new nodes\n requestAnimationFrame(() => {\n fitView({ duration: 300, padding: 0.2 });\n });\n }, [initialNodes, initialEdges, setNodes, setEdges, fitView, prepareEdges]);\n\n const [_activeStepIndex, _setActiveStepIndex] = useState<number | null>(null);\n const [_isFullscreen, _setIsFullscreen] = useState(false);\n const [isShareModalOpen, setIsShareModalOpen] = useState(false);\n const [isExportModalOpen, setIsExportModalOpen] = useState(false);\n const openExportModal = useCallback(() => setIsExportModalOpen(true), []);\n const closeExportModal = useCallback(() => setIsExportModalOpen(false), []);\n const [shareUrlCopySuccess, setShareUrlCopySuccess] = useState(false);\n const [isMermaidView, setMermaidViewState] = useState(initialMermaidView);\n const setIsMermaidView = useCallback(\n (value: boolean) => {\n setMermaidViewState(value);\n onMermaidViewChange?.(value);\n },\n [onMermaidViewChange],\n );\n const showMermaidView = useCallback(\n () => setIsMermaidView(true),\n [setIsMermaidView],\n );\n // Remembered, so the minimap stays on when switching levels (each level is its own page) or diagrams\n const [showMinimap, setShowMinimapState] = useState(getStoredShowMinimap);\n const setShowMinimap = useCallback((show: boolean) => {\n setShowMinimapState(show);\n storeShowMinimap(show);\n }, []);\n const [hasLayoutChanges, setHasLayoutChanges] = useState(false);\n const [isSavingLayout, setIsSavingLayout] = useState(false);\n const initialPositionsRef = useRef<Record<string, { x: number; y: number }>>(\n {},\n );\n const [focusModeOpen, setFocusModeOpen] = useState(false);\n const [focusedNodeId, setFocusedNodeId] = useState<string | null>(null);\n const [swimlanes, setSwimlanes] = useState<FlowGroupBy | null>(null);\n const swimlanesRef = useRef<FlowGroupBy | null>(null);\n const [swimlaneStyle, setSwimlaneStyle] = useState<FlowGroupStyle>(\"boxes\");\n const swimlaneStyleRef = useRef<FlowGroupStyle>(\"boxes\");\n const unlanedGraphRef = useRef<{ nodes: Node[]; edges: Edge[] } | null>(null);\n\n const [isNotesModalOpen, setIsNotesModalOpen] = useState(false);\n const openNotesModal = useCallback(() => setIsNotesModalOpen(true), []);\n\n // Track user interaction (drag/pan/zoom) to pause expensive SVG animations.\n // Uses a ref + direct DOM manipulation to avoid React re-renders.\n const interactionCountRef = useRef(0);\n\n const startInteraction = useCallback(() => {\n interactionCountRef.current += 1;\n if (interactionCountRef.current === 1) {\n reactFlowWrapperRef.current?.classList.add(\"ec-interaction-active\");\n pauseEdgeAnimations(reactFlowWrapperRef.current, true);\n }\n }, []);\n\n const endInteraction = useCallback(() => {\n interactionCountRef.current = Math.max(0, interactionCountRef.current - 1);\n if (interactionCountRef.current === 0) {\n reactFlowWrapperRef.current?.classList.remove(\"ec-interaction-active\");\n pauseEdgeAnimations(reactFlowWrapperRef.current, false);\n }\n }, []);\n\n // Highlight source/target nodes when hovering an edge.\n // Uses direct DOM manipulation (like startInteraction) to avoid re-renders.\n const hoveredEdgeNodesRef = useRef<Element[]>([]);\n\n const handleEdgeMouseEnter = useCallback(\n (_: React.MouseEvent, edge: Edge) => {\n const wrapper = reactFlowWrapperRef.current;\n if (!wrapper) return;\n const nodes = wrapper.querySelectorAll(\n `[data-id=\"${edge.source}\"], [data-id=\"${edge.target}\"]`,\n );\n nodes.forEach((el) => el.classList.add(\"ec-edge-hover-node\"));\n hoveredEdgeNodesRef.current = Array.from(nodes);\n },\n [],\n );\n\n const handleEdgeMouseLeave = useCallback(() => {\n hoveredEdgeNodesRef.current.forEach((el) =>\n el.classList.remove(\"ec-edge-hover-node\"),\n );\n hoveredEdgeNodesRef.current = [];\n }, []);\n\n // Highlight all connected edges + their other-end nodes when hovering a node.\n // Looks up connected edges from the edges array, then queries DOM by edge ID.\n // Uses direct DOM manipulation to avoid re-renders.\n const hoveredNodeEdgesRef = useRef<Element[]>([]);\n const hoveredNodePeersRef = useRef<Element[]>([]);\n\n const handleNodeMouseEnter = useCallback(\n (_: React.MouseEvent, node: Node) => {\n const wrapper = reactFlowWrapperRef.current;\n if (!wrapper) return;\n\n const peerIds = new Set<string>();\n const edgeEls: Element[] = [];\n\n for (const edge of edgesRef.current) {\n if (edge.source !== node.id && edge.target !== node.id) continue;\n const el = wrapper.querySelector(\n `.react-flow__edge[data-id=\"${edge.id}\"]`,\n );\n if (el) {\n el.classList.add(\"ec-node-hover-edge\");\n edgeEls.push(el);\n }\n if (edge.source !== node.id) peerIds.add(edge.source);\n if (edge.target !== node.id) peerIds.add(edge.target);\n }\n hoveredNodeEdgesRef.current = edgeEls;\n\n // Highlight the hovered node + all peer nodes\n peerIds.add(node.id);\n const selector = Array.from(peerIds)\n .map((id) => `[data-id=\"${id}\"]`)\n .join(\", \");\n if (selector) {\n const peerEls = wrapper.querySelectorAll(selector);\n peerEls.forEach((el) => el.classList.add(\"ec-edge-hover-node\"));\n hoveredNodePeersRef.current = Array.from(peerEls);\n }\n },\n [],\n );\n\n const handleNodeMouseLeave = useCallback(() => {\n hoveredNodeEdgesRef.current.forEach((el) =>\n el.classList.remove(\"ec-node-hover-edge\"),\n );\n hoveredNodeEdgesRef.current = [];\n hoveredNodePeersRef.current.forEach((el) =>\n el.classList.remove(\"ec-edge-hover-node\"),\n );\n hoveredNodePeersRef.current = [];\n }, []);\n\n // Check if there are channels to determine if we need the visualizer functionality\n const hasChannels = useMemo(\n () => initialNodes.some((node: any) => node.type === \"channels\"),\n [initialNodes],\n );\n const hasMessages = useMemo(\n () => initialNodes.some(isMessageNode),\n [initialNodes],\n );\n // A flow (its steps are joined by flow edges). Levels don't apply to flows.\n const isFlowGraph = useMemo(\n () => initialEdges.some((edge: Edge) => edge.type === \"flow-edge\"),\n [initialEdges],\n );\n // Groups are sized to fit their nodes as they render, rather than as\n // estimated (a node wider than estimated would poke out of its group)\n const renderedSizeOf = useCallback(\n (node: Node) => {\n const measured = storeApi.getState().nodeLookup.get(node.id)?.measured;\n return measured?.width && measured?.height\n ? { width: measured.width, height: measured.height }\n : getNodeSize(node);\n },\n [storeApi],\n );\n // Graphs in lanes are laid out again without them (the layout doesn't know\n // about them), then put back in them. Boxes are groups the layout lays out\n // with their steps, so graphs in boxes are laid out in them.\n const beforeLayout = useCallback(\n (graph: { nodes: Node[]; edges: Edge[] }) =>\n swimlaneStyleRef.current === \"lanes\" ? removeSwimlanes(graph) : graph,\n [],\n );\n const afterLayout = useCallback((graph: { nodes: Node[]; edges: Edge[] }) => {\n const groupBy = swimlanesRef.current;\n const style = swimlaneStyleRef.current;\n const current = getGrouping(graph.nodes);\n if (!current && !groupBy) return graph;\n if (current?.groupBy === groupBy && current?.style === style) return graph;\n const unlaned = removeSwimlanes(graph);\n // Boxes need laying out (async), which only switching grouping does\n if (!groupBy || style === \"boxes\" || groupBy === \"domain-system\")\n return unlaned;\n unlanedGraphRef.current = unlaned;\n return layoutSwimlanes(unlaned, groupBy, { sizeOf: renderedSizeOf });\n }, []);\n // Graphs levels don't apply to (e.g. an entity map) don't show them\n const hasLevels = useMemo(\n () =>\n initialNodes.some((node: Node) =>\n LEVEL_NODE_TYPES.includes(node.type || \"\"),\n ),\n [initialNodes],\n );\n // Only domains, systems and actors (e.g. a context diagram): a level 1 graph\n const isContextGraph = useMemo(\n () =>\n initialNodes.every((node: Node) =>\n CONTEXT_NODE_TYPES.includes(node.type || \"\"),\n ),\n [initialNodes],\n );\n // Cross-domain communication to highlight (e.g. on a domain's diagram).\n // Only where the toolbar is, to turn it on and off (not e.g. docs embeds).\n const hasOtherDomains = useMemo(\n () =>\n mode === \"full\" &&\n initialNodes.some((node: Node<any>) => !!node.data?.otherDomain),\n [initialNodes, mode],\n );\n // The legend (set once worked out below), for which nodes its entries list\n const legendRef = useRef<Record<string, LegendEntry>>({});\n const matchesLegendKey = useCallback((node: Node<any>, key: string) => {\n const groupId = legendRef.current[key]?.groupId;\n return groupId ? node.data?.group?.id === groupId : node.type === key;\n }, []);\n const {\n hideChannels,\n toggleChannelsVisibility,\n hideMessages,\n toggleMessagesVisibility,\n setDetailLevel,\n isLayingOut,\n hiddenLegendKeys,\n toggleLegendKey,\n highlightCrossDomain,\n toggleHighlightCrossDomain,\n } = useNodeVisibility({\n nodes,\n edges,\n setNodes,\n setEdges,\n hasChannels,\n hasMessages,\n transitionFrom,\n nodeOrigin: NODE_ORIGIN,\n // The Mermaid view would draw every step of the animation between levels\n disableAnimation: isMermaidView,\n hiddenMessagesGraph,\n prepareEdges,\n matchesLegendKey,\n initialHiddenLegendKeys,\n onHiddenLegendKeysChange,\n // The page's kind (the same for its overview and detail graphs), else\n // e.g. \"services\" from \"services/OrderService/1.0.0\"\n preferenceScope: preferenceScope ?? resourceKey?.split(\"/\")[0],\n ignoreSavedLevel: isFlowGraph,\n initialLevel,\n beforeLayout,\n afterLayout,\n });\n\n // Switching to or from the overview graph swaps graphs. The next graph\n // animates from this one's current state (see `transitionFrom`).\n const switchGraph = useCallback(\n (showOverview: boolean) =>\n onShowOverview?.(showOverview, {\n nodes: getNodes(),\n edges: getEdges(),\n viewport: getViewport(),\n }),\n [onShowOverview, getNodes, getEdges, getViewport],\n );\n\n // Levels of detail for the toolbar. With an overview graph (e.g. a system's\n // context diagram) that becomes level 1, followed by the detail levels.\n // Levels of detail for the toolbar, the same on every page: L1 the overview\n // (domains, systems and their relationships), L2 services and data stores,\n // and L3 adding messages and channels. Levels a diagram doesn't have are\n // greyed out, e.g. L1 on a service's diagram.\n const levels = useMemo(() => {\n if (isFlowGraph) return [];\n if (!overviewLabel && !isContextGraph && !hasLevels) return [];\n const selectDetailLevel = (level: 2 | 3) => {\n if (isOverview) switchGraph(false);\n setDetailLevel(level);\n };\n // With an overview graph (level 1), this graph is the detail levels\n const hasDetail = !!overviewLabel || !isContextGraph;\n return [\n {\n description: overviewLabel ?? \"domains, systems and relationships\",\n active: isOverview || (!overviewLabel && isContextGraph),\n disabledReason:\n !overviewLabel && !isContextGraph\n ? \"Not available here: this diagram has no overview of domains or systems\"\n : undefined,\n onSelect: () => {\n if (overviewLabel && !isOverview) switchGraph(true);\n },\n },\n {\n description: \"services and data stores\",\n active:\n !isOverview && !isContextGraph && (hideMessages || !hasMessages),\n disabledReason: hasDetail\n ? undefined\n : \"Not available here: this diagram only shows domains, systems and their relationships\",\n onSelect: () => selectDetailLevel(2),\n },\n {\n description: \"messages and channels\",\n active: !isOverview && hasMessages && !hideMessages,\n // The overview doesn't know if the detail has messages, so allows it\n disabledReason:\n isOverview || hasMessages\n ? undefined\n : \"Not available here: this diagram has no messages or channels\",\n onSelect: () => selectDetailLevel(3),\n },\n ];\n }, [\n overviewLabel,\n isOverview,\n isContextGraph,\n hasLevels,\n isFlowGraph,\n hideMessages,\n hasMessages,\n setDetailLevel,\n switchGraph,\n ]);\n // Tools for the kind of resource shown, in the canvas toolbar\n const canvasTools = useMemo(\n () =>\n hasOtherDomains\n ? [\n {\n label: highlightCrossDomain\n ? \"Stop highlighting cross-domain communication\"\n : \"Highlight cross-domain communication\",\n icon: <Waypoints className=\"w-4 h-4\" />,\n active: highlightCrossDomain,\n onClick: toggleHighlightCrossDomain,\n },\n ]\n : [],\n [hasOtherDomains, highlightCrossDomain, toggleHighlightCrossDomain],\n );\n const searchRef = useRef<VisualiserSearchRef>(null);\n const reactFlowWrapperRef = useRef<HTMLDivElement>(null);\n const scrollableContainerRef = useRef<HTMLElement | null>(null);\n\n // Stable refs — avoids recreating callbacks on every drag/state change\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n const edgesRef = useRef(edges);\n edgesRef.current = edges;\n // Sub-flows are laid out when expanded (async), so only the latest is applied\n const subFlowLayoutRun = useRef(0);\n const hideChannelsRef = useRef(hideChannels);\n hideChannelsRef.current = hideChannels;\n\n // The walkthrough treats expanded wrapper containers as structural rather\n // than walkable steps. Stitched predecessor/successor edges added at expand\n // time already connect real outer steps to the sub-flow's children, so\n // dropping wrapper edges doesn't break traversal.\n // The walkthrough only needs the graph's structure (which steps there are\n // and how they connect), so it's only given a new graph when that changes,\n // not on every position change (e.g. each tick of a drag)\n const walkthroughKeyRef = useRef(\"\");\n const computedWalkthroughKey = `${nodes\n .map((n) => `${n.id}:${n.type}`)\n .join(\",\")}|${edges.map((e) => `${e.source}>${e.target}`).join(\",\")}`;\n if (computedWalkthroughKey !== walkthroughKeyRef.current) {\n walkthroughKeyRef.current = computedWalkthroughKey;\n }\n const walkthroughKey = walkthroughKeyRef.current;\n const { walkthroughNodes, walkthroughEdges } = useMemo(() => {\n const wrapperNodeIds = new Set(\n nodes\n .filter((n) => isExpandedWrapper(n.type) || isSwimlaneNode(n))\n .map((n) => n.id),\n );\n return {\n walkthroughNodes: nodes.filter((n) => !wrapperNodeIds.has(n.id)),\n walkthroughEdges: edges.filter(\n (e) => !wrapperNodeIds.has(e.source) && !wrapperNodeIds.has(e.target),\n ),\n };\n }, [walkthroughKey]);\n\n const animateLayout = useCallback(() => {\n const wrapper = reactFlowWrapperRef.current;\n if (!wrapper) return;\n wrapper.classList.add(\"ec-animating-layout\");\n setTimeout(() => wrapper.classList.remove(\"ec-animating-layout\"), 400);\n }, []);\n\n const makeRoomForRenderedExpandedGroup = useCallback(\n (\n groupNodeId: string,\n groupBounds: { x: number; y: number; width: number; height: number },\n ) => {\n const padding = 80;\n const protectedBounds = {\n x: groupBounds.x - padding,\n y: groupBounds.y - padding,\n width: groupBounds.width + padding * 2,\n height: groupBounds.height + padding * 2,\n };\n const intersectingIds = new Set(\n getIntersectingNodes(protectedBounds, true)\n .filter((node) => node.id !== groupNodeId && !node.parentId)\n .map((node) => node.id),\n );\n\n if (intersectingIds.size === 0) return;\n\n setNodes((currentNodes) => {\n const plannedPositions = packNodesAroundBounds({\n nodes: currentNodes,\n movableNodeIds: intersectingIds,\n protectedBounds,\n groupNodeId,\n });\n\n return currentNodes.map((node) => {\n const plannedPosition = plannedPositions.get(node.id);\n if (!plannedPosition) return node;\n return { ...node, position: plannedPosition };\n });\n });\n },\n [getIntersectingNodes, setNodes],\n );\n\n // Read from refs inside the callback to avoid nodes/edges in the dependency array.\n // This prevents the callback from being recreated on every drag tick (Rule 2).\n const handleCollapseGroup = useCallback(\n (e: React.MouseEvent) => {\n const target = e.target as HTMLElement;\n const collapseBtn = target.closest(\n \".ec-collapse-group-btn, .ec-collapse-flow-btn\",\n );\n if (!collapseBtn) return;\n e.stopPropagation();\n\n // Find the ReactFlow node wrapper to get the node ID\n const nodeWrapper = target.closest(\"[data-id]\");\n if (!nodeWrapper) return;\n const groupNodeId = nodeWrapper.getAttribute(\"data-id\");\n if (!groupNodeId) return;\n\n const currentNodes = nodesRef.current;\n const currentEdges = edgesRef.current;\n\n // Find the expanded container node to get its data\n const expandedNode = currentNodes.find((n) => n.id === groupNodeId);\n if (!expandedNode || !isExpandedWrapper(expandedNode.type)) return;\n // A sub-flow still being laid out would expand into the collapsed graph\n subFlowLayoutRun.current++;\n\n // The wrapper carries a pre-expansion snapshot — use it so nested\n // wrappers (created mid-session and therefore absent from initialNodes)\n // collapse correctly. Fall back to initialNodes for wrappers expanded\n // on a top-level node that was there from page load.\n const stashed = (expandedNode.data as any).__preExpansion as\n | {\n node: Node;\n edges: Edge[];\n nodeIds: string[];\n nodePositions?: Record<string, { x: number; y: number }>;\n edgeRoutes?: Record<string, EdgeRoute>;\n }\n | undefined;\n const originalNode =\n stashed?.node ??\n initialNodes.find(\n (n: Node) =>\n n.id === groupNodeId &&\n (n.type === \"messageGroup\" ||\n n.type === \"flows\" ||\n n.type === \"flow\"),\n );\n if (!originalNode) return;\n const originalEdges =\n stashed?.edges ??\n initialEdges.filter(\n (edge: Edge) =>\n edge.source === groupNodeId || edge.target === groupNodeId,\n );\n\n const childNodeIds = new Set(\n currentNodes.filter((n) => n.parentId === groupNodeId).map((n) => n.id),\n );\n\n // Downstream nodes added on expand are those in the original node's\n // expandedNodes that weren't in the graph just before the expand ran.\n // Use the stashed pre-expansion id snapshot when present (so mid-\n // session wrappers diff against their own \"before\"), else fall back\n // to the initial page-load node set.\n const originalData = originalNode.data as any;\n const preExistingIds = new Set(\n stashed ? stashed.nodeIds : initialNodes.map((n: Node) => n.id),\n );\n const downstreamNodeIds = new Set(\n ((originalData.expandedNodes as any[]) || [])\n .map((n: any) => n.id)\n .filter((id: string) => !preExistingIds.has(id)),\n );\n\n const isDownstreamEdge = (edge: Edge) =>\n edge.id.startsWith(`${groupNodeId}__`);\n\n // Animate the layout transition\n animateLayout();\n\n // Swap: remove expanded container + children + downstream, restore compact node.\n // Only remove downstream nodes that aren't still referenced by surviving edges\n // (another expanded group may share the same channel/consumer nodes).\n setNodes((prev) => {\n // Compute which edges will survive the collapse\n const nextEdges = currentEdges\n .filter(\n (edge) =>\n !childNodeIds.has(edge.source) &&\n !childNodeIds.has(edge.target) &&\n !isDownstreamEdge(edge),\n )\n .concat(originalEdges);\n\n // Nodes still referenced by surviving edges must be kept\n const referencedByEdges = new Set<string>();\n for (const edge of nextEdges) {\n referencedByEdges.add(edge.source);\n referencedByEdges.add(edge.target);\n }\n\n const without = prev\n .filter(\n (n) =>\n n.id !== groupNodeId &&\n !childNodeIds.has(n.id) &&\n !(downstreamNodeIds.has(n.id) && !referencedByEdges.has(n.id)),\n )\n .map((n) => {\n const stashedPosition = stashed?.nodePositions?.[n.id];\n if (!stashedPosition || n.parentId) return n;\n return { ...n, position: stashedPosition };\n });\n const next = [\n ...without,\n {\n ...originalNode,\n position:\n stashed?.nodePositions?.[groupNodeId] ?? expandedNode.position,\n },\n ];\n return next;\n });\n setEdges((prev) => {\n const without = prev.filter(\n (edge) =>\n !childNodeIds.has(edge.source) &&\n !childNodeIds.has(edge.target) &&\n !isDownstreamEdge(edge),\n );\n // Edges go back to the routes they had before the expand\n return [...without, ...originalEdges].map((edge) => {\n const route = stashed?.edgeRoutes?.[edge.id];\n return route ? { ...edge, data: { ...edge.data, route } } : edge;\n });\n });\n },\n [initialNodes, initialEdges, setNodes, setEdges, animateLayout],\n );\n\n // Store initial node positions for change detection (dev mode only)\n useEffect(() => {\n if (isDevMode && initialNodes.length > 0) {\n const positions: Record<string, { x: number; y: number }> = {};\n initialNodes.forEach((node: Node) => {\n positions[node.id] = { x: node.position.x, y: node.position.y };\n });\n initialPositionsRef.current = positions;\n }\n }, [isDevMode, initialNodes]);\n\n // Detect layout changes by comparing current positions to initial positions\n const checkForLayoutChanges = useCallback(() => {\n if (!isDevMode) return;\n const initial = initialPositionsRef.current;\n if (Object.keys(initial).length === 0) return;\n\n const hasChanges = nodesRef.current.some((node) => {\n const initialPos = initial[node.id];\n return (\n initialPos &&\n (Math.abs(node.position.x - initialPos.x) > POSITION_CHANGE_THRESHOLD ||\n Math.abs(node.position.y - initialPos.y) > POSITION_CHANGE_THRESHOLD)\n );\n });\n\n setHasLayoutChanges(hasChanges);\n }, [isDevMode]);\n\n // Wrap onNodesChange to detect layout changes after node drag\n const handleNodesChange = useCallback(\n (changes: NodeChange[]) => {\n onNodesChange(changes);\n // Check for position changes after drag ends\n const hasDragEnd = changes.some(\n (change) => change.type === \"position\" && !change.dragging,\n );\n if (hasDragEnd) {\n // Use setTimeout to ensure state is updated\n setTimeout(checkForLayoutChanges, 0);\n }\n },\n [onNodesChange, checkForLayoutChanges],\n );\n\n // Nothing picked out (e.g. clicking the canvas): only what was dimmed, picked out or selected changes, so a click\n // on a graph that has nothing picked out doesn't re-render anything\n const resetNodesAndEdges = useCallback(() => {\n setNodes((nds) => mapChanged(nds, unpickedNode));\n setEdges((eds) =>\n mapChanged(eds, (edge) => unpickedEdge(edge, animateMessages)),\n );\n }, [setNodes, setEdges, animateMessages]);\n\n useEffect(() => {\n if (!focusNodeId) return;\n const targetNode = nodesRef.current.find((node) => node.id === focusNodeId);\n if (!targetNode) return;\n\n setNodes((nds) =>\n nds.map((node) => ({\n ...node,\n selected: node.id === focusNodeId,\n })),\n );\n\n requestAnimationFrame(() => {\n fitView({\n duration: 450,\n padding: 0.35,\n nodes: [targetNode],\n });\n });\n }, [focusNodeId, focusRequestId, fitView, setNodes]);\n\n useEffect(() => {\n if (fitRequestId == null) return;\n requestAnimationFrame(() => {\n fitView({ duration: 400, padding: 0.2 });\n });\n }, [fitRequestId, fitView]);\n\n const handleNodeClick = useCallback(\n (_: any, node: Node) => {\n // If custom onNodeClick is provided, use it\n if (onNodeClick) {\n onNodeClick(node);\n return;\n }\n\n // Disable focus mode for flow and entity visualizations — but allow\n // flow-type nodes that carry precomputed expandedNodes to continue\n // through to the inline expand handler below.\n const isFlow = edgesRef.current.some(\n (edge: Edge) => edge.type === \"flow-edge\",\n );\n const isEntityVisualizer = nodesRef.current.some(\n (n: Node) => n.type === \"entities\",\n );\n const isExpandableFlow =\n (node.type === \"flows\" || node.type === \"flow\") &&\n Array.isArray((node.data as any)?.expandedNodes) &&\n (node.data as any).expandedNodes.length > 0;\n if ((isFlow || isEntityVisualizer) && !isExpandableFlow) return;\n // Sub-flows expand into the graph as laid out without lanes\n if (isExpandableFlow && swimlanesRef.current) return;\n if (isSwimlaneNode(node)) return;\n\n // Disable focus mode for domain and expanded group nodes\n if (node.type === \"domain\" || node.type === \"domains\") return;\n // System nodes navigate to their map on click (handled by the node itself),\n // so don't open the focus-mode modal for them.\n if (node.type === \"system\" || node.type === \"systems\") return;\n // Context-diagram actor nodes are non-interactive — clicking does nothing.\n if (node.type === \"context-actor\") return;\n // The system-group boundary box on the System Diagram is just a container.\n if (node.type === \"system-group\") return;\n if (isExpandedWrapper(node.type)) return;\n\n // Handle messageGroup click — expand inline\n if (node.type === \"messageGroup\") {\n const groupData = node.data as any;\n const groupNodeId = node.id;\n const currentGroupNode = getExpandedMessageGroupNode(\n nodesRef.current,\n groupNodeId,\n );\n if (currentGroupNode?.type === \"messageGroupExpanded\") {\n const measured = (currentGroupNode as any)?.measured;\n const width =\n measured?.width ??\n (currentGroupNode.style?.width as number | undefined) ??\n 380;\n const height =\n measured?.height ??\n (currentGroupNode.style?.height as number | undefined) ??\n 300;\n\n setCenter(\n currentGroupNode.position.x + width / 2,\n currentGroupNode.position.y + height / 2,\n {\n duration: 300,\n zoom: Math.min(Math.max(getZoom(), 0.55), 1),\n },\n );\n return;\n }\n\n const serviceNodeId = `${groupData.service.id}-${groupData.service.version}`;\n\n // Calculate expanded container dimensions based on message count\n const childCount = groupData.messages?.length || 0;\n const containerWidth = 380;\n const containerHeight = childCount * 190 + 100; // 190px per child + header + padding\n\n // Capture the node, its edges, and the set of node ids as they are\n // right now so collapse can (a) restore the pre-expansion node/edges\n // verbatim even for wrappers created mid-session, and (b) identify\n // which downstream nodes were newly introduced by this expansion.\n const preExpansionEdges = edgesRef.current.filter(\n (e) => e.source === groupNodeId || e.target === groupNodeId,\n );\n const preExpansionNodeIds = nodesRef.current.map((n) => n.id);\n const preExpansionNodePositions = Object.fromEntries(\n nodesRef.current.map((n) => [n.id, { ...n.position }]),\n );\n\n const expandedContainerNode: Node = {\n id: groupNodeId,\n type: \"messageGroupExpanded\",\n position: node.position,\n data: {\n groupName: groupData.groupName,\n direction: groupData.direction,\n messageCount: childCount,\n onCollapse: groupNodeId,\n __preExpansion: {\n node,\n edges: preExpansionEdges,\n nodeIds: preExpansionNodeIds,\n nodePositions: preExpansionNodePositions,\n },\n },\n style: {\n width: containerWidth,\n height: containerHeight,\n },\n };\n\n // Build child message nodes (operation fields are pre-computed server-side)\n const childNodes: Node[] = (groupData.messages || []).map(\n (item: any, index: number) => {\n const msg = item.message;\n const msgId = `${msg.data.id}-${msg.data.version}`;\n return {\n id: `${groupNodeId}__${msgId}`,\n type: msg.collection,\n parentId: groupNodeId,\n extent: \"parent\" as const,\n position: { x: 70, y: 70 + index * 190 },\n data: {\n mode: groupData.mode || \"simple\",\n message: { ...msg.data },\n },\n } as Node;\n },\n );\n\n // Map original message IDs → child node IDs (used for edge remapping)\n const msgIdToChildId = new Map<string, string>();\n for (const item of groupData.messages || []) {\n const msg = item.message;\n const msgId = `${msg.data.id}-${msg.data.version}`;\n msgIdToChildId.set(msgId, `${groupNodeId}__${msgId}`);\n }\n\n // Build service↔child edges.\n // For sends: always create service → child (we stripped this edge server-side).\n // For receives: only create child → service when no channel path already\n // connects this message to the service through downstream edges.\n const childEdges = buildChildEdges(\n groupData,\n groupNodeId,\n serviceNodeId,\n msgIdToChildId,\n );\n\n // Downstream nodes/edges: pre-computed server-side (channels, consumers, producers).\n // Remap edge endpoints from original message IDs to child node IDs.\n // Deduplicate by ID — multiple grouped messages may share the same downstream path.\n // When channels are hidden, filter out channel nodes and their edges.\n const channelsHidden = hideChannelsRef.current;\n const channelNodeIds = channelsHidden\n ? new Set(\n (groupData.expandedNodes || [])\n .filter((n: any) => n.type === \"channels\")\n .map((n: any) => n.id),\n )\n : new Set<string>();\n\n const downstreamNodes: Node[] = (groupData.expandedNodes || []).filter(\n (n: any) => !channelNodeIds.has(n.id),\n );\n\n const seenEdgeIds = new Set<string>();\n const downstreamEdges: Edge[] = (groupData.expandedEdges || [])\n .map((e: any) => ({\n ...e,\n type: \"animated\",\n source: msgIdToChildId.get(e.source) || e.source,\n target: msgIdToChildId.get(e.target) || e.target,\n id: `${groupNodeId}__${e.id}`,\n }))\n .filter((e: Edge) => {\n if (seenEdgeIds.has(e.id)) return false;\n seenEdgeIds.add(e.id);\n // Drop edges that touch a hidden channel node\n if (channelNodeIds.has(e.source) || channelNodeIds.has(e.target))\n return false;\n return true;\n });\n\n // Animate the layout transition\n animateLayout();\n\n // Swap: remove compact node + its edge, add expanded container + children + downstream + edges\n setNodes((prev) => {\n const downstreamX =\n groupData.direction === \"sends\"\n ? node.position.x + containerWidth + 260\n : node.position.x - 420;\n const downstreamY = node.position.y + 40;\n return buildMessageGroupExpansionNodes({\n currentNodes: prev,\n groupNodeId,\n expandedContainerNode,\n childNodes,\n downstreamNodes,\n getDownstreamPosition: (_downstreamNode, index) => ({\n x: downstreamX,\n y: downstreamY + index * 190,\n }),\n }) as Node[];\n });\n setEdges((prev) => {\n const without = prev.filter(\n (e) => e.source !== groupNodeId && e.target !== groupNodeId,\n );\n // Animated (or not) like the rest, as Simulate messages is set\n return [\n ...without,\n ...prepareEdges([...childEdges, ...downstreamEdges]),\n ];\n });\n\n // After React renders the new nodes, measure actual sizes, resize container, and distribute evenly\n requestAnimationFrame(() => {\n let actualContainerBounds = {\n x: node.position.x,\n y: node.position.y,\n width: containerWidth,\n height: containerHeight,\n };\n\n setNodes((prev) => {\n const children = prev.filter((n) => n.parentId === groupNodeId);\n if (children.length === 0) return prev;\n\n // Measure actual rendered dimensions\n const measurements = children.map((n) => {\n const el = document.querySelector(\n `[data-id=\"${n.id}\"]`,\n ) as HTMLElement | null;\n return {\n id: n.id,\n w: el?.offsetWidth ?? 240,\n h: el?.offsetHeight ?? 120,\n };\n });\n\n const padding = 30;\n const headerH = 50;\n const gap = 25;\n const totalChildH =\n measurements.reduce((sum, m) => sum + m.h, 0) +\n gap * (measurements.length - 1);\n const actualContainerH = headerH + totalChildH + padding * 2;\n\n let currentY = headerH + padding;\n actualContainerBounds = {\n x: node.position.x,\n y: node.position.y,\n width: containerWidth,\n height: actualContainerH,\n };\n\n return prev.map((n) => {\n // Resize the container to fit actual content\n if (n.id === groupNodeId) {\n actualContainerBounds = {\n x: n.position.x,\n y: n.position.y,\n width: containerWidth,\n height: actualContainerH,\n };\n return {\n ...n,\n style: {\n ...n.style,\n height: actualContainerH,\n },\n };\n }\n if (n.parentId !== groupNodeId) return n;\n const m = measurements.find((m) => m.id === n.id);\n if (!m) return n;\n const x = Math.max(0, (containerWidth - m.w) / 2);\n const y = currentY;\n currentY += m.h + gap;\n return { ...n, position: { x, y } };\n });\n });\n\n requestAnimationFrame(() => {\n const groupNode = getNodes().find((n) => n.id === groupNodeId);\n const measured = (groupNode as any)?.measured;\n const width =\n measured?.width ??\n (groupNode?.style?.width as number | undefined) ??\n containerWidth;\n const height =\n measured?.height ??\n (groupNode?.style?.height as number | undefined) ??\n actualContainerBounds.height;\n const bounds = {\n x: groupNode?.position.x ?? actualContainerBounds.x,\n y: groupNode?.position.y ?? actualContainerBounds.y,\n width,\n height,\n };\n\n makeRoomForRenderedExpandedGroup(groupNodeId, bounds);\n setCenter(bounds.x + width / 2, bounds.y + height / 2, {\n duration: 450,\n zoom: Math.min(Math.max(getZoom(), 0.55), 1),\n });\n });\n });\n\n return;\n }\n\n // Handle flow-reference click — inline-expand the sub-flow\n if (isExpandableFlow) {\n const flowData = node.data as any;\n const flowNodeId = node.id;\n const subFlowNodes: any[] = flowData.expandedNodes || [];\n const subFlowEdges: any[] = flowData.expandedEdges || [];\n\n const childNodes: Node[] = subFlowNodes.map((child) => ({\n ...child,\n parentId: flowNodeId,\n extent: \"parent\" as const,\n position: { x: 0, y: 0 },\n }));\n\n // Capture the node, its edges, and the set of node ids as they are\n // right now so collapse can (a) restore the pre-expansion node/edges\n // verbatim even for wrappers created mid-session, and (b) identify\n // which downstream nodes were newly introduced by this expansion.\n const preExpansionEdges = edgesRef.current.filter(\n (e) => e.source === flowNodeId || e.target === flowNodeId,\n );\n const preExpansionNodeIds = nodesRef.current.map((n) => n.id);\n // Where everything was, so collapsing puts the graph back as it was\n const preExpansionPositions = Object.fromEntries(\n nodesRef.current\n .filter((n) => !n.parentId)\n .map((n) => [n.id, n.position]),\n );\n const preExpansionRoutes = Object.fromEntries(\n edgesRef.current\n .filter((e) => e.data?.route)\n .map((e) => [e.id, e.data!.route as EdgeRoute]),\n );\n\n const expandedContainerNode: Node = {\n id: flowNodeId,\n type: \"flowExpanded\",\n position: node.position,\n data: {\n flowName: flowData.flow?.name || flowData.flow?.data?.name,\n version: flowData.flow?.version || flowData.flow?.data?.version,\n __preExpansion: {\n node,\n edges: preExpansionEdges,\n nodeIds: preExpansionNodeIds,\n nodePositions: preExpansionPositions,\n edgeRoutes: preExpansionRoutes,\n },\n },\n // Sized to fit its children when the graph is laid out\n style: {\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n overflow: \"visible\",\n },\n };\n\n const childIds = new Set(childNodes.map((n) => n.id));\n const hasIncoming = new Set<string>();\n const hasOutgoing = new Set<string>();\n for (const e of subFlowEdges) {\n if (childIds.has(e.target)) hasIncoming.add(e.target);\n if (childIds.has(e.source)) hasOutgoing.add(e.source);\n }\n const entryChildIds = childNodes\n .map((n) => n.id)\n .filter((id) => !hasIncoming.has(id));\n const terminalChildIds = childNodes\n .map((n) => n.id)\n .filter((id) => !hasOutgoing.has(id));\n\n // Reroute the parent graph's edges across the sub-flow's boundary:\n // each predecessor now targets every entry child; each successor\n // sources from every terminal child.\n const currentEdges = edgesRef.current;\n const predecessorEdges = currentEdges.filter(\n (e: Edge) => e.target === flowNodeId,\n );\n const successorEdges = currentEdges.filter(\n (e: Edge) => e.source === flowNodeId,\n );\n\n const stitchedPredecessors: Edge[] = [];\n for (const e of predecessorEdges) {\n for (const entryId of entryChildIds.length > 0\n ? entryChildIds\n : [flowNodeId]) {\n stitchedPredecessors.push({\n ...e,\n id: `${e.id}__to__${entryId}`,\n target: entryId,\n });\n }\n }\n const stitchedSuccessors: Edge[] = [];\n for (const e of successorEdges) {\n for (const terminalId of terminalChildIds.length > 0\n ? terminalChildIds\n : [flowNodeId]) {\n stitchedSuccessors.push({\n ...e,\n id: `${e.id}__from__${terminalId}`,\n source: terminalId,\n });\n }\n }\n\n // Lay the graph out again with the sub-flow expanded in place (only\n // the latest layout is applied)\n const run = ++subFlowLayoutRun.current;\n const currentNodes = nodesRef.current;\n layoutWithElk({\n nodes: [\n ...currentNodes.filter((n) => n.id !== flowNodeId),\n expandedContainerNode,\n ...childNodes,\n ],\n edges: [\n ...currentEdges.filter(\n (e) => e.source !== flowNodeId && e.target !== flowNodeId,\n ),\n ...subFlowEdges,\n ...stitchedPredecessors,\n ...stitchedSuccessors,\n ],\n }).then((expanded) => {\n if (run !== subFlowLayoutRun.current) return;\n animateLayout();\n setNodes(expanded.nodes);\n setEdges(expanded.edges);\n // Called straight after setNodes so React Flow fits once they're measured\n fitView({ duration: 400, padding: 0.2 });\n });\n\n return;\n }\n\n // Legacy behavior for linksToVisualiser (deprecated - use onNodeClick instead).\n // Keep this after inline expand handlers so embedded overview graphs can\n // still expand message groups/sub-flows without opening focus mode.\n if (linksToVisualiser && onNavigate) {\n return;\n }\n\n // Open focus mode modal\n setFocusedNodeId(node.id);\n setFocusModeOpen(true);\n },\n [\n onNodeClick,\n linksToVisualiser,\n onNavigate,\n makeRoomForRenderedExpandedGroup,\n getNodes,\n getZoom,\n setCenter,\n prepareEdges,\n ],\n );\n\n const toggleAnimateMessages = useCallback(() => {\n setAnimateMessages((prev) => {\n const next = !prev;\n localStorage.setItem(ANIMATE_MESSAGES_STORAGE_KEY, JSON.stringify(next));\n return next;\n });\n }, []);\n\n // Handle fit to view\n const handleFitView = useCallback(() => {\n fitView({ ...DIAGRAM_FIT_VIEW_OPTIONS, duration: 400 });\n }, [fitView]);\n\n // animate messages, between views (see shouldAnimateMessages)\n useEffect(() => {\n setAnimateMessages(\n shouldAnimateMessages({\n disabled: disableMessageAnimation,\n animated,\n nodeCount: initialNodes.length,\n }),\n );\n }, [animated, disableMessageAnimation, initialNodes.length]);\n\n // Toggled (the edges start as it was decided)\n const animatedEdgesFor = useRef(animateMessages);\n useEffect(() => {\n if (animatedEdgesFor.current === animateMessages) return;\n animatedEdgesFor.current = animateMessages;\n setEdges((eds) => applyMessageAnimation(eds, animateMessages));\n }, [animateMessages]);\n\n useEffect(() => {\n // The switch animation fits the view after switching graphs\n if (transitionFrom) return;\n setTimeout(() => {\n fitView({ maxZoom: 1, duration: 800 });\n }, 150);\n }, []);\n\n // Leaving the Mermaid view mounts the diagram again. It may be at another\n // level now, reached without the animation that fits it (see\n // disableAnimation), so fit it once its nodes are measured\n const wasMermaidView = useRef(isMermaidView);\n useEffect(() => {\n if (wasMermaidView.current && !isMermaidView) {\n fitView(INITIAL_FIT_VIEW_OPTIONS);\n }\n wasMermaidView.current = isMermaidView;\n }, [isMermaidView, fitView]);\n\n // Generate mermaid code lazily (only when needed for copy)\n const generateMermaidCode = useCallback(() => {\n try {\n return convertToMermaid(nodesRef.current, edgesRef.current, {\n includeStyles: true,\n direction: \"LR\",\n });\n } catch (error) {\n console.error(\"Error generating mermaid code:\", error);\n return \"\";\n }\n }, []);\n\n // Handle scroll wheel events to forward to page when no modifier keys are pressed\n // Only when zoomOnScroll is disabled\n // This is a fix for when we embed node graphs into pages, and users are scrolling the documentation pages\n // We dont want REACT FLOW to swallow the scroll events, so we forward them to the parent page\n useEffect(() => {\n // Skip scroll handling if zoomOnScroll is enabled\n if (zoomOnScroll) return;\n\n // Cache the scrollable container on mount (expensive operation done once)\n const findScrollableContainer = (): HTMLElement | null => {\n // Try specific known selectors first (fast)\n const selectors = [\n \".docs-layout .overflow-y-auto\",\n \".overflow-y-auto\",\n '[style*=\"overflow-y:auto\"]',\n '[style*=\"overflow-y: auto\"]',\n ];\n\n for (const selector of selectors) {\n const element = document.querySelector(selector) as HTMLElement;\n if (element) return element;\n }\n\n return null;\n };\n\n // Find and cache the scrollable container once\n if (!scrollableContainerRef.current) {\n scrollableContainerRef.current = findScrollableContainer();\n }\n\n const handleWheel = (event: WheelEvent) => {\n // Only forward scroll if no modifier keys are pressed\n if (!event.ctrlKey && !event.shiftKey && !event.metaKey) {\n event.preventDefault();\n\n const scrollableContainer = scrollableContainerRef.current;\n\n if (scrollableContainer) {\n scrollableContainer.scrollBy({\n top: event.deltaY,\n left: event.deltaX,\n behavior: \"instant\",\n });\n } else {\n // Fallback to window scroll\n window.scrollBy({\n top: event.deltaY,\n left: event.deltaX,\n behavior: \"instant\",\n });\n }\n }\n };\n\n const wrapper = reactFlowWrapperRef.current;\n if (wrapper) {\n wrapper.addEventListener(\"wheel\", handleWheel, { passive: false });\n return () => {\n wrapper.removeEventListener(\"wheel\", handleWheel);\n };\n }\n }, [zoomOnScroll]);\n\n const handlePaneClick = useCallback(() => {\n searchRef.current?.hideSuggestions();\n resetNodesAndEdges();\n fitView({ maxZoom: 1, duration: 800 });\n }, [resetNodesAndEdges, fitView]);\n\n const handleNodeSelect = useCallback(\n (node: Node) => {\n handleNodeClick(null, node);\n },\n [handleNodeClick],\n );\n\n const handleSearchClear = useCallback(() => {\n resetNodesAndEdges();\n fitView({ maxZoom: 1, duration: 800 });\n }, [resetNodesAndEdges, fitView]);\n\n const downloadImage = useCallback((dataUrl: string, filename?: string) => {\n const a = document.createElement(\"a\");\n a.setAttribute(\"download\", `${filename || \"eventcatalog\"}.png`);\n a.setAttribute(\"href\", dataUrl);\n a.click();\n }, []);\n\n const openChat = useCallback(() => {\n window.dispatchEvent(new CustomEvent(\"eventcatalog:open-chat\"));\n }, []);\n\n // Layout persistence handlers (dev mode only)\n const handleSaveLayout = useCallback(async (): Promise<boolean> => {\n if (!resourceKey || !onSaveLayout) return false;\n // Grouping is only a way of looking at the graph: grouped, nodes are\n // placed inside their groups, which a saved layout can't show\n if (swimlanesRef.current) return false;\n\n const positions: Record<string, { x: number; y: number }> = {};\n nodesRef.current.forEach((node) => {\n if (isSwimlaneNode(node)) return;\n positions[node.id] = {\n x: node.position.x,\n y: node.position.y,\n };\n });\n\n return await onSaveLayout(resourceKey, positions);\n }, [resourceKey, onSaveLayout]);\n\n // What the diagram shows, for Studio to start a canvas from: the full graph (Studio shows the other levels itself),\n // the levels as the diagram draws them, and the level shown, for it to open at. Taken when Studio asks for it\n // (once the canvas is named), not as the menu item is chosen.\n const getStudioSnapshot =\n useCallback(async (): Promise<VisualiserSnapshot> => {\n const { detail, overview, hiddenMessages } = studioGraphs!;\n const level = (levels.findIndex((entry) => entry.active) + 1 || 3) as\n | 1\n | 2\n | 3;\n // The level shown, as on screen (with anything moved); the others as laid out\n const shown: LevelGraph = {\n nodes: getNodes().filter((node) => !node.hidden),\n edges: getEdges().filter((edge) => !edge.hidden),\n };\n const detailNodes = new Map(detail.nodes.map((node) => [node.id, node]));\n const graph =\n level === 3\n ? toSnapshot(shown.nodes, shown.edges, (node) => {\n const internal = getInternalNode(node.id);\n return {\n position: internal?.internals.positionAbsolute ?? node.position,\n width: internal?.measured.width ?? node.width ?? 0,\n height: internal?.measured.height ?? node.height ?? 0,\n };\n })\n : toSnapshot(detail.nodes, detail.edges, (node) => {\n const position = { ...node.position };\n for (\n let parent = node.parentId && detailNodes.get(node.parentId);\n parent;\n parent = parent.parentId && detailNodes.get(parent.parentId)\n ) {\n position.x += parent.position.x;\n position.y += parent.position.y;\n }\n return { position, ...laidOutSize(node) };\n });\n // A level not shown, with its edges as they're drawn (shown ones already are)\n const asDrawn = ({ nodes, edges }: LevelGraph): LevelGraph => ({\n nodes,\n edges: prepareEdges(edges),\n });\n // Level 2 as the diagram lays it out: the one it was given, or the full graph without its messages and\n // channels (the full graph itself when it has none)\n const levelTwo = async (): Promise<LevelGraph> => {\n if (level === 2) return shown;\n if (hiddenMessages) return asDrawn(hiddenMessages);\n const full = level === 3 ? shown : detail;\n if (!full.nodes.some(isCarrier)) return asDrawn(full);\n return asDrawn(\n await layoutWithElk(hideMessageNodes(full.nodes, full.edges)),\n );\n };\n return {\n title,\n level,\n ...graph,\n levels: {\n // Level 1 as shown, or the overview the diagram has (a context diagram is only level 1)\n ...((level === 1 || overview) && {\n 1: level === 1 ? shown : asDrawn(overview!),\n }),\n 2: await levelTwo(),\n },\n unavailableLevels: {\n ...(levels[0]?.disabledReason && { 1: levels[0].disabledReason }),\n ...(levels[1]?.disabledReason && { 2: levels[1].disabledReason }),\n },\n };\n }, [\n title,\n levels,\n studioGraphs,\n prepareEdges,\n getNodes,\n getEdges,\n getInternalNode,\n ]);\n const handleOpenInStudio = useCallback(() => {\n if (onOpenInStudio && studioGraphs)\n onOpenInStudio({ title, getSnapshot: getStudioSnapshot });\n }, [onOpenInStudio, studioGraphs, title, getStudioSnapshot]);\n\n const handleResetLayout = useCallback(async (): Promise<boolean> => {\n if (!resourceKey || !onResetLayout) return false;\n return await onResetLayout(resourceKey);\n }, [resourceKey, onResetLayout]);\n\n // Quick save handler for the change detection UI\n const handleQuickSaveLayout = useCallback(async () => {\n setIsSavingLayout(true);\n const success = await handleSaveLayout();\n setIsSavingLayout(false);\n if (success) {\n // Update initial positions to current positions after save\n const positions: Record<string, { x: number; y: number }> = {};\n nodesRef.current.forEach((node) => {\n positions[node.id] = { x: node.position.x, y: node.position.y };\n });\n initialPositionsRef.current = positions;\n setHasLayoutChanges(false);\n }\n }, [handleSaveLayout]);\n\n const handleCopyArchitectureCode = useCallback(async () => {\n const code = generateMermaidCode();\n await copyToClipboard(code);\n }, [generateMermaidCode]);\n\n const handleCopyShareUrl = useCallback(async () => {\n const url = typeof window !== \"undefined\" ? window.location.href : \"\";\n await copyToClipboard(url);\n setShareUrlCopySuccess(true);\n setTimeout(() => setShareUrlCopySuccess(false), 2000);\n }, []);\n\n const toggleFullScreen = useCallback(() => {\n if (!document.fullscreenElement) {\n reactFlowWrapperRef.current?.requestFullscreen().catch((err) => {\n console.error(\n `Error attempting to enable full-screen mode: ${err.message} (${err.name})`,\n );\n });\n } else {\n document.exitFullscreen();\n }\n }, []);\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n _setIsFullscreen(!!document.fullscreenElement);\n setTimeout(() => {\n fitView({ duration: 800 });\n }, 100);\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => {\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n };\n }, [fitView]);\n\n const handleExportVisual = useCallback(() => {\n // nodeLookup resolves child node positions (relative to their parent\n // group) to absolute coordinates — without it grouped graphs get cropped\n const nodesBounds = getNodesBounds(getNodes(), {\n nodeLookup: storeApi.getState().nodeLookup,\n });\n const { width, height, viewport } = getExportImageDimensions(nodesBounds);\n\n // Hide controls during export\n const controls = document.querySelector(\n \".react-flow__controls\",\n ) as HTMLElement;\n if (controls) controls.style.display = \"none\";\n\n const viewportElement = document.querySelector(\n \".react-flow__viewport\",\n ) as HTMLElement;\n const removeExportStyles = injectExportStyles(viewportElement);\n\n toPng(viewportElement, {\n backgroundColor: \"#f1f1f1\",\n width,\n height,\n pixelRatio: EXPORT_PIXEL_RATIO,\n style: {\n width: `${width}px`,\n height: `${height}px`,\n transform: `translate(${viewport.x}px, ${viewport.y}px) scale(${viewport.zoom})`,\n },\n })\n .then((dataUrl: string) => addExportBranding(dataUrl, EXPORT_PIXEL_RATIO))\n .then((dataUrl: string) => {\n downloadImage(dataUrl, title);\n })\n .finally(() => {\n removeExportStyles();\n if (controls) controls.style.display = \"block\";\n });\n }, [getNodes, storeApi, downloadImage, title]);\n\n // In the Mermaid view, the image is of the Mermaid diagram, at its own size\n // (not zoomed or panned) on the diagram's background\n const handleExportMermaidImage = useCallback(() => {\n const svg = reactFlowWrapperRef.current?.querySelector<SVGSVGElement>(\n 'svg[id^=\"mermaid-view\"]',\n );\n if (!svg) return;\n const background = getComputedStyle(\n reactFlowWrapperRef.current!,\n ).backgroundColor;\n toPng(svg as unknown as HTMLElement, {\n backgroundColor: background,\n pixelRatio: EXPORT_PIXEL_RATIO,\n })\n // Cropped to the diagram, so with the same space around it as the diagram's image\n .then((dataUrl: string) =>\n addExportBranding(dataUrl, EXPORT_PIXEL_RATIO, {\n padding: EXPORT_PADDING,\n background,\n }),\n )\n .then((dataUrl: string) => downloadImage(dataUrl, title));\n }, [downloadImage, title]);\n\n const handleExportMermaidFile = useCallback(() => {\n const code = generateMermaidCode();\n if (!code) return;\n const url = URL.createObjectURL(\n new Blob([code], { type: \"text/plain;charset=utf-8\" }),\n );\n const a = document.createElement(\"a\");\n a.setAttribute(\"download\", `${title || \"eventcatalog\"}.mmd`);\n a.setAttribute(\"href\", url);\n a.click();\n URL.revokeObjectURL(url);\n }, [generateMermaidCode, title]);\n\n // Legend only depends on node types and groups, not positions.\n // Use a ref to avoid recomputing the key string on every drag tick.\n const legendKeyRef = useRef(\"\");\n const computedLegendKey = nodes\n .map((n: Node<any>) => `${n.id}:${n.type}:${n.data.group?.id || \"\"}`)\n .join(\",\");\n if (computedLegendKey !== legendKeyRef.current) {\n legendKeyRef.current = computedLegendKey;\n }\n const legendKey = legendKeyRef.current;\n\n const graphLegend = useMemo(() => getLegend(nodes), [legendKey]);\n // Hidden entries stay listed (their nodes are no longer in the graph), in the\n // order entries were first listed\n // Starting with the whole graph's, for entries already hidden\n const legendEntries = useRef<Record<string, LegendEntry> | null>(null);\n const legend = useMemo(() => {\n legendEntries.current ??= getLegend(initialNodes);\n Object.assign(legendEntries.current, graphLegend);\n return Object.fromEntries(\n Object.entries(legendEntries.current).filter(\n ([key]) => key in graphLegend || hiddenLegendKeys.includes(key),\n ),\n );\n }, [graphLegend, hiddenLegendKeys]);\n legendRef.current = legend;\n\n // Stable key derived from node IDs — only changes when nodes are added/removed,\n // not when positions change during drag. Used by search, legend, and notes.\n const nodeIdsKeyRef = useRef(\"\");\n const computedNodeIdsKey = nodes.map((n) => n.id).join(\",\");\n if (computedNodeIdsKey !== nodeIdsKeyRef.current) {\n nodeIdsKeyRef.current = computedNodeIdsKey;\n }\n const nodeIdsKey = nodeIdsKeyRef.current;\n\n const searchNodes = useMemo(\n () => nodes.filter((node) => !isSwimlaneNode(node)),\n [nodeIdsKey],\n );\n\n // Collect notes across all nodes for the dropdown menu item.\n // Notes don't change during drag — use nodeIdsKey for stability.\n const allNoteGroups = useMemo(() => {\n const groups: {\n nodeId: string;\n name: string;\n notes: any[];\n nodeType: string;\n }[] = [];\n for (const node of nodes) {\n const result = getNotesFromNode(node);\n if (result) {\n groups.push({\n nodeId: node.id,\n name: result.name,\n notes: result.notes,\n nodeType: result.nodeType,\n });\n }\n }\n return groups;\n }, [nodeIdsKey]);\n\n const totalNotesCount = useMemo(\n () => allNoteGroups.reduce((sum, g) => sum + g.notes.length, 0),\n [allNoteGroups],\n );\n\n // The steps walked so far in the flow walkthrough, numbered on the canvas\n const [walkthroughTrail, setWalkthroughTrail] = useState<string[]>([]);\n // The same, for handlers that run after the graph changes (e.g. regrouping)\n const walkthroughTrailRef = useRef<string[]>([]);\n // A walkthrough step: the way taken to it stays lit (numbered, its edges\n // solid), the ways on from it are lit and moving, and the rest fades back.\n // The view fits the step and the steps it can go on to.\n const handleStepChange = useCallback(\n (\n nodeId: string | null,\n shouldZoomOut?: boolean,\n trail: string[] = nodeId ? [nodeId] : [],\n ) => {\n if (nodeId === null) {\n resetNodesAndEdges();\n setWalkthroughTrail([]);\n walkthroughTrailRef.current = [];\n _setActiveStepIndex(null);\n if (shouldZoomOut) {\n setTimeout(() => {\n fitView({ duration: 800, padding: 0.1 });\n }, 100);\n }\n return;\n }\n\n // Read through refs, so the handler stays the same while nodes move\n const nodes = nodesRef.current;\n const edges = edgesRef.current;\n const activeNode = nodes.find((node: Node) => node.id === nodeId);\n if (!activeNode) return;\n\n const walked = new Set(trail);\n const walkedEdges = new Set<string>();\n trail.slice(1).forEach((target, index) => {\n const source = trail[index];\n edges.forEach((edge: Edge) => {\n if (edge.source === source && edge.target === target)\n walkedEdges.add(edge.id);\n });\n });\n const nextEdges = edges.filter((edge: Edge) => edge.source === nodeId);\n const nextNodeIds = new Set(nextEdges.map((edge) => edge.target));\n\n const opacityOf = (node: Node) =>\n walked.has(node.id) || isSwimlaneNode(node)\n ? 1\n : nextNodeIds.has(node.id)\n ? 0.75\n : 0.15;\n setNodes(\n nodes.map((node: Node) => ({\n ...node,\n className: withWalkthroughCurrent(node, node.id === nodeId),\n style: { ...node.style, opacity: opacityOf(node) },\n })),\n );\n setEdges(\n edges.map((edge: Edge) => {\n const isNext = edge.source === nodeId;\n const lit = isNext || walkedEdges.has(edge.id);\n return {\n ...edge,\n data: { ...edge.data, opacity: lit ? 1 : 0.15, animated: isNext },\n style: {\n ...edge.style,\n opacity: lit ? 1 : 0.15,\n strokeWidth: lit ? 3 : 2,\n },\n labelStyle: { ...edge.labelStyle, opacity: lit ? 1 : 0.15 },\n animated: isNext,\n };\n }),\n );\n setWalkthroughTrail(trail);\n walkthroughTrailRef.current = trail;\n\n // The step and where it can go next, not zoomed in so far the flow is\n // lost, in the canvas above the walkthrough card\n const canvas = reactFlowWrapperRef.current?.getBoundingClientRect();\n if (!canvas) return;\n const bounds = getNodesBounds([nodeId, ...nextNodeIds], {\n nodeLookup: storeApi.getState().nodeLookup,\n });\n const cardSpace = Math.min(WALKTHROUGH_CARD_SPACE, canvas.height * 0.35);\n setViewport(\n getViewportForBounds(\n bounds,\n canvas.width,\n canvas.height - cardSpace,\n 0.1,\n 0.9,\n 0.15,\n ),\n { duration: 700 },\n );\n },\n [setNodes, setEdges, resetNodesAndEdges, setViewport, storeApi],\n );\n\n // Swimlanes: a flow's steps grouped into lanes by domain, system or team.\n // The graph without lanes is kept to lay out again from, and to go back to.\n const swimlaneOptions = useMemo(\n () =>\n isFlowGraph\n ? FLOW_GROUP_BYS.filter((groupBy) =>\n hasSwimlanes(initialNodes, groupBy),\n )\n : [],\n [isFlowGraph, initialNodes],\n );\n const swimlaneCounts = useMemo(\n () =>\n Object.fromEntries(\n swimlaneOptions.map((groupBy) => [\n groupBy,\n countGroups(initialNodes, groupBy),\n ]),\n ),\n [swimlaneOptions, initialNodes],\n );\n // Each time the graph is shown grouped another way (see below)\n const [groupingShown, setGroupingShown] = useState(0);\n // Grouping into boxes is laid out (async), so only the latest is shown\n const groupingRun = useRef(0);\n const handleSwimlanesChange = useCallback(\n (\n requested: FlowGroupBy | null,\n style: FlowGroupStyle = swimlaneStyleRef.current,\n ) => {\n // Lanes don't nest, so domains with their systems become domains\n const groupBy =\n style === \"lanes\" && requested === \"domain-system\"\n ? \"domain\"\n : requested;\n if (\n groupBy === swimlanesRef.current &&\n style === swimlaneStyleRef.current\n )\n return;\n const unlaned = unlanedGraphRef.current ?? {\n nodes: nodesRef.current,\n edges: edgesRef.current,\n };\n unlanedGraphRef.current = groupBy ? unlaned : null;\n swimlanesRef.current = groupBy;\n swimlaneStyleRef.current = style;\n setSwimlanes(groupBy);\n setSwimlaneStyle(style);\n\n const run = ++groupingRun.current;\n const show = (next: { nodes: Node[]; edges: Edge[] }) => {\n if (run !== groupingRun.current) return;\n animateLayout();\n setNodes(next.nodes);\n setEdges(next.edges);\n // Once shown, the walkthrough picks up where it was (see below)\n setGroupingShown((count) => count + 1);\n };\n if (!groupBy) show(unlaned);\n else if (style === \"lanes\" && groupBy !== \"domain-system\")\n show(layoutSwimlanes(unlaned, groupBy, { sizeOf: renderedSizeOf }));\n else\n groupIntoBoxes(unlaned, groupBy, { sizeOf: renderedSizeOf }).then(show);\n\n setGroupInUrl(groupBy, style);\n },\n [animateLayout, setNodes, setEdges, renderedSizeOf],\n );\n // Each time the graph is shown grouped another way: a walkthrough carries\n // on from the step it was on (lit, numbered and in view in the new layout),\n // otherwise the whole graph is shown, without any walkthrough styling the\n // graph had when it was last shown this way. Only when the graph has been\n // grouped another way.\n useEffect(() => {\n if (groupingShown === 0) return;\n const trail = walkthroughTrailRef.current;\n if (trail.length > 0) {\n handleStepChange(trail[trail.length - 1], false, trail);\n } else {\n resetNodesAndEdges();\n fitView({ duration: 400, padding: 0.1 });\n }\n }, [groupingShown]);\n\n // Start grouped when the URL (or the page) asks for it, once the nodes\n // have rendered (so groups fit them)\n const nodesInitialized = useNodesInitialized();\n const groupedOnLoad = useRef(false);\n useEffect(() => {\n if (!nodesInitialized || groupedOnLoad.current) return;\n groupedOnLoad.current = true;\n // The URL's grouping wins over the page's\n const fromUrl = readGroupFromUrl();\n const groupBy = fromUrl.groupBy ?? initialSwimlanes;\n const style = fromUrl.style ?? \"boxes\";\n if (\n isFlowGroupBy(groupBy) &&\n hasSwimlanes(initialNodes, groupBy) &&\n isFlowGroupStyle(style)\n ) {\n handleSwimlanesChange(groupBy, style);\n }\n // Only when the graph is first shown\n }, [nodesInitialized]);\n const isCompactMenuButton = !title;\n const menuButtonClassName = isCompactMenuButton\n ? DIAGRAM_MENU_BUTTON_COMPACT\n : DIAGRAM_MENU_BUTTON;\n const menuIconClassName = isCompactMenuButton\n ? DIAGRAM_MENU_BUTTON_ICON_COMPACT\n : DIAGRAM_MENU_BUTTON_ICON;\n\n // The title, menu and search over the diagram, and over its Mermaid view\n const diagramHeader = (\n <>\n <div className=\"flex space-x-2 justify-between items-center pointer-events-auto\">\n <div className=\"flex space-x-2 ml-4\">\n {/* Settings Dropdown Menu */}\n {showMenu && (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button className={menuButtonClassName} aria-label=\"Open menu\">\n {title && <span className={DIAGRAM_MENU_TITLE}>{title}</span>}\n <MoreVertical className={menuIconClassName} />\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal container={reactFlowWrapperRef.current}>\n <DropdownMenu.Content\n className={DIAGRAM_MENU}\n sideOffset={0}\n align=\"end\"\n alignOffset={-180}\n >\n <DropdownMenu.Arrow className=\"fill-[rgb(var(--ec-page-bg))] stroke-[rgb(var(--ec-page-border))] stroke-1\" />\n <VisualizerDropdownContent\n isMermaidView={isMermaidView}\n setIsMermaidView={setIsMermaidView}\n animateMessages={animateMessages}\n toggleAnimateMessages={toggleAnimateMessages}\n hideAnimateMessages={disableMessageAnimation}\n hideChannels={hideChannels}\n toggleChannelsVisibility={toggleChannelsVisibility}\n hasChannels={hasChannels}\n hideMessages={hideMessages}\n toggleMessagesVisibility={toggleMessagesVisibility}\n hasMessages={hasMessages}\n showMinimap={showMinimap}\n setShowMinimap={setShowMinimap}\n handleFitView={handleFitView}\n searchRef={searchRef}\n isChatEnabled={isChatEnabled}\n openChat={openChat}\n handleCopyArchitectureCode={handleCopyArchitectureCode}\n onOpenExport={openExportModal}\n setIsShareModalOpen={setIsShareModalOpen}\n toggleFullScreen={toggleFullScreen}\n isDevMode={isDevMode}\n onSaveLayout={swimlanes ? undefined : handleSaveLayout}\n onResetLayout={handleResetLayout}\n notesCount={totalNotesCount}\n onOpenNotes={openNotesModal}\n onOpenInStudio={\n onOpenInStudio ? handleOpenInStudio : undefined\n }\n />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n )}\n </div>\n {mode === \"full\" && showSearch && (\n <div className=\"flex justify-end items-center gap-2\">\n {!isMermaidView && (\n <div className={compactSearch ? \"w-60\" : \"w-96\"}>\n <VisualiserSearch\n ref={searchRef}\n nodes={searchNodes}\n onNodeSelect={handleNodeSelect}\n onClear={handleSearchClear}\n />\n </div>\n )}\n </div>\n )}\n </div>\n {links.length > 0 && (\n <div className=\"flex justify-end mt-3\">\n <div className=\"relative flex items-center -mt-1\">\n <span className=\"absolute left-2 pointer-events-none flex items-center h-full\">\n <HistoryIcon className=\"h-4 w-4 text-[rgb(var(--ec-page-text-muted))]\" />\n </span>\n <select\n value={\n links.find((link) => window.location.href.includes(link.url))\n ?.url || links[0].url\n }\n onChange={(e) => {\n // Goes to one of the links given, never to whatever the option's value was changed to\n const link = links.find(\n (link) => link.url === e.target.value,\n )?.url;\n if (!link) return;\n // Another version opens in the Mermaid view too, when the URL keeps it\n const url =\n isMermaidView && isMermaidInUrl()\n ? withMermaidInUrl(link)\n : link;\n if (onNavigate) {\n onNavigate(url);\n } else {\n window.location.href = url;\n }\n }}\n className=\"appearance-none pl-7 pr-6 py-0 text-[14px] bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] rounded-md border border-[rgb(var(--ec-page-border))] hover:bg-[rgb(var(--ec-page-border)/0.5)] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[rgb(var(--ec-accent))]\"\n style={{ minWidth: 120, height: \"26px\" }}\n >\n {links.map((link) => (\n <option key={link.url} value={link.url}>\n {link.label}\n </option>\n ))}\n </select>\n <span className=\"absolute right-2 pointer-events-none\">\n <svg\n className=\"w-4 h-4 text-[rgb(var(--ec-page-text-muted))]\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </span>\n </div>\n </div>\n )}\n </>\n );\n\n return (\n <div\n ref={reactFlowWrapperRef}\n onClick={handleCollapseGroup}\n className=\"relative w-full h-full bg-[rgb(var(--ec-page-bg))] flex flex-col eventcatalog-visualizer\"\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n <PortalContainerProvider value={reactFlowWrapperRef.current}>\n {isMermaidView ? (\n // The same title, menu and toolbar as the diagram, over the Mermaid\n // version of it, so the two look like one tool\n <div className=\"flex-1 overflow-hidden relative\">\n <MermaidView\n nodes={nodes}\n edges={edges}\n maxTextSize={maxTextSize}\n levels={mode === \"full\" ? levels : []}\n zoomOnScroll={zoomOnScroll}\n onShowDiagram={\n mode === \"full\" ? () => setIsMermaidView(false) : undefined\n }\n />\n <Panel\n position=\"top-center\"\n className=\"w-full pr-6 pointer-events-none\"\n >\n {diagramHeader}\n </Panel>\n </div>\n ) : (\n <ReactFlow\n nodeTypes={nodeTypes}\n proOptions={hideAttribution ? HIDE_ATTRIBUTION : undefined}\n edgeTypes={edgeTypes}\n minZoom={0.07}\n nodes={nodes}\n edges={edges}\n // After switching graphs, start where the last one was and let the\n // switch animation fit the view\n fitView={!transitionFrom}\n fitViewOptions={INITIAL_FIT_VIEW_OPTIONS}\n defaultViewport={transitionFrom?.viewport}\n onNodesChange={handleNodesChange}\n onEdgesChange={onEdgesChange}\n onEdgeMouseEnter={handleEdgeMouseEnter}\n onEdgeMouseLeave={handleEdgeMouseLeave}\n connectionLineType={ConnectionLineType.SmoothStep}\n nodeOrigin={NODE_ORIGIN}\n // Selected nodes aren't raised, as their edges would be raised with\n // them and drawn over other nodes\n elevateNodesOnSelect={false}\n onNodeClick={handleNodeClick}\n onNodeMouseEnter={handleNodeMouseEnter}\n onNodeMouseLeave={handleNodeMouseLeave}\n onPaneClick={handlePaneClick}\n onMoveStart={startInteraction}\n onMoveEnd={endInteraction}\n onNodeDragStart={startInteraction}\n onNodeDragStop={endInteraction}\n zoomOnScroll={zoomOnScroll}\n className={`relative${isLayingOut ? \" ec-laying-out\" : \"\"}${\n hasOtherDomains && highlightCrossDomain\n ? \" ec-highlight-cross-domain\"\n : \"\"\n }`}\n >\n <Panel\n position=\"top-center\"\n className=\"w-full pr-6 pointer-events-none\"\n >\n {diagramHeader}\n </Panel>\n\n {includeBackground && <DiagramBackground />}\n {includeBackground && <Controls />}\n {mode === \"full\" && (\n <CanvasToolbar\n levels={levels}\n tools={canvasTools}\n onShowMermaid={showMermaidView}\n animateMessages={animateMessages}\n toggleAnimateMessages={toggleAnimateMessages}\n // Nothing to simulate without edges\n hideAnimateMessages={\n disableMessageAnimation || edges.length === 0\n }\n showMinimap={showMinimap}\n setShowMinimap={setShowMinimap}\n handleFitView={handleFitView}\n />\n )}\n {showMinimap && <DiagramMiniMap />}\n {swimlaneOptions.length > 0 && (\n <Panel\n position=\"top-right\"\n // Under the search box when it's shown\n style={\n mode === \"full\" && showSearch\n ? SWIMLANE_PICKER_PANEL_STYLE_UNDER_SEARCH\n : undefined\n }\n >\n <SwimlanePicker\n options={swimlaneOptions}\n counts={swimlaneCounts}\n value={swimlanes}\n style={swimlaneStyle}\n onChange={handleSwimlanesChange}\n />\n </Panel>\n )}\n {isFlowGraph && showFlowWalkthrough && (\n <WalkthroughBadges trail={walkthroughTrail} />\n )}\n {isFlowGraph && showFlowWalkthrough && (\n <Panel position=\"bottom-left\">\n <StepWalkthrough\n nodes={walkthroughNodes}\n edges={walkthroughEdges}\n isFlowVisualization={isFlowGraph}\n onStepChange={handleStepChange}\n mode={mode}\n />\n </Panel>\n )}\n {/* Dev Mode: Layout change indicator */}\n {isDevMode && hasLayoutChanges && !swimlanes && (\n <Panel\n position=\"bottom-left\"\n style={\n isFlowGraph && showFlowWalkthrough\n ? LAYOUT_CHANGE_PANEL_STYLE_WITH_WALKTHROUGH\n : LAYOUT_CHANGE_PANEL_STYLE_DEFAULT\n }\n >\n <div className=\"bg-[rgb(var(--ec-card-bg))] border border-[rgb(var(--ec-page-border))] rounded-lg shadow-md px-3 py-2 flex items-center gap-3\">\n <span className=\"text-xs text-[rgb(var(--ec-page-text-muted))]\">\n Layout changed\n </span>\n <button\n onClick={handleQuickSaveLayout}\n disabled={isSavingLayout}\n className=\"text-xs font-medium text-white bg-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-hover))] px-2 py-1 rounded transition-colors disabled:opacity-50\"\n >\n {isSavingLayout ? \"Saving...\" : \"Save\"}\n </button>\n </div>\n </Panel>\n )}\n {includeKey && (\n <LegendPanel\n legend={legend}\n hiddenKeys={hiddenLegendKeys}\n showMinimap={showMinimap}\n onLegendClick={toggleLegendKey}\n />\n )}\n </ReactFlow>\n )}\n <FocusModeModal\n isOpen={focusModeOpen}\n onClose={() => {\n setFocusModeOpen(false);\n }}\n initialNodeId={focusedNodeId}\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n />\n <AllNotesModal\n noteGroups={allNoteGroups}\n isOpen={isNotesModalOpen}\n onClose={() => setIsNotesModalOpen(false)}\n nodes={nodes}\n />\n\n {isExportModalOpen && (\n <ExportModal\n onClose={closeExportModal}\n onExportImage={\n isMermaidView ? handleExportMermaidImage : handleExportVisual\n }\n onExportMermaid={handleExportMermaidFile}\n />\n )}\n\n {/* Share Link Modal */}\n {isShareModalOpen && (\n <>\n <div\n className=\"absolute inset-0 bg-black/20 z-40\"\n onClick={() => setIsShareModalOpen(false)}\n style={{ animation: \"fadeIn 150ms ease-out\" }}\n />\n <div\n className=\"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-[rgb(var(--ec-page-bg))] rounded-lg shadow-xl z-50 w-[calc(100%-2rem)] max-w-md p-6 border border-[rgb(var(--ec-page-border))]\"\n style={{ animation: \"slideInCenter 250ms ease-out\" }}\n >\n <style>{`\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes slideInCenter {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: none; }\n }\n `}</style>\n\n <div className=\"flex justify-between items-start mb-4\">\n <h3 className=\"text-lg font-semibold text-[rgb(var(--ec-page-text))]\">\n Share Link\n </h3>\n <button\n onClick={() => setIsShareModalOpen(false)}\n className=\"text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] transition-colors\"\n aria-label=\"Close modal\"\n >\n <ExternalLink className=\"w-5 h-5 rotate-180\" />\n </button>\n </div>\n\n <p className=\"text-sm text-[rgb(var(--ec-page-text-muted))] mb-4\">\n Share this link with your team to let them view this\n visualization.\n </p>\n\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n readOnly\n value={\n typeof window !== \"undefined\" ? window.location.href : \"\"\n }\n className=\"flex-1 px-3 py-2.5 bg-[rgb(var(--ec-input-bg))] border border-[rgb(var(--ec-input-border))] rounded-md text-[rgb(var(--ec-input-text))] text-sm focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]\"\n />\n <button\n onClick={handleCopyShareUrl}\n className={`px-4 py-2.5 rounded-md font-medium transition-all duration-200 flex items-center gap-2 ${\n shareUrlCopySuccess\n ? \"bg-green-500 text-white\"\n : \"bg-[rgb(var(--ec-accent))] text-white hover:opacity-90\"\n }`}\n aria-label={shareUrlCopySuccess ? \"Copied!\" : \"Copy link\"}\n >\n {shareUrlCopySuccess ? (\n <CheckIcon className=\"w-4 h-4\" />\n ) : (\n <ClipboardIcon className=\"w-4 h-4\" />\n )}\n <span>{shareUrlCopySuccess ? \"Copied!\" : \"Copy\"}</span>\n </button>\n </div>\n </div>\n </>\n )}\n </PortalContainerProvider>\n </div>\n );\n};\n\ninterface NodeGraphProps {\n id: string;\n /**\n * Keeps the Mermaid view in the page's URL (`?render=mermaid`), so links open\n * in it. Only for the visualiser's own pages: not diagrams embedded in docs\n * or other apps, which can share a page (or an iframe) with others.\n */\n syncRenderModeWithUrl?: boolean;\n /**\n * The level of detail to open at (1, 2 or 3), rather than the URL's or the\n * saved one, e.g. the level an MCP client asked for\n */\n initialLevel?: 1 | 2 | 3;\n title?: string;\n href?: string;\n hrefLabel?: string;\n nodes?: Node[];\n edges?: Edge[];\n graph?: DslGraph;\n linkTo?: \"docs\" | \"visualiser\";\n includeKey?: boolean;\n footerLabel?: string;\n linksToVisualiser?: boolean;\n links?: { label: string; url: string }[];\n mode?: \"full\" | \"simple\";\n portalId?: string;\n showFlowWalkthrough?: boolean;\n showSearch?: boolean;\n /** Show the settings menu (top left). Defaults to true. */\n showMenu?: boolean;\n /** Use a narrower search box, for small spaces. */\n compactSearch?: boolean;\n /** Hide the React Flow attribution (bottom right). */\n hideAttribution?: boolean;\n zoomOnScroll?: boolean;\n designId?: string;\n isChatEnabled?: boolean;\n maxTextSize?: number;\n isDevMode?: boolean;\n resourceKey?: string;\n /** Controls whether message flow animation is enabled. When set, overrides URL params and localStorage. */\n animated?: boolean;\n /**\n * When true, message-flow animation is unsupported for this graph: it is forced\n * off (ignoring the `animated` prop, URL params and localStorage) and the\n * \"Simulate Messages\" toggle is hidden. Used by graphs that aren't message\n * flows, e.g. the System Diagram.\n */\n disableMessageAnimation?: boolean;\n /**\n * A simpler graph shown as level 1 in the toolbar (e.g. a system's context\n * diagram), before this graph's detail levels.\n */\n overviewGraph?: {\n nodes: Node[];\n edges: Edge[];\n /** Describes the level, e.g. \"system context\" */\n label: string;\n resourceKey?: string;\n };\n /**\n * This graph laid out with its messages and channels hidden (level 2). Used\n * instead of hiding them and laying the graph out again in the browser.\n */\n hiddenMessagesGraph?: { nodes: Node[]; edges: Edge[] };\n /** The kind of diagram (e.g. \"services\"), so the level is remembered for each kind */\n preferenceScope?: string;\n /** Group a flow's steps to start with (the `group` URL parameter wins) */\n swimlanes?: FlowGroupBy;\n /** When set, the graph will zoom to this node id. */\n focusNodeId?: string;\n /** Optional token to force repeated focus for the same node id. */\n focusRequestId?: number;\n /** Optional token to trigger fit-to-screen behavior. */\n fitRequestId?: number;\n\n // Callback API for framework integration\n onNodeClick?: (node: Node) => void;\n onBuildUrl?: (path: string) => string;\n onNavigate?: (url: string) => void;\n onSaveLayout?: (\n resourceKey: string,\n positions: Record<string, { x: number; y: number }>,\n ) => Promise<boolean>;\n onResetLayout?: (resourceKey: string) => Promise<boolean>;\n /** Starts a Studio canvas from what the diagram shows (the menu has \"Open in Studio\" when set) */\n onOpenInStudio?: (request: OpenInStudioRequest) => void;\n}\n\nconst NodeGraph = ({\n id,\n nodes: nodesProp,\n edges: edgesProp,\n graph,\n title: titleProp,\n href,\n linkTo = \"docs\",\n hrefLabel = \"Open in visualizer\",\n includeKey: includeKeyProp,\n footerLabel,\n linksToVisualiser = false,\n links = [],\n syncRenderModeWithUrl = false,\n initialLevel,\n mode = \"full\",\n portalId,\n showFlowWalkthrough = true,\n showSearch: showSearchProp,\n showMenu,\n compactSearch,\n hideAttribution,\n zoomOnScroll = false,\n designId,\n isChatEnabled = false,\n maxTextSize,\n isDevMode = false,\n resourceKey,\n animated: animatedProp,\n disableMessageAnimation,\n overviewGraph,\n hiddenMessagesGraph,\n preferenceScope,\n swimlanes,\n focusNodeId,\n focusRequestId,\n fitRequestId,\n onNodeClick,\n onBuildUrl,\n onNavigate,\n onSaveLayout,\n onResetLayout,\n onOpenInStudio,\n}: NodeGraphProps) => {\n // When a DslGraph is provided, lay it out here (rendered once laid out)\n const [graphLayout, setGraphLayout] = useState<{\n nodes: Node[];\n edges: Edge[];\n } | null>(null);\n useEffect(() => {\n if (!graph) return setGraphLayout(null);\n let current = true;\n layoutGraph(graph.nodes, graph.edges, {\n style: graph.options?.style,\n }).then((layout) => {\n if (current) setGraphLayout(layout);\n });\n return () => {\n current = false;\n };\n }, [graph]);\n const nodes = graphLayout?.nodes ?? nodesProp ?? NO_NODES;\n const edges = graphLayout?.edges ?? edgesProp ?? NO_EDGES;\n // The graphs shown at each level, for Studio\n const studioGraphs = useMemo(\n () => ({\n detail: { nodes, edges },\n overview: overviewGraph,\n hiddenMessages: hiddenMessagesGraph,\n }),\n [nodes, edges, overviewGraph, hiddenMessagesGraph],\n );\n\n // Derive props from graph.options when graph is provided\n const title = titleProp ?? graph?.title;\n const includeKey =\n includeKeyProp !== undefined\n ? includeKeyProp\n : graph?.options?.legend !== false;\n const showSearch =\n showSearchProp !== undefined\n ? showSearchProp\n : graph?.options?.search !== false;\n const animated = animatedProp ?? graph?.options?.animated;\n const [elem, setElem] = useState(null);\n const [showFooter, setShowFooter] = useState(true);\n const containerToRenderInto = portalId || `${id}-portal`;\n\n // Level 1 shows the overview graph when there is one. A diagram with one\n // opens at it, unless the URL asks for another level (`?level=2|3`).\n const [showOverview, setShowOverview] = useState(() => {\n if (!overviewGraph) return false;\n if (initialLevel) return initialLevel === 1;\n const level = new URLSearchParams(window.location.search).get(\"level\");\n return level === null || level === \"1\";\n });\n // The graph being switched away from, for the next one to animate from\n const [transitionFrom, setTransitionFrom] = useState<GraphTransition>();\n const handleShowOverview = useCallback(\n (show: boolean, from: GraphTransition) => {\n setTransitionFrom(from);\n setShowOverview(show);\n if (show) setLevelInUrl(1);\n },\n [],\n );\n const overview = showOverview ? overviewGraph : undefined;\n // Legend entries hidden, kept when switching between the graphs\n const hiddenLegendKeys = useRef<string[]>([]);\n const handleHiddenLegendKeysChange = useCallback((keys: string[]) => {\n hiddenLegendKeys.current = keys;\n }, []);\n // The Mermaid view, kept when switching between the graphs. On the\n // visualiser's own pages it's in the URL too (`?render=mermaid`), so links\n // open in it, as they open at their level\n const isMermaidView = useRef<boolean | null>(null);\n if (isMermaidView.current === null) {\n isMermaidView.current = syncRenderModeWithUrl && isMermaidInUrl();\n }\n const handleMermaidViewChange = useCallback(\n (value: boolean) => {\n isMermaidView.current = value;\n if (syncRenderModeWithUrl) setMermaidInUrl(value);\n },\n [syncRenderModeWithUrl],\n );\n\n useEffect(() => {\n // @ts-ignore\n setElem(document.getElementById(containerToRenderInto));\n }, []);\n\n useEffect(() => {\n const urlParams = new URLSearchParams(window.location.search);\n const embed = urlParams.get(\"embed\");\n if (embed === \"true\") {\n setShowFooter(false);\n }\n }, []);\n\n if (!elem || (graph && !graphLayout)) return null;\n\n return (\n <div>\n {createPortal(\n // Remount when switching graphs so each starts from a clean state\n <ReactFlowProvider key={overview ? \"overview\" : \"graph\"}>\n <NodeGraphBuilder\n edges={overview?.edges ?? edges}\n nodes={overview?.nodes ?? nodes}\n title={title}\n linkTo={linkTo}\n includeKey={includeKey}\n linksToVisualiser={linksToVisualiser}\n links={links}\n mode={mode}\n showFlowWalkthrough={showFlowWalkthrough}\n showSearch={showSearch}\n showMenu={showMenu}\n compactSearch={compactSearch}\n hideAttribution={hideAttribution}\n zoomOnScroll={zoomOnScroll}\n designId={designId || id}\n isChatEnabled={isChatEnabled}\n maxTextSize={maxTextSize}\n isDevMode={isDevMode}\n resourceKey={overview ? overview.resourceKey : resourceKey}\n animated={animated}\n disableMessageAnimation={disableMessageAnimation || !!overview}\n overviewLabel={overviewGraph?.label}\n isOverview={!!overview}\n onShowOverview={handleShowOverview}\n transitionFrom={transitionFrom}\n hiddenMessagesGraph={overview ? undefined : hiddenMessagesGraph}\n initialHiddenLegendKeys={hiddenLegendKeys.current}\n preferenceScope={preferenceScope}\n swimlanes={overview ? undefined : swimlanes}\n onHiddenLegendKeysChange={handleHiddenLegendKeysChange}\n initialMermaidView={isMermaidView.current ?? false}\n initialLevel={initialLevel === 1 ? undefined : initialLevel}\n onMermaidViewChange={handleMermaidViewChange}\n focusNodeId={focusNodeId}\n focusRequestId={focusRequestId}\n fitRequestId={fitRequestId}\n onNodeClick={onNodeClick}\n onBuildUrl={onBuildUrl}\n onNavigate={onNavigate}\n onSaveLayout={onSaveLayout}\n onResetLayout={onResetLayout}\n onOpenInStudio={onOpenInStudio}\n studioGraphs={studioGraphs}\n />\n\n {showFooter && (\n <div className=\"flex justify-between\" id=\"visualiser-footer\">\n {footerLabel && (\n <div className=\"py-2 w-full text-left \">\n <span className=\" text-sm no-underline py-2 text-[rgb(var(--ec-page-text-muted))]\">\n {footerLabel}\n </span>\n </div>\n )}\n\n {href && (\n <div className=\"py-2 w-full text-right flex justify-between\">\n {/* Studio link temporarily hidden */}\n <span />\n <a\n className=\" text-sm underline text-[rgb(var(--ec-page-text))] hover:text-[rgb(var(--ec-accent))]\"\n href={href}\n >\n {hrefLabel} &rarr;\n </a>\n </div>\n )}\n </div>\n )}\n </ReactFlowProvider>,\n elem,\n )}\n </div>\n );\n};\n\nexport type { NodeGraphProps };\nexport default NodeGraph;\n","import { Node, NodeProps, Handle, Position } from \"@xyflow/react\";\nimport React, { memo, useState, useEffect, useRef, useCallback } from \"react\";\nimport { FULL_SIZE_STYLE } from \"../shared-styles\";\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\n// Define the data structure for our NoteNode\nexport type NoteNodeData = {\n id: string;\n text: string;\n color?: string;\n readOnly?: boolean;\n};\n\n// Define the NoteNode type for React Flow\nexport type NoteNode = Node<NoteNodeData, \"note\">;\n\nexport interface NoteNodeProps extends NodeProps<NoteNode> {\n onTextChange?: (id: string, text: string) => void;\n onColorChange?: (id: string, color: string) => void;\n showResizer?: boolean;\n readOnly?: boolean;\n}\n\nconst AVAILABLE_COLORS = {\n yellow: {\n bg: \"bg-gradient-to-br from-yellow-200 to-yellow-300\",\n border: \"border-yellow-400\",\n text: \"text-yellow-900\",\n placeholder: \"placeholder-yellow-600\",\n selectedRing: \"ring-yellow-500\",\n tooltipBorderColor: \"#facc15\",\n },\n blue: {\n bg: \"bg-blue-200\",\n border: \"border-blue-400\",\n text: \"text-blue-900\",\n placeholder: \"placeholder-blue-600\",\n selectedRing: \"ring-blue-500\",\n tooltipBorderColor: \"#60a5fa\",\n },\n green: {\n bg: \"bg-green-200\",\n border: \"border-green-400\",\n text: \"text-green-900\",\n placeholder: \"placeholder-green-600\",\n selectedRing: \"ring-green-500\",\n tooltipBorderColor: \"#4ade80\",\n },\n pink: {\n bg: \"bg-pink-200\",\n border: \"border-pink-400\",\n text: \"text-pink-900\",\n placeholder: \"placeholder-pink-600\",\n selectedRing: \"ring-pink-500\",\n tooltipBorderColor: \"#f472b6\",\n },\n purple: {\n bg: \"bg-purple-200\",\n border: \"border-purple-400\",\n text: \"text-purple-900\",\n placeholder: \"placeholder-purple-600\",\n selectedRing: \"ring-purple-500\",\n tooltipBorderColor: \"#c084fc\",\n },\n gray: {\n bg: \"bg-gray-200\",\n border: \"border-gray-400\",\n text: \"text-gray-900\",\n placeholder: \"placeholder-gray-600\",\n selectedRing: \"ring-gray-500\",\n tooltipBorderColor: \"#9ca3af\",\n },\n} as const;\n\ntype ColorName = keyof typeof AVAILABLE_COLORS;\n\nconst POSITION_RELATIVE_STYLE = { position: \"relative\" } as const;\nconst TEXTAREA_STYLE = { height: \"100%\", minHeight: 0 } as const;\n\nexport default memo(function NoteNodeComponent({\n id,\n data,\n selected,\n onTextChange,\n onColorChange,\n readOnly = false,\n}: NoteNodeProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [currentText, setCurrentText] = useState(\n data.text || \"Double-click to edit...\",\n );\n const [isTextOverflowing, setIsTextOverflowing] = useState(false);\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n const displayRef = useRef<HTMLDivElement>(null);\n\n const currentColorName = (data.color as ColorName) || \"yellow\";\n const colorClasses =\n AVAILABLE_COLORS[currentColorName] || AVAILABLE_COLORS.yellow;\n\n // Simple markdown-like text formatting\n const formatText = (text: string) => {\n return (\n text\n // Headers\n .replace(\n /^### (.*$)/gim,\n '<h3 class=\"text-xs font-medium mb-1\">$1</h3>',\n )\n .replace(\n /^## (.*$)/gim,\n '<h2 class=\"text-xs font-semibold mb-1\">$1</h2>',\n )\n .replace(/^# (.*$)/gim, '<h1 class=\"text-sm font-bold mb-1\">$1</h1>')\n // Bold\n .replace(/\\*\\*(.*?)\\*\\*/gim, '<strong class=\"font-bold\">$1</strong>')\n // Italic\n .replace(/\\*(.*?)\\*/gim, '<em class=\"italic\">$1</em>')\n // Inline code\n .replace(\n /`(.*?)`/gim,\n '<code class=\"bg-gray-200 px-1 rounded text-[9px] font-mono\">$1</code>',\n )\n // Simple lists\n .replace(/^• (.*$)/gim, '<li class=\"text-[10px] ml-3\">• $1</li>')\n .replace(/^- (.*$)/gim, '<li class=\"text-[10px] ml-3\">• $1</li>')\n // Line breaks\n .replace(/\\n/g, \"<br>\")\n );\n };\n\n useEffect(() => {\n // Update internal state if data.text changes from props (e.g. undo/redo, initial load)\n setCurrentText(data.text || \"Double-click to edit...\");\n }, [data.text]);\n\n useEffect(() => {\n if (isEditing && textAreaRef.current) {\n textAreaRef.current.focus();\n // Select all text when starting to edit for quicker replacement\n textAreaRef.current.select();\n }\n }, [isEditing]);\n\n useEffect(() => {\n const element = displayRef.current;\n if (!element || isEditing) return;\n\n const updateOverflow = () => {\n setIsTextOverflowing(element.scrollHeight > element.clientHeight);\n };\n\n updateOverflow();\n\n if (typeof ResizeObserver === \"undefined\") {\n window.addEventListener(\"resize\", updateOverflow);\n return () => window.removeEventListener(\"resize\", updateOverflow);\n }\n\n const observer = new ResizeObserver(updateOverflow);\n observer.observe(element);\n return () => observer.disconnect();\n }, [currentText, isEditing]);\n\n const handleDoubleClick = useCallback(() => {\n if (!readOnly) {\n setIsEditing(true);\n }\n }, [readOnly]);\n\n const handleTextChange = useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n setCurrentText(event.target.value);\n },\n [],\n );\n\n const handleBlur = useCallback(() => {\n setIsEditing(false);\n // Only update if the text has actually changed from what's in data\n // or if data.text was initially undefined/empty and now has content.\n if (currentText !== data.text && onTextChange) {\n onTextChange(id, currentText);\n }\n }, [currentText, data.text, id, onTextChange]);\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault(); // Prevent newline on Enter\n handleBlur(); // Save and exit edit mode\n }\n // Allow Shift+Enter for newlines by default textarea behavior\n if (event.key === \"Escape\") {\n setIsEditing(false);\n // Revert to original text from data on Escape\n setCurrentText(data.text || \"Double-click to edit...\");\n }\n },\n [handleBlur, data.text],\n );\n\n const handleColorChange = useCallback(\n (newColor: ColorName) => {\n if (onColorChange) {\n onColorChange(id, newColor);\n }\n },\n [id, onColorChange],\n );\n\n return (\n <div className=\"relative group\" style={FULL_SIZE_STYLE}>\n <Handle\n type=\"target\"\n position={Position.Left}\n className=\"!left-[-1px] !w-2 !h-2 !bg-gray-400 !border !border-gray-500 !rounded-full !z-10\"\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n className=\"!right-[-1px] !w-2 !h-2 !bg-gray-400 !border !border-gray-500 !rounded-full !z-10\"\n />\n {selected && !isEditing && !readOnly && (\n <div className=\"absolute -top-10 left-1/2 transform -translate-x-1/2 flex space-x-1 p-1 bg-[rgb(var(--ec-card-bg))] rounded-md shadow-lg border border-[rgb(var(--ec-page-border))] z-20\">\n {Object.keys(AVAILABLE_COLORS).map((colorKey) => (\n <button\n key={colorKey}\n onClick={() => handleColorChange(colorKey as ColorName)}\n className={classNames(\n \"w-6 h-6 rounded-full border-2\",\n AVAILABLE_COLORS[colorKey as ColorName].bg,\n AVAILABLE_COLORS[colorKey as ColorName].border,\n currentColorName === colorKey\n ? \"ring-2 ring-offset-1 \" +\n AVAILABLE_COLORS[colorKey as ColorName].selectedRing\n : \"\",\n )}\n title={colorKey.charAt(0).toUpperCase() + colorKey.slice(1)}\n />\n ))}\n </div>\n )}\n <div\n onDoubleClick={handleDoubleClick}\n className={classNames(\n \"w-full h-full rounded-lg border p-3 flex flex-col min-w-[150px] min-h-[150px] relative\",\n colorClasses.bg,\n colorClasses.border,\n colorClasses.text,\n \"prose prose-sm max-w-full\",\n selected\n ? `border-blue-600 ring-2 ${colorClasses.selectedRing} shadow-xl`\n : \"shadow-md hover:shadow-lg\",\n currentColorName === \"yellow\"\n ? \"shadow-yellow-300/50 shadow-lg transform rotate-0.5\"\n : \"\",\n )}\n style={POSITION_RELATIVE_STYLE}\n >\n {isEditing ? (\n <textarea\n ref={textAreaRef}\n value={currentText}\n onChange={handleTextChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n className={classNames(\n \"w-full flex-1 bg-transparent border-none outline-none resize-none text-[10px] p-0 m-0\",\n colorClasses.text,\n colorClasses.placeholder,\n )}\n style={TEXTAREA_STYLE}\n placeholder=\"Enter text...\"\n />\n ) : (\n <>\n <div\n ref={displayRef}\n className=\"whitespace-pre-wrap break-words w-full h-full overflow-y-auto custom-scrollbar text-[10px]\"\n dangerouslySetInnerHTML={{\n __html: formatText(currentText),\n }}\n />\n {isTextOverflowing && (\n <div\n className=\"pointer-events-none absolute left-1/2 bottom-full z-[9999] mb-4 hidden w-max max-w-[320px] -translate-x-1/2 rounded-md border bg-slate-950 px-2.5 py-1.5 text-[11px] font-medium leading-snug text-white shadow-lg group-hover:block\"\n style={{ borderColor: colorClasses.tooltipBorderColor }}\n >\n <span className=\"block whitespace-pre-wrap break-words\">\n {currentText}\n </span>\n <span\n className=\"absolute left-1/2 top-full h-2 w-2 -translate-x-1/2 -translate-y-1/2 rotate-45 border-b border-r bg-slate-950\"\n style={{\n borderBottomColor: colorClasses.tooltipBorderColor,\n borderRightColor: colorClasses.tooltipBorderColor,\n }}\n />\n </div>\n )}\n </>\n )}\n\n {/* PostIt folded corner effect */}\n {currentColorName === \"yellow\" && (\n <div className=\"absolute top-0 right-0 w-4 h-4\">\n <div className=\"absolute top-0 right-0 w-0 h-0 border-l-[16px] border-b-[16px] border-l-transparent border-b-yellow-400/30 rounded-br-lg\"></div>\n </div>\n )}\n </div>\n </div>\n );\n});\n","import { type CSSProperties, useSyncExternalStore } from \"react\";\n\n// ─── Dark mode detection ────────────────────────────────────────────────────\n\n// Every node follows the theme: one observer for all of them, from the first node shown until the last is gone\nconst themeListeners = new Set<() => void>();\nlet themeObserver: MutationObserver | undefined;\n\nfunction subscribeTheme(callback: () => void) {\n themeListeners.add(callback);\n if (!themeObserver) {\n themeObserver = new MutationObserver(() =>\n themeListeners.forEach((listener) => listener()),\n );\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-theme\"],\n });\n }\n return () => {\n themeListeners.delete(callback);\n if (themeListeners.size > 0) return;\n themeObserver?.disconnect();\n themeObserver = undefined;\n };\n}\n\nfunction getIsDark() {\n return (\n typeof document !== \"undefined\" &&\n document.documentElement.getAttribute(\"data-theme\") === \"dark\"\n );\n}\n\nexport function useDarkMode(): boolean {\n return useSyncExternalStore(subscribeTheme, getIsDark, () => false);\n}\n\n/**\n * Shared style constants for node components.\n * Extracting inline style objects to module-level constants ensures React.memo\n * receives stable references and can skip re-renders effectively.\n */\n\n// ─── Common layout ──────────────────────────────────────────────────────────\n\nexport const NODE_WIDTH_STYLE = { width: \"260px\" } as const;\n\nexport const ROTATED_LABEL_STYLE = {\n transform: \"rotate(-90deg)\",\n letterSpacing: \"0.15em\",\n whiteSpace: \"nowrap\",\n} as const satisfies CSSProperties;\n\nexport const TINY_FONT_STYLE = { fontSize: \"0.2em\" } as const;\n\n// ─── WebKit line clamp (summary truncation) ─────────────────────────────────\n\nexport const LINE_CLAMP_STYLE = {\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n} as const satisfies CSSProperties;\n\n// ─── Watermark icon ─────────────────────────────────────────────────────────\n\nexport const WATERMARK_STYLE = {\n opacity: 0.2,\n transform: \"rotate(12deg)\",\n} as const;\n\n// ─── Post-it folded corner (identical across all post-it nodes) ─────────────\n\nexport const FOLDED_CORNER_SHADOW_STYLE = {\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"0 18px 18px 0\",\n borderColor: \"transparent #1e293b12 transparent transparent\",\n} as const satisfies CSSProperties;\n\n// ─── Post-it common shadow ─────────────────────────────────────────────────\n\nexport const POST_IT_BOX_SHADOW =\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\";\n\n// ─── Handle positioning ─────────────────────────────────────────────────────\n\nexport const HANDLE_LEFT_STYLE = { left: \"-1px\" } as const;\nexport const HANDLE_RIGHT_STYLE = { right: \"-1px\" } as const;\nexport const HANDLE_LEFT_OFFSET_STYLE = { left: \"-6px\" } as const;\nexport const HANDLE_RIGHT_OFFSET_STYLE = { right: \"-6px\" } as const;\n\n// ─── Note/Full size style ───────────────────────────────────────────────────\n\nexport const FULL_SIZE_STYLE = { width: \"100%\", height: \"100%\" } as const;\n\n// ─── Owner indicator icon size ──────────────────────────────────────────────\n\nexport const OWNER_ICON_SIZE_STYLE = { width: 10, height: 10 } as const;\n\n// ─── ExternalSystem2 handle ─────────────────────────────────────────────────\n\nexport const EXTERNAL_SYSTEM_HANDLE_STYLE = {\n width: 10,\n height: 10,\n background: \"pink\",\n zIndex: 10,\n} as const;\n\n// ─── Edge styles ────────────────────────────────────────────────────────────\n\nexport const EDGE_WARNING_STYLE = {\n stroke: \"red\",\n strokeWidth: 2.625,\n strokeDasharray: \"5 5\",\n} as const;\n\nexport const EDGE_DEFAULT_STYLE = {\n stroke: \"var(--ec-edge-stroke, #d1d5db)\",\n strokeWidth: 2.625,\n strokeDasharray: \"5 5\",\n} as const;\n\nexport const EDGE_FLOW_BASE_STYLE = {\n strokeWidth: 3,\n stroke: \"var(--ec-edge-stroke, #6b7280)\",\n strokeDasharray: \"5 5\",\n} as const;\n\n// ─── Default empty values (stable references for default props) ─────────────\n\nexport const EMPTY_ARRAY: any[] = [];\nexport const EMPTY_OBJECT: Readonly<Record<string, never>> = {} as const;\n\n// ─── Channel message queue ──────────────────────────────────────────────────\n\nexport const QUEUE_BORDER_STYLE = {\n borderTop: \"1px dashed rgb(var(--ec-page-border))\",\n} as const;\n\n// ─── Handle glow ────────────────────────────────────────────────────────────\n\n// The colour (as \"r, g, b\") of the ring that pulses out from a node's handles,\n// for elements with the `ec-handle-glow` class. The ring only animates\n// transform and opacity, so it runs on the compositor.\nconst glow = (rgb: string) => ({ \"--ec-glow\": rgb }) as CSSProperties;\n\nexport const HANDLE_GLOW = {\n event: glow(\"251, 146, 60\"),\n service: glow(\"236, 72, 153\"),\n command: glow(\"59, 130, 246\"),\n query: glow(\"34, 197, 94\"),\n data: glow(\"59, 130, 246\"),\n channel: glow(\"107, 114, 128\"),\n actor: glow(\"234, 179, 8\"),\n domain: glow(\"234, 179, 8\"),\n external: glow(\"168, 85, 247\"),\n dataProduct: glow(\"99, 102, 241\"),\n view: glow(\"14, 165, 233\"),\n // Nodes without a colour of their own (fields, message groups, custom steps)\n generic: glow(\"251, 146, 60\"),\n} as const;\n","import { memo, useMemo } from \"react\";\nimport { ServerIcon, Globe } from \"lucide-react\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { EventCatalogResource, Service as ServiceType } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n WATERMARK_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nconst SPEC_LABELS: Record<string, string> = {\n openapi: \"OpenAPI\",\n asyncapi: \"AsyncAPI\",\n graphql: \"GraphQL\",\n};\n\nconst SPEC_COLORS: Record<\n string,\n { bg: string; text: string; darkBg: string; darkText: string }\n> = {\n openapi: {\n bg: \"rgba(106,170,63,0.12)\",\n text: \"#4d7c0f\",\n darkBg: \"rgba(106,170,63,0.2)\",\n darkText: \"#a3e635\",\n },\n asyncapi: {\n bg: \"rgba(116,78,194,0.12)\",\n text: \"#6d28d9\",\n darkBg: \"rgba(116,78,194,0.2)\",\n darkText: \"#c4b5fd\",\n },\n graphql: {\n bg: \"rgba(229,53,171,0.12)\",\n text: \"#be185d\",\n darkBg: \"rgba(229,53,171,0.2)\",\n darkText: \"#f9a8d4\",\n },\n};\n\n/** Normalize both array and legacy object spec formats into unique type strings */\nfunction normalizeSpecTypes(specs: unknown): string[] {\n const types = new Set<string>();\n if (Array.isArray(specs)) {\n for (const spec of specs) {\n if (spec?.type) types.add(String(spec.type).toLowerCase());\n }\n } else if (specs && typeof specs === \"object\") {\n const legacy = specs as Record<string, unknown>;\n if (legacy.asyncapiPath) types.add(\"asyncapi\");\n if (legacy.openapiPath) types.add(\"openapi\");\n if (legacy.graphqlPath) types.add(\"graphql\");\n }\n return Array.from(types);\n}\n\nconst SpecBadges = memo(function SpecBadges({\n specifications,\n isDark,\n}: {\n specifications: unknown;\n isDark: boolean;\n}) {\n const specTypes = useMemo(\n () => normalizeSpecTypes(specifications),\n [specifications],\n );\n\n if (specTypes.length === 0) return null;\n\n return (\n <div className=\"flex items-center gap-1 flex-wrap justify-end\">\n {specTypes.map((type) => {\n const colors = SPEC_COLORS[type] || SPEC_COLORS.openapi;\n return (\n <span\n key={type}\n className=\"inline-flex items-center text-[7px] font-bold px-1.5 py-0.5 rounded\"\n style={{\n background: isDark ? colors.darkBg : colors.bg,\n color: isDark ? colors.darkText : colors.text,\n }}\n >\n {SPEC_LABELS[type] || type}\n </span>\n );\n })}\n </div>\n );\n});\n\nconst MiniEnvelope = memo(function MiniEnvelope({\n side,\n delay,\n}: {\n side: \"left\" | \"right\";\n delay: number;\n}) {\n return (\n <svg\n width=\"14\"\n height=\"10\"\n viewBox=\"0 0 14 10\"\n style={{\n animation: `${side === \"left\" ? \"ec-svc-msg-in\" : \"ec-svc-msg-out\"} 2.5s ease-in-out ${delay}s infinite`,\n opacity: 0,\n }}\n >\n <rect\n x=\"0.5\"\n y=\"0.5\"\n width=\"13\"\n height=\"9\"\n rx=\"1.5\"\n fill=\"#9ca3af\"\n opacity={0.85}\n />\n <path\n d=\"M0.5,0.5 L7,5 L13.5,0.5\"\n fill=\"none\"\n stroke=\"white\"\n strokeWidth=\"1\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n});\n\nconst ServiceMessageFlow = memo(function ServiceMessageFlow({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -4,\n transform: \"translateY(-50%)\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n zIndex: 15,\n pointerEvents: \"none\",\n }}\n >\n <MiniEnvelope side={side} delay={0} />\n <MiniEnvelope side={side} delay={0.8} />\n <MiniEnvelope side={side} delay={1.6} />\n </div>\n );\n});\n\nconst GlowHandle = memo(function GlowHandle({\n side,\n external,\n}: {\n side: \"left\" | \"right\";\n external?: boolean;\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: external\n ? \"linear-gradient(135deg, #a855f7, #7e22ce)\"\n : \"linear-gradient(135deg, #ec4899, #be185d)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...(external ? HANDLE_GLOW.external : HANDLE_GLOW.service),\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype PostItPalette = {\n Icon: typeof ServerIcon;\n label: string;\n gradient: string;\n draftBorder: string;\n corner: string;\n ring: string;\n iconClass: string;\n labelClass: string;\n nameText: string;\n nameTextDeprecated: string;\n versionClass: string;\n summaryClass: string;\n tooltipBorderColor: string;\n};\n\nconst POST_IT_SERVICE: PostItPalette = {\n Icon: ServerIcon,\n label: \"Service\",\n gradient: \"linear-gradient(135deg, #fbcfe8 0%, #f9a8d4 40%, #ec4899 100%)\",\n draftBorder: \"rgba(236, 72, 153, 0.5)\",\n corner: \"#db2777\",\n ring: \"ring-2 ring-pink-400/60 ring-offset-1\",\n iconClass: \"w-3 h-3 text-pink-900/50\",\n labelClass: \"text-[8px] font-bold text-pink-900/50 uppercase tracking-widest\",\n nameText: \"text-pink-950\",\n nameTextDeprecated: \"text-pink-950/40 line-through\",\n versionClass: \"text-[9px] text-pink-900/40 font-semibold mt-0.5\",\n summaryClass:\n \"mt-2 pt-1.5 border-t border-pink-900/10 text-[9px] text-pink-950/60 leading-relaxed overflow-hidden\",\n tooltipBorderColor: \"#ec4899\",\n};\n\nconst POST_IT_EXTERNAL: PostItPalette = {\n Icon: Globe,\n label: \"External System\",\n gradient: \"linear-gradient(135deg, #e9d5ff 0%, #c084fc 40%, #a855f7 100%)\",\n draftBorder: \"rgba(168, 85, 247, 0.5)\",\n corner: \"#7e22ce\",\n ring: \"ring-2 ring-purple-400/60 ring-offset-1\",\n iconClass: \"w-3 h-3 text-purple-900/50\",\n labelClass:\n \"text-[8px] font-bold text-purple-900/50 uppercase tracking-widest\",\n nameText: \"text-purple-950\",\n nameTextDeprecated: \"text-purple-950/40 line-through\",\n versionClass: \"text-[9px] text-purple-900/40 font-semibold mt-0.5\",\n summaryClass:\n \"mt-2 pt-1.5 border-t border-purple-900/10 text-[9px] text-purple-950/60 leading-relaxed overflow-hidden\",\n tooltipBorderColor: \"#a855f7\",\n};\n\ntype DefaultPalette = {\n Icon: typeof ServerIcon;\n label: string;\n ring: string;\n borderSolid: string;\n borderDraftDark: string;\n borderDraftLight: string;\n draftStripeDark: string;\n draftStripeLight: string;\n nodeBgVar: string;\n shadowColor: string;\n badgeBg: string;\n ownerAccent: string;\n ownerBorder: string;\n ownerIcon: string;\n tooltipBorderColor: string;\n};\n\nconst DEFAULT_SERVICE: DefaultPalette = {\n Icon: ServerIcon,\n label: \"Service\",\n ring: \"ring-2 ring-pink-400/60 ring-offset-2\",\n borderSolid: \"border-pink-500\",\n borderDraftDark: \"border-dashed border-pink-400\",\n borderDraftLight: \"border-dashed border-pink-400/60\",\n draftStripeDark: \"rgba(236,72,153,0.25)\",\n draftStripeLight: \"rgba(236,72,153,0.15)\",\n nodeBgVar: \"var(--ec-service-node-bg, rgb(var(--ec-card-bg)))\",\n shadowColor: \"rgba(236, 72, 153, 0.15)\",\n badgeBg: \"bg-pink-500\",\n ownerAccent: \"bg-pink-400\",\n ownerBorder: \"rgba(236,72,153,0.08)\",\n ownerIcon: \"text-pink-300\",\n tooltipBorderColor: \"#ec4899\",\n};\n\nconst DEFAULT_EXTERNAL: DefaultPalette = {\n Icon: Globe,\n label: \"External System\",\n ring: \"ring-2 ring-purple-400/60 ring-offset-2\",\n borderSolid: \"border-purple-500\",\n borderDraftDark: \"border-dashed border-purple-400\",\n borderDraftLight: \"border-dashed border-purple-400/60\",\n draftStripeDark: \"rgba(168,85,247,0.25)\",\n draftStripeLight: \"rgba(168,85,247,0.15)\",\n nodeBgVar: \"var(--ec-external-node-bg, rgb(var(--ec-card-bg)))\",\n shadowColor: \"rgba(168, 85, 247, 0.15)\",\n badgeBg: \"bg-purple-500\",\n ownerAccent: \"bg-purple-400\",\n ownerBorder: \"rgba(168,85,247,0.08)\",\n ownerIcon: \"text-purple-300\",\n tooltipBorderColor: \"#a855f7\",\n};\n\ntype ServiceNodeData = EventCatalogResource & {\n service: ServiceType;\n};\n\nexport type ServiceNode = Node<ServiceNodeData, \"service\">;\n\nfunction PostItService(props: ServiceNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n notes,\n specifications,\n externalSystem,\n styles,\n } = props.data.service;\n const mode = props.data.mode || \"simple\";\n const isDark = useDarkMode();\n const p = externalSystem ? POST_IT_EXTERNAL : POST_IT_SERVICE;\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? p.ring : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {/* Inner wrapper with rotation */}\n <div\n className=\"absolute inset-0\"\n style={{\n background: p.gradient,\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? `2px dashed ${p.draftBorder}`\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: `${p.corner} transparent transparent transparent`,\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <p.Icon className={p.iconClass} strokeWidth={2.5} />\n <span className={p.labelClass}>{p.label}</span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-[26px] h-[26px] shrink-0\"\n : \"w-6 h-6 shrink-0\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor={p.tooltipBorderColor}\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated ? p.nameTextDeprecated : p.nameText,\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {version && <div className={p.versionClass}>v{version}</div>}\n\n {mode === \"full\" && summary && (\n <div\n className={p.summaryClass}\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {!!specifications && (\n <div className=\"mt-1.5 flex justify-end\">\n <SpecBadges specifications={specifications} isDark={isDark} />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultService(props: ServiceNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n notes,\n specifications,\n externalSystem,\n styles,\n } = props.data.service;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const owners = useMemo(\n () => normalizeOwners(props.data.service.owners),\n [props.data.service.owners],\n );\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n const p = externalSystem ? DEFAULT_EXTERNAL : DEFAULT_SERVICE;\n const draftStripe = isDark ? p.draftStripeDark : p.draftStripeLight;\n const borderDraft = isDark ? p.borderDraftDark : p.borderDraftLight;\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? p.ring : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? borderDraft\n : p.borderSolid,\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), ${p.nodeBgVar}`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${draftStripe} 4px, ${draftStripe} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${draftStripe} 4px, ${draftStripe} 4.5px), ${p.nodeBgVar}`\n : p.nodeBgVar,\n boxShadow: `0 2px 12px ${p.shadowColor}`,\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" external={externalSystem} />}\n {connected.source && (\n <GlowHandle side=\"right\" external={externalSystem} />\n )}\n\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : p.badgeBg,\n )}\n >\n <p.Icon className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n {p.label}\n {draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-[26px] h-[26px] shrink-0\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor={p.tooltipBorderColor}\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n <div className=\"flex items-end justify-between gap-1\">\n <OwnerIndicator\n owners={owners}\n accentColor={p.ownerAccent}\n borderColor={p.ownerBorder}\n iconClass={p.ownerIcon}\n />\n {!!specifications && (\n <SpecBadges specifications={specifications} isDark={isDark} />\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default memo(function Service(props: ServiceNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItService {...props} />;\n }\n\n return <DefaultService {...props} />;\n});\n","import { memo } from \"react\";\nimport { buildUrl } from \"./url-builder\";\n\nexport function isIconPath(value: string | undefined): value is string {\n if (!value) return false;\n return (\n value.startsWith(\"/\") ||\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\")\n );\n}\n\nexport function resolveIconUrl(value: string): string {\n if (value.startsWith(\"http://\") || value.startsWith(\"https://\")) return value;\n return buildUrl(value).replace(/\\/$/, \"\");\n}\n\nexport const CustomIcon = memo(function CustomIcon({\n src,\n alt,\n className,\n}: {\n src: string;\n alt: string;\n className?: string;\n}) {\n return (\n <img\n src={resolveIconUrl(src)}\n alt={alt}\n loading=\"lazy\"\n className={className}\n style={{ objectFit: \"contain\", borderRadius: 4 }}\n />\n );\n});\n","/**\n * Configurable URL builder utility\n * Consumers (e.g. Astro adapter) can provide a custom builder via setBuildUrlFn\n * to handle base paths, trailing slashes, etc.\n */\n\nlet _customBuildUrl: ((path: string) => string) | null = null;\n\nexport function setBuildUrlFn(fn: ((path: string) => string) | null): void {\n _customBuildUrl = fn;\n}\n\nexport function buildUrl(path: string): string {\n if (_customBuildUrl) {\n return _customBuildUrl(path);\n }\n return path;\n}\n\n/**\n * Navigate to a URL, preferring the host app's view-transition router when it's\n * available so navigations are soft/animated rather than a hard page reload.\n *\n * The visualiser package is intentionally decoupled from Astro, so the host\n * (e.g. EventCatalog's VisualiserLayout) bridges its router onto\n * `window.__ecNavigate`. When that bridge isn't present (standalone usage), we\n * fall back to a normal `location.href` assignment.\n *\n * `url` should already be passed through `buildUrl`.\n */\nexport function navigateTo(url: string): void {\n if (typeof window === \"undefined\") return;\n const ecNavigate = (\n window as unknown as { __ecNavigate?: (url: string) => void }\n ).__ecNavigate;\n if (typeof ecNavigate === \"function\") {\n ecNavigate(url);\n return;\n }\n window.location.href = url;\n}\n","import { memo } from \"react\";\nimport { UserIcon, UsersIcon } from \"lucide-react\";\nimport { OWNER_ICON_SIZE_STYLE } from \"./shared-styles\";\n\n/** Shared style for hidden React Flow handles (avoids inline object allocation). */\nexport const HIDDEN_HANDLE_STYLE = { opacity: 0 } as const;\n\n/**\n * Normalise owners which may arrive as string[] or {id:string}[] from Astro.\n */\nexport function normalizeOwners(raw: any[] | undefined): string[] {\n if (!raw || raw.length === 0) return [];\n return raw\n .filter(Boolean)\n .map((o: any) => (typeof o === \"string\" ? o : (o?.id ?? \"\")));\n}\n\n/**\n * Compact owner indicator for the bottom of a node card.\n * Shows a small icon + primary owner name + overflow pill.\n *\n * @param accentColor - Tailwind color class for the pill, e.g. \"bg-pink-400\"\n * @param borderColor - CSS color string for the top border\n * @param iconClass - Tailwind text color for the icon, e.g. \"text-pink-300\"\n */\nexport const OwnerIndicator = memo(function OwnerIndicator({\n owners,\n accentColor = \"bg-pink-400\",\n borderColor = \"rgba(236,72,153,0.08)\",\n iconClass = \"text-pink-300\",\n}: {\n owners: string[];\n accentColor?: string;\n borderColor?: string;\n iconClass?: string;\n}) {\n if (owners.length === 0) return null;\n\n const primary = owners[0];\n const remaining = owners.length - 1;\n const isLikelyTeam = primary.includes(\" \") || primary.includes(\"-\");\n\n return (\n <div\n className=\"flex items-center gap-1 mt-1.5 pt-1.5\"\n style={{ borderTop: `1px solid ${borderColor}` }}\n title={owners.join(\", \")}\n >\n {/* Icon */}\n {isLikelyTeam ? (\n <UsersIcon\n className={`${iconClass} shrink-0`}\n style={OWNER_ICON_SIZE_STYLE}\n strokeWidth={2.5}\n />\n ) : (\n <UserIcon\n className={`${iconClass} shrink-0`}\n style={OWNER_ICON_SIZE_STYLE}\n strokeWidth={2.5}\n />\n )}\n\n {/* Primary owner name */}\n <span className=\"text-[8px] text-[rgb(var(--ec-page-text-muted))] truncate leading-none\">\n {primary}\n </span>\n\n {/* Overflow count */}\n {remaining > 0 && (\n <span\n className={`shrink-0 inline-flex items-center justify-center text-[7px] font-bold text-white ${accentColor} rounded-full px-1 py-[1px] leading-none`}\n title={owners.slice(1).join(\", \")}\n >\n +{remaining}\n </span>\n )}\n </div>\n );\n});\n","import { useCallback, useMemo } from \"react\";\nimport { useNodeId, useStore, type ReactFlowState } from \"@xyflow/react\";\n\n/**\n * Whether the node this is in has connections coming in (target) and going out (source), e.g. to show its glowing\n * handles. One store subscription returning a number, rather than two `useNodeConnections`: every subscription's\n * selector runs on every store update (every frame of a drag, pan or remote move), and `useNodeConnections` also\n * compares connection maps key by key each time. With two per node, they were among the top costs of a drag.\n */\nexport function useNodeHasConnections() {\n const id = useNodeId();\n const keys = useMemo(() => [`${id}-target`, `${id}-source`] as const, [id]);\n const selector = useCallback(\n (state: ReactFlowState) =>\n (state.connectionLookup.get(keys[0])?.size ? 1 : 0) |\n (state.connectionLookup.get(keys[1])?.size ? 2 : 0),\n [keys],\n );\n const connected = useStore(selector);\n return { target: (connected & 1) > 0, source: (connected & 2) > 0 };\n}\n","import { MessageCircle, AlertTriangle, XIcon } from \"lucide-react\";\nimport { useState, useCallback, memo } from \"react\";\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport type { Note } from \"../types\";\nimport { useDarkMode } from \"./shared-styles\";\n\n/* ------------------------------------------------------------------ */\n/* Constants */\n/* ------------------------------------------------------------------ */\n\nconst AMBER = {\n 50: \"#fffbeb\",\n 100: \"#fef3c7\",\n 200: \"#fde68a\",\n 400: \"#fbbf24\",\n 500: \"#f59e0b\",\n 600: \"#d97706\",\n 700: \"#b45309\",\n 800: \"#92400e\",\n 900: \"#78350f\",\n} as const;\n\nconst PRIORITY: Record<\n string,\n { bg: string; fg: string; border: string; label: string; accent: string }\n> = {\n high: {\n bg: \"#fef2f2\",\n fg: \"#b91c1c\",\n border: \"#fecaca\",\n label: \"High\",\n accent: \"#ef4444\",\n },\n critical: {\n bg: \"#fef2f2\",\n fg: \"#991b1b\",\n border: \"#fecaca\",\n label: \"Critical\",\n accent: \"#dc2626\",\n },\n low: {\n bg: \"#f0fdf4\",\n fg: \"#15803d\",\n border: \"#bbf7d0\",\n label: \"Low\",\n accent: \"#22c55e\",\n },\n};\n\n/* ------------------------------------------------------------------ */\n/* Deterministic avatar color from name */\n/* ------------------------------------------------------------------ */\n\nconst AVATAR_PALETTES = [\n [\"#7c3aed\", \"#a78bfa\"], // violet\n [\"#2563eb\", \"#60a5fa\"], // blue\n [\"#0891b2\", \"#22d3ee\"], // cyan\n [\"#059669\", \"#34d399\"], // emerald\n [\"#d97706\", \"#fbbf24\"], // amber\n [\"#dc2626\", \"#f87171\"], // red\n [\"#db2777\", \"#f472b6\"], // pink\n [\"#4f46e5\", \"#818cf8\"], // indigo\n];\n\nfunction hashStr(s: string): number {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = (h * 31 + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\n/* ------------------------------------------------------------------ */\n/* Shared atoms */\n/* ------------------------------------------------------------------ */\n\nfunction Avatar({ name, size = 18 }: { name: string; size?: number }) {\n const initials = name\n .split(/\\s+/)\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n\n const [c1, c2] = AVATAR_PALETTES[hashStr(name) % AVATAR_PALETTES.length];\n\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: `linear-gradient(135deg, ${c1}, ${c2})`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <span\n style={{\n fontSize: Math.round(size * 0.42),\n fontWeight: 700,\n color: \"white\",\n lineHeight: 1,\n letterSpacing: \"-0.02em\",\n }}\n >\n {initials}\n </span>\n </div>\n );\n}\n\nfunction PriorityPill({\n priority,\n size = \"sm\",\n}: {\n priority: string;\n size?: \"sm\" | \"md\";\n}) {\n const p = PRIORITY[priority.toLowerCase()];\n if (!p) return null;\n const isUrgent = priority === \"high\" || priority === \"critical\";\n const md = size === \"md\";\n\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: md ? 4 : 2,\n fontSize: md ? 11 : 8,\n fontWeight: 700,\n color: p.fg,\n background: p.bg,\n border: `1px solid ${p.border}`,\n borderRadius: 99,\n padding: md ? \"2px 8px\" : \"1px 5px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n lineHeight: 1.4,\n whiteSpace: \"nowrap\",\n }}\n >\n {isUrgent && (\n <AlertTriangle\n style={{ width: md ? 10 : 7, height: md ? 10 : 7 }}\n strokeWidth={2.5}\n />\n )}\n {p.label}\n </span>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Popover (hover preview) */\n/* ------------------------------------------------------------------ */\n\nfunction PopoverCard({ note, last }: { note: Note; last: boolean }) {\n return (\n <div\n style={{\n padding: \"7px 10px\",\n borderBottom: last ? \"none\" : \"1px solid rgb(var(--ec-page-border))\",\n display: \"flex\",\n gap: 6,\n alignItems: \"flex-start\",\n }}\n >\n {note.author && <Avatar name={note.author} size={16} />}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n marginBottom: 2,\n }}\n >\n {note.author && (\n <span\n style={{\n fontSize: 9,\n fontWeight: 700,\n color: \"rgb(var(--ec-page-text))\",\n lineHeight: 1,\n }}\n >\n {note.author}\n </span>\n )}\n {note.priority && <PriorityPill priority={note.priority} />}\n </div>\n <p\n style={{\n fontSize: 9,\n lineHeight: 1.45,\n color: \"rgb(var(--ec-page-text-muted))\",\n margin: 0,\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {note.content}\n </p>\n </div>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Modal note card (thread-style) */\n/* ------------------------------------------------------------------ */\n\nfunction NoteCard({ note, isDark }: { note: Note; isDark: boolean }) {\n const prioStyle = note.priority\n ? PRIORITY[note.priority.toLowerCase()]\n : null;\n\n return (\n <div\n style={{\n background: isDark\n ? `radial-gradient(circle, rgba(255,255,255,0.15) 1px, transparent 1px), rgba(255,255,255,0.04)`\n : `radial-gradient(circle, rgba(212,201,168,0.4) 1px, transparent 1px), #fef9ed`,\n backgroundSize: \"12px 12px\",\n border: `1px solid ${isDark ? \"rgba(255,255,255,0.08)\" : \"#e5dcc3\"}`,\n borderBottom: `2px dashed ${isDark ? \"rgba(255,255,255,0.1)\" : \"#d4c9a8\"}`,\n borderRadius: \"8px 8px 0 0\",\n padding: \"14px 16px 14px\",\n position: \"relative\",\n }}\n >\n {/* Author */}\n {note.author && (\n <span\n style={{\n display: \"block\",\n fontSize: 11,\n fontWeight: 650,\n color: isDark ? \"#e2e8f0\" : \"#1e293b\",\n marginBottom: 8,\n }}\n >\n {note.author}\n </span>\n )}\n\n {/* Content — styled like a handwritten note */}\n <p\n style={{\n fontSize: 13,\n lineHeight: 1.7,\n color: isDark ? \"#cbd5e1\" : \"#1e293b\",\n margin: 0,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n fontStyle: \"italic\",\n }}\n >\n &ldquo;{note.content}&rdquo;\n </p>\n </div>\n );\n}\n\n/** Group notes by priority: critical/high first, then low, then no priority */\nfunction groupNotes(\n notes: Note[],\n): { label: string; notes: Note[]; color: string }[] {\n const urgent: Note[] = [];\n const low: Note[] = [];\n const normal: Note[] = [];\n\n for (const n of notes) {\n const p = n.priority?.toLowerCase();\n if (p === \"critical\" || p === \"high\") urgent.push(n);\n else if (p === \"low\") low.push(n);\n else normal.push(n);\n }\n\n const groups: { label: string; notes: Note[]; color: string }[] = [];\n if (urgent.length > 0)\n groups.push({ label: \"High Priority\", notes: urgent, color: \"#ef4444\" });\n if (normal.length > 0)\n groups.push({ label: \"Notes\", notes: normal, color: \"#f59e0b\" });\n if (low.length > 0)\n groups.push({ label: \"Low Priority\", notes: low, color: \"#22c55e\" });\n return groups;\n}\n\n/* ------------------------------------------------------------------ */\n/* Full-screen modal */\n/* ------------------------------------------------------------------ */\n\nexport function NotesModal({\n notes,\n isOpen,\n onClose,\n resourceName,\n resourceVersion,\n resourceType,\n accentColor,\n icon,\n}: {\n notes: Note[];\n isOpen: boolean;\n onClose: () => void;\n resourceName?: string;\n resourceVersion?: string;\n resourceType?: string;\n accentColor?: string;\n icon?: React.ReactNode;\n}) {\n const isDark = useDarkMode();\n const portalContainer = usePortalContainer();\n const count = notes.length;\n const urgent = notes.filter(\n (n) =>\n n.priority &&\n (n.priority.toLowerCase() === \"high\" ||\n n.priority.toLowerCase() === \"critical\"),\n );\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <Dialog.Portal container={portalContainer}>\n <div\n className=\"fixed inset-0 z-[99999]\"\n style={{ isolation: \"isolate\" }}\n >\n <Dialog.Overlay\n style={{\n position: \"fixed\",\n inset: 0,\n background: isDark\n ? \"rgba(0, 0, 0, 0.7)\"\n : \"rgba(15, 23, 42, 0.55)\",\n backdropFilter: \"blur(8px)\",\n }}\n />\n\n <Dialog.Content\n style={{\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"92vw\",\n maxWidth: 500,\n maxHeight: \"80vh\",\n background: isDark ? \"#1e2330\" : \"#ffffff\",\n borderRadius: 16,\n border: `1px solid ${isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.08)\"}`,\n boxShadow: isDark\n ? \"0 24px 48px rgba(0,0,0,0.5)\"\n : \"0 24px 48px rgba(0,0,0,0.15)\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n outline: \"none\",\n }}\n >\n {/* -------- Header -------- */}\n <div\n style={{\n padding: \"20px 22px 16px\",\n borderBottom: `1px solid ${isDark ? \"rgba(255,255,255,0.06)\" : \"rgba(0,0,0,0.06)\"}`,\n display: \"flex\",\n alignItems: \"center\",\n gap: 14,\n }}\n >\n {/* Resource icon */}\n <div\n style={{\n width: 36,\n height: 36,\n borderRadius: 10,\n background:\n accentColor ||\n `linear-gradient(135deg, ${AMBER[400]}, ${AMBER[500]})`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n {icon || (\n <MessageCircle\n style={{ width: 18, height: 18, color: \"white\" }}\n strokeWidth={2.5}\n />\n )}\n </div>\n\n {/* Title block */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <Dialog.Title\n style={{\n fontSize: 15,\n fontWeight: 700,\n color: isDark ? \"#f1f5f9\" : \"#0f172a\",\n margin: 0,\n lineHeight: 1.3,\n letterSpacing: \"-0.01em\",\n display: \"flex\",\n alignItems: \"baseline\",\n gap: 6,\n }}\n >\n {resourceName || \"Notes\"}\n {resourceVersion && (\n <span\n style={{\n fontSize: 11,\n fontWeight: 500,\n color: isDark ? \"#64748b\" : \"#94a3b8\",\n }}\n >\n v{resourceVersion}\n </span>\n )}\n </Dialog.Title>\n <Dialog.Description\n style={{\n fontSize: 12,\n color: isDark ? \"#94a3b8\" : \"#64748b\",\n margin: 0,\n marginTop: 3,\n lineHeight: 1.3,\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}\n >\n {resourceType && (\n <span\n style={{\n fontSize: 10,\n fontWeight: 700,\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n }}\n >\n {resourceType}\n </span>\n )}\n {resourceType && (\n <span style={{ opacity: 0.4 }}>&middot;</span>\n )}\n {count} note{count !== 1 ? \"s\" : \"\"}\n {urgent.length > 0 &&\n ` \\u00b7 ${urgent.length} high priority`}\n </Dialog.Description>\n </div>\n\n {/* Close */}\n <Dialog.Close asChild>\n <button\n aria-label=\"Close\"\n style={{\n width: 32,\n height: 32,\n borderRadius: 8,\n border: \"none\",\n background: isDark\n ? \"rgba(255,255,255,0.06)\"\n : \"rgba(0,0,0,0.04)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: isDark ? \"#94a3b8\" : \"#94a3b8\",\n flexShrink: 0,\n }}\n >\n <XIcon style={{ width: 16, height: 16 }} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* -------- Grouped notes -------- */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px 22px 24px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 18,\n }}\n >\n {groupNotes(notes).map((group) => (\n <div key={group.label}>\n {/* Group header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 10,\n }}\n >\n <div\n style={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: group.color,\n flexShrink: 0,\n }}\n />\n <span\n style={{\n fontSize: 11,\n fontWeight: 700,\n color: isDark ? \"#94a3b8\" : \"#64748b\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n }}\n >\n {group.label}\n </span>\n <span\n style={{\n fontSize: 10,\n fontWeight: 600,\n color: isDark ? \"#475569\" : \"#94a3b8\",\n }}\n >\n ({group.notes.length})\n </span>\n <div\n style={{\n flex: 1,\n height: 1,\n background: isDark\n ? \"rgba(255,255,255,0.06)\"\n : \"rgba(0,0,0,0.06)\",\n }}\n />\n </div>\n {/* Notes in group */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n {group.notes.map((note, i) => (\n <NoteCard key={i} note={note} isDark={isDark} />\n ))}\n </div>\n </div>\n ))}\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Main indicator */\n/* ------------------------------------------------------------------ */\n\nexport const NotesIndicator = memo(function NotesIndicator({\n notes,\n resourceName,\n}: {\n notes: Note[];\n resourceName?: string;\n}) {\n const [isHovered, setIsHovered] = useState(false);\n const [isModalOpen, setIsModalOpen] = useState(false);\n\n const handleClick = useCallback((e: React.MouseEvent) => {\n e.stopPropagation();\n setIsHovered(false);\n setIsModalOpen(true);\n }, []);\n\n if (!notes || notes.length === 0) return null;\n\n const count = notes.length;\n const hasUrgent = notes.some(\n (n) =>\n n.priority &&\n (n.priority.toLowerCase() === \"high\" ||\n n.priority.toLowerCase() === \"critical\"),\n );\n\n return (\n <>\n <div\n className=\"absolute -top-2.5 -right-2.5 z-30 nopan nodrag\"\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {/* Count badge */}\n <div\n className=\"flex items-center justify-center cursor-pointer\"\n onClick={handleClick}\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n background: hasUrgent\n ? \"linear-gradient(135deg, #ef4444, #dc2626)\"\n : `linear-gradient(135deg, ${AMBER[400]}, ${AMBER[500]})`,\n boxShadow: `0 0 0 2.5px rgb(var(--ec-card-bg)), 0 2px 6px rgba(0,0,0,0.15)`,\n transition: \"transform 0.15s ease\",\n transform: isHovered ? \"scale(1.15)\" : \"scale(1)\",\n }}\n >\n <span\n style={{\n fontSize: 11,\n fontWeight: 800,\n color: \"white\",\n lineHeight: 1,\n }}\n >\n {count}\n </span>\n </div>\n\n {/* Hover popover */}\n {isHovered && !isModalOpen && (\n <div\n className=\"absolute top-full right-0 mt-2 pointer-events-none\"\n style={{ minWidth: 200, maxWidth: 250, zIndex: 50 }}\n >\n <div\n style={{\n background: \"rgb(var(--ec-card-bg))\",\n borderRadius: 10,\n border: `1px solid ${AMBER[200]}`,\n boxShadow:\n \"0 4px 20px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\",\n overflow: \"hidden\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"6px 10px\",\n background: AMBER[50],\n borderBottom: `1px solid ${AMBER[200]}`,\n display: \"flex\",\n alignItems: \"center\",\n gap: 5,\n }}\n >\n <MessageCircle\n style={{ width: 10, height: 10, color: AMBER[600] }}\n strokeWidth={2.5}\n />\n <span\n style={{\n fontSize: 9,\n fontWeight: 700,\n color: AMBER[800],\n flex: 1,\n letterSpacing: \"0.01em\",\n }}\n >\n {count} note{count !== 1 ? \"s\" : \"\"}\n </span>\n <span\n style={{\n fontSize: 8,\n color: AMBER[600],\n fontWeight: 500,\n opacity: 0.8,\n }}\n >\n click to open\n </span>\n </div>\n\n {/* List */}\n <div style={{ maxHeight: 150, overflowY: \"auto\" }}>\n {notes.slice(0, 3).map((note, i) => (\n <PopoverCard\n key={i}\n note={note}\n last={i === Math.min(count, 3) - 1 && count <= 3}\n />\n ))}\n </div>\n\n {count > 3 && (\n <div\n style={{\n padding: \"5px 10px\",\n borderTop: \"1px solid rgb(var(--ec-page-border))\",\n textAlign: \"center\",\n }}\n >\n <span\n style={{\n fontSize: 8,\n fontWeight: 600,\n color: \"#94a3b8\",\n }}\n >\n +{count - 3} more\n </span>\n </div>\n )}\n </div>\n\n {/* Arrow pointing up */}\n <div\n style={{\n position: \"absolute\",\n top: -5,\n right: 10,\n width: 10,\n height: 10,\n background: \"rgb(var(--ec-card-bg))\",\n border: `1px solid ${AMBER[200]}`,\n borderRight: \"none\",\n borderBottom: \"none\",\n transform: \"rotate(45deg)\",\n zIndex: 1,\n }}\n />\n </div>\n )}\n </div>\n\n <NotesModal\n notes={notes}\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n resourceName={resourceName}\n />\n </>\n );\n});\n","import { createContext, useContext } from \"react\";\n\n/**\n * Context that provides a reference to the .eventcatalog-visualizer container element.\n * Used by Radix UI portals so they render inside the scoped CSS boundary\n * instead of at document.body.\n */\nconst PortalContainerContext = createContext<HTMLElement | null>(null);\n\nexport const PortalContainerProvider = PortalContainerContext.Provider;\n\nexport function usePortalContainer(): HTMLElement | undefined {\n const container = useContext(PortalContainerContext);\n return container ?? undefined;\n}\n","import {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\n\ntype TruncatedResourceNameProps = {\n as?: \"div\" | \"span\";\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n tooltipBorderColor?: string;\n value: string;\n};\n\nexport function TruncatedResourceName({\n as: Component = \"span\",\n children,\n className,\n style,\n tooltipBorderColor = \"rgb(var(--ec-page-border))\",\n value,\n}: TruncatedResourceNameProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useEffect(() => {\n const element = ref.current;\n if (!element) return;\n\n const updateTruncation = () => {\n setIsTruncated(element.scrollWidth > element.clientWidth);\n };\n\n // Measured once layout has happened, not while mounting: reading the layout\n // here forces a reflow for every node that mounts (e.g. when switching levels)\n if (typeof ResizeObserver === \"undefined\") {\n const frame = requestAnimationFrame(updateTruncation);\n window.addEventListener(\"resize\", updateTruncation);\n return () => {\n cancelAnimationFrame(frame);\n window.removeEventListener(\"resize\", updateTruncation);\n };\n }\n\n // Also reports the element's first size, after layout\n const observer = new ResizeObserver(updateTruncation);\n observer.observe(element);\n return () => observer.disconnect();\n }, [value]);\n\n return (\n <Component className=\"ec-truncated-resource-name group relative min-w-0 max-w-full flex-1\">\n <span\n ref={ref}\n className={`block min-w-0 ${className || \"\"}`}\n style={style}\n >\n {children}\n </span>\n {isTruncated && (\n <span\n className=\"ec-truncated-resource-name-tooltip pointer-events-none absolute left-1/2 bottom-full z-[9999] mb-4 hidden w-max max-w-[320px] -translate-x-1/2 rounded-md border-2 bg-slate-950 px-2.5 py-1.5 text-[11px] font-medium leading-snug text-white shadow-lg group-hover:block group-focus-within:block\"\n style={{ borderColor: tooltipBorderColor }}\n >\n <span className=\"block whitespace-normal break-words\">{value}</span>\n <span\n className=\"absolute left-1/2 top-full h-2 w-2 -translate-x-1/2 -translate-y-1/2 rotate-45 border-b border-r bg-slate-950\"\n style={{\n borderBottomColor: tooltipBorderColor,\n borderRightColor: tooltipBorderColor,\n }}\n />\n </span>\n )}\n </Component>\n );\n}\n","import { LocateFixed } from \"lucide-react\";\n\nexport function FocusedResourceIndicator() {\n return (\n <>\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute -inset-1.5 z-[5] rounded-[14px] border-2 border-indigo-500/70 shadow-lg\"\n />\n <div className=\"pointer-events-none absolute -bottom-2.5 right-2 z-30 inline-flex items-center gap-1 rounded-full border border-white/80 bg-indigo-600 px-2 py-0.5 text-[7px] font-bold uppercase tracking-widest text-white shadow-sm\">\n <LocateFixed className=\"h-2.5 w-2.5\" strokeWidth={2.5} />\n Viewing\n </div>\n </>\n );\n}\n","import { memo, useMemo } from \"react\";\nimport { Bot } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../utils/node-connections\";\nimport { EventCatalogResource } from \"../types\";\nimport { NotesIndicator } from \"./NotesIndicator\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"./OwnerIndicator\";\nimport { LINE_CLAMP_STYLE, useDarkMode, HANDLE_GLOW } from \"./shared-styles\";\nimport { CustomIcon, isIconPath, resolveIconUrl } from \"../utils/custom-icon\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #0ea5e9, #0369a1)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.dataProduct,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nconst getProviderIconSrc = (provider: string | undefined, isDark: boolean) => {\n if (!provider) return null;\n const providerIconName = provider\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"\");\n\n const iconPath =\n providerIconName === \"openai\" || providerIconName === \"anthropic\"\n ? `/icons/agent/${providerIconName}-${isDark ? \"dark\" : \"light\"}.svg`\n : `/icons/agent/${providerIconName}.svg`;\n\n return resolveIconUrl(iconPath);\n};\n\ntype AgentNodeData = EventCatalogResource & {\n agent: {\n id: string;\n version: string;\n name: string;\n summary?: string;\n owners?: any[];\n deprecated?: boolean;\n draft?: boolean;\n notes?: import(\"../types\").Note[];\n model?: {\n provider?: string;\n name?: string;\n version?: string;\n };\n styles?: {\n icon?: string;\n node?: { color?: string; label?: string };\n };\n };\n};\n\nexport type AgentNode = Node<AgentNodeData, \"agent\">;\n\nfunction Agent(props: AgentNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n notes,\n owners,\n model,\n styles,\n } = props.data.agent;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const normalizedOwners = useMemo(() => normalizeOwners(owners), [owners]);\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n const draftStripe = isDark\n ? \"rgba(14,165,233,0.25)\"\n : \"rgba(14,165,233,0.15)\";\n const providerLabel = model?.provider;\n const providerIconSrc = getProviderIconSrc(providerLabel, isDark);\n const modelLabel = model?.name;\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-sky-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? \"border-dashed border-sky-400\"\n : \"border-sky-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-agent-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${draftStripe} 4px, ${draftStripe} 4.5px), var(--ec-agent-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-agent-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(14, 165, 233, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-sky-500\",\n )}\n >\n <Bot className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Agent\n {draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-[26px] h-[26px] shrink-0\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#0ea5e9\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {(providerLabel || modelLabel) && (\n <div className=\"flex items-center gap-1 flex-wrap mt-1.5\">\n {providerLabel && (\n <span className=\"inline-flex items-center text-[7px] font-bold px-1.5 py-0.5 rounded bg-sky-500/10 text-sky-700 dark:text-sky-300 uppercase tracking-wide\">\n {providerIconSrc && (\n <img\n src={providerIconSrc}\n alt=\"\"\n className=\"w-2 h-2 shrink-0 mr-1 object-contain\"\n loading=\"lazy\"\n />\n )}\n {providerLabel}\n </span>\n )}\n {modelLabel && (\n <span className=\"inline-flex items-center text-[7px] font-bold px-1.5 py-0.5 rounded bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))] border border-sky-500/30 max-w-[8.5rem] truncate\">\n {modelLabel}\n </span>\n )}\n </div>\n )}\n\n <OwnerIndicator\n owners={normalizedOwners}\n accentColor=\"bg-sky-400\"\n borderColor=\"rgba(14,165,233,0.08)\"\n iconClass=\"text-sky-300\"\n />\n </div>\n </div>\n );\n}\n\nexport default memo(Agent);\n","import { memo } from \"react\";\nimport { Wrench } from \"lucide-react\";\nimport { Handle, Node, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../utils/node-connections\";\nimport { EventCatalogResource } from \"../types\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { LINE_CLAMP_STYLE, useDarkMode, HANDLE_GLOW } from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\nimport { CustomIcon, isIconPath } from \"../utils/custom-icon\";\nimport mcpDark from \"../icons/protocols/mcp-dark.svg?raw\";\nimport mcpLight from \"../icons/protocols/mcp-light.svg?raw\";\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype AgentToolData = EventCatalogResource & {\n agentTool: {\n id?: string;\n name: string;\n type: string;\n icon?: string;\n url?: string;\n description?: string;\n };\n};\n\nexport type AgentToolNode = Node<AgentToolData, \"agentTool\">;\n\nconst normalizeType = (type?: string) => (type || \"\").trim().toLowerCase();\n\nfunction ToolTypeBadge({ type }: { type: string }) {\n const isDark = useDarkMode();\n const normalizedType = normalizeType(type);\n const label = type.toUpperCase();\n\n if (normalizedType === \"mcp\") {\n return (\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold px-1.5 py-0.5 rounded bg-violet-500/10 text-violet-700 dark:text-violet-300 border border-violet-500/25\">\n <span\n className=\"w-2 h-2 shrink-0 [&>svg]:w-2 [&>svg]:h-2\"\n dangerouslySetInnerHTML={{ __html: isDark ? mcpDark : mcpLight }}\n />\n MCP\n </span>\n );\n }\n\n return (\n <span className=\"inline-flex items-center text-[7px] font-bold px-1.5 py-0.5 rounded bg-violet-500/10 text-violet-700 dark:text-violet-300 border border-violet-500/25\">\n {label}\n </span>\n );\n}\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #8b5cf6, #6d28d9)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.dataProduct,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nfunction AgentTool(props: AgentToolNode) {\n const { name, type, icon, url, description } = props.data.agentTool;\n const customIcon = isIconPath(icon) ? icon : undefined;\n const connected = useNodeHasConnections();\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible border-violet-500\",\n props?.selected ? \"ring-2 ring-violet-400/60 ring-offset-2\" : \"\",\n )}\n style={{\n background: \"var(--ec-agent-tool-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(139, 92, 246, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-violet-500\">\n <Wrench className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Tool\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-center gap-2 min-w-0\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className=\"w-4 h-4 shrink-0\"\n />\n )}\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#8b5cf6\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {description && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={description}\n >\n {description}\n </div>\n )}\n\n <div className=\"mt-1.5 flex items-center gap-1 flex-wrap\">\n <ToolTypeBadge type={type} />\n {url && (\n <span className=\"inline-flex items-center text-[7px] font-bold px-1.5 py-0.5 rounded bg-[rgb(var(--ec-page-bg))] text-[rgb(var(--ec-page-text-muted))] border border-violet-500/25 max-w-[9rem] truncate\">\n {url}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default memo(AgentTool);\n","<svg fill=\"#ffffff\" fill-rule=\"evenodd\" height=\"1em\" style=\"flex:none;line-height:1\" viewBox=\"0 0 24 24\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><title>ModelContextProtocol</title><path d=\"M15.688 2.343a2.588 2.588 0 00-3.61 0l-9.626 9.44a.863.863 0 01-1.203 0 .823.823 0 010-1.18l9.626-9.44a4.313 4.313 0 016.016 0 4.116 4.116 0 011.204 3.54 4.3 4.3 0 013.609 1.18l.05.05a4.115 4.115 0 010 5.9l-8.706 8.537a.274.274 0 000 .393l1.788 1.754a.823.823 0 010 1.18.863.863 0 01-1.203 0l-1.788-1.753a1.92 1.92 0 010-2.754l8.706-8.538a2.47 2.47 0 000-3.54l-.05-.049a2.588 2.588 0 00-3.607-.003l-7.172 7.034-.002.002-.098.097a.863.863 0 01-1.204 0 .823.823 0 010-1.18l7.273-7.133a2.47 2.47 0 00-.003-3.537z\"/><path d=\"M14.485 4.703a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a4.115 4.115 0 000 5.9 4.314 4.314 0 006.016 0l7.12-6.982a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a2.588 2.588 0 01-3.61 0 2.47 2.47 0 010-3.54l7.12-6.982z\"/></svg>","<svg fill=\"#000000\" fill-rule=\"evenodd\" height=\"1em\" style=\"flex:none;line-height:1\" viewBox=\"0 0 24 24\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><title>ModelContextProtocol</title><path d=\"M15.688 2.343a2.588 2.588 0 00-3.61 0l-9.626 9.44a.863.863 0 01-1.203 0 .823.823 0 010-1.18l9.626-9.44a4.313 4.313 0 016.016 0 4.116 4.116 0 011.204 3.54 4.3 4.3 0 013.609 1.18l.05.05a4.115 4.115 0 010 5.9l-8.706 8.537a.274.274 0 000 .393l1.788 1.754a.823.823 0 010 1.18.863.863 0 01-1.203 0l-1.788-1.753a1.92 1.92 0 010-2.754l8.706-8.538a2.47 2.47 0 000-3.54l-.05-.049a2.588 2.588 0 00-3.607-.003l-7.172 7.034-.002.002-.098.097a.863.863 0 01-1.204 0 .823.823 0 010-1.18l7.273-7.133a2.47 2.47 0 00-.003-3.537z\"/><path d=\"M14.485 4.703a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a4.115 4.115 0 000 5.9 4.314 4.314 0 006.016 0l7.12-6.982a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a2.588 2.588 0 01-3.61 0 2.47 2.47 0 010-3.54l7.12-6.982z\"/></svg>","import { memo, useMemo } from \"react\";\nimport { Zap } from \"lucide-react\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { Message, EventCatalogResource } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { MethodBadge, ApiPath, StatusCodes } from \"../ApiInfo\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nconst GlowHandle = memo(function GlowHandle({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #fb923c, #ea580c)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.event,\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype MessageNodeData = EventCatalogResource & {\n message: Message;\n};\n\nexport type EventNode = Node<MessageNodeData, \"event\">;\n\nfunction PostItEvent(props: EventNode) {\n const { version, name, summary, deprecated, draft, notes, styles } =\n props?.data?.message;\n const mode = props?.data?.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-orange-400/60 ring-offset-1\" : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {/* Inner wrapper with rotation — keeps handles aligned to the unrotated bounding box */}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #fed7aa 0%, #fdba74 40%, #fb923c 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(251, 146, 60, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#f97316 transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n {/* Content sits on top, unrotated, so text stays crisp */}\n <div className=\"relative px-3.5 py-3\">\n {/* Type label row */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <Zap className=\"w-3 h-3 text-orange-900/50\" strokeWidth={2.5} />\n <span className=\"text-[8px] font-bold text-orange-900/50 uppercase tracking-widest\">\n Event\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n {/* Name */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#f97316\"\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated\n ? \"text-orange-950/40 line-through\"\n : \"text-orange-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {/* Version */}\n {version && (\n <div className=\"text-[9px] text-orange-900/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-orange-900/10 text-[9px] text-orange-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultEvent(props: EventNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n schema,\n notes,\n method,\n path,\n statusCodes,\n styles,\n } = props?.data?.message;\n const mode = props?.data?.mode || \"simple\";\n const hasApiInfo = !!(method || path);\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const owners = useMemo(\n () => normalizeOwners(props?.data?.message?.owners),\n [props?.data?.message?.owners],\n );\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-orange-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-orange-400\" : \"border-orange-400/60\"}`\n : \"border-orange-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-event-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(251,146,60,0.25)\" : \"rgba(251,146,60,0.15)\"} 4px, ${isDark ? \"rgba(251,146,60,0.25)\" : \"rgba(251,146,60,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(251,146,60,0.25)\" : \"rgba(251,146,60,0.15)\"} 4px, ${isDark ? \"rgba(251,146,60,0.25)\" : \"rgba(251,146,60,0.15)\"} 4.5px), var(--ec-event-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-event-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(251, 146, 60, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-orange-500\",\n )}\n >\n <Zap className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Event{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n {/* Schema badge top-right */}\n {schema && (\n <span\n className=\"z-10 text-[7px] font-semibold text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg))] border border-orange-500 rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{ position: \"absolute\", top: -8, right: 10 }}\n >\n {schema.includes(\".\") ? schema.split(\".\").pop() : schema}\n </span>\n )}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* API method + path row */}\n {hasApiInfo && (\n <div className=\"flex items-center gap-1.5 mb-1 overflow-hidden min-w-0\">\n {method && <MethodBadge method={method} />}\n {path && <ApiPath path={path} />}\n </div>\n )}\n\n {/* Name + version */}\n {!hasApiInfo && (\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#f97316\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span\n className=\"text-[10px] font-normal shrink-0\"\n style={{ color: isDark ? \"#dce3eb\" : \"#6b7280\" }}\n >\n (v{version})\n </span>\n )}\n </div>\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] leading-relaxed overflow-hidden\"\n style={{\n ...LINE_CLAMP_STYLE,\n color: isDark ? \"#f0f4f8\" : \"#374151\",\n }}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Status codes */}\n {statusCodes && statusCodes.length > 0 && (\n <StatusCodes codes={statusCodes} />\n )}\n\n {/* Owners + Notes row */}\n <div className=\"flex items-end justify-between\">\n <OwnerIndicator\n owners={owners}\n accentColor=\"bg-orange-400\"\n borderColor=\"rgba(251,146,60,0.08)\"\n iconClass=\"text-orange-300\"\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default memo(function Event(props: EventNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItEvent {...props} />;\n }\n\n return <DefaultEvent {...props} />;\n});\n","import { memo } from \"react\";\n\nconst METHOD_COLORS: Record<string, { bg: string; text: string }> = {\n GET: { bg: \"rgba(34,197,94,0.15)\", text: \"#22c55e\" },\n POST: { bg: \"rgba(59,130,246,0.15)\", text: \"#3b82f6\" },\n PUT: { bg: \"rgba(245,158,11,0.15)\", text: \"#f59e0b\" },\n PATCH: { bg: \"rgba(245,158,11,0.15)\", text: \"#f59e0b\" },\n DELETE: { bg: \"rgba(239,68,68,0.15)\", text: \"#ef4444\" },\n OPTIONS: { bg: \"rgba(139,92,246,0.15)\", text: \"#8b5cf6\" },\n HEAD: { bg: \"rgba(107,114,128,0.15)\", text: \"#6b7280\" },\n};\n\nconst STATUS_COLORS: Record<string, { bg: string; text: string }> = {\n \"2\": { bg: \"rgba(34,197,94,0.15)\", text: \"#22c55e\" },\n \"3\": { bg: \"rgba(59,130,246,0.15)\", text: \"#3b82f6\" },\n \"4\": { bg: \"rgba(245,158,11,0.15)\", text: \"#f59e0b\" },\n \"5\": { bg: \"rgba(239,68,68,0.15)\", text: \"#ef4444\" },\n};\n\nfunction getStatusColor(code: number) {\n const prefix = String(code)[0];\n return STATUS_COLORS[prefix] || STATUS_COLORS[\"2\"];\n}\n\nexport const MethodBadge = memo(function MethodBadge({\n method,\n}: {\n method: string;\n}) {\n const upper = method.toUpperCase();\n const colors = METHOD_COLORS[upper] || { bg: \"#6b7280\", text: \"#ffffff\" };\n return (\n <span\n className=\"inline-flex items-center text-[8px] font-extrabold uppercase tracking-wide px-1.5 py-0.5 rounded\"\n style={{ background: colors.bg, color: colors.text }}\n >\n {upper}\n </span>\n );\n});\n\nexport const StatusCodes = memo(function StatusCodes({\n codes,\n}: {\n codes: number[];\n}) {\n return (\n <div className=\"flex items-center gap-1 flex-wrap mt-1.5\">\n {codes.map((code) => {\n const colors = getStatusColor(code);\n return (\n <span\n key={code}\n className=\"inline-flex items-center text-[8px] font-bold px-1.5 py-0.5 rounded\"\n style={{ background: colors.bg, color: colors.text }}\n >\n {code}\n </span>\n );\n })}\n </div>\n );\n});\n\nexport const ApiPath = memo(function ApiPath({ path }: { path: string }) {\n return (\n <span\n className=\"text-[12px] font-mono font-medium text-[rgb(var(--ec-page-text))] truncate min-w-0\"\n title={path}\n >\n {path}\n </span>\n );\n});\n","import { Connection, MarkerType } from \"@xyflow/react\";\nimport { Zap } from \"lucide-react\";\nimport { NodeConfiguration } from \"../../types\";\nimport { SERVICE, CHANNEL, EVENT } from \"../node-types\";\n\nexport default {\n type: \"event\",\n icon: Zap,\n color: \"orange\",\n targetCanConnectTo: [...SERVICE, ...CHANNEL],\n sourceCanConnectTo: [...SERVICE, ...CHANNEL],\n validateConnection: (connection: Connection) => {\n return connection.source !== connection.target;\n },\n getEdgeOptions: (connection: Connection) => {\n if (\n EVENT.includes(connection.source) &&\n SERVICE.includes(connection.target)\n ) {\n return {\n label: \"Publishes\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n }\n return {\n label: \"Subscribes\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n },\n defaultData: {\n name: \"New Event\",\n version: \"0.0.1\",\n summary: \"New event. Click edit to change the details.\",\n mode: \"full\",\n },\n editor: {\n title: \"Event\",\n subtitle: \"Edit the details of the event\",\n schema: {\n type: \"object\",\n required: [\"name\", \"version\"],\n properties: {\n name: {\n type: \"string\",\n title: \"Name\",\n default: \"Random value\",\n description:\n \"The name of the event. Use a verb-noun format (e.g., OrderPlaced).\",\n },\n version: {\n type: \"string\",\n title: \"Version\",\n default: \"1.0.0\",\n description: \"The version number (e.g., 1.0.0)\",\n pattern: \"^\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[\\\\w.-]+)?(?:\\\\+[\\\\w.-]+)?$\",\n },\n summary: {\n type: \"string\",\n title: \"Summary\",\n default: \"\",\n description: \"A brief summary of the event\",\n },\n },\n },\n },\n} as NodeConfiguration;\n","import { memo, useMemo } from \"react\";\nimport { Search } from \"lucide-react\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { Message, EventCatalogResource } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { MethodBadge, ApiPath, StatusCodes } from \"../ApiInfo\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nconst GlowHandle = memo(function GlowHandle({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #22c55e, #15803d)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.query,\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype QueryNodeData = EventCatalogResource & {\n message: Message;\n};\n\nexport type QueryNode = Node<QueryNodeData, \"query\">;\n\nfunction PostItQuery(props: QueryNode) {\n const { version, name, summary, deprecated, draft, notes, styles } =\n props.data.message;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-green-400/60 ring-offset-1\" : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #bbf7d0 0%, #86efac 40%, #22c55e 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(34, 197, 94, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#16a34a transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <Search className=\"w-3 h-3 text-green-900/50\" strokeWidth={2.5} />\n <span className=\"text-[8px] font-bold text-green-900/50 uppercase tracking-widest\">\n Query\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#22c55e\"\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated ? \"text-green-950/40 line-through\" : \"text-green-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {version && (\n <div className=\"text-[9px] text-green-900/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-green-900/10 text-[9px] text-green-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultQuery(props: QueryNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n schema,\n notes,\n method,\n path,\n statusCodes,\n styles,\n } = props.data.message;\n const mode = props.data.mode || \"simple\";\n const hasApiInfo = !!(method || path);\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const owners = useMemo(\n () => normalizeOwners(props.data.message?.owners),\n [props.data.message?.owners],\n );\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-green-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-green-400\" : \"border-green-400/60\"}`\n : \"border-green-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-query-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(34,197,94,0.25)\" : \"rgba(34,197,94,0.15)\"} 4px, ${isDark ? \"rgba(34,197,94,0.25)\" : \"rgba(34,197,94,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(34,197,94,0.25)\" : \"rgba(34,197,94,0.15)\"} 4px, ${isDark ? \"rgba(34,197,94,0.25)\" : \"rgba(34,197,94,0.15)\"} 4.5px), var(--ec-query-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-query-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(34, 197, 94, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-green-500\",\n )}\n >\n <Search className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Query{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n {/* Schema badge top-right */}\n {schema && (\n <span\n className=\"z-10 text-[7px] font-semibold text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg))] border border-green-500 rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{ position: \"absolute\", top: -8, right: 10 }}\n >\n {schema.includes(\".\") ? schema.split(\".\").pop() : schema}\n </span>\n )}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* API method + path row */}\n {hasApiInfo && (\n <div className=\"flex items-center gap-1.5 mb-1 overflow-hidden min-w-0\">\n {method && <MethodBadge method={method} />}\n {path && <ApiPath path={path} />}\n </div>\n )}\n\n {/* Name + version */}\n {!hasApiInfo && (\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#22c55e\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Status codes */}\n {statusCodes && statusCodes.length > 0 && (\n <StatusCodes codes={statusCodes} />\n )}\n\n {/* Owners */}\n <OwnerIndicator\n owners={owners}\n accentColor=\"bg-green-400\"\n borderColor=\"rgba(34,197,94,0.08)\"\n iconClass=\"text-green-300\"\n />\n </div>\n </div>\n );\n}\n\nexport default memo(function Query(props: QueryNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItQuery {...props} />;\n }\n\n return <DefaultQuery {...props} />;\n});\n","import { memo, useMemo } from \"react\";\nimport { MessageSquare } from \"lucide-react\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { Message, EventCatalogResource } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { MethodBadge, ApiPath, StatusCodes } from \"../ApiInfo\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nconst GlowHandle = memo(function GlowHandle({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #3b82f6, #1d4ed8)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.command,\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype CommandNodeData = EventCatalogResource & {\n message: Message;\n};\n\nexport type CommandNode = Node<CommandNodeData, \"command\">;\n\nfunction PostItCommand(props: CommandNode) {\n const { version, name, summary, deprecated, draft, notes, styles } =\n props.data.message;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-blue-400/60 ring-offset-1\" : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #bfdbfe 0%, #93c5fd 40%, #3b82f6 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(59, 130, 246, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#1d4ed8 transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <MessageSquare\n className=\"w-3 h-3 text-blue-900/50\"\n strokeWidth={2.5}\n />\n <span className=\"text-[8px] font-bold text-blue-900/50 uppercase tracking-widest\">\n Command\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#3b82f6\"\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated ? \"text-blue-950/40 line-through\" : \"text-blue-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {version && (\n <div className=\"text-[9px] text-blue-900/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-blue-900/10 text-[9px] text-blue-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultCommand(props: CommandNode) {\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n schema,\n notes,\n method,\n path,\n statusCodes,\n styles,\n } = props.data.message;\n const mode = props.data.mode || \"simple\";\n const hasApiInfo = !!(method || path);\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const owners = useMemo(\n () => normalizeOwners(props.data.message?.owners),\n [props.data.message?.owners],\n );\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-blue-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-blue-400\" : \"border-blue-400/60\"}`\n : \"border-blue-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-command-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(59,130,246,0.25)\" : \"rgba(59,130,246,0.15)\"} 4px, ${isDark ? \"rgba(59,130,246,0.25)\" : \"rgba(59,130,246,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(59,130,246,0.25)\" : \"rgba(59,130,246,0.15)\"} 4px, ${isDark ? \"rgba(59,130,246,0.25)\" : \"rgba(59,130,246,0.15)\"} 4.5px), var(--ec-command-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-command-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(59, 130, 246, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-blue-500\",\n )}\n >\n <MessageSquare className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Command{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n {/* Schema badge top-right */}\n {schema && (\n <span\n className=\"z-10 text-[7px] font-semibold text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg))] border border-blue-500 rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{ position: \"absolute\", top: -8, right: 10 }}\n >\n {schema.includes(\".\") ? schema.split(\".\").pop() : schema}\n </span>\n )}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* API method + path row */}\n {hasApiInfo && (\n <div className=\"flex items-center gap-1.5 mb-1 overflow-hidden min-w-0\">\n {method && <MethodBadge method={method} />}\n {path && <ApiPath path={path} />}\n </div>\n )}\n\n {/* Name + version */}\n {!hasApiInfo && (\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#3b82f6\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Status codes */}\n {statusCodes && statusCodes.length > 0 && (\n <StatusCodes codes={statusCodes} />\n )}\n\n {/* Owners */}\n <OwnerIndicator\n owners={owners}\n accentColor=\"bg-blue-400\"\n borderColor=\"rgba(59,130,246,0.08)\"\n iconClass=\"text-blue-300\"\n />\n </div>\n </div>\n );\n}\n\nexport default memo(function Command(props: CommandNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItCommand {...props} />;\n }\n\n return <DefaultCommand {...props} />;\n});\n","import { ArrowRightLeft, Link } from \"lucide-react\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { EventCatalogResource, Channel as ChannelType } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n EMPTY_ARRAY,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nimport { memo, useMemo } from \"react\";\n\nconst DELIVERY_GUARANTEE_LABELS: Record<string, string> = {\n \"at-most-once\": \"At most once\",\n \"at-least-once\": \"At least once\",\n \"exactly-once\": \"Exactly once\",\n};\n\nconst GUARANTEE_COLORS: Record<string, { hex: string; rgb: string }> = {\n \"exactly-once\": { hex: \"#22d3ee\", rgb: \"34,211,238\" },\n \"at-least-once\": { hex: \"#a78bfa\", rgb: \"167,139,250\" },\n \"at-most-once\": { hex: \"#f87171\", rgb: \"248,113,113\" },\n};\n\nconst DEFAULT_GUARANTEE = { hex: \"#6b7280\", rgb: \"107,114,128\" };\n\nfunction getGuarantee(guarantee?: string) {\n return (guarantee && GUARANTEE_COLORS[guarantee]) || DEFAULT_GUARANTEE;\n}\n\n/**\n * Delivery guarantee dot icon.\n * - exactly-once → filled circle\n * - at-least-once → half-filled circle\n * - at-most-once → hollow ring\n */\nfunction GuaranteeDot({\n guarantee,\n size = 6,\n}: {\n guarantee: string;\n size?: number;\n}) {\n const { hex } = getGuarantee(guarantee);\n\n if (guarantee === \"exactly-once\") {\n return (\n <span\n className=\"shrink-0 rounded-full\"\n style={{ width: size, height: size, background: hex }}\n />\n );\n }\n\n if (guarantee === \"at-least-once\") {\n return (\n <span\n className=\"shrink-0 rounded-full overflow-hidden\"\n style={{\n width: size,\n height: size,\n background: `linear-gradient(90deg, ${hex} 50%, transparent 50%)`,\n border: `1.5px solid ${hex}`,\n boxSizing: \"border-box\",\n }}\n />\n );\n }\n\n // at-most-once → hollow ring\n return (\n <span\n className=\"shrink-0 rounded-full\"\n style={{\n width: size,\n height: size,\n border: `1.5px solid ${hex}`,\n boxSizing: \"border-box\",\n }}\n />\n );\n}\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #6b7280, #374151)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.channel,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\ntype ChannelNodeData = EventCatalogResource & {\n channel: ChannelType;\n};\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nexport type ChannelNode = Node<ChannelNodeData, \"channel\">;\n\nfunction PostItChannel(props: ChannelNode) {\n const { data } = props;\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n protocols = EMPTY_ARRAY,\n notes,\n deliveryGuarantee,\n styles,\n } = data.channel;\n const mode = props.data.mode || \"simple\";\n const guarantee = getGuarantee(deliveryGuarantee);\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-gray-400/60 ring-offset-1\" : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #e5e7eb 0%, #d1d5db 40%, #6b7280 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(107, 114, 128, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#374151 transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n {/* Type badge row */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <ArrowRightLeft\n className=\"w-3 h-3 text-gray-900/50\"\n strokeWidth={2.5}\n />\n <span className=\"text-[8px] font-bold text-gray-900/50 uppercase tracking-widest\">\n Channel\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n </div>\n\n {/* Name + version */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1.5 min-w-0\">\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#6b7280\"\n className={classNames(\n \"text-[13px] font-bold leading-snug truncate\",\n deprecated ? \"text-gray-950/40 line-through\" : \"text-gray-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[9px] text-gray-900/30 font-medium shrink-0\">\n v{version}\n </span>\n )}\n </div>\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1 text-[9px] text-gray-950/50 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Operational row: delivery guarantee + protocol pills */}\n {(deliveryGuarantee || protocols?.[0]) && (\n <div className=\"flex items-center gap-1 flex-wrap mt-2\">\n {deliveryGuarantee && (\n <span\n className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-wide rounded-full px-1.5 py-0.5\"\n style={{\n background: `rgba(${guarantee.rgb}, 0.12)`,\n color: guarantee.hex,\n }}\n >\n <GuaranteeDot guarantee={deliveryGuarantee} size={5} />\n {DELIVERY_GUARANTEE_LABELS[deliveryGuarantee] ||\n deliveryGuarantee}\n </span>\n )}\n {protocols?.[0] && (\n <span className=\"inline-flex items-center text-[7px] font-semibold text-gray-900/50 bg-gray-900/10 rounded-full px-1.5 py-0.5 uppercase tracking-wide\">\n {protocols[0]}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultChannel(props: ChannelNode) {\n const { data } = props;\n const {\n version,\n name,\n summary,\n deprecated,\n draft,\n protocols = EMPTY_ARRAY,\n address,\n notes,\n deliveryGuarantee,\n styles,\n } = data.channel;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const owners = useMemo(\n () => normalizeOwners(data.channel?.owners),\n [data.channel?.owners],\n );\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n const guarantee = getGuarantee(deliveryGuarantee);\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-gray-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-gray-400\" : \"border-gray-400/60\"}`\n : isDark\n ? \"border-gray-400\"\n : \"border-gray-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-channel-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(107,114,128,0.25)\" : \"rgba(107,114,128,0.15)\"} 4px, ${isDark ? \"rgba(107,114,128,0.25)\" : \"rgba(107,114,128,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(107,114,128,0.25)\" : \"rgba(107,114,128,0.15)\"} 4px, ${isDark ? \"rgba(107,114,128,0.25)\" : \"rgba(107,114,128,0.15)\"} 4.5px), var(--ec-channel-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-channel-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(107, 114, 128, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-gray-500\",\n )}\n >\n <ArrowRightLeft className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Channel{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n {/* Protocol badge top-right — removed, now in operational row */}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name + version */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1.5 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#6b7280\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span\n className=\"text-[9px] font-normal shrink-0\"\n style={{\n color: \"rgb(var(--ec-page-text-muted))\",\n opacity: 0.5,\n }}\n >\n v{version}\n </span>\n )}\n </div>\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={{ ...LINE_CLAMP_STYLE, marginBottom: 4 }}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Address */}\n {mode === \"full\" && address && (\n <div className=\"flex items-center gap-1 mt-1\">\n <Link className=\"w-2.5 h-2.5 text-[rgb(var(--ec-page-text-muted))]\" />\n <span className=\"text-[8px] text-[rgb(var(--ec-page-text-muted))] font-mono\">\n {address}\n </span>\n </div>\n )}\n\n {/* Operational row: delivery guarantee + protocol pills */}\n {(deliveryGuarantee || protocols?.[0]) && (\n <div className=\"flex items-center gap-1 flex-wrap mt-2\">\n {deliveryGuarantee && (\n <span\n className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-wide rounded-full px-1.5 py-0.5\"\n style={{\n background: `rgba(${guarantee.rgb}, 0.08)`,\n color: guarantee.hex,\n }}\n >\n <GuaranteeDot guarantee={deliveryGuarantee} size={5} />\n {DELIVERY_GUARANTEE_LABELS[deliveryGuarantee] ||\n deliveryGuarantee}\n </span>\n )}\n {protocols?.[0] && (\n <span\n className=\"inline-flex items-center text-[7px] font-semibold rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{\n background: isDark\n ? \"rgba(255,255,255,0.08)\"\n : \"rgba(107,114,128,0.1)\",\n color: \"rgb(var(--ec-page-text-muted))\",\n }}\n >\n {protocols[0]}\n </span>\n )}\n </div>\n )}\n\n {/* Owners */}\n <OwnerIndicator\n owners={owners}\n accentColor=\"bg-gray-400\"\n borderColor=\"rgba(107,114,128,0.08)\"\n iconClass=\"text-gray-300\"\n />\n </div>\n </div>\n );\n}\n\nexport default memo(function Channel(props: ChannelNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItChannel {...props} />;\n }\n\n return <DefaultChannel {...props} />;\n});\n","import { memo, useMemo } from \"react\";\nimport { Database } from \"lucide-react\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { EventCatalogResource, Data as DataType } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n EMPTY_ARRAY,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { CustomIcon, isIconPath } from \"../../utils/custom-icon\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #6366f1, #4f46e5)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.data,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nconst CONTAINER_TYPE_LABELS: Record<string, string> = {\n database: \"Database\",\n cache: \"Cache\",\n objectStore: \"Object Store\",\n searchIndex: \"Search Index\",\n dataWarehouse: \"Data Warehouse\",\n dataLake: \"Data Lake\",\n externalSaaS: \"External SaaS\",\n other: \"Other\",\n};\n\nfunction getDataNodeTypeLabel(\n containerType: string | undefined,\n type: string | undefined,\n): string {\n if (containerType) {\n return CONTAINER_TYPE_LABELS[containerType] ?? containerType;\n }\n return type ?? \"Database\";\n}\n\ntype DataNodeData = EventCatalogResource & {\n data: DataType;\n};\n\nexport type DataNode = Node<DataNodeData, \"data\">;\n\nfunction PostItData(props: DataNode) {\n const {\n version,\n owners = EMPTY_ARRAY,\n schemas = EMPTY_ARRAY,\n name,\n summary,\n deprecated,\n draft,\n notes,\n styles,\n } = props.data.data;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-indigo-400/60 ring-offset-1\" : \"\",\n )}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {/* Inner wrapper with rotation */}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #c7d2fe 0%, #a5b4fc 40%, #6366f1 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(99, 102, 241, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#4f46e5 transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n {/* Content sits on top, unrotated */}\n <div className=\"relative px-3.5 py-3\">\n {/* Type label row */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <Database\n className=\"w-3 h-3 text-indigo-950/50\"\n strokeWidth={2.5}\n />\n <span className=\"text-[8px] font-bold text-indigo-950/50 uppercase tracking-widest\">\n Data\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n {/* Name */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#6366f1\"\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated\n ? \"text-indigo-950/40 line-through\"\n : \"text-indigo-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {/* Version */}\n {version && (\n <div className=\"text-[9px] text-indigo-950/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-indigo-950/10 text-[9px] text-indigo-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultData(props: DataNode) {\n const {\n version,\n owners = EMPTY_ARRAY,\n schemas = EMPTY_ARRAY,\n name,\n summary,\n type,\n container_type,\n deprecated,\n draft,\n notes,\n styles,\n } = props.data.data;\n const typeLabel = getDataNodeTypeLabel(container_type, type);\n\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const ownersNormalized = useMemo(() => normalizeOwners(owners), [owners]);\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-indigo-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-indigo-400\" : \"border-indigo-400/60\"}`\n : \"border-indigo-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-data-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4.5px), var(--ec-data-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-data-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(99, 102, 241, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-indigo-500\",\n )}\n >\n <Database className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Data{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n {typeLabel && (\n <span\n className=\"z-10 text-[7px] font-semibold text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg))] border border-indigo-500 rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{ position: \"absolute\", top: -8, right: 10 }}\n >\n {typeLabel}\n </span>\n )}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name + version */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-5 h-5 shrink-0 mt-0.5\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#6366f1\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Owners */}\n <OwnerIndicator\n owners={ownersNormalized}\n accentColor=\"bg-indigo-400\"\n borderColor=\"rgba(99,102,241,0.08)\"\n iconClass=\"text-indigo-300\"\n />\n </div>\n </div>\n );\n}\n\nexport default memo(function Data(props: DataNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItData {...props} />;\n }\n\n return <DefaultData {...props} />;\n});\n","import { Connection, MarkerType } from \"@xyflow/react\";\nimport { Database } from \"lucide-react\";\nimport { NodeConfiguration } from \"../../types\";\nimport { SERVICE, CHANNEL, ACTOR } from \"../node-types\";\n\nexport default {\n type: \"data\",\n icon: Database,\n color: \"indigo\",\n targetCanConnectTo: [...SERVICE, ...CHANNEL, \"external-system\", ...ACTOR],\n sourceCanConnectTo: [...SERVICE, ...CHANNEL, \"external-system\", ...ACTOR],\n validateConnection: (connection: Connection) => {\n return connection.source !== connection.target;\n },\n getEdgeOptions: (connection: Connection) => {\n if (connection.source === \"data\" && connection.target === \"service\") {\n return {\n label: \"Provides data to\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n }\n if (connection.source === \"service\" && connection.target === \"data\") {\n return {\n label: \"Stores data in\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n }\n return {\n label: \"Connected to\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n },\n defaultData: {\n name: \"New Database\",\n version: \"0.0.1\",\n summary: \"New data store. Click edit to change the details.\",\n type: \"Database\",\n mode: \"full\",\n },\n editor: {\n title: \"Data Store\",\n subtitle: \"Edit the details of the data store\",\n schema: {\n type: \"object\",\n required: [\"name\", \"version\"],\n properties: {\n name: {\n type: \"string\",\n title: \"Name\",\n default: \"UserDatabase\",\n description: \"The name of the data store\",\n },\n version: {\n type: \"string\",\n title: \"Version\",\n default: \"1.0.0\",\n description: \"The version number (e.g., 1.0.0)\",\n pattern: \"^\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[\\\\w.-]+)?(?:\\\\+[\\\\w.-]+)?$\",\n },\n summary: {\n type: \"string\",\n title: \"Summary\",\n default: \"\",\n description: \"A brief summary of the data store\",\n },\n type: {\n type: \"string\",\n title: \"Type\",\n default: \"Database\",\n description: \"The type of data store (Database, Cache, Queue, etc.)\",\n enum: [\n \"Database\",\n \"Cache\",\n \"Queue\",\n \"File System\",\n \"Data Lake\",\n \"Data Warehouse\",\n ],\n },\n },\n },\n },\n} as NodeConfiguration;\n","import { memo, useMemo } from \"react\";\nimport { MonitorIcon } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { EventCatalogResource, View as ViewType } from \"../../types\";\nimport {\n OwnerIndicator,\n normalizeOwners,\n HIDDEN_HANDLE_STYLE,\n} from \"../OwnerIndicator\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { LINE_CLAMP_STYLE, EMPTY_ARRAY, HANDLE_GLOW } from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"../FocusedResourceIndicator\";\n\n// Views are sky blue, so they stand apart from commands (blue) and data stores (indigo)\nconst VIEW_COLOR = \"#0ea5e9\";\n\nconst GlowHandle = memo(function GlowHandle({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #38bdf8, #0284c7)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.view,\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\ntype ViewNodeData = EventCatalogResource & {\n view: ViewType;\n};\n\nexport type ViewNode = Node<ViewNodeData, \"view\">;\n\nexport default memo(function View(props: ViewNode) {\n const {\n name,\n version,\n summary,\n screenshot,\n owners = EMPTY_ARRAY,\n notes,\n } = props.data.view;\n const mode = props.data.mode || \"simple\";\n const ownersNormalized = useMemo(() => normalizeOwners(owners), [owners]);\n const connected = useNodeHasConnections();\n\n return (\n <div\n className={[\n \"relative min-w-48 max-w-60 rounded-xl border-2 border-sky-500 overflow-visible\",\n props.selected ? \"ring-2 ring-sky-400/60 ring-offset-2\" : \"\",\n ].join(\" \")}\n style={{\n background: \"rgb(var(--ec-card-bg))\",\n boxShadow: \"0 2px 12px rgba(14, 165, 233, 0.15)\",\n }}\n >\n {props.data.isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-sky-500\">\n <MonitorIcon className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n View\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name + version */}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor={VIEW_COLOR}\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {/* Screenshot */}\n {mode === \"full\" && screenshot && (\n <img\n src={screenshot}\n alt={`${name} screenshot`}\n className=\"mt-2 w-full h-24 object-cover rounded-md border border-[rgb(var(--ec-page-border))]\"\n />\n )}\n\n {/* Owners */}\n <OwnerIndicator\n owners={ownersNormalized}\n accentColor=\"bg-sky-400\"\n borderColor=\"rgba(14,165,233,0.08)\"\n iconClass=\"text-sky-300\"\n />\n </div>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { User } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { EventCatalogResource, Note } from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { HIDDEN_HANDLE_STYLE } from \"../OwnerIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #eab308, #a16207)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.actor,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype ActorNodeData = EventCatalogResource & {\n name: string;\n summary: string;\n deprecated?: boolean;\n draft?: boolean;\n notes?: Note[];\n};\n\nexport type ActorNode = Node<ActorNodeData, \"actor\">;\n\nfunction PostItActor(props: ActorNode) {\n const { name, summary, deprecated, draft, notes } = props?.data;\n const mode = props?.data?.mode || \"simple\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-yellow-400/60 ring-offset-1\" : \"\",\n )}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #fef9c3 0%, #fde047 40%, #eab308 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(234, 179, 8, 0.5)\"\n : \"none\",\n }}\n >\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#a16207 transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <User className=\"w-3 h-3 text-yellow-900/50\" strokeWidth={2.5} />\n <span className=\"text-[8px] font-bold text-yellow-900/50 uppercase tracking-widest\">\n Actor\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#eab308\"\n className={classNames(\n \"text-[13px] font-bold leading-snug truncate\",\n deprecated ? \"text-yellow-950/40 line-through\" : \"text-yellow-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-yellow-900/10 text-[9px] text-yellow-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultActor(props: ActorNode) {\n const { name, summary, deprecated, draft, notes } = props?.data;\n const mode = props?.data?.mode || \"simple\";\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-yellow-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-yellow-400\" : \"border-yellow-400/60\"}`\n : \"border-yellow-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-actor-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(234,179,8,0.25)\" : \"rgba(234,179,8,0.15)\"} 4px, ${isDark ? \"rgba(234,179,8,0.25)\" : \"rgba(234,179,8,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(234,179,8,0.25)\" : \"rgba(234,179,8,0.15)\"} 4px, ${isDark ? \"rgba(234,179,8,0.25)\" : \"rgba(234,179,8,0.15)\"} 4.5px), var(--ec-actor-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-actor-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Badge positioned outside top-left corner */}\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-yellow-500\",\n )}\n >\n <User className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Actor{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name */}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#eab308\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport default memo(function Actor(props: ActorNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItActor {...props} />;\n }\n\n return <DefaultActor {...props} />;\n});\n","import { Connection, MarkerType } from \"@xyflow/react\";\nimport { User } from \"lucide-react\";\nimport { NodeConfiguration } from \"../../types\";\nimport { SERVICE, MESSAGE, CHANNEL } from \"../node-types\";\n\nexport default {\n type: \"actor\",\n icon: User,\n color: \"yellow\",\n targetCanConnectTo: [\n ...SERVICE,\n ...MESSAGE,\n ...CHANNEL,\n \"external-system\",\n \"view\",\n ],\n sourceCanConnectTo: [\n ...SERVICE,\n ...MESSAGE,\n ...CHANNEL,\n \"external-system\",\n \"view\",\n ],\n validateConnection: (connection: Connection) => {\n return connection.source !== connection.target;\n },\n getEdgeOptions: (_connection: Connection) => {\n return {\n label: \"Interacts\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n },\n defaultData: {\n name: \"New Actor\",\n summary:\n \"A person or user in the system. Click edit to change the details.\",\n mode: \"full\",\n },\n editor: {\n title: \"Actor\",\n subtitle: \"Edit the details of the actor\",\n schema: {\n type: \"object\",\n required: [\"name\"],\n properties: {\n name: {\n type: \"string\",\n title: \"Name\",\n default: \"New Actor\",\n description: \"The name of the actor (person/user)\",\n },\n summary: {\n type: \"string\",\n title: \"Description\",\n default: \"\",\n description: \"A brief description of the actor\",\n },\n },\n },\n },\n} as NodeConfiguration;\n","import { memo } from \"react\";\nimport { Database } from \"lucide-react\";\nimport { HIDDEN_HANDLE_STYLE } from \"../OwnerIndicator\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { useDarkMode, HANDLE_GLOW } from \"../shared-styles\";\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #06b6d4, #0891b2)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.generic,\n pointerEvents: \"none\" as const,\n }}\n />\n );\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype FieldNodeData = {\n name: string;\n type?: string;\n mode?: \"simple\" | \"full\";\n};\n\nexport type FieldNode = Node<FieldNodeData, \"field\">;\n\nexport default memo(function Field(props: FieldNode) {\n const { name, type: fieldType } = props.data;\n const mode = props.data.mode || \"simple\";\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-cyan-400/60 ring-offset-2\" : \"\",\n \"border-cyan-500\",\n )}\n style={{\n background: \"var(--ec-field-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(6, 182, 212, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Type badge top-left */}\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-cyan-600\">\n <Database className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Field\n </span>\n </div>\n\n {/* Field type badge top-right */}\n {fieldType && (\n <span\n className=\"z-10 text-[7px] font-semibold text-[rgb(var(--ec-page-text))] bg-[rgb(var(--ec-card-bg))] border border-cyan-500 rounded-full px-1.5 py-0.5 uppercase tracking-wide\"\n style={{ position: \"absolute\", top: -8, right: 10 }}\n >\n {fieldType}\n </span>\n )}\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name */}\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))]\">\n {name}\n </span>\n </div>\n\n {/* Type info in full mode */}\n {mode === \"full\" && fieldType && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed\"\n title={`Type: ${fieldType}`}\n >\n Type: {fieldType}\n </div>\n )}\n </div>\n </div>\n );\n});\n","import { MarkerType } from \"@xyflow/react\";\nimport { Database } from \"lucide-react\";\nimport { NodeConfiguration } from \"../../types\";\n\nexport default {\n type: \"field\",\n icon: Database,\n color: \"cyan\",\n targetCanConnectTo: [],\n sourceCanConnectTo: [],\n validateConnection: () => false,\n getEdgeOptions: () => ({\n label: \"contains\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#06b6d4\" },\n }),\n defaultData: { name: \"New Field\", type: \"string\", mode: \"full\" },\n editor: {\n title: \"Field\",\n subtitle: \"Schema field\",\n schema: {\n type: \"object\",\n required: [\"name\"],\n properties: {\n name: { type: \"string\", title: \"Field Path\" },\n type: { type: \"string\", title: \"Type\" },\n },\n },\n },\n} as NodeConfiguration;\n","import { memo } from \"react\";\nimport { Globe } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport {\n EventCatalogResource,\n ExternalSystem as ExternalSystemType,\n} from \"../../types\";\nimport { NotesIndicator } from \"../NotesIndicator\";\nimport { HIDDEN_HANDLE_STYLE } from \"../OwnerIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #a855f7, #7e22ce)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.external,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype ExternalSystemNodeData = EventCatalogResource & {\n externalSystem: ExternalSystemType & {\n deprecated?: boolean;\n draft?: boolean;\n };\n};\n\nexport type ExternalSystemNode = Node<\n ExternalSystemNodeData,\n \"external-system\"\n>;\n\nfunction PostItExternalSystem(props: ExternalSystemNode) {\n const { version, name, summary, deprecated, draft, notes } =\n props.data.externalSystem;\n const mode = props.data.mode || \"simple\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-purple-400/60 ring-offset-1\" : \"\",\n )}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #e9d5ff 0%, #c084fc 40%, #a855f7 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(-1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(168, 85, 247, 0.5)\"\n : \"none\",\n }}\n >\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#7e22ce transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"relative px-3.5 py-3\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <Globe className=\"w-3 h-3 text-purple-900/50\" strokeWidth={2.5} />\n <span className=\"text-[8px] font-bold text-purple-900/50 uppercase tracking-widest\">\n External\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#a855f7\"\n className={classNames(\n \"text-[13px] font-bold leading-snug truncate\",\n deprecated ? \"text-purple-950/40 line-through\" : \"text-purple-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n\n {version && (\n <div className=\"text-[9px] text-purple-900/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-purple-900/10 text-[9px] text-purple-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultExternalSystem(props: ExternalSystemNode) {\n const { version, name, summary, deprecated, draft, notes } =\n props.data.externalSystem;\n const mode = props.data.mode || \"simple\";\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-purple-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-purple-400\" : \"border-purple-400/60\"}`\n : \"border-purple-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-external-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(168,85,247,0.25)\" : \"rgba(168,85,247,0.15)\"} 4px, ${isDark ? \"rgba(168,85,247,0.25)\" : \"rgba(168,85,247,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(168,85,247,0.25)\" : \"rgba(168,85,247,0.15)\"} 4px, ${isDark ? \"rgba(168,85,247,0.25)\" : \"rgba(168,85,247,0.15)\"} 4.5px), var(--ec-external-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-external-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(168, 85, 247, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Badge positioned outside top-left corner */}\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-purple-500\",\n )}\n >\n <Globe className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n External System{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name + version */}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#a855f7\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport default memo(function ExternalSystem(props: ExternalSystemNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItExternalSystem {...props} />;\n }\n\n return <DefaultExternalSystem {...props} />;\n});\n","import { Connection, MarkerType } from \"@xyflow/react\";\nimport { Globe } from \"lucide-react\";\nimport { NodeConfiguration } from \"../../types\";\nimport { SERVICE, CHANNEL, ACTOR, MESSAGE } from \"../node-types\";\n\nexport default {\n type: \"external-system\",\n icon: Globe,\n color: \"pink\",\n targetCanConnectTo: [...SERVICE, ...CHANNEL, ...MESSAGE, ...ACTOR],\n sourceCanConnectTo: [...SERVICE, ...CHANNEL, ...MESSAGE, ...ACTOR],\n validateConnection: (connection: Connection) => {\n return connection.source !== connection.target;\n },\n getEdgeOptions: (connection: Connection) => {\n return {\n label: \"Connects\",\n markerEnd: { type: MarkerType.ArrowClosed, color: \"#000000\" },\n };\n },\n defaultData: {\n mode: \"full\",\n externalSystem: {\n id: \"1\",\n name: \"New External System\",\n version: \"0.0.1\",\n summary: \"New external system. Click edit to change the details.\",\n },\n },\n editor: {\n title: \"External System\",\n subtitle: \"Edit the details of the external system\",\n schema: {\n type: \"object\",\n required: [\"externalSystem\", \"mode\"],\n properties: {\n externalSystem: {\n type: \"object\",\n required: [\"name\", \"version\"],\n properties: {\n name: {\n type: \"string\",\n title: \"Name\",\n default: \"Random value\",\n description: \"The name of the external system\",\n },\n version: {\n type: \"string\",\n title: \"Version\",\n default: \"1.0.0\",\n description: \"The version number (e.g., 1.0.0)\",\n pattern: \"^\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[\\\\w.-]+)?(?:\\\\+[\\\\w.-]+)?$\",\n },\n summary: {\n type: \"string\",\n title: \"Summary\",\n default: \"\",\n description: \"A brief summary of the external system\",\n },\n },\n },\n },\n },\n },\n} as NodeConfiguration;\n","import { memo } from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport { User } from \"lucide-react\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\ninterface Data {\n name: string;\n}\n\n/**\n * An actor (person/role) on the System Diagram.\n *\n * Deliberately styled differently from the boxy resource nodes: a soft, pill-ish\n * card with the actor icon in a circular badge centered at the top and the actor\n * name centered below. This reads as \"a person\", not \"a system\", at a glance.\n */\nexport default memo(function ContextActorNode({ data }: any) {\n const { name } = data as Data;\n\n return (\n <div\n className=\"relative flex w-44 flex-col items-center rounded-2xl border-2 border-yellow-500 bg-[var(--ec-actor-node-bg,rgb(var(--ec-card-bg)))] px-3 pb-3 pt-5\"\n style={{ boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.15)\" }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n\n {/* Icon badge — centered, straddling the top border like an avatar */}\n <div className=\"absolute -top-4 left-1/2 -translate-x-1/2\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full border-2 border-yellow-500 bg-[rgb(var(--ec-card-bg))] shadow-sm\">\n <User className=\"h-4 w-4 text-yellow-500\" strokeWidth={2} />\n </div>\n </div>\n\n <TruncatedResourceName\n as=\"div\"\n value={name}\n className=\"mt-1 max-w-full text-center text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n\n <span className=\"mt-0.5 text-[8px] font-bold uppercase tracking-widest text-yellow-600 dark:text-yellow-400\">\n Actor\n </span>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport { Boxes as BoxesIcon, Group as GroupIcon } from \"lucide-react\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { FocusedResourceIndicator } from \"./FocusedResourceIndicator\";\n\nexport type SystemGroupNodeData = {\n system?: {\n name: string;\n version?: string;\n };\n // Set for a domain boundary (a `domain-group` node) instead of a system\n domain?: {\n name: string;\n version?: string;\n };\n // The domain is a subdomain of another domain on the graph\n subdomain?: boolean;\n // The system being viewed on this page\n isFocused?: boolean;\n};\n\n/**\n * A boundary box wrapping all of a system's nodes on the System Diagram, so the\n * services / data stores / messages inside visibly belong to one parent system.\n *\n * Sized + positioned by the node-graph (it wraps the laid-out children); this\n * component only renders the chrome — a rounded violet box with a header banner\n * carrying the system name + icon.\n */\nconst CONTAINER_STYLE = {\n width: \"100%\",\n height: \"100%\",\n borderRadius: 14,\n border: \"2px solid var(--ec-system-group-border, #c4b5fd)\",\n // Slightly gray, translucent body so the grouped children read as \"inside\".\n backgroundColor: \"var(--ec-system-group-bg, rgba(100, 116, 139, 0.06))\",\n position: \"relative\" as const,\n overflow: \"visible\" as const,\n boxShadow: \"0 2px 16px rgba(139, 92, 246, 0.10)\",\n} as const;\n\nconst HEADER_STYLE = {\n position: \"absolute\" as const,\n top: 0,\n left: 0,\n right: 0,\n height: 48,\n borderTopLeftRadius: 12,\n borderTopRightRadius: 12,\n // Faint violet wash on the header, separated from the body by a hairline.\n background: \"var(--ec-system-group-header-bg, rgba(139, 92, 246, 0.05))\",\n borderBottom: \"1px solid var(--ec-system-group-border, #c4b5fd)\",\n display: \"flex\",\n alignItems: \"center\" as const,\n padding: \"0 16px\",\n overflow: \"visible\" as const,\n} as const;\n\n// Floating \"SYSTEM\" badge on the top-left border — mirrors the System node badge.\nconst BADGE_STYLE = {\n position: \"absolute\" as const,\n top: -11,\n left: 14,\n display: \"inline-flex\",\n alignItems: \"center\" as const,\n gap: 4,\n fontSize: 8,\n fontWeight: 700,\n letterSpacing: \"0.12em\",\n textTransform: \"uppercase\" as const,\n color: \"white\",\n background: \"#8b5cf6\",\n padding: \"2px 7px\",\n borderRadius: 5,\n boxShadow: \"0 1px 2px rgba(0,0,0,0.12)\",\n zIndex: 10,\n} as const;\n\nconst NAME_STYLE = {\n fontSize: 14,\n fontWeight: 700,\n // Falls back to the group text colour, which is lighter in dark mode\n color: \"var(--ec-system-group-text, var(--ec-group-text, #5b21b6))\",\n whiteSpace: \"nowrap\" as const,\n} as const;\n\nconst VERSION_STYLE = {\n fontSize: 10,\n fontWeight: 500,\n color: \"#a78bfa\",\n marginLeft: 6,\n} as const;\n\n// Domains use the same boundary box, in the domain colour (yellow)\nconst DOMAIN_CONTAINER_STYLE = {\n ...CONTAINER_STYLE,\n border: \"2px solid var(--ec-domain-group-border, #facc15)\",\n backgroundColor: \"var(--ec-domain-group-bg, rgba(250, 204, 21, 0.04))\",\n boxShadow: \"0 2px 16px rgba(234, 179, 8, 0.10)\",\n} as const;\nconst DOMAIN_HEADER_STYLE = {\n ...HEADER_STYLE,\n background: \"var(--ec-domain-group-header-bg, rgba(250, 204, 21, 0.08))\",\n borderBottom: \"1px solid var(--ec-domain-group-border, #facc15)\",\n} as const;\nconst DOMAIN_BADGE_STYLE = { ...BADGE_STYLE, background: \"#eab308\" } as const;\nconst DOMAIN_NAME_STYLE = {\n ...NAME_STYLE,\n color: \"var(--ec-domain-group-text, rgb(var(--ec-page-text)))\",\n} as const;\n\nexport default memo(function SystemGroupNode({ data }: NodeProps) {\n const { system, domain, subdomain, isFocused } =\n data as unknown as SystemGroupNodeData;\n const isDomain = !!domain;\n const resource = domain ?? system;\n const typeLabel = isDomain ? (subdomain ? \"Subdomain\" : \"Domain\") : \"System\";\n\n return (\n <div style={isDomain ? DOMAIN_CONTAINER_STYLE : CONTAINER_STYLE}>\n {isFocused && <FocusedResourceIndicator />}\n {/* Lets other nodes connect to the whole system (e.g. related systems) */}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {/* Floating type badge, styled like the System node's badge */}\n <span style={isDomain ? DOMAIN_BADGE_STYLE : BADGE_STYLE}>\n {isDomain ? (\n <BoxesIcon size={10} strokeWidth={2.5} />\n ) : (\n <GroupIcon size={10} strokeWidth={2.5} />\n )}\n {typeLabel}\n </span>\n\n {/* Header banner carrying the system (or domain) name */}\n <div style={isDomain ? DOMAIN_HEADER_STYLE : HEADER_STYLE}>\n <TruncatedResourceName\n value={resource?.name || typeLabel}\n tooltipBorderColor={isDomain ? \"#eab308\" : \"#8b5cf6\"}\n className=\"truncate\"\n style={isDomain ? DOMAIN_NAME_STYLE : NAME_STYLE}\n >\n {resource?.name || typeLabel}\n </TruncatedResourceName>\n {resource?.version && (\n <span style={VERSION_STYLE}>v{resource.version}</span>\n )}\n </div>\n </div>\n );\n});\n","import { Handle, Position } from \"@xyflow/react\";\nimport {\n Boxes as BoxesIcon,\n Box as BoxIcon,\n Group as GroupIcon,\n Server as ServerIcon,\n} from \"lucide-react\";\nimport { memo, type KeyboardEvent } from \"react\";\nimport { buildUrl, navigateTo } from \"../utils/url-builder\";\nimport { HANDLE_GLOW, LINE_CLAMP_STYLE } from \"./shared-styles\";\nimport { useNodeHasConnections } from \"../utils/node-connections\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\ninterface Data {\n mode: \"simple\" | \"full\";\n domain: {\n id: string;\n version: string;\n name: string;\n summary?: string;\n };\n systemsCount?: number;\n servicesCount?: number;\n entitiesCount?: number;\n /** The domain is a subdomain of another domain */\n subdomain?: boolean;\n /** Set to false where click is owned by the host (e.g. an editor canvas) */\n navigable?: boolean;\n}\n\nconst CARD_STYLE = {\n background: \"var(--ec-domain-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(234, 179, 8, 0.15)\",\n} as const;\n\n// Shown on the sides with edges, as on every other card\nconst GlowHandle = memo(function GlowHandle({\n side,\n}: {\n side: \"left\" | \"right\";\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #eab308, #a16207)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.domain,\n pointerEvents: \"none\",\n }}\n />\n );\n});\n\n/**\n * A domain shown as a single card (not expanded into its systems), e.g. another\n * domain on a domain's diagram. Styled like the system node, in the domain\n * colour, with counts of what the domain contains.\n * Left-clicking the card opens the domain's diagram.\n */\nexport default memo(function DomainCardNode({ data }: any) {\n const {\n domain,\n mode = \"simple\",\n systemsCount = 0,\n servicesCount = 0,\n entitiesCount = 0,\n subdomain = false,\n navigable = true,\n } = data as Data;\n const { id, version, name, summary } = domain;\n const connected = useNodeHasConnections();\n\n const stats = [\n { icon: GroupIcon, label: \"Systems\", count: systemsCount },\n { icon: ServerIcon, label: \"Services\", count: servicesCount },\n { icon: BoxIcon, label: \"Entities\", count: entitiesCount },\n ].filter((stat) => stat.count > 0);\n\n const goToDiagram = () =>\n navigateTo(buildUrl(`/visualiser/domains/${id}/${version}`));\n\n return (\n <div\n {...(navigable\n ? {\n role: \"button\" as const,\n tabIndex: 0,\n onClick: goToDiagram,\n onKeyDown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") goToDiagram();\n },\n title: `Open the ${name} diagram`,\n }\n : {})}\n className={`relative min-w-48 max-w-60 rounded-xl border-2 border-yellow-400 overflow-visible${navigable ? \" cursor-pointer\" : \"\"}`}\n style={CARD_STYLE}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Floating type badge on the top-left border */}\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-yellow-500\">\n <BoxesIcon className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n {subdomain ? \"Subdomain\" : \"Domain\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#eab308\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {stats.length > 0 && (\n <div className=\"mt-2 flex items-center gap-3 border-t border-[rgb(var(--ec-page-border))] pt-1.5\">\n {stats.map(({ icon: Icon, label, count }) => (\n <div\n key={label}\n title={`${count} ${label}`}\n className=\"flex items-center gap-1 text-[10px] text-[rgb(var(--ec-page-text-muted))]\"\n >\n <Icon className=\"w-3 h-3 text-yellow-500\" strokeWidth={2} />\n <span className=\"font-medium\">{count}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n});\n","import { memo, useMemo } from \"react\";\nimport { Handle } from \"@xyflow/react\";\nimport { Maximize2 } from \"lucide-react\";\nimport * as ContextMenu from \"@radix-ui/react-context-menu\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport { buildUrl } from \"../utils/url-builder\";\nimport { getIcon } from \"../utils/badges\";\nimport {\n NODE_WIDTH_STYLE,\n ROTATED_LABEL_STYLE,\n TINY_FONT_STYLE,\n EMPTY_ARRAY,\n} from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\ninterface FlowData {\n id: string;\n version: string;\n name: string;\n summary?: string;\n owners?: string[];\n sidebar?: {\n badge?: string;\n };\n styles?: {\n backgroundColor?: string;\n borderColor?: string;\n icon?: string;\n node?: {\n color?: string;\n label?: string;\n };\n };\n}\n\ninterface Data {\n label: string;\n bgColor: string;\n color: string;\n mode: \"simple\" | \"full\";\n flow: {\n data: FlowData;\n };\n showTarget?: boolean;\n showSource?: boolean;\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nexport default memo(function FlowNode({\n data,\n sourcePosition,\n targetPosition,\n}: any) {\n const { mode, flow } = data as Data;\n const canExpand =\n Array.isArray((data as any)?.expandedNodes) &&\n (data as any).expandedNodes.length > 0;\n\n const { id, version, owners = EMPTY_ARRAY, name, styles } = flow.data;\n const { node: { color = \"teal\", label } = {}, icon = \"QueueListIcon\" } =\n styles || {};\n\n const Icon = useMemo(() => getIcon(icon), [icon]);\n const portalContainer = usePortalContainer();\n const nodeLabel = label || flow?.data?.sidebar?.badge || \"Flow\";\n const fontSize = nodeLabel.length > 10 ? \"7px\" : \"9px\";\n\n return (\n <ContextMenu.Root>\n <ContextMenu.Trigger>\n <div\n className=\"relative\"\n style={{ isolation: \"isolate\", ...NODE_WIDTH_STYLE }}\n >\n {/* Stacked shadow layers behind the card signal a sub-flow the user can expand. */}\n {canExpand && (\n <>\n <div\n className={`absolute inset-0 rounded-md border border-${color}-400 bg-[rgb(var(--ec-card-bg))]`}\n style={{ transform: \"translate(6px, 6px)\", opacity: 0.5 }}\n aria-hidden\n />\n <div\n className={`absolute inset-0 rounded-md border border-${color}-400 bg-[rgb(var(--ec-card-bg))]`}\n style={{ transform: \"translate(3px, 3px)\", opacity: 0.7 }}\n aria-hidden\n />\n </>\n )}\n <div\n className={classNames(\n `relative rounded-md border flex justify-start bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] border-${color}-400`,\n )}\n style={NODE_WIDTH_STYLE}\n >\n <div\n className={classNames(\n `bg-gradient-to-b from-${color}-500 to-${color}-700 relative flex flex-col items-center w-5 justify-between rounded-l-sm text-${color}-100`,\n `border-r-[1px] border-${color}-500`,\n )}\n >\n {Icon && <Icon className=\"w-4 h-4 opacity-90 text-white mt-1\" />}\n {mode === \"full\" && (\n <span\n className={`text-center text-[${fontSize}] text-white font-bold uppercase mb-4`}\n style={ROTATED_LABEL_STYLE}\n >\n {nodeLabel}\n </span>\n )}\n </div>\n <div className=\"p-1 flex-1 min-w-0\">\n {targetPosition && (\n <Handle type=\"target\" position={targetPosition} />\n )}\n {sourcePosition && (\n <Handle type=\"source\" position={sourcePosition} />\n )}\n <div\n className={classNames(\n mode === \"full\"\n ? `border-b border-[rgb(var(--ec-page-border))]`\n : \"\",\n )}\n >\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#14b8a6\"\n className=\"text-xs font-bold truncate pt-0.5 pb-0.5\"\n >\n {name}\n </TruncatedResourceName>\n <div className=\"flex justify-between\">\n <span className=\"text-[10px] font-light block pt-0.5 pb-0.5 \">\n v{version}\n </span>\n {mode === \"simple\" && (\n <span className=\"text-[10px] text-[rgb(var(--ec-page-text-muted))] font-light block pt-0.5 pb-0.5 \">\n {nodeLabel}\n </span>\n )}\n </div>\n </div>\n {mode === \"full\" && (\n <div className=\"divide-y divide-[rgb(var(--ec-page-border))] \">\n <div className=\"leading-3 py-1\">\n <span className=\"text-[8px] font-light\">\n {flow.data.summary}\n </span>\n </div>\n\n <div className=\"grid grid-cols-2 gap-x-4 py-1\">\n <span className=\"text-xs\" style={TINY_FONT_STYLE}>\n Owners: {owners.length}\n </span>\n </div>\n </div>\n )}\n {canExpand && (\n <div className=\"mt-1 flex items-center gap-1 text-[8px] text-[rgb(var(--ec-page-text-muted))]\">\n <Maximize2 className=\"w-2.5 h-2.5\" />\n Click to explore\n </div>\n )}\n </div>\n </div>\n </div>\n </ContextMenu.Trigger>\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content className=\"min-w-[220px] bg-[rgb(var(--ec-card-bg))] rounded-md p-1 shadow-md border border-[rgb(var(--ec-page-border))]\">\n <ContextMenu.Item\n asChild\n className=\"text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center\"\n >\n <a href={buildUrl(`/docs/flows/${id}/${version}`)}>\n Read documentation\n </a>\n </ContextMenu.Item>\n <ContextMenu.Item\n asChild\n className=\"text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center\"\n >\n <a href={buildUrl(`/visualiser/flows/${id}/${version}`)}>\n Focus node\n </a>\n </ContextMenu.Item>\n <ContextMenu.Separator className=\"h-[1px] bg-[rgb(var(--ec-page-border))] m-1\" />\n <ContextMenu.Item asChild>\n <a\n href={buildUrl(`/docs/flows/${id}/${version}/changelog`)}\n className=\"text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Read changelog\n </a>\n </ContextMenu.Item>\n </ContextMenu.Content>\n </ContextMenu.Portal>\n </ContextMenu.Root>\n );\n});\n","import * as HeroIcons from \"@heroicons/react/24/outline\";\nimport { getIconForProtocol } from \"./protocols\";\n\nexport function getIcon(iconName: string): React.ComponentType<any> | null {\n // Try protocol icons first\n const entry = getIconForProtocol(iconName);\n if (entry) return entry.component;\n\n // Fall back to HeroIcons\n const heroIcon = HeroIcons[iconName as keyof typeof HeroIcons];\n return heroIcon || null;\n}\n","import { Server, Radio, Wifi, Network, Globe, Cloud } from \"lucide-react\";\n\n// AWS Architecture Icons (from official AWS icon set)\n// Source: https://github.com/boyney123/awsicons (MIT)\nfunction AwsEventBridge({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 40 40\" className={className}>\n <defs>\n <linearGradient x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\" id=\"eb-g\">\n <stop stopColor=\"#B0084D\" offset=\"0%\" />\n <stop stopColor=\"#FF4F8B\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <rect width=\"40\" height=\"40\" rx=\"4\" fill=\"url(#eb-g)\" />\n <path\n fill=\"#FFF\"\n d=\"M11.056 28.594a2.09 2.09 0 01-2.08-2.096 2.09 2.09 0 012.08-2.095c1.146 0 2.08.94 2.08 2.095a2.09 2.09 0 01-2.08 2.096zm1.857.363a3.093 3.093 0 001.223-2.459c0-1.711-1.382-3.103-3.08-3.103-.42 0-.817.086-1.181.24l-1.799-3.139 2.362-4.122-.865-.504-2.506 4.375a.504.504 0 000 .503l1.966 3.43a3.09 3.09 0 00-1.056 2.32c0 1.712 1.38 3.104 3.079 3.104.342 0 .665-.07.973-.174l1.531 2.844a.5.5 0 00.44.263h5.5v-1.008h-5.203l-1.385-2.57zM29.944 16.56a2.09 2.09 0 01-2.08-2.096 2.09 2.09 0 012.08-2.096 2.09 2.09 0 012.078 2.096 2.09 2.09 0 01-2.079 2.096zm2.023.224a3.095 3.095 0 001.055-2.32c0-1.711-1.38-3.104-3.079-3.104-.34 0-.662.07-.97.173L27.442 8.62A.497.497 0 0027 8.351h-5.5V9.36h5.2l1.39 2.644a3.1 3.1 0 00-1.226 2.462c0 1.71 1.381 3.103 3.08 3.103.42 0 .818-.086 1.18-.24l1.799 3.14-2.362 4.12.866.504 2.505-4.373a.504.504 0 000-.504l-1.965-3.43zm-4.573 16.207a2.09 2.09 0 01-2.08-2.095 2.09 2.09 0 012.08-2.095 2.09 2.09 0 012.079 2.095 2.09 2.09 0 01-2.08 2.095zm-9.19-8.491l-2.293-4.002 2.292-4h4.584l2.294 4-2.294 4.002h-4.584zm-4.568-12.303a2.09 2.09 0 01-2.08-2.095 2.09 2.09 0 012.08-2.095c1.146 0 2.08.94 2.08 2.095a2.09 2.09 0 01-2.08 2.095zm13.758 15.596c-.625 0-1.206.191-1.692.515l-2.07-3.267 2.46-4.29a.504.504 0 000-.504l-2.582-4.505a.498.498 0 00-.433-.252h-4.752l-2.279-3.481a3.088 3.088 0 00.67-1.907c0-1.711-1.382-3.103-3.08-3.103-1.699 0-3.08 1.392-3.08 3.103 0 1.712 1.381 3.103 3.08 3.103a3.04 3.04 0 001.668-.502l2.09 3.194-2.492 4.35a.504.504 0 000 .503l2.58 4.506a.497.497 0 00.433.252h4.828l2.218 3.505A3.092 3.092 0 0027.395 34c1.698 0 3.079-1.393 3.079-3.103 0-1.712-1.381-3.103-3.08-3.103z\"\n />\n </svg>\n );\n}\n\nfunction AwsSqs({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 40 40\" className={className}>\n <defs>\n <linearGradient x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\" id=\"sqs-g\">\n <stop stopColor=\"#B0084D\" offset=\"0%\" />\n <stop stopColor=\"#FF4F8B\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <rect width=\"40\" height=\"40\" rx=\"4\" fill=\"url(#sqs-g)\" />\n <path\n fill=\"#FFF\"\n d=\"M14.342 22.35l1.505-1.444a.501.501 0 00.013-.708l-1.505-1.555-.72.695.676.7h-2.32v.999h2.274l-.617.592.694.72zm12.016.003l1.55-1.453a.5.5 0 00.011-.717l-1.55-1.546-.708.707.694.694H24.01v.999H26.3l-.627.588.686.728zm-8.77 1.008a6.458 6.458 0 012.417-.467c.842 0 1.665.163 2.416.467-.669-1.771-.669-3.971 0-5.742-1.502.607-3.331.607-4.833 0 .669 1.77.669 3.97 0 5.742zm-1.944 1.98a.494.494 0 010-.707c1.94-1.936 1.94-6.352 0-8.289a.494.494 0 010-.706.502.502 0 01.709 0c.921.92 2.252 1.447 3.652 1.447 1.4 0 2.731-.528 3.653-1.447a.502.502 0 01.854.354c0 .128-.05.255-.146.352-1.942 1.937-1.942 6.353 0 8.29a.501.501 0 01-.708.706c-.922-.92-2.253-1.447-3.653-1.447s-2.731.527-3.652 1.447a.502.502 0 01-.709 0zm16.898-5.905a1.562 1.562 0 00-1.106-.456 1.558 1.558 0 00-1.105 2.662c.61.608 1.601.608 2.211 0a1.56 1.56 0 000-2.206zm.708 2.913a2.56 2.56 0 01-1.814.749 2.56 2.56 0 01-1.813-4.369c1-.997 2.628-.997 3.627 0 1 .999 1 2.622 0 3.62zM9.67 19.447a1.562 1.562 0 00-1.106-.456 1.56 1.56 0 00-1.105 2.662 1.56 1.56 0 102.21-2.206zm.708 2.912a2.56 2.56 0 01-1.814.749A2.559 2.559 0 016.75 18.74c1-.997 2.627-.997 3.627 0 1 .999 1 2.622 0 3.62zm17.057 6.551A10.514 10.514 0 0119.957 32a10.51 10.51 0 01-7.475-3.09c-1.316-1.312-2.074-2.44-2.537-3.774l-.947.327c.51 1.466 1.365 2.747 2.776 4.154A11.506 11.506 0 0019.957 33c3.093 0 6-1.201 8.185-3.383 1.14-1.139 2.279-2.43 2.87-4.156l-.948-.323c-.525 1.532-1.575 2.719-2.63 3.772zM9.945 15.86l-.947-.328c.512-1.467 1.368-2.749 2.778-4.156 4.51-4.5 11.85-4.502 16.362 0 1.08 1.077 2.266 2.414 2.874 4.156l-.948.328c-.54-1.55-1.635-2.78-2.634-3.777a10.508 10.508 0 00-7.473-3.087 10.508 10.508 0 00-7.472 3.087c-1.298 1.295-2.081 2.46-2.54 3.777z\"\n />\n </svg>\n );\n}\n\nfunction AwsSns({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 40 40\" className={className}>\n <defs>\n <linearGradient x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\" id=\"sns-g\">\n <stop stopColor=\"#B0084D\" offset=\"0%\" />\n <stop stopColor=\"#FF4F8B\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <rect width=\"40\" height=\"40\" rx=\"4\" fill=\"url(#sns-g)\" />\n <path\n fill=\"#FFF\"\n d=\"M7.01 20.078a1.1 1.1 0 011.105-1.093 1.1 1.1 0 011.104 1.093 1.1 1.1 0 01-1.104 1.093 1.1 1.1 0 01-1.105-1.093zM20.776 33C14.813 33 9.645 28.375 8.47 22.136a2.1 2.1 0 001.69-1.558h2.949v-1h-2.95a2.104 2.104 0 00-1.653-1.554C9.72 12.252 14.838 8 20.776 8c2.933 0 5.354.643 7.194 1.911l.575-.821C26.534 7.703 23.92 7 20.776 7c-6.51 0-12.104 4.726-13.308 11.096C6.62 18.368 6 19.149 6 20.078c0 .916.602 1.688 1.431 1.971C8.591 28.894 14.24 34 20.776 34c3.285 0 6.788-1.667 8.786-3.094l-.59-.811C26.947 31.541 23.627 33 20.777 33zM14.79 18.242c1.111.274 2.523.321 3.343.321.833 0 2.271-.047 3.402-.32l-2.401 5.014a.507.507 0 00-.048.215v2.324l-1.957.915v-3.239a.514.514 0 00-.044-.206l-2.295-5.024zm3.343-1.757c2.314 0 3.554.311 3.951.52-.417.234-1.745.558-3.95.558-2.184 0-3.483-.327-3.873-.558.37-.206 1.582-.52 3.872-.52zm-1.78 11.438a.511.511 0 00.486.03l2.968-1.388a.5.5 0 00.288-.452v-2.529l2.909-6.074a.806.806 0 00.189-.51c0-1.252-2.751-1.515-5.06-1.515-2.266 0-4.969.263-4.969 1.515 0 .19.067.355.18.502l2.775 6.077V27.5c0 .172.088.331.235.423zM30.877 27a1.1 1.1 0 011.104 1.093 1.1 1.1 0 01-1.104 1.093 1.1 1.1 0 01-1.104-1.093A1.1 1.1 0 0130.876 27zm0-16.03a1.1 1.1 0 011.104 1.093 1.1 1.1 0 01-1.104 1.093 1.1 1.1 0 01-1.104-1.093 1.1 1.1 0 011.104-1.093zm1.01 8.015a1.1 1.1 0 011.104 1.093 1.1 1.1 0 01-1.104 1.093 1.1 1.1 0 01-1.104-1.093 1.1 1.1 0 011.104-1.093zm-4.607 1.593h2.561a2.108 2.108 0 002.046 1.593A2.106 2.106 0 0034 20.078a2.106 2.106 0 00-2.114-2.093c-.992 0-1.818.681-2.046 1.593H27.28v-7.015h1.551a2.108 2.108 0 002.046 1.593 2.106 2.106 0 002.114-2.093 2.106 2.106 0 00-2.114-2.093c-.991 0-1.818.681-2.046 1.593h-2.056a.502.502 0 00-.505.5v7.515h-3.061v1h3.061v7.515c0 .277.226.5.505.5h2.056a2.108 2.108 0 002.046 1.593 2.106 2.106 0 002.114-2.093A2.106 2.106 0 0030.876 26c-.991 0-1.818.681-2.046 1.593H27.28v-7.015z\"\n />\n </svg>\n );\n}\n\n// Icon type: \"svg\" = full self-contained SVG, \"lucide\" = Lucide component (needs wrapper)\ntype IconEntry = { component: any; type: \"svg\" | \"lucide\" };\n\n// Map protocol names to icons\nconst protocolIconMap: { [key: string]: IconEntry } = {\n // Web protocols\n http: { component: Server, type: \"lucide\" },\n https: { component: Server, type: \"lucide\" },\n ws: { component: Radio, type: \"lucide\" },\n wss: { component: Radio, type: \"lucide\" },\n websocket: { component: Radio, type: \"lucide\" },\n\n // Messaging protocols\n mqtt: { component: Wifi, type: \"lucide\" },\n amqp: { component: Network, type: \"lucide\" },\n grpc: { component: Globe, type: \"lucide\" },\n graphql: { component: Globe, type: \"lucide\" },\n\n // Message brokers\n kafka: { component: Network, type: \"lucide\" },\n rabbitmq: { component: Network, type: \"lucide\" },\n redis: { component: Network, type: \"lucide\" },\n nats: { component: Network, type: \"lucide\" },\n pulsar: { component: Network, type: \"lucide\" },\n solace: { component: Network, type: \"lucide\" },\n activemq: { component: Network, type: \"lucide\" },\n\n // AWS\n sqs: { component: AwsSqs, type: \"svg\" },\n sns: { component: AwsSns, type: \"svg\" },\n eventbridge: { component: AwsEventBridge, type: \"svg\" },\n kinesis: { component: Network, type: \"lucide\" },\n msk: { component: Network, type: \"lucide\" },\n\n // Google Cloud\n pubsub: { component: Cloud, type: \"lucide\" },\n googlepubsub: { component: Cloud, type: \"lucide\" },\n cloudtasks: { component: Cloud, type: \"lucide\" },\n\n // Azure\n servicebus: { component: Cloud, type: \"lucide\" },\n azureservicebus: { component: Cloud, type: \"lucide\" },\n eventhubs: { component: Cloud, type: \"lucide\" },\n azureeventhubs: { component: Cloud, type: \"lucide\" },\n eventgrid: { component: Cloud, type: \"lucide\" },\n azureeventgrid: { component: Cloud, type: \"lucide\" },\n};\n\nexport const getIconForProtocol = (protocol?: string): IconEntry | null => {\n if (!protocol) return null;\n const normalizedProtocol = protocol.replace(/[-_\\s]/g, \"\").toLowerCase();\n return protocolIconMap[normalizedProtocol] || null;\n};\n","import { memo } from \"react\";\nimport { Workflow, Minimize2 } from \"lucide-react\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\nexport type FlowExpandedNodeData = {\n flowName?: string;\n version?: string;\n};\n\n// Container body keeps a visible teal tint that works in both themes — the\n// teal is the sub-flow identity, while theme-aware variables handle text\n// and header colour. The header uses the card-bg variable so it blends\n// naturally over the dotted background in light and dark modes.\nconst CONTAINER_STYLE: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n borderRadius: 12,\n border: \"2px solid rgba(20, 184, 166, 0.5)\",\n backgroundColor: \"rgba(20, 184, 166, 0.08)\",\n boxShadow: \"0 2px 12px rgba(20, 184, 166, 0.12)\",\n position: \"relative\",\n overflow: \"visible\",\n};\n\nconst HEADER_STYLE: React.CSSProperties = {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n height: 44,\n borderTopLeftRadius: 10,\n borderTopRightRadius: 10,\n background: \"rgba(20, 184, 166, 0.12)\",\n borderBottom: \"1px solid rgba(20, 184, 166, 0.3)\",\n overflow: \"visible\",\n};\n\nconst BADGE_STYLE: React.CSSProperties = {\n position: \"absolute\",\n top: -10,\n left: 12,\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 3,\n padding: \"2px 8px\",\n borderRadius: 4,\n background: \"#0d9488\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n zIndex: 10,\n fontSize: 8,\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\" as const,\n color: \"white\",\n};\n\nconst HEADER_CONTENT_STYLE: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n height: \"100%\",\n padding: \"0 12px 0 14px\",\n gap: 12,\n};\n\nconst FLOW_NAME_STYLE: React.CSSProperties = {\n fontSize: 11,\n fontWeight: 700,\n color: \"rgb(var(--ec-page-text))\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n};\n\nconst VERSION_STYLE: React.CSSProperties = {\n fontSize: 10,\n fontWeight: 500,\n color: \"#5eead4\",\n marginLeft: 8,\n};\n\nconst COLLAPSE_BUTTON_STYLE: React.CSSProperties = {\n background: \"#0d9488\",\n border: \"1px solid #5eead4\",\n borderRadius: 6,\n padding: \"4px 10px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 10,\n fontWeight: 600,\n color: \"white\",\n};\n\nexport default memo(function FlowExpandedNode({\n data,\n}: {\n data: FlowExpandedNodeData;\n}) {\n const { flowName, version } = data;\n\n return (\n <div style={CONTAINER_STYLE}>\n <div style={HEADER_STYLE}>\n <div style={BADGE_STYLE}>\n <Workflow size={10} strokeWidth={2.5} />\n Sub-flow\n </div>\n\n <div style={HEADER_CONTENT_STYLE}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0,\n flex: 1,\n }}\n >\n <TruncatedResourceName\n value={flowName || \"Flow\"}\n tooltipBorderColor=\"#14b8a6\"\n className=\"truncate\"\n style={FLOW_NAME_STYLE}\n >\n {flowName || \"Flow\"}\n </TruncatedResourceName>\n {version && <span style={VERSION_STYLE}>v{version}</span>}\n </div>\n\n <button\n style={COLLAPSE_BUTTON_STYLE}\n className=\"ec-collapse-flow-btn nodrag nopan\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n <Minimize2 size={12} strokeWidth={2.5} />\n Collapse\n </button>\n </div>\n </div>\n </div>\n );\n});\n","import { Handle, Position, useUpdateNodeInternals } from \"@xyflow/react\";\nimport { getIcon } from \"../utils/badges\";\nimport * as ContextMenu from \"@radix-ui/react-context-menu\";\nimport { buildUrl } from \"../utils/url-builder\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ChevronDownIcon, ChevronRightIcon } from \"@heroicons/react/20/solid\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport {\n HANDLE_LEFT_OFFSET_STYLE,\n HANDLE_RIGHT_OFFSET_STYLE,\n EMPTY_ARRAY,\n} from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\nexport const ENTITY_TARGET_HANDLE_ID = \"__eventcatalog-entity-target\";\n\nexport interface EntityProperty {\n name: string;\n type: string;\n required?: boolean;\n description?: string;\n references?: string;\n referencesIdentifier?: string;\n referenceTarget?: \"entity\";\n relationType?: string;\n enum?: string[];\n properties?: EntityProperty[];\n items?: {\n type: string;\n properties?: EntityProperty[];\n };\n}\n\ninterface EntityData {\n id: string;\n name: string;\n version: string;\n properties?: EntityProperty[];\n aggregateRoot?: boolean;\n sidebar?: any;\n styles?: {\n backgroundColor?: string;\n borderColor?: string;\n icon?: string;\n node?: {\n color?: string;\n label?: string;\n };\n };\n}\n\ninterface Data {\n title: string;\n label: string;\n bgColor: string;\n color: string;\n mode: \"simple\" | \"full\";\n entity: {\n data: EntityData;\n };\n showTarget?: boolean;\n showSource?: boolean;\n externalToDomain?: boolean;\n domainName?: string;\n domainId?: string;\n entityTargetHandle?: string;\n referencePropertyNames?: string[];\n group?: {\n type: string;\n value: string;\n };\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nexport const getPropertyTypeLabel = (property: any) => {\n if (property.type === \"array\" && property.items?.type) {\n return `${property.items.type}[]`;\n }\n\n return property.type;\n};\n\nexport const getNestedEntityProperties = (\n property: EntityProperty,\n): EntityProperty[] => {\n if (property.properties?.length) return property.properties;\n if (property.type === \"array\" && property.items?.properties?.length) {\n return property.items.properties;\n }\n return [];\n};\n\nexport default memo(function EntityNode({\n id,\n data,\n sourcePosition,\n targetPosition,\n}: any) {\n const {\n mode,\n entity,\n externalToDomain,\n domainName,\n entityTargetHandle = ENTITY_TARGET_HANDLE_ID,\n referencePropertyNames = EMPTY_ARRAY,\n } = data as Data;\n const {\n name,\n version,\n properties = EMPTY_ARRAY,\n aggregateRoot,\n styles,\n sidebar: _sidebar,\n } = entity.data;\n\n const {\n node: { color: _color = \"blue\", label: _label } = {},\n icon = \"CubeIcon\",\n } = styles || {};\n\n const Icon = useMemo(() => getIcon(icon), [icon]);\n\n const [hoveredProperty, setHoveredProperty] = useState<string | null>(null);\n const [expandedProperties, setExpandedProperties] = useState<Set<string>>(\n () => new Set(),\n );\n const previousExpandedProperties = useRef(expandedProperties);\n const updateNodeInternals = useUpdateNodeInternals();\n const portalContainer = usePortalContainer();\n const referenceProperties = useMemo(\n () => new Set(referencePropertyNames),\n [referencePropertyNames],\n );\n\n const toggleProperty = useCallback((propertyPath: string) => {\n setExpandedProperties((current) => {\n const next = new Set(current);\n if (next.has(propertyPath)) {\n next.delete(propertyPath);\n } else {\n next.add(propertyPath);\n }\n return next;\n });\n }, []);\n\n useEffect(() => {\n if (previousExpandedProperties.current === expandedProperties) return;\n previousExpandedProperties.current = expandedProperties;\n updateNodeInternals(id);\n }, [expandedProperties, id, updateNodeInternals]);\n\n const renderPropertyRows = (\n entityProperties: EntityProperty[],\n depth = 0,\n parentPath = \"\",\n ): React.ReactNode =>\n entityProperties.map((property, index) => {\n const propertyPath = parentPath\n ? `${parentPath}.${property.name}`\n : property.name;\n const propertyKey = `${propertyPath}-${index}`;\n const isHovered = hoveredProperty === propertyKey;\n const nestedProperties = getNestedEntityProperties(property);\n const isExpandable = nestedProperties.length > 0;\n const isExpanded = expandedProperties.has(propertyPath);\n const isTopLevel = depth === 0;\n const referencedEntityId =\n property.references ||\n (isTopLevel && referenceProperties.has(property.name)\n ? property.items?.type\n : undefined);\n\n return (\n <div key={propertyKey}>\n <div\n className={classNames(\n \"relative flex items-center justify-between py-2 pr-4 hover:bg-[rgb(var(--ec-page-border)/0.2)]\",\n isExpandable && \"nodrag nopan cursor-pointer\",\n )}\n style={{ paddingLeft: `${16 + depth * 16}px` }}\n role={isExpandable ? \"button\" : undefined}\n tabIndex={isExpandable ? 0 : undefined}\n aria-label={\n isExpandable\n ? `${isExpanded ? \"Collapse\" : \"Expand\"} ${property.name}`\n : undefined\n }\n aria-expanded={isExpandable ? isExpanded : undefined}\n onClick={(event) => {\n if (!isExpandable) return;\n const target = event.target as HTMLElement;\n if (target.closest(\".react-flow__handle\")) return;\n toggleProperty(propertyPath);\n }}\n onKeyDown={(event) => {\n if (!isExpandable || (event.key !== \"Enter\" && event.key !== \" \"))\n return;\n event.preventDefault();\n toggleProperty(propertyPath);\n }}\n onMouseEnter={() =>\n property.description && setHoveredProperty(propertyKey)\n }\n onMouseLeave={() => setHoveredProperty(null)}\n >\n {isTopLevel && (\n <>\n <Handle\n type=\"target\"\n position={Position.Left}\n id={`${property.name}-target`}\n className=\"!w-3 !h-3 !bg-[rgb(var(--ec-card-bg))] !border-2 !border-[rgb(var(--ec-page-border))] !rounded-full !left-[-0px]\"\n style={HANDLE_LEFT_OFFSET_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n id={`${property.name}-source`}\n className=\"!w-3 !h-3 !bg-[rgb(var(--ec-card-bg))] !border-2 !border-[rgb(var(--ec-page-border))] !rounded-full !right-[-0px]\"\n style={HANDLE_RIGHT_OFFSET_STYLE}\n />\n </>\n )}\n\n <div className=\"flex-1 flex items-center justify-between gap-3 min-w-0\">\n <div className=\"flex items-center gap-1 min-w-0\">\n {isExpandable && (\n <span\n className=\"shrink-0 text-[rgb(var(--ec-page-text-muted))]\"\n aria-hidden=\"true\"\n >\n {isExpanded ? (\n <ChevronDownIcon className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRightIcon className=\"h-3.5 w-3.5\" />\n )}\n </span>\n )}\n <span className=\"text-sm font-medium text-[rgb(var(--ec-page-text))] truncate\">\n {property.name}\n </span>\n {property.required && (\n <span className=\"text-red-500 text-xs\">*</span>\n )}\n </div>\n <span className=\"text-sm text-[rgb(var(--ec-page-text-muted))] font-mono shrink-0\">\n {getPropertyTypeLabel(property)}\n </span>\n </div>\n\n {referencedEntityId && (\n <div className=\"absolute right-2 top-1/2 transform -translate-y-1/2\">\n <div\n className=\"w-2 h-2 bg-blue-500 rounded-full\"\n title={`References ${referencedEntityId}`}\n ></div>\n </div>\n )}\n\n {isHovered && property.description && (\n <div className=\"absolute left-full ml-2 top-1/2 transform -translate-y-1/2 z-[9999] w-[200px] bg-gray-900 text-white text-xs rounded-lg py-2 px-3 pointer-events-none shadow-xl max-w-xl opacity-100\">\n <div className=\"text-gray-200 whitespace-normal break-words\">\n {property.description}\n </div>\n <div className=\"absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900\"></div>\n </div>\n )}\n </div>\n\n {isExpandable && isExpanded && (\n <div className=\"divide-y divide-[rgb(var(--ec-page-border))] border-t border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-content-hover)/0.18)]\">\n {renderPropertyRows(nestedProperties, depth + 1, propertyPath)}\n </div>\n )}\n </div>\n );\n });\n\n return (\n <ContextMenu.Root>\n <ContextMenu.Trigger>\n <div\n className={classNames(\n \"bg-[rgb(var(--ec-card-bg))] border rounded-lg shadow-sm min-w-[200px]\",\n externalToDomain ? \"border-amber-500/60\" : \"border-blue-400/50\",\n )}\n >\n {/* Table Header */}\n <div\n className={classNames(\n \"relative px-4 py-2 rounded-t-lg border-b border-[rgb(var(--ec-page-border))]\",\n externalToDomain ? \"bg-amber-500/20\" : \"bg-blue-500/15\",\n )}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n id={entityTargetHandle}\n className=\"!w-3 !h-3 !bg-[rgb(var(--ec-card-bg))] !border-2 !border-[rgb(var(--ec-page-border))] !rounded-full !left-[-0px]\"\n style={HANDLE_LEFT_OFFSET_STYLE}\n />\n <div className=\"flex items-center gap-2 min-w-0\">\n {Icon && (\n <Icon className=\"w-4 h-4 text-[rgb(var(--ec-page-text-muted))]\" />\n )}\n <TruncatedResourceName\n value={name}\n tooltipBorderColor={externalToDomain ? \"#f59e0b\" : \"#60a5fa\"}\n className=\"font-semibold text-[rgb(var(--ec-page-text))] text-sm truncate\"\n >\n {name}\n </TruncatedResourceName>\n {aggregateRoot && (\n <span className=\"text-xs bg-amber-500/20 text-amber-600 dark:text-amber-400 px-1.5 py-0.5 rounded font-medium shrink-0\">\n AR\n </span>\n )}\n </div>\n {domainName && (\n <div className=\"text-xs text-[rgb(var(--ec-page-text-muted))] font-medium mt-1\">\n from {domainName} domain\n </div>\n )}\n {mode === \"full\" && (\n <div className=\"text-xs text-[rgb(var(--ec-page-text-muted))] mt-1\">\n v{version}\n </div>\n )}\n </div>\n\n {/* Properties Table */}\n {properties.length > 0 ? (\n <div className=\"divide-y divide-[rgb(var(--ec-page-border))] relative\">\n {renderPropertyRows(properties)}\n </div>\n ) : (\n <div className=\"px-4 py-3 text-sm text-[rgb(var(--ec-page-text-muted))] text-center\">\n No properties defined\n </div>\n )}\n\n {/* Main node handles (if no properties) */}\n {properties.length === 0 && (\n <>\n {targetPosition && (\n <Handle type=\"target\" position={targetPosition} />\n )}\n {sourcePosition && (\n <Handle type=\"source\" position={sourcePosition} />\n )}\n </>\n )}\n </div>\n </ContextMenu.Trigger>\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content\n className=\"min-w-[220px] bg-[rgb(var(--ec-card-bg))] rounded-md p-1 shadow-md border border-[rgb(var(--ec-page-border))]\"\n onClick={(e) => e.stopPropagation()}\n >\n <ContextMenu.Item\n asChild\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-accent-subtle))] rounded-sm flex items-center\"\n >\n <a href={buildUrl(`/docs/entities/${entity.data.id}/${version}`)}>\n Read documentation\n </a>\n </ContextMenu.Item>\n <ContextMenu.Item\n asChild\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-accent-subtle))] rounded-sm flex items-center\"\n >\n <a\n href={buildUrl(\n `/visualiser/entities/${entity.data.id}/${version}`,\n )}\n >\n Focus node\n </a>\n </ContextMenu.Item>\n </ContextMenu.Content>\n </ContextMenu.Portal>\n </ContextMenu.Root>\n );\n});\n","import { memo } from \"react\";\nimport { UserIcon } from \"@heroicons/react/20/solid\";\nimport { Handle } from \"@xyflow/react\";\nimport { NODE_WIDTH_STYLE, ROTATED_LABEL_STYLE } from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\ninterface Data {\n title: string;\n label: string;\n bgColor: string;\n color: string;\n mode: \"simple\" | \"full\";\n step: {\n id: string;\n title: string;\n summary: string;\n name: string;\n actor: { name: string };\n };\n showTarget?: boolean;\n showSource?: boolean;\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nexport default memo(function UserNode({\n data,\n sourcePosition,\n targetPosition,\n}: any) {\n const {\n mode,\n step,\n showTarget: _showTarget = true,\n showSource: _showSource = true,\n } = data as Data;\n\n const { summary, actor: { name } = {} } = step;\n const displayName = name || step.name || step.title || \"Actor\";\n\n return (\n <div\n className={classNames(\n `rounded-md border flex justify-start bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] border-yellow-400`,\n mode === \"full\" ? \"min-h-[5em]\" : \"min-h-[2em]\",\n )}\n style={NODE_WIDTH_STYLE}\n >\n <div\n className={classNames(\n \"bg-gradient-to-b from-yellow-400 to-yellow-600 relative flex flex-col items-center w-5 justify-between rounded-l-sm text-orange-100-500\",\n `border-r-[1px] border-yellow-500`,\n )}\n >\n <UserIcon className=\"w-4 h-4 opacity-90 text-white mt-1\" />\n {mode === \"full\" && (\n <span\n className=\"text-center text-[9px] text-white font-bold uppercase mb-4\"\n style={ROTATED_LABEL_STYLE}\n >\n ACTOR\n </span>\n )}\n </div>\n <div className=\"p-1 flex-1 min-w-0\">\n {targetPosition && <Handle type=\"target\" position={targetPosition} />}\n {sourcePosition && <Handle type=\"source\" position={sourcePosition} />}\n\n {(!summary || mode !== \"full\") && (\n <div className=\"h-full min-w-0\">\n <TruncatedResourceName\n as=\"div\"\n value={displayName}\n tooltipBorderColor=\"#eab308\"\n className=\"text-sm font-bold truncate pb-0.5\"\n >\n {displayName}\n </TruncatedResourceName>\n {mode === \"simple\" && (\n <div className=\"w-full text-right\">\n <span className=\" w-full text-[10px] text-[rgb(var(--ec-page-text-muted))] font-light block pt-0.5 pb-0.5 \">\n Event\n </span>\n </div>\n )}\n </div>\n )}\n\n {summary && mode === \"full\" && (\n <div>\n <div\n className={classNames(\n mode === \"full\"\n ? `border-b border-[rgb(var(--ec-page-border))]`\n : \"\",\n )}\n >\n <TruncatedResourceName\n as=\"div\"\n value={displayName}\n tooltipBorderColor=\"#eab308\"\n className=\"text-xs font-bold truncate pb-0.5\"\n >\n {displayName}\n </TruncatedResourceName>\n </div>\n {mode === \"full\" && (\n <div className=\"divide-y divide-[rgb(var(--ec-page-border))] \">\n <div className=\"leading-3 py-1\">\n <span className=\"text-[8px] font-light\">{summary}</span>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { NODE_WIDTH_STYLE, ROTATED_LABEL_STYLE } from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\ninterface Data {\n title: string;\n label: string;\n bgColor: string;\n color: string;\n mode: \"simple\" | \"full\";\n step: { id: string; title: string; summary: string };\n showTarget?: boolean;\n showSource?: boolean;\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\nexport default memo(function StepNode({\n data,\n sourcePosition,\n targetPosition,\n}: any) {\n const { mode, step } = data as Data;\n\n const { title, summary } = step;\n\n return (\n <div\n className={classNames(\n \"rounded-md border flex justify-start bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] border-blue-400 min-h-[3em]\",\n )}\n style={NODE_WIDTH_STYLE}\n >\n <div\n className={classNames(\n \"bg-gradient-to-b from-gray-700 to-gray-700 relative flex flex-col items-center w-5 justify-end rounded-l-sm text-orange-100-500\",\n `border-r-[1px] border-gray-500`,\n )}\n >\n {mode === \"full\" && (\n <span\n className=\"text-center text-[9px] text-white font-bold uppercase mb-4\"\n style={ROTATED_LABEL_STYLE}\n >\n Step\n </span>\n )}\n </div>\n <div className=\"p-1 flex-1 min-w-0\">\n <Handle\n type=\"target\"\n position={targetPosition || Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={sourcePosition || Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n\n {!summary && (\n <div className=\"h-full flex items-center min-w-0\">\n <TruncatedResourceName\n as=\"div\"\n value={title}\n tooltipBorderColor=\"#60a5fa\"\n className=\"text-sm font-bold truncate pb-0.5\"\n >\n {title}\n </TruncatedResourceName>\n </div>\n )}\n\n {summary && (\n <div>\n <div\n className={classNames(\n mode === \"full\"\n ? `border-b border-[rgb(var(--ec-page-border))]`\n : \"\",\n )}\n >\n <TruncatedResourceName\n as=\"div\"\n value={title}\n tooltipBorderColor=\"#60a5fa\"\n className=\"text-xs font-bold truncate pb-0.5\"\n >\n {title}\n </TruncatedResourceName>\n </div>\n {mode === \"full\" && (\n <div className=\"divide-y divide-[rgb(var(--ec-page-border))] \">\n <div className=\"leading-3 py-1\">\n <span className=\"text-[8px] font-light\">{summary}</span>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n","import {\n Handle,\n useReactFlow,\n useOnSelectionChange,\n Position,\n} from \"@xyflow/react\";\nimport * as ContextMenu from \"@radix-ui/react-context-menu\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport { buildUrl } from \"../utils/url-builder\";\nimport { getIcon } from \"../utils/badges\";\nimport { memo, useState, useCallback, useMemo } from \"react\";\nimport { HANDLE_LEFT_STYLE, HANDLE_RIGHT_STYLE } from \"./shared-styles\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\n\ninterface DomainData {\n id: string;\n version: string;\n name: string;\n services?: string[];\n styles?: {\n backgroundColor?: string;\n borderColor?: string;\n icon?: string;\n };\n}\n\ninterface Data {\n mode: \"simple\" | \"full\";\n domain: {\n data: DomainData;\n };\n}\n\nexport default memo(function DomainNode({ data, id: nodeId }: any) {\n const { mode, domain } = data as Data;\n const reactFlow = useReactFlow();\n const [highlightedServices, setHighlightedServices] = useState<Set<string>>(\n new Set(),\n );\n\n const { id, version, name, services = [], styles } = domain.data;\n const { icon = \"RectangleGroupIcon\" } = styles || {};\n\n const Icon = useMemo(() => getIcon(icon), [icon]);\n const ServerIcon = useMemo(() => getIcon(\"ServerIcon\"), []);\n const portalContainer = usePortalContainer();\n\n // Every domain hears every selection change: it only re-renders when what it highlights changes\n const highlight = useCallback(\n (ids: Set<string>) =>\n setHighlightedServices((current) =>\n current.size === ids.size && [...ids].every((id) => current.has(id))\n ? current\n : ids,\n ),\n [],\n );\n\n // Listen for selection changes to highlight connected services\n const handleSelectionChange = useCallback(\n ({ nodes: selectedNodes }: { nodes: any[] }) => {\n const selectedNode = selectedNodes[0];\n if (!selectedNode) {\n highlight(new Set());\n return;\n }\n\n // Get all edges\n const edges = reactFlow.getEdges();\n const connectedServiceIds = new Set<string>();\n\n // Find services connected to the selected node\n edges.forEach((edge) => {\n if (\n edge.source === selectedNode.id ||\n edge.target === selectedNode.id\n ) {\n // Check if this edge connects to our domain\n if (edge.source === nodeId && edge.sourceHandle) {\n // Extract service ID from sourceHandle (format: \"serviceId-source\")\n const serviceId = edge.sourceHandle.replace(\"-source\", \"\");\n connectedServiceIds.add(serviceId);\n }\n if (edge.target === nodeId && edge.targetHandle) {\n // Extract service ID from targetHandle (format: \"serviceId-target\")\n const serviceId = edge.targetHandle.replace(\"-target\", \"\");\n connectedServiceIds.add(serviceId);\n }\n }\n });\n\n highlight(connectedServiceIds);\n },\n [nodeId, reactFlow, highlight],\n );\n\n useOnSelectionChange({\n onChange: handleSelectionChange,\n });\n\n return (\n <ContextMenu.Root>\n <ContextMenu.Trigger>\n <div className=\"w-full rounded-lg border-2 border-yellow-400 bg-[rgb(var(--ec-card-bg))] shadow-lg\">\n {/* Lets edges connect to the domain itself, not only its services */}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n <div className=\"bg-[rgb(var(--ec-domain-header-bg,253_224_71)/0.2)] px-3 py-2 flex items-center space-x-2\">\n {Icon && <Icon className=\"w-4 h-4 text-yellow-500\" />}\n <div>\n <span className=\"text-sm font-bold text-[rgb(var(--ec-page-text))]\">\n {name}\n </span>\n <span className=\"text-xs text-yellow-500 ml-2\">v{version}</span>\n </div>\n </div>\n {mode === \"full\" && services.length > 0 && (\n <div>\n {services.map((service: any, index: number) => {\n const isHighlighted = highlightedServices.has(service.data.id);\n\n return (\n <ContextMenu.Root key={`${service.data.id}-${index}`}>\n <ContextMenu.Trigger asChild>\n <div\n className={`relative flex items-center justify-between px-3 py-2 cursor-pointer ${index !== services.length - 1 ? \"border-b border-[rgb(var(--ec-page-border))]\" : \"\"} ${isHighlighted ? \"bg-pink-100 border-pink-300\" : \"\"}`}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n id={`${service.data.id}-target`}\n className=\"!left-[-1px] !w-2 !h-2 !bg-gray-400 !border !border-gray-500 !rounded-full !z-10\"\n style={HANDLE_LEFT_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n id={`${service.data.id}-source`}\n className=\"!right-[-1px] !w-2 !h-2 !bg-gray-400 !border !border-gray-500 !rounded-full !z-10\"\n style={HANDLE_RIGHT_STYLE}\n />\n <div className=\"flex items-center space-x-3\">\n <div className=\"flex items-center justify-center w-5 h-5 bg-pink-500 rounded\">\n {ServerIcon && (\n <ServerIcon className=\"w-3 h-3 text-white\" />\n )}\n </div>\n <span className=\"text-sm font-medium text-[rgb(var(--ec-page-text))]\">\n {service.data.name || service.data.id}\n </span>\n </div>\n <div className=\"flex items-center space-x-4 text-sm text-[rgb(var(--ec-page-text-muted))]\">\n <span className=\"text-xs\">\n v{service.data.version}\n </span>\n </div>\n </div>\n </ContextMenu.Trigger>\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content className=\"min-w-[220px] bg-[rgb(var(--ec-card-bg))] rounded-md p-1 shadow-md border border-[rgb(var(--ec-page-border))]\">\n <ContextMenu.Item\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-page-border)/0.5)] rounded-sm flex items-center\"\n onClick={() =>\n (window.location.href = buildUrl(\n `/docs/services/${service.data.id}/${service.data.version}`,\n ))\n }\n >\n View Service Documentation\n </ContextMenu.Item>\n <ContextMenu.Item\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-page-border)/0.5)] rounded-sm flex items-center\"\n onClick={() =>\n (window.location.href = buildUrl(\n `/visualiser/services/${service.data.id}/${service.data.version}`,\n ))\n }\n >\n View Service Visualizer\n </ContextMenu.Item>\n </ContextMenu.Content>\n </ContextMenu.Portal>\n </ContextMenu.Root>\n );\n })}\n </div>\n )}\n </div>\n </ContextMenu.Trigger>\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content className=\"min-w-[220px] bg-[rgb(var(--ec-card-bg))] rounded-md p-1 shadow-md border border-[rgb(var(--ec-page-border))]\">\n <ContextMenu.Item\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-page-border)/0.5)] rounded-sm flex items-center\"\n onClick={() =>\n (window.location.href = buildUrl(\n `/docs/domains/${id}/${version}`,\n ))\n }\n >\n View Domain Documentation\n </ContextMenu.Item>\n <ContextMenu.Item\n className=\"text-sm text-[rgb(var(--ec-page-text))] px-2 py-1.5 outline-none cursor-pointer hover:bg-[rgb(var(--ec-page-border)/0.5)] rounded-sm flex items-center\"\n onClick={() =>\n (window.location.href = buildUrl(\n `/visualiser/domains/${id}/${version}`,\n ))\n }\n >\n View Domain Visualizer\n </ContextMenu.Item>\n </ContextMenu.Content>\n </ContextMenu.Portal>\n </ContextMenu.Root>\n );\n});\n","import { Handle, Position } from \"@xyflow/react\";\nimport {\n Group as GroupIcon,\n Server as ServerIcon,\n Box as BoxIcon,\n Database as DatabaseIcon,\n MessageSquare as MessageSquareIcon,\n} from \"lucide-react\";\nimport { buildUrl, navigateTo } from \"../utils/url-builder\";\nimport { memo, type KeyboardEvent } from \"react\";\nimport { LINE_CLAMP_STYLE, useDarkMode } from \"./shared-styles\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\nimport { FocusedResourceIndicator } from \"./FocusedResourceIndicator\";\n\ninterface SystemData {\n id: string;\n version: string;\n name: string;\n summary?: string;\n // \"external\" marks a third-party/SaaS system (e.g. Resend, Stripe). Such\n // systems are shaded in the graph. Defaults to internal when absent.\n scope?: \"internal\" | \"external\";\n}\n\ninterface Data {\n mode: \"simple\" | \"full\";\n system: SystemData;\n servicesCount?: number;\n entitiesCount?: number;\n containersCount?: number;\n // Total messages handled by the system's services (sends + receives).\n messagesCount?: number;\n // The system being viewed on this page\n isFocused?: boolean;\n // Set to false where click is owned by the host (e.g. an editor canvas)\n navigable?: boolean;\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\n/**\n * A system rendered on the System Diagram.\n *\n * Styled to match the other resource nodes (e.g. the service node): a rounded,\n * bordered card with a floating type badge + icon on the top-left border.\n * Left-clicking the node navigates to the system's architecture map.\n * Right-click (handled by the NodeGraph context-menu wrapper) offers docs / map / context.\n */\nexport default memo(function SystemNode({ data }: any) {\n const {\n system,\n mode = \"simple\",\n servicesCount = 0,\n entitiesCount = 0,\n containersCount = 0,\n messagesCount = 0,\n isFocused = false,\n navigable = true,\n } = data as Data;\n const { id, version, name, summary, scope } = system;\n const isExternal = scope === \"external\";\n const isDark = useDarkMode();\n // Flow diagrams already own click (walkthrough / selection). A system step\n // links to its docs through the context menu, same as a service step, instead\n // of leaving the flow for the system map.\n const isFlowStep = Boolean((data as { step?: unknown }).step);\n const opensMap = navigable && !isFlowStep;\n\n const stats = [\n { icon: ServerIcon, label: \"Services\", count: servicesCount },\n { icon: MessageSquareIcon, label: \"Messages\", count: messagesCount },\n { icon: BoxIcon, label: \"Entities\", count: entitiesCount },\n { icon: DatabaseIcon, label: \"Data Stores\", count: containersCount },\n ].filter((stat) => stat.count > 0);\n\n // External systems get a subtle gray fill so they read as outside the org,\n // without the busier striped treatment.\n const cardBackground = isExternal\n ? isDark\n ? \"rgba(148,163,184,0.12)\"\n : \"rgba(148,163,184,0.1)\"\n : \"var(--ec-system-node-bg, rgb(var(--ec-card-bg)))\";\n\n const goToMap = () => {\n // Soft, animated navigation via the host's view-transition router when\n // available (falls back to a hard nav). Both the System Diagram and\n // the target system Map share a `transition:name=\"visualiser-graph\"` portal,\n // so this reads as drilling one level deeper into the system.\n navigateTo(buildUrl(`/visualiser/systems/${id}/${version}`));\n };\n\n return (\n <div\n {...(!opensMap\n ? {}\n : {\n role: \"button\" as const,\n tabIndex: 0,\n onClick: goToMap,\n onKeyDown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") goToMap();\n },\n title: `Open the ${name} map`,\n })}\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n opensMap && \"cursor-pointer\",\n isExternal ? \"border-dashed border-violet-400\" : \"border-violet-500\",\n )}\n style={{\n background: cardBackground,\n boxShadow: \"0 2px 12px rgba(139, 92, 246, 0.15)\",\n }}\n >\n {isFocused && <FocusedResourceIndicator />}\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n\n {/* Floating type badge on the top-left border */}\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-violet-500\">\n <GroupIcon className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n {isExternal ? \"External System\" : \"System\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#8b5cf6\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n\n {mode === \"full\" && summary && (\n <div\n className={classNames(\n \"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\",\n )}\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {stats.length > 0 && (\n <div className=\"mt-2 flex items-center gap-3 border-t border-[rgb(var(--ec-page-border))] pt-1.5\">\n {stats.map(({ icon: Icon, label, count }) => (\n <div\n key={label}\n title={`${count} ${label}`}\n className=\"flex items-center gap-1 text-[10px] text-[rgb(var(--ec-page-text-muted))]\"\n >\n <Icon className=\"w-3 h-3 text-violet-500\" strokeWidth={2} />\n <span className=\"font-medium\">{count}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport { BoxesIcon } from \"lucide-react\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\nexport type GroupNodeData = {\n mode: string;\n domain: {\n name: string;\n version: string;\n summary: string;\n };\n};\n\nconst GROUP_CONTAINER_STYLE = {\n width: \"100%\",\n height: \"100%\",\n borderRadius: 12,\n border: \"2px solid var(--ec-group-border, #c4b5fd)\",\n backgroundColor: \"var(--ec-group-bg, rgba(250, 248, 255, 0.35))\",\n position: \"relative\" as const,\n overflow: \"visible\" as const,\n} as const;\n\nconst GROUP_HEADER_STYLE = {\n position: \"absolute\" as const,\n top: 0,\n left: 0,\n right: 0,\n height: 44,\n borderTopLeftRadius: 10,\n borderTopRightRadius: 10,\n background: \"var(--ec-group-header-bg, rgba(237, 233, 254, 0.7))\",\n borderBottom: \"1px solid var(--ec-group-border, #c4b5fd)\",\n overflow: \"visible\" as const,\n} as const;\n\nconst GROUP_WATERMARK_STYLE = {\n position: \"absolute\" as const,\n top: 6,\n right: 10,\n opacity: 0.12,\n transform: \"rotate(12deg)\",\n pointerEvents: \"none\" as const,\n} as const;\n\nconst GROUP_ICON_CIRCLE_STYLE = {\n position: \"absolute\" as const,\n top: -14,\n left: 12,\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n background: \"#7c3aed\",\n border: \"2px solid #a78bfa\",\n display: \"flex\",\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n boxShadow: \"0 1px 3px rgba(0,0,0,0.1)\",\n zIndex: 10,\n} as const;\n\nconst GROUP_BANNER_CONTENT_STYLE = {\n display: \"flex\",\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n height: \"100%\",\n padding: \"0 40px\",\n minWidth: 0,\n} as const;\n\nconst GROUP_BANNER_INNER_STYLE = {\n display: \"flex\",\n alignItems: \"center\" as const,\n gap: 8,\n minWidth: 0,\n} as const;\n\nconst GROUP_DOMAIN_NAME_STYLE = {\n fontSize: 15,\n fontWeight: 800,\n color: \"var(--ec-group-text, #5b21b6)\",\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\" as const,\n whiteSpace: \"nowrap\" as const,\n} as const;\n\nconst GROUP_VERSION_STYLE = {\n fontSize: 9,\n fontWeight: 500,\n color: \"#a78bfa\",\n} as const;\n\nconst GROUP_ICON_COLOR_STYLE = { color: \"#7c3aed\" } as const;\nconst GROUP_ICON_WHITE_STYLE = { color: \"white\" } as const;\n\nexport default memo(function GroupNode({ data }: NodeProps) {\n const { domain } = data as unknown as GroupNodeData;\n\n return (\n <div style={GROUP_CONTAINER_STYLE}>\n {/* Header banner */}\n <div style={GROUP_HEADER_STYLE}>\n {/* Watermark icon in banner */}\n <div style={GROUP_WATERMARK_STYLE}>\n <BoxesIcon size={28} strokeWidth={2} style={GROUP_ICON_COLOR_STYLE} />\n </div>\n\n {/* Icon circle overlapping top of banner */}\n <div style={GROUP_ICON_CIRCLE_STYLE}>\n <BoxesIcon\n size={16}\n strokeWidth={2.5}\n style={GROUP_ICON_WHITE_STYLE}\n />\n </div>\n\n {/* Banner text content */}\n <div style={GROUP_BANNER_CONTENT_STYLE}>\n <div style={GROUP_BANNER_INNER_STYLE}>\n <TruncatedResourceName\n value={domain?.name || \"Domain\"}\n tooltipBorderColor=\"#7c3aed\"\n className=\"truncate\"\n style={GROUP_DOMAIN_NAME_STYLE}\n >\n {domain?.name || \"Domain\"}\n </TruncatedResourceName>\n {domain?.version && (\n <span style={GROUP_VERSION_STYLE}>v{domain.version}</span>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n});\n","import { memo, useMemo, type ComponentType } from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../utils/node-connections\";\nimport * as Icons from \"@heroicons/react/24/solid\";\nimport * as ContextMenu from \"@radix-ui/react-context-menu\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport {\n EMPTY_ARRAY,\n EMPTY_OBJECT,\n LINE_CLAMP_STYLE,\n HANDLE_GLOW,\n} from \"./shared-styles\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\n\ntype MenuItem = {\n label: string;\n url?: string;\n};\n\ntype CustomColor =\n | \"blue\"\n | \"teal\"\n | \"red\"\n | \"green\"\n | \"purple\"\n | \"orange\"\n | \"pink\"\n | \"yellow\"\n | \"gray\"\n | \"indigo\"\n | \"cyan\"\n | \"slate\"\n | \"amber\"\n | \"emerald\"\n | \"violet\"\n | \"rose\";\n\ntype CustomPalette = {\n border: string;\n badge: string;\n ring: string;\n shadow: string;\n glow: string;\n pillBorder: string;\n};\n\nconst PALETTES: Record<CustomColor, CustomPalette> = {\n blue: {\n border: \"border-blue-500\",\n badge: \"bg-blue-500\",\n ring: \"ring-2 ring-blue-400/60 ring-offset-2\",\n shadow: \"rgba(59, 130, 246, 0.15)\",\n glow: \"linear-gradient(135deg, #3b82f6, #2563eb)\",\n pillBorder: \"#3b82f6\",\n },\n teal: {\n border: \"border-teal-500\",\n badge: \"bg-teal-500\",\n ring: \"ring-2 ring-teal-400/60 ring-offset-2\",\n shadow: \"rgba(20, 184, 166, 0.15)\",\n glow: \"linear-gradient(135deg, #14b8a6, #0f766e)\",\n pillBorder: \"#14b8a6\",\n },\n red: {\n border: \"border-red-500\",\n badge: \"bg-red-500\",\n ring: \"ring-2 ring-red-400/60 ring-offset-2\",\n shadow: \"rgba(239, 68, 68, 0.15)\",\n glow: \"linear-gradient(135deg, #ef4444, #b91c1c)\",\n pillBorder: \"#ef4444\",\n },\n green: {\n border: \"border-green-500\",\n badge: \"bg-green-500\",\n ring: \"ring-2 ring-green-400/60 ring-offset-2\",\n shadow: \"rgba(34, 197, 94, 0.15)\",\n glow: \"linear-gradient(135deg, #22c55e, #15803d)\",\n pillBorder: \"#22c55e\",\n },\n purple: {\n border: \"border-purple-500\",\n badge: \"bg-purple-500\",\n ring: \"ring-2 ring-purple-400/60 ring-offset-2\",\n shadow: \"rgba(168, 85, 247, 0.15)\",\n glow: \"linear-gradient(135deg, #a855f7, #7e22ce)\",\n pillBorder: \"#a855f7\",\n },\n orange: {\n border: \"border-orange-500\",\n badge: \"bg-orange-500\",\n ring: \"ring-2 ring-orange-400/60 ring-offset-2\",\n shadow: \"rgba(251, 146, 60, 0.15)\",\n glow: \"linear-gradient(135deg, #fb923c, #ea580c)\",\n pillBorder: \"#fb923c\",\n },\n pink: {\n border: \"border-pink-500\",\n badge: \"bg-pink-500\",\n ring: \"ring-2 ring-pink-400/60 ring-offset-2\",\n shadow: \"rgba(236, 72, 153, 0.15)\",\n glow: \"linear-gradient(135deg, #ec4899, #be185d)\",\n pillBorder: \"#ec4899\",\n },\n yellow: {\n border: \"border-yellow-500\",\n badge: \"bg-yellow-500\",\n ring: \"ring-2 ring-yellow-400/60 ring-offset-2\",\n shadow: \"rgba(234, 179, 8, 0.15)\",\n glow: \"linear-gradient(135deg, #eab308, #a16207)\",\n pillBorder: \"#eab308\",\n },\n gray: {\n border: \"border-gray-500\",\n badge: \"bg-gray-500\",\n ring: \"ring-2 ring-gray-400/60 ring-offset-2\",\n shadow: \"rgba(107, 114, 128, 0.15)\",\n glow: \"linear-gradient(135deg, #6b7280, #374151)\",\n pillBorder: \"#6b7280\",\n },\n indigo: {\n border: \"border-indigo-500\",\n badge: \"bg-indigo-500\",\n ring: \"ring-2 ring-indigo-400/60 ring-offset-2\",\n shadow: \"rgba(99, 102, 241, 0.15)\",\n glow: \"linear-gradient(135deg, #6366f1, #4338ca)\",\n pillBorder: \"#6366f1\",\n },\n cyan: {\n border: \"border-cyan-500\",\n badge: \"bg-cyan-500\",\n ring: \"ring-2 ring-cyan-400/60 ring-offset-2\",\n shadow: \"rgba(6, 182, 212, 0.15)\",\n glow: \"linear-gradient(135deg, #06b6d4, #0e7490)\",\n pillBorder: \"#06b6d4\",\n },\n slate: {\n border: \"border-slate-500\",\n badge: \"bg-slate-500\",\n ring: \"ring-2 ring-slate-400/60 ring-offset-2\",\n shadow: \"rgba(100, 116, 139, 0.15)\",\n glow: \"linear-gradient(135deg, #64748b, #334155)\",\n pillBorder: \"#64748b\",\n },\n amber: {\n border: \"border-amber-500\",\n badge: \"bg-amber-500\",\n ring: \"ring-2 ring-amber-400/60 ring-offset-2\",\n shadow: \"rgba(245, 158, 11, 0.15)\",\n glow: \"linear-gradient(135deg, #f59e0b, #b45309)\",\n pillBorder: \"#f59e0b\",\n },\n emerald: {\n border: \"border-emerald-500\",\n badge: \"bg-emerald-500\",\n ring: \"ring-2 ring-emerald-400/60 ring-offset-2\",\n shadow: \"rgba(16, 185, 129, 0.15)\",\n glow: \"linear-gradient(135deg, #10b981, #047857)\",\n pillBorder: \"#10b981\",\n },\n violet: {\n border: \"border-violet-500\",\n badge: \"bg-violet-500\",\n ring: \"ring-2 ring-violet-400/60 ring-offset-2\",\n shadow: \"rgba(139, 92, 246, 0.15)\",\n glow: \"linear-gradient(135deg, #8b5cf6, #6d28d9)\",\n pillBorder: \"#8b5cf6\",\n },\n rose: {\n border: \"border-rose-500\",\n badge: \"bg-rose-500\",\n ring: \"ring-2 ring-rose-400/60 ring-offset-2\",\n shadow: \"rgba(244, 63, 94, 0.15)\",\n glow: \"linear-gradient(135deg, #f43f5e, #be123c)\",\n pillBorder: \"#f43f5e\",\n },\n};\n\ninterface Data {\n mode: \"simple\" | \"full\";\n step: {\n id: string;\n title: string;\n summary?: string;\n };\n custom: {\n icon?: string;\n type?: string;\n title?: string;\n summary?: string;\n url?: string;\n color?: string;\n properties?: Record<string, string | number>;\n menu?: MenuItem[];\n height?: number;\n };\n}\n\nfunction classNames(...classes: any[]) {\n return classes.filter(Boolean).join(\" \");\n}\n\nfunction getPalette(color: string | undefined) {\n return PALETTES[(color as CustomColor) || \"blue\"] ?? PALETTES.blue;\n}\n\nfunction GlowHandle({\n side,\n gradient,\n}: {\n side: \"left\" | \"right\";\n gradient: string;\n}) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: gradient,\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.generic,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nexport default memo(function CustomNode({ data, selected }: any) {\n const { mode, custom: customProps, step } = data as Data;\n const {\n color = \"blue\",\n title = step?.title || \"Custom\",\n icon = \"CubeIcon\",\n type = \"Custom\",\n summary = step?.summary || \"\",\n url,\n properties = EMPTY_OBJECT,\n menu = EMPTY_ARRAY,\n height = 5,\n } = customProps;\n\n const palette = getPalette(color);\n const IconComponent = useMemo<\n ComponentType<{ className?: string }> | undefined\n >(() => Icons[icon as keyof typeof Icons] || Icons.CubeIcon, [icon]);\n const portalContainer = usePortalContainer();\n const connected = useNodeHasConnections();\n const propertyEntries = Object.entries(properties);\n const contextMenuItems = url\n ? [{ label: `Open ${type.toLowerCase()}`, url }, ...menu]\n : menu;\n\n return (\n <ContextMenu.Root>\n <ContextMenu.Trigger>\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n selected ? palette.ring : \"\",\n palette.border,\n )}\n style={{\n background: \"var(--ec-custom-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: `0 2px 12px ${palette.shadow}`,\n minHeight: mode === \"full\" ? `${height}em` : undefined,\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {connected.target && (\n <GlowHandle side=\"left\" gradient={palette.glow} />\n )}\n {connected.source && (\n <GlowHandle side=\"right\" gradient={palette.glow} />\n )}\n\n <div className=\"absolute -top-3 left-2.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n palette.badge,\n )}\n >\n {IconComponent && (\n <IconComponent className=\"w-2.5 h-2.5\" aria-hidden />\n )}\n {type}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <div className=\"flex items-center gap-2\">\n <TruncatedResourceName\n value={title}\n tooltipBorderColor={palette.pillBorder}\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {title}\n </TruncatedResourceName>\n </div>\n\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n\n {mode === \"full\" && propertyEntries.length > 0 && (\n <div className=\"mt-2 pt-1.5 border-t border-[rgb(var(--ec-page-border))] grid grid-cols-2 gap-x-2 gap-y-1\">\n {propertyEntries.map(([key, value]) => (\n <div key={key} className=\"min-w-0\">\n <div className=\"text-[7px] font-bold uppercase tracking-wide text-[rgb(var(--ec-page-text-muted))] truncate\">\n {key}\n </div>\n {typeof value === \"string\" && value.startsWith(\"http\") ? (\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block text-[8px] text-blue-500 underline truncate\"\n title={value}\n >\n {value}\n </a>\n ) : (\n <div\n className=\"text-[8px] text-[rgb(var(--ec-page-text))] truncate\"\n title={String(value)}\n >\n {value}\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </ContextMenu.Trigger>\n {contextMenuItems.length > 0 && (\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content className=\"min-w-[220px] bg-[rgb(var(--ec-card-bg))] rounded-md p-1 shadow-md border border-[rgb(var(--ec-page-border))]\">\n {contextMenuItems.map((item) => (\n <ContextMenu.Item\n asChild\n key={`${item.label}-${item.url || \"\"}`}\n className=\"text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center\"\n >\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-[rgb(var(--ec-page-text))] no-underline\"\n >\n {item.label}\n </a>\n </ContextMenu.Item>\n ))}\n </ContextMenu.Content>\n </ContextMenu.Portal>\n )}\n </ContextMenu.Root>\n );\n});\n","import { memo } from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport ExternalSystemComponent from \"./external-system/ExternalSystem\";\nimport { EXTERNAL_SYSTEM_HANDLE_STYLE } from \"./shared-styles\";\n\nexport default memo(function ExternalSystemNode(props: any) {\n return (\n <div className=\"relative\">\n <Handle\n type=\"target\"\n position={Position.Left}\n style={EXTERNAL_SYSTEM_HANDLE_STYLE}\n className=\"bg-gray-500\"\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={EXTERNAL_SYSTEM_HANDLE_STYLE}\n className=\"bg-gray-500\"\n />\n <ExternalSystemComponent {...props} />\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { Package } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../utils/node-connections\";\nimport { EventCatalogResource } from \"../types\";\nimport { NotesIndicator } from \"./NotesIndicator\";\nimport { HIDDEN_HANDLE_STYLE } from \"./OwnerIndicator\";\nimport {\n LINE_CLAMP_STYLE,\n FOLDED_CORNER_SHADOW_STYLE,\n useDarkMode,\n HANDLE_GLOW,\n} from \"./shared-styles\";\nimport { CustomIcon, isIconPath } from \"../utils/custom-icon\";\nimport { TruncatedResourceName } from \"./TruncatedResourceName\";\n\nfunction GlowHandle({ side }: { side: \"left\" | \"right\" }) {\n return (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n [side]: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #6366f1, #4338ca)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.dataProduct,\n pointerEvents: \"none\",\n }}\n />\n );\n}\n\nfunction classNames(...classes: any) {\n return classes.filter(Boolean).join(\" \");\n}\n\ntype DataProductNodeData = EventCatalogResource & {\n dataProduct: {\n id: string;\n version: string;\n name: string;\n summary?: string;\n inputs?: any[];\n outputs?: any[];\n owners?: any[];\n deprecated?: boolean;\n draft?: boolean;\n notes?: import(\"../types\").Note[];\n styles?: {\n icon?: string;\n node?: { color?: string; label?: string };\n };\n };\n};\n\nexport type DataProductNode = Node<DataProductNodeData, \"data-product\">;\n\nfunction PostItDataProduct(props: DataProductNode) {\n const { version, name, summary, deprecated, draft, notes, styles } =\n props.data.dataProduct;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n\n return (\n <div\n className={classNames(\n \"relative min-w-44 max-w-56 min-h-[120px]\",\n props?.selected ? \"ring-2 ring-indigo-400/60 ring-offset-1\" : \"\",\n )}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {/* Inner wrapper with rotation */}\n <div\n className=\"absolute inset-0\"\n style={{\n background:\n \"linear-gradient(135deg, #c7d2fe 0%, #a5b4fc 40%, #6366f1 100%)\",\n boxShadow:\n \"1px 1px 3px rgba(0,0,0,0.15), 3px 4px 8px rgba(0,0,0,0.08)\",\n transform: \"rotate(1deg)\",\n border: deprecated\n ? \"2px dashed rgba(239, 68, 68, 0.5)\"\n : draft\n ? \"2px dashed rgba(99, 102, 241, 0.5)\"\n : \"none\",\n }}\n >\n {/* Folded corner */}\n <div style={FOLDED_CORNER_SHADOW_STYLE} />\n <div\n style={{\n position: \"absolute\",\n top: 0,\n right: 0,\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n borderWidth: \"18px 0 0 18px\",\n borderColor: \"#4338ca transparent transparent transparent\",\n opacity: 0.3,\n }}\n />\n </div>\n\n {/* Content sits on top, unrotated */}\n <div className=\"relative px-3.5 py-3\">\n {/* Type label row */}\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-1\">\n <Package className=\"w-3 h-3 text-indigo-900/50\" strokeWidth={2.5} />\n <span className=\"text-[8px] font-bold text-indigo-900/50 uppercase tracking-widest\">\n Data Product\n </span>\n </div>\n {draft && (\n <span className=\"text-[8px] font-extrabold text-amber-900 bg-amber-100 border border-dashed border-amber-400 px-1.5 py-0.5 rounded uppercase\">\n Draft\n </span>\n )}\n {deprecated && (\n <span className=\"text-[7px] font-bold text-white bg-red-500 border border-red-600 px-1.5 py-0.5 rounded uppercase\">\n Deprecated\n </span>\n )}\n </div>\n\n {/* Name */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-[26px] h-[26px] shrink-0\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <TruncatedResourceName\n as=\"div\"\n value={name}\n tooltipBorderColor=\"#6366f1\"\n className={classNames(\n \"text-[13px] font-bold leading-snug min-w-0 truncate\",\n deprecated\n ? \"text-indigo-950/40 line-through\"\n : \"text-indigo-950\",\n )}\n >\n {name}\n </TruncatedResourceName>\n </div>\n\n {/* Version */}\n {version && (\n <div className=\"text-[9px] text-indigo-900/40 font-semibold mt-0.5\">\n v{version}\n </div>\n )}\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-2 pt-1.5 border-t border-indigo-900/10 text-[9px] text-indigo-950/60 leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction DefaultDataProduct(props: DataProductNode) {\n const { version, name, summary, deprecated, draft, notes, styles } =\n props.data.dataProduct;\n const mode = props.data.mode || \"simple\";\n const customIcon = isIconPath(styles?.icon) ? styles!.icon! : undefined;\n const connected = useNodeHasConnections();\n const isDark = useDarkMode();\n const deprecatedStripe = isDark\n ? \"rgba(239,68,68,0.25)\"\n : \"rgba(239,68,68,0.1)\";\n\n return (\n <div\n className={classNames(\n \"relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible\",\n props?.selected ? \"ring-2 ring-indigo-400/60 ring-offset-2\" : \"\",\n deprecated\n ? \"border-dashed border-red-500\"\n : draft\n ? `border-dashed ${isDark ? \"border-indigo-400\" : \"border-indigo-400/60\"}`\n : \"border-indigo-500\",\n )}\n style={{\n background: deprecated\n ? `repeating-linear-gradient(135deg, transparent, transparent 6px, ${deprecatedStripe} 6px, ${deprecatedStripe} 7px), var(--ec-dp-node-bg, rgb(var(--ec-card-bg)))`\n : draft\n ? `repeating-linear-gradient(135deg, transparent, transparent 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4.5px), repeating-linear-gradient(45deg, transparent, transparent 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4px, ${isDark ? \"rgba(99,102,241,0.25)\" : \"rgba(99,102,241,0.15)\"} 4.5px), var(--ec-dp-node-bg, rgb(var(--ec-card-bg)))`\n : \"var(--ec-dp-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(99, 102, 241, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n {notes && notes.length > 0 && (\n <NotesIndicator notes={notes} resourceName={name} />\n )}\n {connected.target && <GlowHandle side=\"left\" />}\n {connected.source && <GlowHandle side=\"right\" />}\n\n {/* Badge positioned outside top-left corner */}\n <div className=\"absolute -top-2.5 left-2.5 flex items-center gap-1.5 z-10\">\n <span\n className={classNames(\n \"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm\",\n deprecated ? \"bg-red-500\" : \"bg-indigo-500\",\n )}\n >\n <Package className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Data Product{draft && \" (Draft)\"}\n {deprecated && \" (Deprecated)\"}\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n {/* Name + version */}\n <div className=\"flex items-center gap-2\">\n {customIcon && (\n <CustomIcon\n src={customIcon}\n alt={name}\n className={\n mode === \"full\"\n ? \"w-[26px] h-[26px] shrink-0\"\n : \"w-4 h-4 shrink-0 -my-1\"\n }\n />\n )}\n <div className=\"flex items-baseline gap-1 min-w-0\">\n <TruncatedResourceName\n value={name}\n tooltipBorderColor=\"#6366f1\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {name}\n </TruncatedResourceName>\n {version && (\n <span className=\"text-[10px] font-normal text-[rgb(var(--ec-page-text-muted))] shrink-0\">\n (v{version})\n </span>\n )}\n </div>\n </div>\n\n {/* Summary */}\n {mode === \"full\" && summary && (\n <div\n className=\"mt-1.5 text-[9px] text-[rgb(var(--ec-page-text-muted))] leading-relaxed overflow-hidden\"\n style={LINE_CLAMP_STYLE}\n title={summary}\n >\n {summary}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport default memo(function DataProductNode(props: DataProductNode) {\n const nodeStyle = props?.data?.style;\n\n if (nodeStyle === \"post-it\") {\n return <PostItDataProduct {...props} />;\n }\n\n return <DefaultDataProduct {...props} />;\n});\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport { Boxes, Globe, Group, HelpCircle, Users } from \"lucide-react\";\nimport {\n LANE_HEADER_WIDTH,\n LANE_LABEL,\n type SwimlaneGroupBy,\n type SwimlaneNodeData,\n} from \"../utils/swimlanes\";\n\nexport const LANE_ICONS: Record<SwimlaneGroupBy, typeof Boxes> = {\n domain: Boxes,\n system: Group,\n team: Users,\n};\n\n// Lanes are tinted in the colour of what they group (as the domain and system\n// boundary boxes are), every other lane a little more so neighbouring lanes\n// are easy to tell apart. External and unassigned lanes are grey. Colours are\n// comma separated for rgba(), as the visualiser's theme variables are.\nexport const LANE_TINTS: Record<SwimlaneGroupBy, string> = {\n domain: \"234, 179, 8\",\n system: \"139, 92, 246\",\n team: \"14, 165, 233\",\n};\nconst NEUTRAL_TINT = \"var(--ec-page-text)\";\nconst tinted = (tint: string, alpha: number) => `rgba(${tint}, ${alpha})`;\n\n// The name runs down the lane's header\nconst VERTICAL_LABEL_STYLE = { transform: \"rotate(90deg)\" } as const;\n\n// A lane has lines above and below; a box is outlined, with rounded corners\nconst BOX_RADIUS = 12;\nconst laneStyle = (tint: string, shaded: boolean, box: boolean) =>\n ({\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n background: tinted(tint, shaded ? 0.1 : 0.05),\n ...(box\n ? {\n border: `2px solid ${tinted(tint, 0.45)}`,\n borderRadius: BOX_RADIUS,\n overflow: \"hidden\",\n }\n : {\n borderTop: `2px solid ${tinted(tint, 0.3)}`,\n borderBottom: `2px solid ${tinted(tint, 0.3)}`,\n }),\n }) as const;\n\n// The header is opaque (the lane's tint over the card background), so the\n// lane's name stays readable over the canvas dots\nconst headerStyle = (tint: string) =>\n ({\n width: LANE_HEADER_WIDTH,\n flexShrink: 0,\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRight: `2px solid ${tinted(tint, 0.3)}`,\n background: `linear-gradient(${tinted(tint, 0.14)}, ${tinted(tint, 0.14)}), rgb(var(--ec-card-bg))`,\n }) as const;\n\n// Reads bottom to top, like the lanes of a process diagram\nconst LABEL_STYLE = {\n writingMode: \"vertical-rl\",\n transform: \"rotate(180deg)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: LANE_LABEL.gap,\n whiteSpace: \"nowrap\",\n // Large, as flows are usually zoomed out to fit\n fontSize: LANE_LABEL.fontSize,\n fontWeight: 700,\n letterSpacing: \"0.01em\",\n color: \"rgb(var(--ec-page-text))\",\n} as const;\n\n/**\n * A group of flow steps that belong to one domain, system or team, with its\n * name down the left-hand side: a full-width swimlane (sized and positioned\n * by `layoutSwimlanes`), or a box around its steps (by `groupIntoBoxes`).\n */\nexport default memo(function SwimlaneNode({ data }: NodeProps) {\n const { label, level, kind, index, style } =\n data as unknown as SwimlaneNodeData;\n const Icon =\n kind === \"external\"\n ? Globe\n : kind === \"unassigned\"\n ? HelpCircle\n : LANE_ICONS[level];\n\n const tint = kind === \"lane\" ? LANE_TINTS[level] : NEUTRAL_TINT;\n const box = style === \"boxes\";\n\n return (\n <div style={laneStyle(tint, !box && index % 2 === 1, box)}>\n <div style={headerStyle(tint)}>\n <div style={LABEL_STYLE}>\n <Icon\n size={LANE_LABEL.iconSize}\n style={VERTICAL_LABEL_STYLE}\n color=\"rgb(var(--ec-page-text-muted))\"\n />\n <span\n style={\n kind === \"lane\"\n ? undefined\n : { color: \"rgb(var(--ec-page-text-muted))\" }\n }\n >\n {label}\n </span>\n </div>\n </div>\n </div>\n );\n});\n","import { memo, useMemo } from \"react\";\nimport { Layers, Zap, Terminal, HelpCircle, Maximize2 } from \"lucide-react\";\nimport { Node, Handle, Position } from \"@xyflow/react\";\nimport { useNodeHasConnections } from \"../../utils/node-connections\";\nimport { HIDDEN_HANDLE_STYLE } from \"../OwnerIndicator\";\nimport { useDarkMode, HANDLE_GLOW } from \"../shared-styles\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\n\nexport type MessageGroupNodeData = {\n mode?: string;\n groupName: string;\n direction: \"sends\" | \"receives\";\n messageCount: number;\n messageTypes: string[];\n messages: Array<{\n message: any;\n channels: any[];\n }>;\n service: { id: string; version: string };\n};\n\nexport type MessageGroupNode = Node<MessageGroupNodeData, \"messageGroup\">;\n\nconst TYPE_ICONS: Record<string, React.ComponentType<any>> = {\n events: Zap,\n commands: Terminal,\n queries: HelpCircle,\n};\n\nconst CARD_STYLE: React.CSSProperties = {\n borderRadius: 12,\n border: \"2px solid rgba(139, 92, 246, 0.4)\",\n background: \"var(--ec-message-group-node-bg, rgb(var(--ec-card-bg)))\",\n pointerEvents: \"none\" as const,\n};\n\nexport default memo(function MessageGroupNode(props: MessageGroupNode) {\n const { groupName, messageCount } = props.data;\n const isDark = useDarkMode();\n const connected = useNodeHasConnections();\n const stackDepth = messageCount >= 3 ? 3 : messageCount;\n\n const typeBreakdown = useMemo(() => {\n const counts: Record<string, number> = {};\n props.data.messages.forEach(({ message }) => {\n const type = message?.collection || \"unknown\";\n counts[type] = (counts[type] || 0) + 1;\n });\n return counts;\n }, [props.data.messages]);\n\n return (\n <div className=\"relative\" style={{ isolation: \"isolate\" }}>\n {/* Stack layers — positioned behind the main card */}\n {stackDepth >= 3 && (\n <div\n style={{\n ...CARD_STYLE,\n position: \"absolute\",\n inset: 0,\n transform: \"translate(6px, 6px)\",\n opacity: 0.5,\n }}\n />\n )}\n {stackDepth >= 2 && (\n <div\n style={{\n ...CARD_STYLE,\n position: \"absolute\",\n inset: 0,\n transform: \"translate(3px, 3px)\",\n opacity: 0.7,\n }}\n />\n )}\n\n {/* Main card */}\n <div\n className={`relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible ${\n props.selected ? \"ring-2 ring-violet-400/60 ring-offset-2\" : \"\"\n } border-violet-500`}\n style={{\n background: \"var(--ec-message-group-node-bg, rgb(var(--ec-card-bg)))\",\n boxShadow: \"0 2px 12px rgba(139, 92, 246, 0.15)\",\n }}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n style={HIDDEN_HANDLE_STYLE}\n />\n <Handle\n type=\"source\"\n position={Position.Right}\n style={HIDDEN_HANDLE_STYLE}\n />\n\n {connected.target && (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #a78bfa, #7c3aed)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.generic,\n pointerEvents: \"none\",\n }}\n />\n )}\n {connected.source && (\n <div\n className=\"ec-handle-glow\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n right: -6,\n transform: \"translateY(-50%)\",\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n background: \"linear-gradient(135deg, #a78bfa, #7c3aed)\",\n border: \"2px solid rgb(var(--ec-page-bg))\",\n zIndex: 20,\n ...HANDLE_GLOW.generic,\n pointerEvents: \"none\",\n }}\n />\n )}\n\n <div className=\"absolute -top-2.5 left-2.5 z-10\">\n <span className=\"inline-flex items-center gap-1 text-[7px] font-bold uppercase tracking-widest text-white px-1.5 py-0.5 rounded shadow-sm bg-violet-600\">\n <Layers className=\"w-2.5 h-2.5\" strokeWidth={2.5} />\n Group\n </span>\n </div>\n\n <div className=\"px-3 pt-3.5 pb-2.5\">\n <TruncatedResourceName\n as=\"div\"\n value={groupName}\n tooltipBorderColor=\"#8b5cf6\"\n className=\"text-[13px] font-semibold leading-snug text-[rgb(var(--ec-page-text))] truncate\"\n >\n {groupName}\n </TruncatedResourceName>\n\n <div className=\"mt-1.5 flex items-center gap-2\">\n <span\n className=\"text-[10px] font-medium px-1.5 py-0.5 rounded\"\n style={{\n background: isDark\n ? \"rgba(139, 92, 246, 0.2)\"\n : \"rgba(139, 92, 246, 0.1)\",\n color: isDark ? \"#c4b5fd\" : \"#6d28d9\",\n }}\n >\n {messageCount} {messageCount === 1 ? \"message\" : \"messages\"}\n </span>\n <div className=\"flex items-center gap-1\">\n {Object.entries(typeBreakdown).map(([type, count]) => {\n const Icon = TYPE_ICONS[type] || HelpCircle;\n return (\n <span\n key={type}\n className=\"flex items-center gap-0.5 text-[9px] text-[rgb(var(--ec-page-text-muted))]\"\n >\n <Icon className=\"w-2.5 h-2.5\" strokeWidth={2} />\n {count}\n </span>\n );\n })}\n </div>\n </div>\n\n <div className=\"mt-1.5 flex items-center gap-1 text-[8px] text-[rgb(var(--ec-page-text-muted))]\">\n <Maximize2 className=\"w-2.5 h-2.5\" />\n Click to explore\n </div>\n </div>\n </div>\n </div>\n );\n});\n","import { memo } from \"react\";\nimport { Layers, Minimize2 } from \"lucide-react\";\nimport { TruncatedResourceName } from \"../TruncatedResourceName\";\n\nexport type MessageGroupExpandedNodeData = {\n groupName: string;\n direction: \"sends\" | \"receives\";\n messageCount: number;\n onCollapse?: string; // group node ID to collapse back to\n};\n\nconst CONTAINER_STYLE: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n borderRadius: 12,\n border: \"2px solid rgba(139, 92, 246, 0.5)\",\n backgroundColor: \"rgba(139, 92, 246, 0.05)\",\n position: \"relative\",\n overflow: \"visible\",\n};\n\nconst HEADER_STYLE: React.CSSProperties = {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n height: 44,\n borderTopLeftRadius: 10,\n borderTopRightRadius: 10,\n background: \"rgba(139, 92, 246, 0.12)\",\n borderBottom: \"1px solid rgba(139, 92, 246, 0.3)\",\n overflow: \"visible\",\n};\n\nconst BADGE_STYLE: React.CSSProperties = {\n position: \"absolute\",\n top: -10,\n left: 12,\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 3,\n padding: \"2px 8px\",\n borderRadius: 4,\n background: \"#7c3aed\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.15)\",\n zIndex: 10,\n fontSize: 8,\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\" as const,\n color: \"white\",\n};\n\nconst HEADER_CONTENT_STYLE: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n height: \"100%\",\n padding: \"0 12px 0 14px\",\n gap: 12,\n};\n\nconst GROUP_NAME_STYLE: React.CSSProperties = {\n fontSize: 11,\n fontWeight: 700,\n color: \"var(--ec-group-text, #5b21b6)\",\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n};\n\nconst COUNT_STYLE: React.CSSProperties = {\n fontSize: 10,\n fontWeight: 500,\n color: \"#a78bfa\",\n marginLeft: 8,\n};\n\nconst COLLAPSE_BUTTON_STYLE: React.CSSProperties = {\n background: \"#7c3aed\",\n border: \"1px solid #a78bfa\",\n borderRadius: 6,\n padding: \"4px 10px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 10,\n fontWeight: 600,\n color: \"white\",\n};\n\nexport default memo(function MessageGroupExpandedNode({\n data,\n}: {\n data: MessageGroupExpandedNodeData;\n}) {\n const { groupName, messageCount } = data;\n\n return (\n <div style={CONTAINER_STYLE}>\n <div style={HEADER_STYLE}>\n <div style={BADGE_STYLE}>\n <Layers size={10} strokeWidth={2.5} />\n Group\n </div>\n\n <div style={HEADER_CONTENT_STYLE}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n minWidth: 0,\n flex: 1,\n }}\n >\n <TruncatedResourceName\n value={groupName || \"Group\"}\n tooltipBorderColor=\"#8b5cf6\"\n className=\"truncate\"\n style={GROUP_NAME_STYLE}\n >\n {groupName || \"Group\"}\n </TruncatedResourceName>\n </div>\n\n <button\n style={COLLAPSE_BUTTON_STYLE}\n className=\"ec-collapse-group-btn nodrag nopan\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n <Minimize2 size={12} strokeWidth={2.5} />\n Collapse\n </button>\n </div>\n </div>\n </div>\n );\n});\n","import type { ComponentType } from \"react\";\nimport { Service } from \"./service\";\nimport AgentNode from \"./Agent\";\nimport AgentToolNode from \"./AgentTool\";\nimport { Event } from \"./event\";\nimport { Query } from \"./query\";\nimport { Command } from \"./command\";\nimport { Channel } from \"./channel\";\nimport { Data } from \"./data\";\nimport { View } from \"./view\";\nimport { Actor } from \"./actor\";\nimport { Note } from \"./note\";\nimport { Field } from \"./field\";\nimport { ExternalSystem } from \"./external-system\";\nimport ContextActorNode from \"./ContextActor\";\nimport SystemGroupNode from \"./SystemGroupNode\";\nimport DomainCardNode from \"./DomainCard\";\nimport FlowNode from \"./Flow\";\nimport FlowExpandedNode from \"./FlowExpandedNode\";\nimport EntityNode from \"./Entity\";\nimport UserNode from \"./User\";\nimport StepNode from \"./Step\";\nimport DomainNode from \"./Domain\";\nimport SystemNode from \"./System\";\nimport GroupNode from \"./GroupNode\";\nimport CustomNode from \"./Custom\";\nimport ExternalSystem2Node from \"./ExternalSystem2\";\nimport DataProductNode from \"./DataProduct\";\nimport SwimlaneNode from \"./SwimlaneNode\";\nimport { MessageGroupNode, MessageGroupExpandedNode } from \"./message-group\";\n\n/**\n * The component a diagram draws each type of node with (types as EventCatalog's node graphs build them, singular\n * and plural). Studio draws diagrams' levels with them too, so they look the same.\n */\nexport const diagramNodeComponents: Record<string, ComponentType<any>> = {\n service: Service,\n services: Service,\n agent: AgentNode,\n agents: AgentNode,\n agentTool: AgentToolNode,\n \"agent-tool\": AgentToolNode,\n flow: FlowNode,\n flows: FlowNode,\n event: Event,\n events: Event,\n channel: Channel,\n channels: Channel,\n query: Query,\n queries: Query,\n command: Command,\n commands: Command,\n domain: DomainNode,\n domains: DomainNode,\n system: SystemNode,\n systems: SystemNode,\n step: StepNode,\n user: UserNode,\n custom: CustomNode,\n externalSystem: ExternalSystem,\n \"external-system\": ExternalSystem2Node,\n entity: EntityNode,\n entities: EntityNode,\n data: Data,\n view: View,\n actor: Actor,\n \"context-actor\": ContextActorNode,\n container: Data,\n \"data-product\": DataProductNode,\n \"data-products\": DataProductNode,\n group: GroupNode,\n \"system-group\": SystemGroupNode,\n \"domain-group\": SystemGroupNode,\n \"context-domain\": DomainCardNode,\n note: Note,\n field: Field,\n messageGroup: MessageGroupNode,\n messageGroupExpanded: MessageGroupExpandedNode,\n flowExpanded: FlowExpandedNode,\n swimlane: SwimlaneNode,\n};\n\n/** Node types that show a resource, which can have a context menu (`data.contextMenu`) */\nexport const RESOURCE_NODE_TYPES = new Set([\n \"service\",\n \"services\",\n \"agent\",\n \"agents\",\n \"agentTool\",\n \"agent-tool\",\n \"flow\",\n \"flows\",\n \"event\",\n \"events\",\n \"channel\",\n \"channels\",\n \"query\",\n \"queries\",\n \"command\",\n \"commands\",\n \"domain\",\n \"domains\",\n \"system\",\n \"systems\",\n \"externalSystem\",\n \"external-system\",\n \"entity\",\n \"entities\",\n \"data\",\n \"view\",\n \"container\",\n \"data-product\",\n \"data-products\",\n \"field\",\n]);\n","import { memo, useMemo } from \"react\";\nimport { BaseEdge } from \"@xyflow/react\";\nimport { EDGE_WARNING_STYLE, EDGE_DEFAULT_STYLE } from \"../nodes/shared-styles\";\nimport EdgeLabel from \"./EdgeLabel\";\nimport { getStepPath, useRoute } from \"./route\";\nimport DomainEdgeEnds from \"./DomainEdgeEnds\";\nimport { CROSS_DOMAIN_CLASS, isCrossDomain } from \"./use-cross-domain\";\n\n/** Map collection type → envelope fill color (module-level, zero allocation). */\nfunction messageColor(collection: string): string {\n switch (collection) {\n case \"events\":\n return \"orange\";\n case \"commands\":\n return \"blue\";\n case \"queries\":\n return \"green\";\n default:\n return \"gray\";\n }\n}\n\nconst AnimatedMessageEdge = memo(\n ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n data,\n label = \"\",\n markerEnd,\n markerStart,\n }: any) => {\n const [edgePath, labelX, labelY, zIndex, domainEnds] = useRoute(\n {\n data,\n source,\n target,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourceHandleId,\n targetHandleId,\n },\n getStepPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n }),\n );\n\n const collection = data?.message?.collection;\n const opacity = data?.opacity ?? 1;\n const customColor =\n data?.customColor || messageColor(collection ?? \"default\");\n const warning = data?.warning;\n\n const customColors = Array.isArray(customColor)\n ? customColor\n : [customColor];\n\n const randomDelay = useMemo(() => Math.random() * 1, []);\n\n const opacityClass = opacity === 1 ? \"z-30 opacity-100\" : \"z-30 opacity-10\";\n\n const animatedNodes = useMemo(\n () =>\n customColors.map((color: string, index: number) => {\n const delay = randomDelay + index * 0.3;\n return (\n <g\n className={`ec-animated-msg ${opacityClass}`}\n key={`${id}-${color}-${index}`}\n >\n <g>\n <rect\n x=\"-7\"\n y=\"-5\"\n width=\"14\"\n height=\"10\"\n rx=\"1.5\"\n ry=\"1.5\"\n fill={color}\n />\n <path\n d=\"M-7,-5 L0,1 L7,-5\"\n fill=\"none\"\n stroke=\"rgb(var(--ec-card-bg))\"\n strokeWidth=\"1.2\"\n strokeLinejoin=\"round\"\n />\n <animateMotion\n dur=\"2s\"\n repeatCount=\"indefinite\"\n path={edgePath}\n rotate=\"auto\"\n begin={`${delay}s`}\n >\n <mpath href={`#${id}`} />\n </animateMotion>\n </g>\n </g>\n );\n }),\n // edgePath changes when endpoints move — that's the only time we need to rebuild SVG\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [edgePath, id, customColors.join(\",\"), opacity, randomDelay],\n );\n\n const crossDomain = isCrossDomain(data);\n\n return (\n <>\n <BaseEdge\n id={id}\n path={edgePath}\n markerEnd={markerEnd}\n markerStart={markerStart}\n style={warning ? EDGE_WARNING_STYLE : EDGE_DEFAULT_STYLE}\n className={crossDomain ? CROSS_DOMAIN_CLASS : undefined}\n />\n <DomainEdgeEnds ends={domainEnds} />\n {animatedNodes}\n <EdgeLabel\n zIndex={zIndex}\n crossDomain={crossDomain}\n label={label}\n labelX={labelX}\n labelY={labelY}\n />\n </>\n );\n },\n);\n\nexport default AnimatedMessageEdge;\n","import type { ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useStore, type ReactFlowState } from \"@xyflow/react\";\n\n/**\n * React Flow's `EdgeLabelRenderer` and `ViewportPortal`, without their cost: each finds its layer with\n * `domNode.querySelector` in a store selector, which runs for every one of them on every store update (every frame of\n * a drag, pan, zoom or someone else's move). That's one query per edge label, and the viewport portal's layer comes\n * after every node in the DOM, so each of its queries walks all the nodes. Here the layer is found once per canvas and\n * kept (found again only if it's gone).\n */\nconst layerSelector = (className: string) => {\n const found = new WeakMap<HTMLElement, Element | null>();\n return (state: ReactFlowState) => {\n const root = state.domNode;\n if (!root) return null;\n let layer = found.get(root);\n if (!layer?.isConnected) {\n layer = root.querySelector(className);\n found.set(root, layer);\n }\n return layer;\n };\n};\n\nconst selectEdgeLabelLayer = layerSelector(\".react-flow__edgelabel-renderer\");\nconst selectViewportLayer = layerSelector(\".react-flow__viewport-portal\");\n\n/** Instead of React Flow's `EdgeLabelRenderer`: HTML drawn over the edges, in the canvas's coordinates */\nexport function EdgeLabelPortal({ children }: { children: ReactNode }) {\n const layer = useStore(selectEdgeLabelLayer);\n return layer ? createPortal(children, layer) : null;\n}\n\n/** Instead of React Flow's `ViewportPortal`: drawn above the nodes, in the canvas's coordinates */\nexport function CanvasPortal({ children }: { children: ReactNode }) {\n const layer = useStore(selectViewportLayer);\n return layer ? createPortal(children, layer) : null;\n}\n","/** Class on the path and label of an edge to or from another domain */\nexport const CROSS_DOMAIN_CLASS = \"ec-cross-domain\";\n\n/**\n * Whether an edge is part of cross-domain communication (`data.crossDomain`,\n * set when the graph is built), to highlight it.\n */\nexport const isCrossDomain = (data?: object) =>\n !!(data as { crossDomain?: boolean } | undefined)?.crossDomain;\n","import { EdgeLabelPortal } from \"../utils/flow-portals\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { CROSS_DOMAIN_CLASS } from \"./use-cross-domain\";\n\ninterface EdgeLabelProps {\n /** The edge's layer, so the label is drawn with it rather than on top of nodes */\n zIndex: number;\n /** Part of cross-domain communication, to highlight */\n crossDomain?: boolean;\n label: ReactNode;\n labelX: number;\n labelY: number;\n style?: CSSProperties;\n}\n\nexport default function EdgeLabel({\n zIndex,\n crossDomain = false,\n label,\n labelX,\n labelY,\n style,\n}: EdgeLabelProps) {\n if (label === undefined || label === null || label === \"\") return null;\n\n const lines = String(label).split(\"\\n\");\n\n return (\n <EdgeLabelPortal>\n <div\n className={`ec-edge-label ${crossDomain ? CROSS_DOMAIN_CLASS : \"\"} nodrag nopan rounded-md border border-[rgb(var(--ec-page-border))] px-2 py-1 text-center text-[10px] font-medium leading-tight text-[rgb(var(--ec-page-text))] shadow-sm`}\n style={{\n position: \"absolute\",\n transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,\n zIndex,\n pointerEvents: \"none\",\n backgroundColor: \"rgb(var(--ec-card-bg))\",\n ...style,\n }}\n >\n {lines.map((line, index) => (\n <div\n key={`${line}-${index}`}\n className={`whitespace-nowrap ${index > 0 ? \"italic\" : \"\"}`}\n >\n {line}\n </div>\n ))}\n </div>\n </EdgeLabelPortal>\n );\n}\n","import { useCallback } from \"react\";\nimport {\n getSmoothStepPath,\n Position,\n useStore,\n type ReactFlowState,\n} from \"@xyflow/react\";\nimport type { EdgeRoute } from \"../utils/elk-layout\";\n\ntype Point = { x: number; y: number };\ntype Route = EdgeRoute;\n\n// How far an edge's end can be from its handle before the route no longer\n// fits (nodes render a little wider or narrower than the layout estimated).\n// Vertically, edges can start or end anywhere along a node's side (the layout\n// spreads them out), so that allows for tall nodes and groups.\nconst ROUTE_TOLERANCE = { x: 60, y: 400 };\n\nconst isStraight = (a: Point, b: Point) => a.x === b.x || a.y === b.y;\nconst add = (a: Point, b: Point) => ({ x: a.x + b.x, y: a.y + b.y });\nconst NOT_MOVED = { x: 0, y: 0 };\n\n// How far inside a node's top and bottom corners an edge's end stays\nconst END_INSET = 8;\n\n/**\n * Where an end of the route goes down its node's side. Nodes often render\n * shorter than the layout estimated, so an end in the middle of the node as\n * laid out would be below the node (and miss its handle). The end keeps how\n * far it was from the middle (edges spread along a side stay as far apart, so\n * their labels don't overlap), measured from the middle as rendered, and stays\n * on the side.\n */\nconst alongSide = (end: Point, node: Route[\"source\"], height?: number) => {\n if (!node?.height || !height) return end;\n const fromMiddle = end.y - (node.y + node.height / 2);\n const furthest = Math.max(height / 2 - END_INSET, 0);\n return {\n x: end.x,\n y:\n node.y + height / 2 + Math.min(Math.max(fromMiddle, -furthest), furthest),\n };\n};\n\n/**\n * SVG path along a laid out route (at right angles), and where its label goes.\n * Its ends are moved onto the sides of the edge's source and target (they\n * render a little wider or narrower than the layout estimated), and with them\n * when they've moved since they were laid out (e.g. dragged): the segments at\n * the ends stay flat, and the whole route moves when both nodes move together.\n * Undefined when the ends are too far from the route to use it.\n */\nexport const getRoutePath = (\n route: Route,\n source: Point,\n target: Point,\n {\n // Ends at a specific handle (e.g. a service listed in a domain) go exactly\n // to it, rather than where the layout spread them along the node's side\n toSourceHandle = false,\n toTargetHandle = false,\n // How far the source and target have moved since they were laid out\n sourceMoved = NOT_MOVED,\n targetMoved = NOT_MOVED,\n // How tall the source and target render\n sourceHeight,\n targetHeight,\n }: {\n toSourceHandle?: boolean;\n toTargetHandle?: boolean;\n sourceMoved?: Point;\n targetMoved?: Point;\n sourceHeight?: number;\n targetHeight?: number;\n } = {},\n) => {\n const { points } = route;\n if (points.length < 2) return undefined;\n const last = points.length - 1;\n const start = add(\n alongSide(points[0], route.source, sourceHeight),\n sourceMoved,\n );\n const end = add(\n alongSide(points[last], route.target, targetHeight),\n targetMoved,\n );\n const fits = (a: Point, b: Point) =>\n Math.abs(a.x - b.x) <= ROUTE_TOLERANCE.x &&\n Math.abs(a.y - b.y) <= ROUTE_TOLERANCE.y;\n if (!fits(start, source) || !fits(end, target)) return undefined;\n\n const movedTogether =\n Math.abs(sourceMoved.x - targetMoved.x) < 1 &&\n Math.abs(sourceMoved.y - targetMoved.y) < 1;\n const moved = points.map((point) =>\n movedTogether ? add(point, sourceMoved) : { ...point },\n );\n // Keep where the layout spread the ends along each side, just on the sides\n moved[0] = { x: source.x, y: toSourceHandle ? source.y : start.y };\n moved[last] = { x: target.x, y: toTargetHandle ? target.y : end.y };\n // Keep the first and last segments flat as their ends move\n if (last > 1 && points[1].y === points[0].y) moved[1].y = moved[0].y;\n if (last > 1 && points[last - 1].y === points[last].y)\n moved[last - 1].y = moved[last].y;\n\n // Anything no longer at right angles gets a step in the middle\n const path = [moved[0]];\n moved.slice(1).forEach((point) => {\n const previous = path[path.length - 1];\n if (!isStraight(previous, point)) {\n const middleX = (previous.x + point.x) / 2;\n path.push({ x: middleX, y: previous.y }, { x: middleX, y: point.y });\n }\n path.push(point);\n });\n\n return {\n path: path\n .map((point, index) => `${index === 0 ? \"M\" : \"L\"} ${point.x} ${point.y}`)\n .join(\" \"),\n label: route.label && moveLabel(route.label, points, moved),\n start: moved[0],\n end: moved[last],\n };\n};\n\n/** Moves a label with the segment of the route it sits on */\nconst moveLabel = (label: Point, points: Point[], moved: Point[]) => {\n const distance = (index: number) => {\n const [a, b] = [points[index], points[index + 1]];\n const x = Math.min(\n Math.max(label.x, Math.min(a.x, b.x)),\n Math.max(a.x, b.x),\n );\n const y = Math.min(\n Math.max(label.y, Math.min(a.y, b.y)),\n Math.max(a.y, b.y),\n );\n return Math.hypot(label.x - x, label.y - y);\n };\n const segment = points\n .slice(1)\n .map((_, index) => index)\n .reduce((nearest, index) =>\n distance(index) < distance(nearest) ? index : nearest,\n );\n const shift = (index: number) => ({\n x: moved[index].x - points[index].x,\n y: moved[index].y - points[index].y,\n });\n const [a, b] = [shift(segment), shift(segment + 1)];\n return { x: label.x + (a.x + b.x) / 2, y: label.y + (a.y + b.y) / 2 };\n};\n\n/**\n * A step path between two nodes (for an edge the layout didn't route), with its\n * label on its last stretch, into the target. React Flow puts the label in the\n * middle, on the stretch that turns between the nodes: edges from one node to\n * nodes in the same column turn at the same place, so there the label can sit\n * on another edge's line (e.g. \"reads and writes\" on the line to an event).\n * Edges that loop back (the target left of the source) keep the middle.\n */\nexport const getStepPath = (\n props: Parameters<typeof getSmoothStepPath>[0],\n): ReturnType<typeof getSmoothStepPath> => {\n const [path, labelX, labelY, offsetX, offsetY] = getSmoothStepPath(props);\n const { sourceX, targetX, targetY } = props;\n const forwards =\n (props.sourcePosition ?? Position.Bottom) === Position.Right &&\n (props.targetPosition ?? Position.Top) === Position.Left &&\n targetX > sourceX;\n if (!forwards) return [path, labelX, labelY, offsetX, offsetY];\n // Halfway along the last stretch, which runs from where the path turns (labelX) to the target\n return [path, (labelX + targetX) / 2, targetY, offsetX, offsetY];\n};\n\n// How far a node has moved since it was laid out (top-left, in the flow)\nconst getMoved = (state: ReactFlowState, nodeId: string, at: Point) => {\n const position = state.nodeLookup.get(nodeId)?.internals.positionAbsolute;\n return position && { x: position.x - at.x, y: position.y - at.y };\n};\ntype EdgeState = {\n moved?: [Point, Point];\n heights?: [number | undefined, number | undefined];\n zIndex: number;\n // Which ends are on a domain's box (1: source, 2: target)\n domainEnds: number;\n};\nconst isSamePoint = (a: Point, b: Point) => a.x === b.x && a.y === b.y;\nconst isSameEdgeState = (a: EdgeState, b: EdgeState) =>\n a.zIndex === b.zIndex &&\n a.domainEnds === b.domainEnds &&\n a.heights?.[0] === b.heights?.[0] &&\n a.heights?.[1] === b.heights?.[1] &&\n (a.moved === b.moved ||\n (!!a.moved &&\n !!b.moved &&\n isSamePoint(a.moved[0], b.moved[0]) &&\n isSamePoint(a.moved[1], b.moved[1])));\n\nconst isDomainBox = (state: ReactFlowState, nodeId: string) =>\n state.nodeLookup.get(nodeId)?.type === \"domain-group\";\n\n/** Where an edge meets a domain's box, for the dot drawn there (domains have no handles of their own to show) */\nexport type DomainEnds = { source?: Point; target?: Point };\nconst NO_DOMAIN_ENDS: DomainEnds = {};\n\n/**\n * An edge's path, label position and layer: along the route the layout gave it\n * (`data.route`), following its nodes when they move (e.g. dragged or between\n * layouts), otherwise the fallback (e.g. a smooth step path) passed in. The\n * layer (z-index) is React Flow's for the edge: above the groups its nodes are\n * in and under the nodes, for its label to be drawn in too. Also where its ends\n * meet a domain's box.\n */\nexport const useRoute = (\n {\n data,\n source,\n target,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourceHandleId,\n targetHandleId,\n }: {\n data?: object;\n source: string;\n target: string;\n sourceX: number;\n sourceY: number;\n targetX: number;\n targetY: number;\n sourceHandleId?: string | null;\n targetHandleId?: string | null;\n },\n [path, labelX, labelY]: [string, number, number, ...unknown[]],\n): [string, number, number, number, DomainEnds] => {\n const route = (data as { route?: Route } | undefined)?.route;\n // One subscription per edge, as selectors run on every store update\n const { moved, heights, zIndex, domainEnds } = useStore(\n useCallback(\n (state: ReactFlowState): EdgeState => {\n const z = (nodeId: string) => {\n const node = state.nodeLookup.get(nodeId);\n return node?.parentId ? node.internals.z : 0;\n };\n const zIndex = Math.max(z(source), z(target));\n const domainEnds =\n (isDomainBox(state, source) ? 1 : 0) |\n (isDomainBox(state, target) ? 2 : 0);\n if (!route?.source || !route.target) return { zIndex, domainEnds };\n const sourceMoved = getMoved(state, source, route.source);\n const targetMoved = getMoved(state, target, route.target);\n const height = (nodeId: string) =>\n state.nodeLookup.get(nodeId)?.measured.height;\n return {\n zIndex,\n domainEnds,\n moved:\n sourceMoved && targetMoved ? [sourceMoved, targetMoved] : undefined,\n heights: [height(source), height(target)],\n };\n },\n [route, source, target],\n ),\n isSameEdgeState,\n );\n const routed =\n route &&\n moved &&\n getRoutePath(\n route,\n { x: sourceX, y: sourceY },\n { x: targetX, y: targetY },\n {\n toSourceHandle: !!sourceHandleId,\n toTargetHandle: !!targetHandleId,\n sourceMoved: moved[0],\n targetMoved: moved[1],\n sourceHeight: heights?.[0],\n targetHeight: heights?.[1],\n },\n );\n const start = routed?.start ?? { x: sourceX, y: sourceY };\n const end = routed?.end ?? { x: targetX, y: targetY };\n const ends = domainEnds\n ? {\n ...(domainEnds & 1 ? { source: start } : {}),\n ...(domainEnds & 2 ? { target: end } : {}),\n }\n : NO_DOMAIN_ENDS;\n if (!routed) return [path, labelX, labelY, zIndex, ends];\n return [\n routed.path,\n routed.label?.x ?? labelX,\n routed.label?.y ?? labelY,\n zIndex,\n ends,\n ];\n};\n","import { memo } from \"react\";\nimport type { DomainEnds } from \"./route\";\n\n// The domain's colour, as the handles of other nodes are in theirs\nconst DOMAIN_COLOR = \"#eab308\";\nconst RING_COLOR = \"rgba(234, 179, 8, 0.5)\";\n\nconst Dot = memo(function Dot({ x, y }: { x: number; y: number }) {\n return (\n <g className=\"ec-domain-edge-end\" pointerEvents=\"none\">\n {/* The ring around other nodes' handles (not pulsing: a domain's box isn't one node to hover) */}\n <circle\n cx={x}\n cy={y}\n r={7}\n fill=\"none\"\n stroke={RING_COLOR}\n strokeWidth={2}\n />\n <circle\n cx={x}\n cy={y}\n r={5}\n fill={DOMAIN_COLOR}\n stroke=\"rgb(var(--ec-page-bg))\"\n strokeWidth={2}\n />\n </g>\n );\n});\n\n/**\n * Dots where an edge meets a domain's box, like the handles other nodes show\n * where their edges connect. Drawn by the edge, as its ends are spread along\n * the box's side (one dot on the box wouldn't be where they meet it).\n */\nexport default memo(function DomainEdgeEnds({ ends }: { ends: DomainEnds }) {\n return (\n <>\n {ends.source && <Dot x={ends.source.x} y={ends.source.y} />}\n {ends.target && <Dot x={ends.target.x} y={ends.target.y} />}\n </>\n );\n});\n","import { memo } from \"react\";\nimport { type EdgeProps, getSmoothStepPath } from \"@xyflow/react\";\nimport EdgeLabel from \"./EdgeLabel\";\nimport { useRoute } from \"./route\";\nimport DomainEdgeEnds from \"./DomainEdgeEnds\";\nimport { CROSS_DOMAIN_CLASS, isCrossDomain } from \"./use-cross-domain\";\n\nexport default memo(function MultilineEdgeLabel(props: EdgeProps) {\n const {\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n label,\n markerStart, // <-- forward these\n markerEnd,\n style,\n selected,\n data,\n } = props;\n\n const [edgePath, labelX, labelY, zIndex, domainEnds] = useRoute(\n {\n data,\n source,\n target,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourceHandleId,\n targetHandleId,\n },\n getSmoothStepPath({\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n }),\n );\n\n const crossDomain = isCrossDomain(data);\n\n return (\n <>\n <path\n id={id}\n d={edgePath}\n className={`react-flow__edge-path${selected ? \" selected\" : \"\"}${crossDomain ? ` ${CROSS_DOMAIN_CLASS}` : \"\"}`}\n markerStart={markerStart}\n markerEnd={markerEnd}\n style={style as any}\n />\n <DomainEdgeEnds ends={domainEnds} />\n\n <EdgeLabel\n zIndex={zIndex}\n crossDomain={crossDomain}\n label={label}\n labelX={labelX}\n labelY={labelY}\n />\n </>\n );\n});\n","import { memo, useMemo } from \"react\";\nimport {\n BaseEdge,\n getSmoothStepPath,\n type EdgeProps as XYFlowEdgeProps,\n} from \"@xyflow/react\";\nimport { EdgeLabelPortal } from \"../utils/flow-portals\";\nimport { EDGE_FLOW_BASE_STYLE } from \"../nodes/shared-styles\";\nimport { useRoute } from \"./route\";\nimport { CROSS_DOMAIN_CLASS, isCrossDomain } from \"./use-cross-domain\";\n\ninterface EdgeData {\n message?: {\n collection?: string;\n };\n opacity?: number;\n animated?: boolean;\n}\n\nexport interface CustomEdgeProps extends Omit<XYFlowEdgeProps, \"data\"> {\n data?: EdgeData;\n}\n\n/** Map collection type → circle fill color (module-level, zero allocation). */\nfunction messageColor(collection: string): string {\n switch (collection) {\n case \"events\":\n return \"orange\";\n case \"commands\":\n return \"blue\";\n case \"queries\":\n return \"green\";\n default:\n return \"gray\";\n }\n}\n\nconst EMPTY_STYLE = {} as const;\n\nexport default memo(function CustomEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n style = EMPTY_STYLE,\n markerEnd,\n label,\n labelStyle,\n data,\n}: CustomEdgeProps) {\n const [edgePath, labelX, labelY, zIndex] = useRoute(\n {\n data,\n source,\n target,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourceHandleId,\n targetHandleId,\n },\n getSmoothStepPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n }),\n );\n\n const randomDelay = useMemo(() => Math.random() * 1, []);\n const collection = data?.message?.collection;\n const opacity = data?.opacity ?? 1;\n\n const mergedStyle = useMemo(\n () => ({ ...EDGE_FLOW_BASE_STYLE, ...style }),\n [style],\n );\n\n // In the edge's layer, so the label isn't drawn on top of nodes\n const crossDomain = isCrossDomain(data);\n const labelPositionStyle = useMemo(\n () => ({\n position: \"absolute\" as const,\n transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,\n zIndex,\n ...(labelStyle as any),\n }),\n [labelX, labelY, labelStyle, zIndex],\n );\n\n return (\n <>\n <BaseEdge\n path={edgePath}\n markerEnd={markerEnd}\n style={mergedStyle}\n className={crossDomain ? CROSS_DOMAIN_CLASS : undefined}\n />\n {data?.animated && (\n <g\n className={`ec-animated-msg z-30 ${opacity === 1 ? \"opacity-100\" : \"opacity-10\"}`}\n >\n <circle\n cx=\"0\"\n cy=\"0\"\n r=\"7\"\n fill={messageColor(collection || \"default\")}\n >\n <animateMotion\n dur=\"2s\"\n repeatCount=\"indefinite\"\n path={edgePath}\n rotate=\"auto\"\n begin={`${randomDelay}s`}\n >\n <mpath href={`#${id}`} />\n </animateMotion>\n </circle>\n </g>\n )}\n {label && (\n <EdgeLabelPortal>\n <div\n style={labelPositionStyle}\n className={`ec-edge-label ${crossDomain ? CROSS_DOMAIN_CLASS : \"\"} nodrag nopan max-w-[120px] text-xs bg-[rgb(var(--ec-card-bg))] px-2 py-1 rounded border border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text-muted))] font-medium shadow-sm text-center`}\n >\n {label}\n </div>\n </EdgeLabelPortal>\n )}\n </>\n );\n});\n","import { BaseEdge, getBezierPath, type EdgeProps } from \"@xyflow/react\";\nimport { memo, type CSSProperties } from \"react\";\nimport EdgeLabel from \"./EdgeLabel\";\nimport { getStepPath, useRoute } from \"./route\";\nimport DomainEdgeEnds from \"./DomainEdgeEnds\";\nimport { CROSS_DOMAIN_CLASS, isCrossDomain } from \"./use-cross-domain\";\n\ntype PathType = \"bezier\" | \"smoothstep\" | \"step\";\n\nfunction LabelledEdge({\n pathType,\n ...props\n}: EdgeProps & { pathType: PathType }) {\n const {\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n source,\n target,\n sourceHandleId,\n targetHandleId,\n markerStart,\n markerEnd,\n style,\n label,\n labelStyle,\n data,\n } = props;\n\n const pathProps = {\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n };\n const [edgePath, labelX, labelY, zIndex, domainEnds] = useRoute(\n {\n data,\n source,\n target,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourceHandleId,\n targetHandleId,\n },\n pathType === \"bezier\"\n ? getBezierPath(pathProps)\n : getStepPath({\n ...pathProps,\n ...(pathType === \"step\" ? { borderRadius: 0 } : {}),\n }),\n );\n\n const crossDomain = isCrossDomain(data);\n\n return (\n <>\n <BaseEdge\n id={id}\n path={edgePath}\n markerStart={markerStart}\n markerEnd={markerEnd}\n style={style}\n className={crossDomain ? CROSS_DOMAIN_CLASS : undefined}\n />\n <DomainEdgeEnds ends={domainEnds} />\n <EdgeLabel\n zIndex={zIndex}\n crossDomain={crossDomain}\n label={label}\n labelX={labelX}\n labelY={labelY}\n style={labelStyle as CSSProperties}\n />\n </>\n );\n}\n\n// Memoized like every edge (these draw every message edge when messages aren't simulated)\nexport const LabelledDefaultEdge = memo(function LabelledDefaultEdge(\n props: EdgeProps,\n) {\n return <LabelledEdge {...props} pathType=\"bezier\" />;\n});\n\nexport const LabelledSmoothStepEdge = memo(function LabelledSmoothStepEdge(\n props: EdgeProps,\n) {\n return <LabelledEdge {...props} pathType=\"smoothstep\" />;\n});\n\nexport const LabelledStepEdge = memo(function LabelledStepEdge(\n props: EdgeProps,\n) {\n return <LabelledEdge {...props} pathType=\"step\" />;\n});\n","import {\n useState,\n useCallback,\n useRef,\n useEffect,\n forwardRef,\n useImperativeHandle,\n memo,\n} from \"react\";\nimport type { Node } from \"@xyflow/react\";\nimport {\n Blocks,\n Bot,\n Database,\n Group,\n Layers,\n ListTree,\n MessageSquare,\n Search as SearchIcon,\n Server,\n User,\n Workflow,\n Wrench,\n Zap,\n} from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\n\n// Define interfaces for different node data structures\ninterface ResourceData {\n id?: string;\n name?: string;\n version?: string;\n}\n\ntype MessageData = ResourceData;\n\ntype ServiceData = ResourceData;\ntype AgentData = ResourceData;\ntype AgentToolData = ResourceData;\n\ntype DomainData = ResourceData;\n\ntype EntityData = ResourceData;\n\ninterface NodeDataContent extends Record<string, unknown> {\n message?: { data?: MessageData } & MessageData;\n service?: { data?: ServiceData } & ServiceData;\n agent?: { data?: AgentData } & AgentData;\n agentTool?: { data?: AgentToolData } & AgentToolData;\n domain?: { data?: DomainData } & DomainData;\n system?: { data?: ResourceData } & ResourceData;\n entity?: { data?: EntityData } & EntityData;\n channel?: { data?: ResourceData } & ResourceData;\n dataProduct?: { data?: ResourceData } & ResourceData;\n data?: ResourceData;\n name?: string;\n version?: string;\n groupName?: string;\n messages?: Array<{\n message?: {\n collection?: string;\n data?: MessageData & { id?: string };\n };\n }>;\n}\n\n// Extend the Node type with our custom data structure\ntype CustomNode = Node<NodeDataContent>;\n\ntype SearchSuggestion = {\n key: string;\n node: CustomNode;\n label: string;\n searchText: string;\n type: string;\n resourceKey: string;\n groupName?: string;\n isGroupedMessage?: boolean;\n};\n\ntype NodeTypeMeta = {\n label: string;\n Icon: LucideIcon;\n iconClass: string;\n badgeClass: string;\n};\n\nconst formatVersionedName = (name: string, version?: string) => {\n if (version) {\n const nameWithoutVersion = name.replace(\n new RegExp(`-v?${version.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}$`),\n \"\",\n );\n return `${nameWithoutVersion} (v${version})`;\n }\n\n const versionMatch = name.match(\n /^(.+)-v?(\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?)$/,\n );\n if (!versionMatch) return name;\n\n return `${versionMatch[1]} (v${versionMatch[2]})`;\n};\n\nconst normalizeCollectionType = (type: string) => {\n const aliases: Record<string, string> = {\n event: \"events\",\n command: \"commands\",\n query: \"queries\",\n agent: \"agents\",\n service: \"services\",\n domain: \"domains\",\n channel: \"channels\",\n entity: \"entities\",\n };\n\n return aliases[type] || type;\n};\n\nconst splitVersionedName = (name: string, version?: string) => {\n if (version) {\n return {\n id: name.replace(\n new RegExp(`-v?${version.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}$`),\n \"\",\n ),\n version,\n };\n }\n\n const versionMatch = name.match(\n /^(.+)-v?(\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?)$/,\n );\n if (!versionMatch) return { id: name, version: undefined };\n\n return { id: versionMatch[1], version: versionMatch[2] };\n};\n\nconst getResourceKey = ({\n type,\n id,\n name,\n version,\n}: {\n type: string;\n id?: string;\n name: string;\n version?: string;\n}) => {\n const parsed = splitVersionedName(id || name, version);\n return `${normalizeCollectionType(type)}:${parsed.id}:${parsed.version || \"\"}`.toLowerCase();\n};\n\nconst getNodeResourceData = (\n data: NodeDataContent,\n key:\n | \"message\"\n | \"agent\"\n | \"agentTool\"\n | \"service\"\n | \"domain\"\n | \"system\"\n | \"entity\"\n | \"channel\"\n | \"dataProduct\"\n | \"data\",\n) => {\n const resource = data?.[key];\n if (!resource || typeof resource !== \"object\") return undefined;\n return \"data\" in resource && resource.data ? resource.data : resource;\n};\n\ninterface VisualiserSearchProps {\n nodes: CustomNode[];\n onNodeSelect: (node: CustomNode) => void;\n onClear: () => void;\n onPaneClick?: () => void;\n}\n\nexport interface VisualiserSearchRef {\n hideSuggestions: () => void;\n}\n\nconst VisualiserSearch = memo(\n forwardRef<VisualiserSearchRef, VisualiserSearchProps>(\n ({ nodes, onNodeSelect, onClear, onPaneClick: _onPaneClick }, ref) => {\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [filteredSuggestions, setFilteredSuggestions] = useState<\n SearchSuggestion[]\n >([]);\n const [showSuggestions, setShowSuggestions] = useState(false);\n const [selectedSuggestionIndex, setSelectedSuggestionIndex] =\n useState(-1);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const suggestionsListRef = useRef<HTMLDivElement>(null);\n const suggestionItemRefs = useRef<Array<HTMLDivElement | null>>([]);\n\n const hideSuggestions = useCallback(() => {\n setShowSuggestions(false);\n setSelectedSuggestionIndex(-1);\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n hideSuggestions,\n }),\n [hideSuggestions],\n );\n\n const getNodeDisplayName = useCallback((node: CustomNode) => {\n if (node.type === \"messageGroup\") {\n return (node.data as any)?.groupName || node.id;\n }\n if (node.type === \"messageGroupExpanded\") {\n return (node.data as any)?.groupName || node.id;\n }\n const message = getNodeResourceData(node.data, \"message\");\n const agent = getNodeResourceData(node.data, \"agent\");\n const agentTool = getNodeResourceData(node.data, \"agentTool\");\n const service = getNodeResourceData(node.data, \"service\");\n const domain = getNodeResourceData(node.data, \"domain\");\n const system = getNodeResourceData(node.data, \"system\");\n const entity = getNodeResourceData(node.data, \"entity\");\n const channel = getNodeResourceData(node.data, \"channel\");\n const dataProduct = getNodeResourceData(node.data, \"dataProduct\");\n const data = getNodeResourceData(node.data, \"data\");\n const name =\n message?.name ||\n message?.id ||\n agent?.name ||\n agent?.id ||\n agentTool?.name ||\n agentTool?.id ||\n service?.name ||\n service?.id ||\n domain?.name ||\n domain?.id ||\n system?.name ||\n system?.id ||\n entity?.name ||\n entity?.id ||\n channel?.name ||\n channel?.id ||\n dataProduct?.name ||\n dataProduct?.id ||\n data?.name ||\n data?.id ||\n node.data?.name ||\n node.id;\n const version =\n message?.version ||\n agent?.version ||\n agentTool?.version ||\n service?.version ||\n domain?.version ||\n system?.version ||\n entity?.version ||\n channel?.version ||\n dataProduct?.version ||\n data?.version ||\n node.data?.version;\n return formatVersionedName(name, version);\n }, []);\n\n const getNodeResourceKey = useCallback(\n (node: CustomNode, label: string) => {\n if (\n node.type === \"messageGroup\" ||\n node.type === \"messageGroupExpanded\"\n ) {\n return `${node.type}:${node.id}`.toLowerCase();\n }\n\n const data = node.data as any;\n const resource =\n getNodeResourceData(data, \"message\") ||\n getNodeResourceData(data, \"agent\") ||\n getNodeResourceData(data, \"agentTool\") ||\n getNodeResourceData(data, \"service\") ||\n getNodeResourceData(data, \"domain\") ||\n getNodeResourceData(data, \"system\") ||\n getNodeResourceData(data, \"entity\") ||\n getNodeResourceData(data, \"channel\") ||\n getNodeResourceData(data, \"dataProduct\") ||\n data?.data ||\n data;\n\n return getResourceKey({\n type: node.type || \"unknown\",\n id: resource?.id,\n name: resource?.name || resource?.id || label || node.id,\n version: resource?.version || data?.version,\n });\n },\n [],\n );\n\n const dedupeSearchSuggestions = useCallback(\n (suggestions: SearchSuggestion[]) => {\n const uniqueSuggestions: SearchSuggestion[] = [];\n const indexByResourceKey = new Map<string, number>();\n\n suggestions.forEach((suggestion) => {\n const existingIndex = indexByResourceKey.get(\n suggestion.resourceKey,\n );\n\n if (existingIndex === undefined) {\n indexByResourceKey.set(\n suggestion.resourceKey,\n uniqueSuggestions.length,\n );\n uniqueSuggestions.push(suggestion);\n return;\n }\n\n if (\n suggestion.isGroupedMessage &&\n !uniqueSuggestions[existingIndex].isGroupedMessage\n ) {\n uniqueSuggestions[existingIndex] = suggestion;\n }\n });\n\n return uniqueSuggestions;\n },\n [],\n );\n\n const getSearchSuggestions = useCallback(\n (nodesToIndex: CustomNode[]): SearchSuggestion[] => {\n const suggestions = nodesToIndex.flatMap((node) => {\n // Boundary/container nodes aren't searchable resources — e.g. the\n // system-group wrapper on a System Diagram. Skip them so they don't\n // appear in the \"Search Nodes\" filter.\n if (node.type === \"system-group\") return [];\n\n const nodeName = getNodeDisplayName(node);\n const suggestions: SearchSuggestion[] = [\n {\n key: node.id,\n node,\n label: nodeName,\n searchText: nodeName,\n type: node.type || \"unknown\",\n resourceKey: getNodeResourceKey(node, nodeName),\n },\n ];\n\n if (node.type !== \"messageGroup\") return suggestions;\n\n const groupName = node.data?.groupName || nodeName;\n const groupedMessages = node.data?.messages || [];\n groupedMessages.forEach((item, index) => {\n const message = item.message;\n const messageName = message?.data?.name || message?.data?.id;\n if (!messageName) return;\n\n const version = message?.data?.version;\n const label = formatVersionedName(messageName, version);\n\n suggestions.push({\n key: `${node.id}:${message?.data?.id || messageName}:${version || index}`,\n node,\n label,\n searchText: `${label} ${groupName}`,\n type: message?.collection || \"message\",\n resourceKey: getResourceKey({\n type: message?.collection || \"message\",\n id: message?.data?.id,\n name: messageName,\n version,\n }),\n groupName,\n isGroupedMessage: true,\n });\n });\n\n return suggestions;\n });\n\n return dedupeSearchSuggestions(suggestions);\n },\n [dedupeSearchSuggestions, getNodeDisplayName, getNodeResourceKey],\n );\n\n const getNodeTypeMeta = useCallback((nodeType: string): NodeTypeMeta => {\n const meta: Record<string, NodeTypeMeta> = {\n events: {\n label: \"Event\",\n Icon: Zap,\n iconClass: \"border-orange-500/25 bg-orange-500/10 text-orange-500\",\n badgeClass:\n \"border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300\",\n },\n event: {\n label: \"Event\",\n Icon: Zap,\n iconClass: \"border-orange-500/25 bg-orange-500/10 text-orange-500\",\n badgeClass:\n \"border-orange-500/25 bg-orange-500/10 text-orange-700 dark:text-orange-300\",\n },\n commands: {\n label: \"Command\",\n Icon: MessageSquare,\n iconClass: \"border-blue-500/25 bg-blue-500/10 text-blue-500\",\n badgeClass:\n \"border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300\",\n },\n command: {\n label: \"Command\",\n Icon: MessageSquare,\n iconClass: \"border-blue-500/25 bg-blue-500/10 text-blue-500\",\n badgeClass:\n \"border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300\",\n },\n queries: {\n label: \"Query\",\n Icon: SearchIcon,\n iconClass: \"border-green-500/25 bg-green-500/10 text-green-500\",\n badgeClass:\n \"border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300\",\n },\n query: {\n label: \"Query\",\n Icon: SearchIcon,\n iconClass: \"border-green-500/25 bg-green-500/10 text-green-500\",\n badgeClass:\n \"border-green-500/25 bg-green-500/10 text-green-700 dark:text-green-300\",\n },\n services: {\n label: \"Service\",\n Icon: Server,\n iconClass: \"border-pink-500/25 bg-pink-500/10 text-pink-500\",\n badgeClass:\n \"border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300\",\n },\n agents: {\n label: \"Agent\",\n Icon: Bot,\n iconClass: \"border-sky-500/25 bg-sky-500/10 text-sky-500\",\n badgeClass:\n \"border-sky-500/25 bg-sky-500/10 text-sky-700 dark:text-sky-300\",\n },\n agent: {\n label: \"Agent\",\n Icon: Bot,\n iconClass: \"border-sky-500/25 bg-sky-500/10 text-sky-500\",\n badgeClass:\n \"border-sky-500/25 bg-sky-500/10 text-sky-700 dark:text-sky-300\",\n },\n agentTool: {\n label: \"Agent Tool\",\n Icon: Wrench,\n iconClass: \"border-violet-500/25 bg-violet-500/10 text-violet-500\",\n badgeClass:\n \"border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300\",\n },\n \"agent-tool\": {\n label: \"Agent Tool\",\n Icon: Wrench,\n iconClass: \"border-violet-500/25 bg-violet-500/10 text-violet-500\",\n badgeClass:\n \"border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300\",\n },\n domains: {\n label: \"Domain\",\n Icon: Blocks,\n iconClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400\",\n badgeClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300\",\n },\n systems: {\n label: \"System\",\n Icon: Group,\n iconClass: \"border-violet-500/25 bg-violet-500/10 text-violet-500\",\n badgeClass:\n \"border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300\",\n },\n flows: {\n label: \"Flow\",\n Icon: Workflow,\n iconClass: \"border-teal-500/25 bg-teal-500/10 text-teal-500\",\n badgeClass:\n \"border-teal-500/25 bg-teal-500/10 text-teal-700 dark:text-teal-300\",\n },\n channels: {\n label: \"Channel\",\n Icon: ListTree,\n iconClass: \"border-gray-500/25 bg-gray-500/10 text-gray-500\",\n badgeClass:\n \"border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300\",\n },\n data: {\n label: \"Data\",\n Icon: Database,\n iconClass: \"border-blue-500/25 bg-blue-500/10 text-blue-500\",\n badgeClass:\n \"border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300\",\n },\n entities: {\n label: \"Entity\",\n Icon: Database,\n iconClass: \"border-blue-500/25 bg-blue-500/10 text-blue-500\",\n badgeClass:\n \"border-blue-500/25 bg-blue-500/10 text-blue-700 dark:text-blue-300\",\n },\n externalSystem: {\n label: \"External\",\n Icon: Server,\n iconClass: \"border-pink-500/25 bg-pink-500/10 text-pink-500\",\n badgeClass:\n \"border-pink-500/25 bg-pink-500/10 text-pink-700 dark:text-pink-300\",\n },\n actor: {\n label: \"Actor\",\n Icon: User,\n iconClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400\",\n badgeClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300\",\n },\n \"context-actor\": {\n label: \"Actor\",\n Icon: User,\n iconClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400\",\n badgeClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300\",\n },\n user: {\n label: \"User\",\n Icon: User,\n iconClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400\",\n badgeClass:\n \"border-yellow-500/25 bg-yellow-500/10 text-yellow-700 dark:text-yellow-300\",\n },\n messageGroup: {\n label: \"Group\",\n Icon: Layers,\n iconClass: \"border-violet-500/25 bg-violet-500/10 text-violet-500\",\n badgeClass:\n \"border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300\",\n },\n messageGroupExpanded: {\n label: \"Group\",\n Icon: Layers,\n iconClass: \"border-violet-500/25 bg-violet-500/10 text-violet-500\",\n badgeClass:\n \"border-violet-500/25 bg-violet-500/10 text-violet-700 dark:text-violet-300\",\n },\n };\n\n return (\n meta[nodeType] || {\n label: nodeType,\n Icon: Layers,\n iconClass: \"border-gray-500/25 bg-gray-500/10 text-gray-500\",\n badgeClass:\n \"border-gray-500/25 bg-gray-500/10 text-gray-700 dark:text-gray-300\",\n }\n );\n }, []);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const query = event.target.value;\n setSearchQuery(query);\n\n if (query.length > 0) {\n const search = query.toLowerCase();\n const filtered = getSearchSuggestions(nodes).filter((suggestion) =>\n suggestion.searchText.toLowerCase().includes(search),\n );\n setFilteredSuggestions(filtered);\n setShowSuggestions(true);\n setSelectedSuggestionIndex(-1);\n } else {\n setFilteredSuggestions(getSearchSuggestions(nodes));\n setShowSuggestions(true);\n setSelectedSuggestionIndex(-1);\n }\n },\n [nodes, getSearchSuggestions],\n );\n\n const handleSearchFocus = useCallback(() => {\n const suggestions = getSearchSuggestions(nodes);\n const search = searchQuery.toLowerCase();\n setFilteredSuggestions(\n searchQuery.length === 0\n ? suggestions\n : suggestions.filter((suggestion) =>\n suggestion.searchText.toLowerCase().includes(search),\n ),\n );\n setShowSuggestions(true);\n setSelectedSuggestionIndex(-1);\n }, [nodes, searchQuery, getSearchSuggestions]);\n\n const handleSuggestionClick = useCallback(\n (suggestion: SearchSuggestion) => {\n setSearchQuery(\"\");\n setFilteredSuggestions([]);\n setShowSuggestions(false);\n setSelectedSuggestionIndex(-1);\n onNodeSelect(suggestion.node);\n },\n [onNodeSelect],\n );\n\n const handleSearchKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n if (filteredSuggestions.length === 0) return;\n setShowSuggestions(true);\n setSelectedSuggestionIndex((prev) =>\n prev < filteredSuggestions.length - 1 ? prev + 1 : 0,\n );\n break;\n case \"ArrowUp\":\n event.preventDefault();\n if (filteredSuggestions.length === 0) return;\n setShowSuggestions(true);\n setSelectedSuggestionIndex((prev) =>\n prev > 0 ? prev - 1 : filteredSuggestions.length - 1,\n );\n break;\n case \"Enter\":\n event.preventDefault();\n if (\n showSuggestions &&\n selectedSuggestionIndex >= 0 &&\n selectedSuggestionIndex < filteredSuggestions.length\n ) {\n handleSuggestionClick(\n filteredSuggestions[selectedSuggestionIndex],\n );\n }\n break;\n case \"Escape\":\n setShowSuggestions(false);\n setSelectedSuggestionIndex(-1);\n break;\n }\n },\n [\n showSuggestions,\n filteredSuggestions,\n selectedSuggestionIndex,\n handleSuggestionClick,\n ],\n );\n\n const clearSearch = useCallback(() => {\n setSearchQuery(\"\");\n setShowSuggestions(false);\n setFilteredSuggestions([]);\n setSelectedSuggestionIndex(-1);\n onClear();\n if (searchInputRef.current) {\n searchInputRef.current.focus();\n }\n }, [onClear]);\n\n useEffect(() => {\n suggestionItemRefs.current = suggestionItemRefs.current.slice(\n 0,\n filteredSuggestions.length,\n );\n }, [filteredSuggestions.length]);\n\n useEffect(() => {\n if (!showSuggestions || selectedSuggestionIndex < 0) return;\n\n const list = suggestionsListRef.current;\n const item = suggestionItemRefs.current[selectedSuggestionIndex];\n if (!list || !item) return;\n\n const itemTop = item.offsetTop;\n const itemBottom = itemTop + item.offsetHeight;\n const visibleTop = list.scrollTop;\n const visibleBottom = visibleTop + list.clientHeight;\n\n if (itemTop < visibleTop) {\n list.scrollTop = itemTop;\n } else if (itemBottom > visibleBottom) {\n list.scrollTop = itemBottom - list.clientHeight;\n }\n }, [\n showSuggestions,\n selectedSuggestionIndex,\n filteredSuggestions.length,\n ]);\n\n // Close suggestions when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as any)\n ) {\n setShowSuggestions(false);\n setSelectedSuggestionIndex(-1);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n return (\n <div ref={containerRef} className=\"w-full max-w-md mx-auto relative\">\n <div className=\"relative\">\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder=\"Search nodes...\"\n value={searchQuery}\n onChange={handleSearchChange}\n onKeyDown={handleSearchKeyDown}\n onFocus={handleSearchFocus}\n className=\"w-full px-4 py-2 pr-10 bg-[rgb(var(--ec-input-bg))] border border-[rgb(var(--ec-input-border))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-page-text-muted))] rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))] focus:border-transparent\"\n />\n {searchQuery && (\n <button\n onClick={clearSearch}\n className=\"absolute right-2 top-1/2 transform -translate-y-1/2 text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))]\"\n aria-label=\"Clear search\"\n >\n <svg\n className=\"w-5 h-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n {showSuggestions && filteredSuggestions.length > 0 && (\n <div\n ref={suggestionsListRef}\n className=\"absolute top-full left-0 right-0 mt-1 bg-[rgb(var(--ec-card-bg))] border border-[rgb(var(--ec-page-border))] rounded-md shadow-lg z-50 max-h-60 overflow-y-auto\"\n >\n {filteredSuggestions.map((suggestion, index) => {\n const nodeTypeMeta = getNodeTypeMeta(suggestion.type);\n const Icon = nodeTypeMeta.Icon;\n const isSelected = index === selectedSuggestionIndex;\n return (\n <div\n key={`${suggestion.key}:${index}`}\n ref={(element) => {\n suggestionItemRefs.current[index] = element;\n }}\n onClick={() => handleSuggestionClick(suggestion)}\n onMouseEnter={() => setSelectedSuggestionIndex(index)}\n className={`px-3 py-2 cursor-pointer flex items-start gap-3 ${\n isSelected\n ? \"bg-[rgb(var(--ec-accent-subtle))] outline outline-1 -outline-offset-1 outline-[rgb(var(--ec-accent))]\"\n : \"hover:bg-[rgb(var(--ec-page-border)/0.5)]\"\n }`}\n >\n <span\n className={`mt-0.5 flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-md border ${nodeTypeMeta.iconClass}`}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-[rgb(var(--ec-page-text))]\">\n {suggestion.label}\n </span>\n {suggestion.isGroupedMessage && suggestion.groupName && (\n <span className=\"mt-0.5 block truncate text-xs text-[rgb(var(--ec-page-text-muted))]\">\n in {suggestion.groupName}\n </span>\n )}\n </span>\n <span\n className={`mt-0.5 flex-shrink-0 rounded border px-2 py-0.5 text-xs font-medium ${nodeTypeMeta.badgeClass}`}\n >\n {nodeTypeMeta.label}\n </span>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n },\n ),\n);\n\nVisualiserSearch.displayName = \"VisualiserSearch\";\n\nexport default VisualiserSearch;\n","import React, {\n useState,\n useEffect,\n useLayoutEffect,\n useCallback,\n useMemo,\n useRef,\n memo,\n} from \"react\";\nimport {\n ChevronLeft,\n ChevronRight,\n ExternalLink,\n Play,\n RotateCcw,\n X,\n} from \"lucide-react\";\nimport type { Edge } from \"@xyflow/react\";\nimport { buildUrl } from \"../utils/url-builder\";\nimport { isTyping } from \"../utils/keyboard\";\nimport {\n getNodeDocUrl,\n NODE_COLOR_CLASSES,\n NODE_TYPE_LABELS,\n} from \"./FocusMode/utils\";\n\ntype Resource = {\n summary?: string;\n data?: { summary?: string };\n};\n\n// A type (not an interface) so it's a record of node data, as React Flow's are\ntype NodeData = {\n summary?: string;\n step?: {\n title?: string;\n summary?: string;\n };\n service?: Resource;\n message?: Resource;\n agent?: Resource;\n flow?: Resource;\n container?: Resource;\n dataProduct?: Resource;\n custom?: {\n type?: string;\n summary?: string;\n url?: string;\n };\n externalSystem?: {\n url?: string;\n };\n};\n\ninterface CustomNode {\n id: string;\n type?: string;\n data: NodeData;\n}\n\ninterface StepWalkthroughProps {\n nodes: CustomNode[];\n edges: Edge[];\n isFlowVisualization: boolean;\n /**\n * Called when the step changes: the step (null when the walkthrough ends),\n * whether to zoom out to the whole flow, and the steps walked so far, in\n * order (ending with this one)\n */\n onStepChange: (\n nodeId: string | null,\n shouldZoomOut?: boolean,\n trail?: string[],\n ) => void;\n mode?: \"full\" | \"simple\";\n}\n\ninterface PathOption {\n targetId: string;\n label?: string;\n targetNode: CustomNode;\n}\n\n/** What the walkthrough shows for a step */\nconst getStepInfo = (node: CustomNode) => {\n const { data } = node;\n const type = node.type ?? \"step\";\n // What the step points at (its service, message...), for its summary\n const resource =\n data.service ??\n data.message ??\n data.agent ??\n data.flow ??\n data.container ??\n data.dataProduct;\n // The flow's own words for the step first, then what the resource is\n const stepSummary = data.step?.summary;\n const resourceSummary =\n resource?.summary ||\n resource?.data?.summary ||\n data.custom?.summary ||\n data.summary;\n const docsPath = getNodeDocUrl(node);\n return {\n // The catalog names every step (after what it points at, if untitled)\n title: data.step?.title || node.id,\n typeLabel: data.custom?.type || NODE_TYPE_LABELS[type] || \"Step\",\n colorClass: NODE_COLOR_CLASSES[type] ?? NODE_COLOR_CLASSES.step,\n summary: stepSummary || resourceSummary,\n detail:\n stepSummary && resourceSummary && resourceSummary !== stepSummary\n ? resourceSummary\n : undefined,\n docsUrl: docsPath\n ? buildUrl(docsPath)\n : data.custom?.url || data.externalSystem?.url,\n };\n};\n\n// Small, as the walkthrough sits over the flow\nconst BUTTON =\n \"flex items-center justify-center gap-1 h-7 text-xs rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--ec-accent))] transition-colors\";\nconst PRIMARY_BUTTON = `${BUTTON} px-2.5 font-semibold text-white bg-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-hover))]`;\nconst QUIET_BUTTON = `${BUTTON} px-2 font-medium text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-page-border)/0.4)]`;\nconst ICON_BUTTON =\n \"flex items-center justify-center w-6 h-6 rounded text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-page-border)/0.4)]\";\n\nexport default memo(function StepWalkthrough({\n nodes,\n edges,\n isFlowVisualization,\n onStepChange,\n}: StepWalkthroughProps) {\n // The steps walked so far, in order (empty before the walkthrough starts)\n const [trail, setTrail] = useState<string[]>([]);\n const currentNodeId = trail[trail.length - 1] ?? null;\n const [startNodeId, setStartNodeId] = useState<string | null>(null);\n\n // Stable structural keys — only change when nodes/edges are added/removed,\n // not when positions change during drag.\n const nodeIdsKeyRef = useRef(\"\");\n const computedNodeIdsKey = nodes.map((n) => n.id).join(\",\");\n if (computedNodeIdsKey !== nodeIdsKeyRef.current) {\n nodeIdsKeyRef.current = computedNodeIdsKey;\n }\n const nodeIdsKey = nodeIdsKeyRef.current;\n\n const edgeKeyRef = useRef(\"\");\n const computedEdgeKey = edges.map((e) => `${e.source}-${e.target}`).join(\",\");\n if (computedEdgeKey !== edgeKeyRef.current) {\n edgeKeyRef.current = computedEdgeKey;\n }\n const edgeKey = edgeKeyRef.current;\n\n const nodesById = useMemo(\n () => new Map(nodes.map((node) => [node.id, node])),\n [nodeIdsKey],\n );\n\n useEffect(() => {\n if (!isFlowVisualization || nodes.length === 0) return;\n // The flow starts at the first step with no edges into it. Worked out\n // again when the cached one no longer exists (e.g. a sub-flow expanded)\n const targets = new Set(edges.map((edge) => edge.target));\n const start = nodes.find((node) => !targets.has(node.id));\n if (start && !(startNodeId && nodesById.has(startNodeId))) {\n setStartNodeId(start.id);\n }\n }, [nodeIdsKey, edgeKey, isFlowVisualization, startNodeId]);\n\n // The current step no longer exists (e.g. the sub-flow it was in was\n // collapsed): start again\n useEffect(() => {\n if (currentNodeId && !nodesById.has(currentNodeId)) setTrail([]);\n }, [currentNodeId, nodesById]);\n\n const pathsFrom = useCallback(\n (nodeId: string | null): PathOption[] =>\n nodeId\n ? edges\n .filter((edge) => edge.source === nodeId)\n .map((edge) => ({\n targetId: edge.target,\n label: edge.label as string | undefined,\n targetNode: nodesById.get(edge.target)!,\n }))\n .filter((path) => !!path.targetNode)\n : [],\n [edgeKey, nodesById],\n );\n const availablePaths = useMemo(\n () => pathsFrom(currentNodeId),\n [pathsFrom, currentNodeId],\n );\n\n // How many steps the flow has on the way it's being walked: those walked,\n // then the first way on from each step until it ends (or loops)\n const stepsAfter = useCallback(\n (nodeId: string, walked: string[]) => {\n const seen = new Set(walked);\n let steps = 0;\n let next = pathsFrom(nodeId)[0]?.targetId;\n while (next && !seen.has(next)) {\n seen.add(next);\n steps++;\n next = pathsFrom(next)[0]?.targetId;\n }\n return steps;\n },\n [pathsFrom],\n );\n const totalSteps = useMemo(\n () => (currentNodeId ? trail.length + stepsAfter(currentNodeId, trail) : 0),\n [trail, currentNodeId, stepsAfter],\n );\n // The same, before starting\n const startSteps = useMemo(\n () => (startNodeId ? 1 + stepsAfter(startNodeId, [startNodeId]) : 0),\n [startNodeId, stepsAfter],\n );\n\n const goTo = useCallback(\n (nextTrail: string[]) => {\n setTrail(nextTrail);\n const nodeId = nextTrail[nextTrail.length - 1];\n if (!nodeId) {\n onStepChange(null);\n return;\n }\n onStepChange(nodeId, false, nextTrail);\n },\n [onStepChange],\n );\n\n const start = useCallback(() => {\n if (startNodeId) goTo([startNodeId]);\n }, [startNodeId, goTo]);\n // At a branch, the way on picked in the dropdown (the first to start with)\n const [selectedPath, setSelectedPath] = useState(0);\n useEffect(() => setSelectedPath(0), [currentNodeId]);\n const next = useCallback(\n (index = selectedPath) => {\n const path = availablePaths[index];\n if (path) goTo([...trail, path.targetId]);\n },\n [availablePaths, selectedPath, trail, goTo],\n );\n const previous = useCallback(() => goTo(trail.slice(0, -1)), [trail, goTo]);\n const finish = useCallback(() => {\n setTrail([]);\n onStepChange(null, true); // Zoom out to the whole flow again\n }, [onStepChange]);\n\n // ←/→ to step through, 1–9 to pick a way on, Esc to stop\n const isWalking = trail.length > 0;\n useEffect(() => {\n if (!isWalking) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n if (isTyping(event.target)) return;\n if (event.key === \"ArrowRight\") next();\n else if (event.key === \"ArrowLeft\") previous();\n else if (event.key === \"Escape\") finish();\n else if (/^[1-9]$/.test(event.key) && availablePaths.length > 1)\n next(Number(event.key) - 1);\n else return;\n event.preventDefault();\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [isWalking, availablePaths, next, previous, finish]);\n\n const currentNode = currentNodeId ? nodesById.get(currentNodeId) : undefined;\n const info = useMemo(\n () => (currentNode ? getStepInfo(currentNode) : undefined),\n [currentNode],\n );\n\n // Long text is cut short (the title to a line, the summary to two), and\n // can be expanded to read in full. Collapsed again on each step.\n const [expanded, setExpanded] = useState(false);\n const [isCut, setIsCut] = useState(false);\n const titleRef = useRef<HTMLHeadingElement>(null);\n const summaryRef = useRef<HTMLParagraphElement>(null);\n useEffect(() => setExpanded(false), [currentNodeId]);\n useLayoutEffect(() => {\n if (expanded) return;\n const title = titleRef.current;\n const summary = summaryRef.current;\n setIsCut(\n !!info?.detail ||\n (!!title && title.scrollWidth > title.clientWidth) ||\n (!!summary && summary.scrollHeight > summary.clientHeight + 1),\n );\n }, [info, expanded]);\n\n const startInfo = useMemo(() => {\n const startNode = startNodeId ? nodesById.get(startNodeId) : undefined;\n return startNode ? getStepInfo(startNode) : undefined;\n }, [startNodeId, nodesById]);\n\n if (!isFlowVisualization || nodes.length === 0) {\n return null;\n }\n\n // Before starting: the same card as while walking (so starting doesn't\n // change its size), naming the step the flow starts with\n if (!isWalking || !info) {\n return (\n <div className=\"ml-12 w-[360px] rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] shadow-lg overflow-hidden\">\n <div className=\"h-0.5 bg-[rgb(var(--ec-page-border)/0.5)]\" />\n <div className=\"px-3 pt-2 pb-2\">\n {/* As tall as the step's title row (its icon buttons) */}\n <div className=\"flex items-center gap-2 min-w-0 h-6\">\n <span className=\"flex items-center justify-center shrink-0 w-5 h-5 rounded-full bg-[rgb(var(--ec-accent))] text-white\">\n <Play className=\"w-2.5 h-2.5 fill-current\" />\n </span>\n <h3 className=\"flex-1 min-w-0 truncate text-sm font-semibold text-[rgb(var(--ec-page-text))]\">\n Walk through this flow\n </h3>\n </div>\n <p className=\"mt-1 text-xs leading-snug text-[rgb(var(--ec-page-text-muted))] line-clamp-2\">\n Step through it one hop at a time\n {startInfo ? `, starting at ${startInfo.title}.` : \".\"}\n </p>\n <div className=\"flex items-center justify-between gap-2 mt-2\">\n <span className=\"px-2 text-xs text-[rgb(var(--ec-page-text-muted))]\">\n {startSteps > 0 && `${startSteps} steps`}\n </span>\n <button\n type=\"button\"\n onClick={start}\n title=\"Start walking through the flow\"\n className={PRIMARY_BUTTON}\n >\n Start\n <ChevronRight className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n const stepNumber = trail.length;\n const atEnd = availablePaths.length === 0;\n const isBranch = availablePaths.length > 1;\n\n return (\n <div className=\"ml-12 w-[360px] rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] shadow-lg overflow-hidden\">\n {/* Progress through the flow, on the way it's being walked */}\n <div className=\"h-0.5 bg-[rgb(var(--ec-page-border)/0.5)]\">\n <div\n className=\"h-full bg-[rgb(var(--ec-accent))] transition-[width] duration-300\"\n style={{ width: `${(stepNumber / totalSteps) * 100}%` }}\n />\n </div>\n\n <div className=\"px-3 pt-2 pb-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"shrink-0 text-[11px] font-semibold tabular-nums text-[rgb(var(--ec-page-text-muted))]\">\n {stepNumber}/{totalSteps}\n </span>\n <span\n className={`shrink-0 px-1.5 py-px rounded text-[9px] font-bold uppercase tracking-wide text-white ${info.colorClass}`}\n >\n {info.typeLabel}\n </span>\n <h3\n ref={titleRef}\n className={`flex-1 min-w-0 text-sm font-semibold text-[rgb(var(--ec-page-text))] ${\n expanded ? \"break-words\" : \"truncate\"\n }`}\n title={expanded ? undefined : info.title}\n >\n {info.title}\n </h3>\n {info.docsUrl && (\n <a\n href={info.docsUrl}\n aria-label={`Open the docs for ${info.title}`}\n title=\"Open docs\"\n className={ICON_BUTTON}\n >\n <ExternalLink className=\"w-3.5 h-3.5\" />\n </a>\n )}\n <button\n type=\"button\"\n onClick={finish}\n aria-label=\"Stop walking through the flow\"\n title=\"Stop (Esc)\"\n className={`${ICON_BUTTON} -mr-1`}\n >\n <X className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n\n {info.summary && (\n <p\n ref={summaryRef}\n onClick={isCut ? () => setExpanded(!expanded) : undefined}\n className={`mt-1 text-xs leading-snug text-[rgb(var(--ec-page-text-muted))] ${\n expanded ? \"max-h-40 overflow-y-auto\" : \"line-clamp-2\"\n } ${isCut ? \"cursor-pointer\" : \"\"}`}\n >\n {info.summary}\n </p>\n )}\n {expanded && info.detail && (\n <p className=\"mt-1.5 pt-1.5 border-t border-[rgb(var(--ec-page-border)/0.6)] text-xs leading-snug text-[rgb(var(--ec-page-text-muted))] max-h-32 overflow-y-auto\">\n {info.detail}\n </p>\n )}\n {isCut && (\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n aria-expanded={expanded}\n className=\"mt-0.5 text-[11px] font-medium text-[rgb(var(--ec-accent))] hover:underline\"\n >\n {expanded ? \"Less\" : \"More\"}\n </button>\n )}\n\n <div className=\"flex items-center justify-between gap-2 mt-2\">\n <button\n type=\"button\"\n onClick={previous}\n title=\"Back (←)\"\n className={QUIET_BUTTON}\n >\n <ChevronLeft className=\"w-3.5 h-3.5\" />\n Back\n </button>\n {atEnd ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={start}\n title=\"Walk through again\"\n className={QUIET_BUTTON}\n >\n <RotateCcw className=\"w-3 h-3\" />\n Restart\n </button>\n <button type=\"button\" onClick={finish} className={PRIMARY_BUTTON}>\n Finish\n </button>\n </div>\n ) : isBranch ? (\n // A branch: pick the way on (or press its number), then Next\n <div className=\"flex items-center justify-end gap-1 flex-1 min-w-0\">\n <select\n value={selectedPath}\n onChange={(event) =>\n setSelectedPath(Number(event.target.value))\n }\n aria-label=\"Which way the flow goes next\"\n title=\"Which way next (or press its number)\"\n className=\"min-w-0 flex-1 max-w-[210px] h-7 pl-2 pr-6 text-xs truncate rounded-md border border-[rgb(var(--ec-input-border))] bg-[rgb(var(--ec-input-bg))] text-[rgb(var(--ec-input-text))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]\"\n >\n {availablePaths.map((path, index) => {\n const target = getStepInfo(path.targetNode).title;\n return (\n <option key={path.targetId} value={index}>\n {index + 1}.{\" \"}\n {path.label ? `${path.label} → ${target}` : target}\n </option>\n );\n })}\n </select>\n <button\n type=\"button\"\n onClick={() => next()}\n title=\"Next (→)\"\n className={PRIMARY_BUTTON}\n >\n Next\n <ChevronRight className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => next()}\n title=\"Next (→)\"\n className={PRIMARY_BUTTON}\n >\n Next\n <ChevronRight className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n </div>\n </div>\n );\n});\n","/** Whether a key press is someone typing in a field (so global shortcuts leave it alone) */\nexport const isTyping = (target: EventTarget | null) =>\n target instanceof HTMLElement &&\n (target.isContentEditable ||\n [\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName));\n","import type { Node, Edge } from \"@xyflow/react\";\n\nexport interface NodeDisplayInfo {\n id: string;\n name: string;\n type: string;\n version?: string;\n description?: string;\n}\n\nexport interface ConnectedNodes {\n leftNodes: Node[];\n rightNodes: Node[];\n}\n\nexport const NODE_COLOR_CLASSES: Record<string, string> = {\n events: \"bg-orange-600\",\n agent: \"bg-sky-600\",\n agents: \"bg-sky-600\",\n agentTool: \"bg-violet-600\",\n \"agent-tool\": \"bg-violet-600\",\n services: \"bg-pink-600\",\n flows: \"bg-teal-600\",\n commands: \"bg-blue-600\",\n queries: \"bg-green-600\",\n channels: \"bg-gray-600\",\n systems: \"bg-purple-600\",\n externalSystem: \"bg-pink-600\",\n actor: \"bg-yellow-500\",\n step: \"bg-gray-700\",\n data: \"bg-blue-600\",\n \"data-products\": \"bg-indigo-600\",\n domains: \"bg-yellow-600\",\n entities: \"bg-purple-600\",\n field: \"bg-cyan-600\",\n messageGroup: \"bg-violet-600\",\n messageGroupExpanded: \"bg-violet-600\",\n};\n\nexport const NODE_TYPE_LABELS: Record<string, string> = {\n events: \"Event\",\n agent: \"Agent\",\n agents: \"Agent\",\n agentTool: \"Agent Tool\",\n \"agent-tool\": \"Agent Tool\",\n services: \"Service\",\n flows: \"Flow\",\n commands: \"Command\",\n queries: \"Query\",\n channels: \"Channel\",\n systems: \"System\",\n externalSystem: \"External System\",\n actor: \"Actor\",\n step: \"Step\",\n data: \"Data\",\n \"data-products\": \"Data Product\",\n domains: \"Domain\",\n entities: \"Entity\",\n field: \"Field\",\n messageGroup: \"Message Group\",\n messageGroupExpanded: \"Message Group\",\n};\n\n/**\n * Get connected nodes for a given center node\n * Left nodes: incoming edges (they send TO this node)\n * Right nodes: outgoing edges (this node sends TO them)\n */\nexport function getConnectedNodes(\n centerNodeId: string,\n nodes: Node[],\n edges: Edge[],\n): ConnectedNodes {\n const leftIds = new Set<string>();\n const rightIds = new Set<string>();\n\n edges.forEach((edge) => {\n if (edge.target === centerNodeId) {\n leftIds.add(edge.source);\n }\n if (edge.source === centerNodeId) {\n rightIds.add(edge.target);\n }\n });\n\n return {\n leftNodes: nodes.filter((n) => leftIds.has(n.id)),\n rightNodes: nodes.filter((n) => rightIds.has(n.id)),\n };\n}\n\n// Entity keys that follow the standard data structure pattern\nconst ENTITY_KEYS = [\n \"agent\",\n \"service\",\n \"message\",\n \"flow\",\n \"channel\",\n \"domain\",\n \"entity\",\n \"dataProduct\",\n \"agentTool\",\n] as const;\n\n/**\n * Extract display information from a ReactFlow node\n */\nexport function getNodeDisplayInfo(node: Node): NodeDisplayInfo {\n const nodeType = node.type || \"unknown\";\n const data = node.data as any;\n\n // Handle field nodes\n if (nodeType === \"field\") {\n return {\n id: node.id,\n name: data?.name || node.id,\n type: \"field\",\n version: undefined,\n description: `Type: ${data?.type || \"unknown\"}`,\n };\n }\n\n // Handle message group nodes\n if (nodeType === \"messageGroup\") {\n return {\n id: node.id,\n name: data?.groupName || node.id,\n type: \"messageGroup\",\n version: undefined,\n description: `${data?.messageCount || 0} messages (${data?.direction || \"unknown\"})`,\n };\n }\n\n if (nodeType === \"messageGroupExpanded\") {\n return {\n id: node.id,\n name: data?.groupName || node.id,\n type: \"messageGroupExpanded\",\n version: undefined,\n description: `${data?.messageCount || 0} messages (expanded)`,\n };\n }\n\n // Find the entity in data using standard keys\n const entityKey = ENTITY_KEYS.find((key) => data[key]);\n const entity = entityKey ? data[entityKey] : null;\n\n const name =\n entity?.data?.name || entity?.id || data.label || data.name || node.id;\n const version =\n entity?.data?.version || entity?.version || data.version || \"\";\n const description =\n entity?.data?.summary ||\n entity?.data?.description ||\n entity?.summary ||\n entity?.description ||\n data.summary ||\n data.description ||\n \"\";\n\n return {\n id: node.id,\n name,\n type: nodeType,\n version,\n description: description\n ? truncateDescription(description, 100)\n : undefined,\n };\n}\n\n/**\n * Truncate description to a max length\n */\nfunction truncateDescription(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength).trim() + \"...\";\n}\n\n/**\n * Get the color class for a node type\n */\nexport function getNodeColorClass(nodeType: string): string {\n return NODE_COLOR_CLASSES[nodeType] || \"bg-gray-500\";\n}\n\n/**\n * Get the display label for a node type\n */\nexport function getNodeTypeLabel(nodeType: string): string {\n return NODE_TYPE_LABELS[nodeType] || nodeType;\n}\n\n// Mapping from entity key to doc path\nconst DOC_PATH_MAP: Record<string, string> = {\n service: \"services\",\n agent: \"agents\",\n flow: \"flows\",\n channel: \"channels\",\n system: \"systems\",\n domain: \"domains\",\n entity: \"entities\",\n dataProduct: \"data-products\",\n};\n\n/**\n * Get the documentation URL for a node\n */\nexport function getNodeDocUrl(\n node: Pick<Node, \"type\" | \"data\">,\n): string | null {\n const nodeType = node.type || \"unknown\";\n const data = node.data as any;\n\n // Handle message type separately due to type mapping\n if (data.message) {\n const id = data.message.data?.id || data.message.id || \"\";\n const version = data.message.data?.version || data.message.version || \"\";\n const collectionType =\n nodeType === \"events\"\n ? \"events\"\n : nodeType === \"commands\"\n ? \"commands\"\n : \"queries\";\n return id && version ? `/docs/${collectionType}/${id}/${version}` : null;\n }\n\n // Handle data/container nodes with nested data.data structure\n if (data.data && nodeType === \"data\") {\n const id = data.data.id || \"\";\n const version = data.data.version || \"\";\n return id && version ? `/docs/containers/${id}/${version}` : null;\n }\n\n // Handle standard entity types\n for (const [key, path] of Object.entries(DOC_PATH_MAP)) {\n if (data[key]) {\n const id = data[key].data?.id || data[key].id || \"\";\n const version = data[key].data?.version || data[key].version || \"\";\n return id && version ? `/docs/${path}/${id}/${version}` : null;\n }\n }\n\n return null;\n}\n","import { memo } from \"react\";\nimport { useInternalNode } from \"@xyflow/react\";\nimport { CanvasPortal } from \"../utils/flow-portals\";\n\nconst BADGE_SIZE = 30;\n\nconst Badge = memo(function Badge({\n nodeId,\n number,\n current,\n}: {\n nodeId: string;\n number: number;\n current: boolean;\n}) {\n const node = useInternalNode(nodeId);\n if (!node) return null;\n const { x, y } = node.internals.positionAbsolute;\n return (\n <div\n className={`absolute flex items-center justify-center rounded-full font-bold text-white shadow-md bg-[rgb(var(--ec-accent))] ${\n current ? \"ring-4 ring-[rgb(var(--ec-accent)/0.3)]\" : \"opacity-90\"\n }`}\n style={{\n width: BADGE_SIZE,\n height: BADGE_SIZE,\n fontSize: 14,\n // On the node's top left corner\n transform: `translate(${x - BADGE_SIZE / 2}px, ${y - BADGE_SIZE / 2}px)`,\n zIndex: 2000,\n pointerEvents: \"none\",\n }}\n >\n {number}\n </div>\n );\n});\n\n/**\n * Numbers the steps walked so far in a flow walkthrough (on the nodes, in the\n * order they were walked), so the way taken through the flow stays visible.\n * A step walked more than once (a loop) shows when it was last walked.\n */\nexport default memo(function WalkthroughBadges({ trail }: { trail: string[] }) {\n if (trail.length === 0) return null;\n const numbers = new Map<string, number>();\n trail.forEach((nodeId, index) => numbers.set(nodeId, index + 1));\n const current = trail[trail.length - 1];\n return (\n <CanvasPortal>\n {[...numbers].map(([nodeId, number]) => (\n <Badge\n key={nodeId}\n nodeId={nodeId}\n number={number}\n current={nodeId === current}\n />\n ))}\n </CanvasPortal>\n );\n});\n","import { Fragment, memo, type ReactNode } from \"react\";\nimport { Panel, useReactFlow, useStore } from \"@xyflow/react\";\nimport { Code, Map, Maximize, Zap, ZoomIn, ZoomOut } from \"lucide-react\";\nimport { Tip, TipProvider } from \"./Tip\";\n\nexport type CanvasLevel = {\n description: string;\n active: boolean;\n /** Why the level is greyed out (e.g. the diagram doesn't have it), shown on hover */\n disabledReason?: string;\n onSelect: () => void;\n};\n\n/** A tool for the kind of resource shown (e.g. a domain's) */\nexport type CanvasTool = {\n label: string;\n icon: ReactNode;\n active: boolean;\n onClick: () => void;\n};\n\ninterface CanvasToolbarProps {\n /** Levels of detail, shown as L1, L2, ... */\n levels: CanvasLevel[];\n /** Tools for the resource shown, between the levels and the canvas tools */\n tools?: CanvasTool[];\n /** Shows the diagram as Mermaid (the button after the levels) */\n onShowMermaid?: () => void;\n animateMessages: boolean;\n toggleAnimateMessages: () => void;\n /** Hide the \"Simulate messages\" action (e.g. on the Context Diagram). */\n hideAnimateMessages?: boolean;\n showMinimap: boolean;\n setShowMinimap: (value: boolean) => void;\n handleFitView: () => void;\n}\n\n// A toolbar button's colours: muted, highlighted with the catalog's accent when selected, greyed out when it can't\n// be used\nconst toolbarButtonColors = ({\n active = false,\n disabled = false,\n}: {\n active?: boolean;\n disabled?: boolean;\n}) =>\n disabled\n ? \"opacity-40 cursor-not-allowed text-[rgb(var(--ec-page-text-muted))]\"\n : active\n ? \"bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.15)] text-[rgb(var(--ec-catalog-accent,79_70_229))] hover:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.22)]\"\n : \"text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.08)] hover:text-[rgb(var(--ec-page-text))]\";\n\n/** A button in a toolbar, with its tooltip (what it does, and why it can't be used when it can't) */\nexport const ToolbarButton = ({\n label,\n hint,\n active = false,\n disabled = false,\n onClick,\n children,\n}: {\n label: string;\n /** Shown under the label on hover */\n hint?: string;\n active?: boolean;\n disabled?: boolean;\n onClick: () => void;\n children: ReactNode;\n}) => {\n return (\n <Tip label={label} hint={hint}>\n <button\n type=\"button\"\n aria-label={label}\n aria-pressed={active}\n // Not `disabled`, which would stop the tooltip explaining why showing\n aria-disabled={disabled || undefined}\n onClick={disabled ? undefined : onClick}\n className={`flex items-center justify-center w-8 h-8 rounded-md transition-colors ${toolbarButtonColors(\n { active, disabled },\n )}`}\n >\n {children}\n </button>\n </Tip>\n );\n};\n\n/**\n * How far the canvas is zoomed in, as a percentage. Isolated, so what it's in only re-renders when the zoom changes\n * (not on every pan). Studio's bar shows it too.\n */\nexport const ZoomLevel = memo(function ZoomLevel({\n className = \"\",\n}: {\n className?: string;\n}) {\n const zoom = useStore((state) => Math.round(state.transform[2] * 100));\n return (\n <div\n className={`w-12 text-center text-xs font-medium tabular-nums text-[rgb(var(--ec-page-text-muted))] ${className}`}\n >\n {zoom}%\n </div>\n );\n});\n\nexport const ToolbarDivider = () => (\n <div className=\"w-px h-5 mx-1 bg-[rgb(var(--ec-page-border))]\" />\n);\n\n/** The frame of a toolbar (e.g. the bar at the bottom of a diagram, or of a Studio canvas), with tooltips */\nexport const Toolbar = ({ children }: { children: ReactNode }) => (\n <TipProvider>\n <div className=\"flex items-center gap-0.5 p-1 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] shadow-md\">\n {children}\n </div>\n </TipProvider>\n);\n\n/**\n * Switches between the diagram and its Mermaid view: in the same place in\n * both toolbars, after the levels, and on while the Mermaid view is shown\n */\nexport const MermaidToggle = ({\n active,\n onClick,\n}: {\n active: boolean;\n onClick: () => void;\n}) => (\n <ToolbarButton label=\"Render as Mermaid\" active={active} onClick={onClick}>\n <Code className=\"w-4 h-4\" />\n </ToolbarButton>\n);\n\n/** The levels of detail, as L1, L2, ... (the diagram's toolbar, and its Mermaid view's) */\nexport const LevelButtons = ({ levels }: { levels: CanvasLevel[] }) => (\n <div\n role=\"group\"\n aria-label=\"Level of detail\"\n className=\"flex items-center gap-0.5\"\n >\n {levels.map((level, index) => (\n <ToolbarButton\n key={level.description}\n label={`Level ${index + 1}: ${level.description}`}\n hint={level.disabledReason}\n active={level.active}\n disabled={!!level.disabledReason}\n onClick={level.onSelect}\n >\n <span className=\"text-xs font-semibold\">L{index + 1}</span>\n </ToolbarButton>\n ))}\n </div>\n);\n\n/**\n * Floating action bar at the bottom of the canvas for quick view actions.\n */\nconst CanvasToolbar = memo(function CanvasToolbar({\n levels,\n tools = [],\n onShowMermaid,\n animateMessages,\n toggleAnimateMessages,\n hideAnimateMessages = false,\n showMinimap,\n setShowMinimap,\n handleFitView,\n}: CanvasToolbarProps) {\n const { zoomIn, zoomOut } = useReactFlow();\n // In the same places as Studio's bar: the view on the left, then the levels, then the rest\n const groups = [\n <>\n <ToolbarButton label=\"Fit view\" onClick={handleFitView}>\n <Maximize className=\"w-4 h-4\" />\n </ToolbarButton>\n <ToolbarButton\n label=\"Zoom out\"\n onClick={() => void zoomOut({ duration: 200 })}\n >\n <ZoomOut className=\"w-4 h-4\" />\n </ToolbarButton>\n <ZoomLevel />\n <ToolbarButton\n label=\"Zoom in\"\n onClick={() => void zoomIn({ duration: 200 })}\n >\n <ZoomIn className=\"w-4 h-4\" />\n </ToolbarButton>\n </>,\n levels.length > 0 && <LevelButtons levels={levels} />,\n onShowMermaid && <MermaidToggle active={false} onClick={onShowMermaid} />,\n tools.length > 0 &&\n tools.map((tool) => (\n <ToolbarButton\n key={tool.label}\n label={tool.label}\n active={tool.active}\n onClick={tool.onClick}\n >\n {tool.icon}\n </ToolbarButton>\n )),\n <>\n {!hideAnimateMessages && (\n <ToolbarButton\n label=\"Simulate messages\"\n active={animateMessages}\n onClick={toggleAnimateMessages}\n >\n <Zap className=\"w-4 h-4\" />\n </ToolbarButton>\n )}\n <ToolbarButton\n label={showMinimap ? \"Hide minimap\" : \"Show minimap\"}\n active={showMinimap}\n onClick={() => setShowMinimap(!showMinimap)}\n >\n <Map className=\"w-4 h-4\" />\n </ToolbarButton>\n </>,\n ].filter(Boolean);\n return (\n <Panel position=\"bottom-center\">\n <Toolbar>\n {groups.map((group, index) => (\n <Fragment key={index}>\n {index > 0 && <ToolbarDivider />}\n {group}\n </Fragment>\n ))}\n </Toolbar>\n </Panel>\n );\n});\n\nexport default CanvasToolbar;\n","import type { ReactNode } from \"react\";\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\n\n/** Tooltips for a group of controls (e.g. a toolbar): shown after a moment, then straight away while moving along */\nexport const TipProvider = ({ children }: { children: ReactNode }) => (\n <Tooltip.Provider delayDuration={300}>{children}</Tooltip.Provider>\n);\n\n/**\n * A tooltip above a control: what it does, and optionally why it can't be used (`hint`). The control stays\n * focusable when unavailable (`aria-disabled`, not `disabled`), so it can still say why. Used in a TipProvider.\n */\nexport const Tip = ({\n label,\n hint,\n children,\n}: {\n label: string;\n hint?: string;\n /** The control: one element that takes a ref */\n children: ReactNode;\n}) => {\n const portalContainer = usePortalContainer();\n return (\n <Tooltip.Root>\n <Tooltip.Trigger asChild>{children}</Tooltip.Trigger>\n <Tooltip.Portal container={portalContainer}>\n <Tooltip.Content\n side=\"top\"\n sideOffset={8}\n className=\"z-50 max-w-[240px] rounded-md bg-[rgb(var(--ec-page-text))] px-2 py-1 text-xs text-[rgb(var(--ec-page-bg))] shadow-md\"\n >\n {label}\n {hint && <div className=\"mt-0.5 opacity-70\">{hint}</div>}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n};\n","import { memo, useEffect, useState, type ReactElement } from \"react\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { Check, ChevronDown, Group, Layers, Ungroup, X } from \"lucide-react\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport { isTyping } from \"../utils/keyboard\";\nimport { LANE_ICONS, LANE_TINTS } from \"../nodes/SwimlaneNode\";\nimport {\n SWIMLANE_GROUP_BY_LABELS,\n type FlowGroupBy,\n type FlowGroupStyle,\n type SwimlaneGroupBy,\n} from \"../utils/swimlanes\";\n\ninterface SwimlanePickerProps {\n /** The ways the flow can be grouped (those its steps have groups for) */\n options: FlowGroupBy[];\n /** How many groups each way of grouping makes */\n counts: Partial<Record<FlowGroupBy, number>>;\n value: FlowGroupBy | null;\n style: FlowGroupStyle;\n onChange: (value: FlowGroupBy | null, style: FlowGroupStyle) => void;\n}\n\nconst OPTIONS: Record<\n FlowGroupBy,\n {\n label: string;\n level: SwimlaneGroupBy;\n noun: string;\n hint?: string;\n icon?: typeof Layers;\n }\n> = {\n domain: {\n label: SWIMLANE_GROUP_BY_LABELS.domain,\n level: \"domain\",\n noun: \"domain\",\n },\n system: {\n label: SWIMLANE_GROUP_BY_LABELS.system,\n level: \"system\",\n noun: \"system\",\n },\n team: { label: SWIMLANE_GROUP_BY_LABELS.team, level: \"team\", noun: \"team\" },\n \"domain-system\": {\n label: SWIMLANE_GROUP_BY_LABELS[\"domain-system\"],\n level: \"domain\",\n noun: \"domain\",\n hint: \"Systems nested in their domain\",\n icon: Layers,\n },\n};\n\nconst plural = (count: number, noun: string) =>\n `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n\nconst rowClassName =\n \"flex items-center gap-2.5 px-2 py-1.5 rounded-md text-xs cursor-pointer outline-none transition-colors text-[rgb(var(--ec-page-text))] data-[highlighted]:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.05)] data-[state=checked]:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.14)] data-[state=checked]:font-semibold\";\n\nconst sectionLabelClassName =\n \"px-2 pt-1 pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-[rgb(var(--ec-page-text-muted))]\";\n\n/** What a way of grouping looks like: its icon, in the colour of its groups */\nconst LevelIcon = ({\n level,\n icon,\n}: {\n level: SwimlaneGroupBy | null;\n icon?: typeof Layers;\n}) => {\n const Icon = icon ?? (level ? LANE_ICONS[level] : Ungroup);\n const tint = level ? LANE_TINTS[level] : \"var(--ec-page-text-muted)\";\n return (\n <span\n className=\"flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-md\"\n style={{\n background: `rgba(${tint}, 0.12)`,\n color: `rgb(${tint})`,\n }}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n </span>\n );\n};\n\n// Small pictures of the two ways groups are shown\nconst BoxesPreview = () => (\n <svg viewBox=\"0 0 64 36\" className=\"h-9 w-16\" aria-hidden>\n <rect\n x=\"2\"\n y=\"4\"\n width=\"26\"\n height=\"28\"\n rx=\"4\"\n fill=\"currentColor\"\n fillOpacity=\"0.1\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.5\"\n strokeWidth=\"1.5\"\n />\n <rect\n x=\"34\"\n y=\"10\"\n width=\"28\"\n height=\"18\"\n rx=\"4\"\n fill=\"currentColor\"\n fillOpacity=\"0.1\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.5\"\n strokeWidth=\"1.5\"\n />\n <rect\n x=\"8\"\n y=\"10\"\n width=\"14\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n <rect\n x=\"8\"\n y=\"20\"\n width=\"14\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n <rect\n x=\"41\"\n y=\"16\"\n width=\"14\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n </svg>\n);\nconst LanesPreview = () => (\n <svg viewBox=\"0 0 64 36\" className=\"h-9 w-16\" aria-hidden>\n {[2, 13, 24].map((y) => (\n <rect\n key={y}\n x=\"1\"\n y={y}\n width=\"62\"\n height=\"10\"\n fill=\"currentColor\"\n fillOpacity={y === 13 ? 0.16 : 0.08}\n />\n ))}\n <rect\n x=\"1\"\n y=\"2\"\n width=\"4\"\n height=\"32\"\n fill=\"currentColor\"\n fillOpacity=\"0.35\"\n />\n <rect\n x=\"10\"\n y=\"4\"\n width=\"12\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n <rect\n x=\"28\"\n y=\"15\"\n width=\"12\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n <rect\n x=\"46\"\n y=\"26\"\n width=\"12\"\n height=\"6\"\n rx=\"1.5\"\n fill=\"currentColor\"\n fillOpacity=\"0.6\"\n />\n </svg>\n);\n\nconst STYLES: {\n value: FlowGroupStyle;\n label: string;\n Preview: () => ReactElement;\n}[] = [\n { value: \"boxes\", label: \"Boxes\", Preview: BoxesPreview },\n { value: \"lanes\", label: \"Lanes\", Preview: LanesPreview },\n];\n\n/**\n * Picks what a flow's steps are grouped by, if anything, and whether the\n * groups are boxes around their steps or full-width lanes. A single button\n * (showing the grouping, with a button to clear it) that opens a menu; G\n * opens it too. The menu stays open while choosing, so ways of grouping can\n * be compared.\n */\nexport default memo(function SwimlanePicker({\n options,\n counts,\n value,\n style,\n onChange,\n}: SwimlanePickerProps) {\n const portalContainer = usePortalContainer();\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (\n event.key.toLowerCase() !== \"g\" ||\n event.metaKey ||\n event.ctrlKey ||\n event.altKey ||\n isTyping(event.target)\n )\n return;\n event.preventDefault();\n setOpen((isOpen) => !isOpen);\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, []);\n\n const choose = (next: string) => {\n const groupBy = next === \"none\" ? null : (next as FlowGroupBy);\n // Only boxes nest, so domains with their systems are always boxes\n onChange(groupBy, groupBy === \"domain-system\" ? \"boxes\" : style);\n };\n const current = value ? OPTIONS[value] : null;\n\n return (\n <div className=\"flex items-stretch h-10 rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] shadow-sm\">\n <DropdownMenu.Root open={open} onOpenChange={setOpen}>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n title=\"Group steps (G)\"\n className={`flex items-center gap-2 pl-3 pr-2.5 text-sm outline-none transition-colors hover:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.06)] focus-visible:ring-2 focus-visible:ring-[rgb(var(--ec-catalog-accent,79_70_229))] ${value ? \"rounded-l-md\" : \"rounded-md\"}`}\n >\n <Group className=\"h-4 w-4 text-[rgb(var(--ec-page-text-muted))]\" />\n <span className=\"text-[rgb(var(--ec-page-text-muted))]\">\n Group by\n </span>\n {current && (\n <span\n className={`font-semibold text-[rgb(var(--ec-catalog-accent,79_70_229))]`}\n >\n {current.label}\n </span>\n )}\n <ChevronDown\n className={`h-3.5 w-3.5 text-[rgb(var(--ec-page-text-muted))] transition-transform`}\n style={open ? { transform: \"rotate(180deg)\" } : undefined}\n />\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal container={portalContainer}>\n <DropdownMenu.Content\n align=\"end\"\n sideOffset={6}\n className=\"z-50 w-80 p-1.5 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] shadow-xl animate-in fade-in zoom-in-95 duration-150\"\n >\n <DropdownMenu.Label className={sectionLabelClassName}>\n Group steps by\n </DropdownMenu.Label>\n <DropdownMenu.RadioGroup\n value={value ?? \"none\"}\n onValueChange={choose}\n >\n <DropdownMenu.RadioItem\n value=\"none\"\n className={rowClassName}\n onSelect={(event) => event.preventDefault()}\n >\n <LevelIcon level={null} />\n <span className=\"flex-1 font-medium\">Nothing</span>\n <DropdownMenu.ItemIndicator>\n <Check\n className={`h-3.5 w-3.5 text-[rgb(var(--ec-catalog-accent,79_70_229))]`}\n />\n </DropdownMenu.ItemIndicator>\n </DropdownMenu.RadioItem>\n {options.map((option) => {\n const { label, level, noun, hint, icon } = OPTIONS[option];\n const count = counts[option] ?? 0;\n return (\n <DropdownMenu.RadioItem\n key={option}\n value={option}\n className={rowClassName}\n onSelect={(event) => event.preventDefault()}\n >\n <LevelIcon level={level} icon={icon} />\n <span className=\"flex-1 min-w-0\">\n <span className=\"block font-medium\">{label}</span>\n {hint && (\n <span className=\"block text-[11px] text-[rgb(var(--ec-page-text-muted))]\">\n {hint}\n </span>\n )}\n </span>\n <span className=\"text-[11px] tabular-nums text-[rgb(var(--ec-page-text-muted))]\">\n {plural(count, noun)}\n </span>\n <span className=\"w-3.5\">\n <DropdownMenu.ItemIndicator>\n <Check\n className={`h-3.5 w-3.5 text-[rgb(var(--ec-catalog-accent,79_70_229))]`}\n />\n </DropdownMenu.ItemIndicator>\n </span>\n </DropdownMenu.RadioItem>\n );\n })}\n </DropdownMenu.RadioGroup>\n\n <DropdownMenu.Separator className=\"my-1.5 h-px bg-[rgb(var(--ec-page-border))]\" />\n\n <DropdownMenu.Label className={sectionLabelClassName}>\n Show groups as\n </DropdownMenu.Label>\n <DropdownMenu.RadioGroup\n value={style}\n onValueChange={(next) => onChange(value, next as FlowGroupStyle)}\n className=\"grid grid-cols-2 gap-1.5 px-0.5 pb-0.5\"\n >\n {STYLES.map(({ value: option, label, Preview }) => {\n const active = !!value && style === option;\n // Lanes don't nest: domains with their systems show as domains\n const note =\n option === \"lanes\" && value === \"domain-system\"\n ? \"Domains only\"\n : null;\n return (\n <DropdownMenu.RadioItem\n key={option}\n value={option}\n disabled={!value}\n onSelect={(event) => event.preventDefault()}\n className={`flex flex-col items-center gap-1 rounded-md border px-2 pt-2 pb-1.5 text-xs outline-none cursor-pointer transition-colors data-[disabled]:cursor-not-allowed data-[disabled]:opacity-40 ${\n active\n ? `border-[rgb(var(--ec-catalog-accent,79_70_229))] bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.08)] text-[rgb(var(--ec-catalog-accent,79_70_229))]`\n : `border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text-muted))] data-[highlighted]:border-[rgb(var(--ec-catalog-accent,79_70_229)/0.5)] data-[highlighted]:text-[rgb(var(--ec-page-text))]`\n }`}\n >\n <Preview />\n <span className={active ? \"font-semibold\" : \"font-medium\"}>\n {label}\n </span>\n {note && (\n <span className=\"text-[10px] text-[rgb(var(--ec-page-text-muted))]\">\n {note}\n </span>\n )}\n </DropdownMenu.RadioItem>\n );\n })}\n </DropdownMenu.RadioGroup>\n {!value && (\n <p className=\"px-2 pt-1.5 pb-0.5 text-[11px] text-[rgb(var(--ec-page-text-muted))]\">\n Pick something to group by first.\n </p>\n )}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n {value && (\n <button\n type=\"button\"\n aria-label=\"Stop grouping\"\n title=\"Stop grouping\"\n onClick={() => onChange(null, style)}\n className={`flex items-center px-2 rounded-r-md border-l border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text-muted))] outline-none transition-colors hover:bg-[rgb(var(--ec-catalog-accent,79_70_229)/0.06)] hover:text-[rgb(var(--ec-page-text))] focus-visible:ring-2 focus-visible:ring-[rgb(var(--ec-catalog-accent,79_70_229))]`}\n >\n <X className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </div>\n );\n});\n","import React, { useState, useCallback, useEffect } from \"react\";\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { XIcon, FocusIcon } from \"lucide-react\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport {\n ReactFlowProvider,\n type Node,\n type Edge,\n type NodeTypes,\n type EdgeTypes,\n} from \"@xyflow/react\";\nimport FocusModeContent from \"./FocusMode/FocusModeContent\";\nimport { getNodeDisplayInfo } from \"./FocusMode/utils\";\nimport { useDarkMode } from \"../nodes/shared-styles\";\n\ninterface FocusModeModalProps {\n isOpen: boolean;\n onClose: () => void;\n initialNodeId: string | null;\n nodes: Node[];\n edges: Edge[];\n nodeTypes: NodeTypes;\n edgeTypes: EdgeTypes;\n}\n\nconst FocusModeModal: React.FC<FocusModeModalProps> = ({\n isOpen,\n onClose,\n initialNodeId,\n nodes,\n edges,\n nodeTypes,\n edgeTypes,\n}) => {\n const [centerNodeId, setCenterNodeId] = useState<string | null>(\n initialNodeId,\n );\n const isDark = useDarkMode();\n const portalContainer = usePortalContainer();\n\n // Reset center node when modal opens with new initial node\n useEffect(() => {\n if (isOpen && initialNodeId) {\n setCenterNodeId(initialNodeId);\n }\n }, [isOpen, initialNodeId]);\n\n const handleSwitchCenter = useCallback(\n (newCenterNodeId: string, _direction: \"left\" | \"right\") => {\n setCenterNodeId(newCenterNodeId);\n },\n [],\n );\n\n // Get center node info for title\n const centerNode = centerNodeId\n ? nodes.find((n) => n.id === centerNodeId)\n : null;\n const centerNodeInfo = centerNode ? getNodeDisplayInfo(centerNode) : null;\n\n if (!centerNodeId) {\n return null;\n }\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <Dialog.Portal>\n <div\n className=\"eventcatalog-visualizer\"\n style={{\n position: \"fixed\",\n inset: 0,\n isolation: \"isolate\",\n zIndex: 99999,\n }}\n >\n <Dialog.Overlay\n style={{\n position: \"fixed\",\n inset: 0,\n background: isDark\n ? \"rgba(0, 0, 0, 0.75)\"\n : \"rgba(15, 23, 42, 0.55)\",\n backdropFilter: \"blur(2px)\",\n }}\n />\n <Dialog.Content\n style={{\n position: \"fixed\",\n inset: \"5%\",\n borderRadius: 12,\n background: isDark ? \"#0f172a\" : \"#ffffff\",\n border: `1px solid ${\n isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.08)\"\n }`,\n boxShadow: isDark\n ? \"0 24px 48px rgba(0,0,0,0.5)\"\n : \"0 24px 48px rgba(0,0,0,0.15)\",\n outline: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n >\n {/* Header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"1rem 1.5rem\",\n borderBottom: `1px solid ${\n isDark ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.08)\"\n }`,\n flexShrink: 0,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 12 }}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 40,\n height: 40,\n borderRadius: 10,\n background: isDark\n ? \"rgba(59, 130, 246, 0.18)\"\n : \"rgba(59, 130, 246, 0.12)\",\n }}\n >\n <FocusIcon\n style={{\n width: 20,\n height: 20,\n color: isDark ? \"#93c5fd\" : \"#2563eb\",\n }}\n />\n </div>\n <div>\n <Dialog.Title\n style={{\n fontSize: 18,\n fontWeight: 600,\n color: isDark ? \"#f8fafc\" : \"#0f172a\",\n }}\n >\n Focus Mode\n </Dialog.Title>\n <Dialog.Description\n style={{\n marginTop: 2,\n fontSize: 14,\n color: isDark ? \"#94a3b8\" : \"#475569\",\n }}\n >\n {centerNodeInfo\n ? `Exploring: ${centerNodeInfo.name} - Click on connected nodes to navigate`\n : \"Explore node connections\"}\n </Dialog.Description>\n </div>\n </div>\n <Dialog.Close asChild>\n <button\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 40,\n height: 40,\n borderRadius: 10,\n border: \"none\",\n cursor: \"pointer\",\n background: \"transparent\",\n color: isDark ? \"#94a3b8\" : \"#64748b\",\n }}\n aria-label=\"Close\"\n >\n <XIcon style={{ width: 20, height: 20 }} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Content */}\n <div style={{ flex: 1, overflow: \"hidden\" }}>\n <ReactFlowProvider>\n <FocusModeContent\n centerNodeId={centerNodeId}\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n onSwitchCenter={handleSwitchCenter}\n />\n </ReactFlowProvider>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n};\n\nexport default FocusModeModal;\n","import React, {\n useMemo,\n useCallback,\n useEffect,\n useState,\n useRef,\n} from \"react\";\nimport {\n ReactFlow,\n Background,\n Controls,\n useReactFlow,\n useNodesState,\n useEdgesState,\n type Node,\n type Edge,\n type NodeTypes,\n type EdgeTypes,\n} from \"@xyflow/react\";\nimport { getConnectedNodes, getNodeDisplayInfo } from \"./utils\";\nimport FocusModeNodeActions from \"./FocusModeNodeActions\";\nimport FocusModePlaceholder from \"./FocusModePlaceholder\";\n\n// Static props for ReactFlow: a new object on every render would re-render the whole canvas\nconst HIDE_ATTRIBUTION = { hideAttribution: true };\n\ninterface FocusModeContentProps {\n centerNodeId: string;\n nodes: Node[];\n edges: Edge[];\n nodeTypes: NodeTypes;\n edgeTypes: EdgeTypes;\n onSwitchCenter: (\n newCenterNodeId: string,\n direction: \"left\" | \"right\",\n ) => void;\n}\n\nconst HORIZONTAL_SPACING = 450;\nconst VERTICAL_SPACING = 200;\nconst SLIDE_DURATION = 300;\n\nconst FocusModeContent: React.FC<FocusModeContentProps> = ({\n centerNodeId,\n nodes: allNodes,\n edges: allEdges,\n nodeTypes,\n edgeTypes,\n onSwitchCenter,\n}) => {\n const { fitView } = useReactFlow();\n const [isAnimating, setIsAnimating] = useState(false);\n const [needsFitView, setNeedsFitView] = useState(false);\n const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);\n const [isReady, setIsReady] = useState(false);\n const reactFlowInitialized = useRef(false);\n const animationTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (animationTimeoutRef.current) {\n clearTimeout(animationTimeoutRef.current);\n }\n };\n }, []);\n\n // Calculate focused nodes and edges with positions\n const calculateFocusedGraph = useCallback(\n (centerId: string) => {\n const centerNode = allNodes.find((n) => n.id === centerId);\n if (!centerNode) {\n return { nodes: [], edges: [] };\n }\n\n const { leftNodes, rightNodes } = getConnectedNodes(\n centerId,\n allNodes,\n allEdges,\n );\n const centerNodeInfo = getNodeDisplayInfo(centerNode);\n const positionedNodes: Node[] = [];\n\n // Center node at origin (strip parentId/extent so it renders independently)\n positionedNodes.push({\n ...centerNode,\n parentId: undefined,\n extent: undefined,\n position: { x: 0, y: 0 },\n style: { ...centerNode.style, opacity: 1 },\n data: { ...centerNode.data, isFocusCenter: true },\n });\n\n // Left nodes (incoming) - strip parentId/extent so they render independently\n leftNodes.forEach((node, index) => {\n const yOffset = (index - (leftNodes.length - 1) / 2) * VERTICAL_SPACING;\n positionedNodes.push({\n ...node,\n parentId: undefined,\n extent: undefined,\n position: { x: -HORIZONTAL_SPACING, y: yOffset },\n style: { ...node.style, opacity: 1 },\n });\n });\n\n // Right nodes (outgoing) - strip parentId/extent so they render independently\n rightNodes.forEach((node, index) => {\n const yOffset =\n (index - (rightNodes.length - 1) / 2) * VERTICAL_SPACING;\n positionedNodes.push({\n ...node,\n parentId: undefined,\n extent: undefined,\n position: { x: HORIZONTAL_SPACING, y: yOffset },\n style: { ...node.style, opacity: 1 },\n });\n });\n\n // Add placeholder nodes if no connections exist\n if (leftNodes.length === 0) {\n positionedNodes.push({\n id: \"__placeholder-left__\",\n type: \"placeholder\",\n position: { x: -HORIZONTAL_SPACING, y: 0 },\n data: {\n label: `No inputs found for \"${centerNodeInfo.name}\" in this diagram`,\n side: \"left\",\n },\n draggable: false,\n selectable: false,\n } as Node);\n }\n\n if (rightNodes.length === 0) {\n positionedNodes.push({\n id: \"__placeholder-right__\",\n type: \"placeholder\",\n position: { x: HORIZONTAL_SPACING, y: 0 },\n data: {\n label: `No outputs found for \"${centerNodeInfo.name}\" in this diagram`,\n side: \"right\",\n },\n draggable: false,\n selectable: false,\n } as Node);\n }\n\n // Filter edges - only show edges connected to center node\n const focusedNodeIds = new Set(positionedNodes.map((n) => n.id));\n const filteredEdges = allEdges\n .filter((edge) => {\n // Only include edges where center node is either source or target\n const connectsToCenter =\n edge.source === centerId || edge.target === centerId;\n // And the other end is in our focused nodes\n const otherEndInFocus =\n focusedNodeIds.has(edge.source) && focusedNodeIds.has(edge.target);\n return connectsToCenter && otherEndInFocus;\n })\n .map((edge) => ({\n ...edge,\n style: { ...edge.style, opacity: 1 },\n labelStyle: { ...edge.labelStyle, opacity: 1 },\n data: { ...edge.data, opacity: 1, animated: false },\n animated: false,\n }));\n\n return { nodes: positionedNodes, edges: filteredEdges };\n },\n [allNodes, allEdges],\n );\n\n // Initial graph\n const initialGraph = useMemo(\n () => calculateFocusedGraph(centerNodeId),\n [centerNodeId, calculateFocusedGraph],\n );\n\n const [displayNodes, setDisplayNodes] = useNodesState(initialGraph.nodes);\n const [displayEdges, setDisplayEdges] = useEdgesState(initialGraph.edges);\n\n // Update when centerNodeId changes externally\n useEffect(() => {\n const { nodes, edges } = calculateFocusedGraph(centerNodeId);\n setDisplayNodes(nodes);\n setDisplayEdges(edges);\n setNeedsFitView(true);\n }, [centerNodeId, calculateFocusedGraph, setDisplayNodes, setDisplayEdges]);\n\n // FitView when needed - triggered after nodes are updated\n useEffect(() => {\n if (needsFitView && reactFlowInitialized.current) {\n // Small delay to ensure nodes are rendered, then fit view\n const timer = setTimeout(() => {\n fitView({ padding: 0.2, duration: 300 });\n setNeedsFitView(false);\n }, 50);\n return () => clearTimeout(timer);\n }\n }, [needsFitView, displayNodes, fitView]);\n\n // Handle ReactFlow initialization\n const handleInit = useCallback(() => {\n reactFlowInitialized.current = true;\n // Dialog opens instantly (no animation), so fitView immediately\n requestAnimationFrame(() => {\n fitView({ padding: 0.2, duration: 0 });\n setIsReady(true);\n });\n }, [fitView]);\n\n // Handle switching to a new center node with animation\n const handleSwitchNode = useCallback(\n (nodeId: string, direction: \"left\" | \"right\") => {\n if (nodeId === centerNodeId || isAnimating) return;\n\n setIsAnimating(true);\n\n // Animate: clicked node slides to center, current center hides\n setDisplayNodes((currentNodes) =>\n currentNodes.map((node) => {\n if (node.id === nodeId) {\n // Clicked node slides to center\n return {\n ...node,\n position: { x: 0, y: 0 },\n style: {\n ...node.style,\n transition: `all ${SLIDE_DURATION}ms ease-out`,\n },\n };\n }\n if (node.id === centerNodeId) {\n // Current center node hides\n return {\n ...node,\n style: {\n ...node.style,\n opacity: 0,\n transition: `opacity ${SLIDE_DURATION}ms ease-out`,\n },\n };\n }\n return node;\n }),\n );\n\n // After slide completes, switch to new center\n animationTimeoutRef.current = setTimeout(() => {\n onSwitchCenter(nodeId, direction);\n setIsAnimating(false);\n }, SLIDE_DURATION);\n },\n [centerNodeId, isAnimating, setDisplayNodes, onSwitchCenter],\n );\n\n // Handle node click with animation\n const handleNodeClick = useCallback(\n (_: React.MouseEvent, clickedNode: Node) => {\n if (clickedNode.id === centerNodeId || isAnimating) return;\n const direction = (clickedNode.position?.x ?? 0) < 0 ? \"left\" : \"right\";\n handleSwitchNode(clickedNode.id, direction);\n },\n [centerNodeId, isAnimating, handleSwitchNode],\n );\n\n // Handle edge hover for animation\n const handleEdgeMouseEnter = useCallback(\n (_: React.MouseEvent, edge: Edge) => {\n setHoveredEdgeId(edge.id);\n },\n [],\n );\n\n const handleEdgeMouseLeave = useCallback(() => {\n setHoveredEdgeId(null);\n }, []);\n\n // Apply hover animation to edges - use ReactFlow's built-in animated property\n const edgesWithHover = useMemo(() => {\n return displayEdges.map((edge) => {\n if (edge.id === hoveredEdgeId) {\n return {\n ...edge,\n animated: true,\n };\n }\n return edge;\n });\n }, [displayEdges, hoveredEdgeId]);\n\n // Merge nodeTypes with placeholder\n const mergedNodeTypes = useMemo(\n () => ({\n ...nodeTypes,\n placeholder: FocusModePlaceholder,\n }),\n [nodeTypes],\n );\n\n if (displayNodes.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-[rgb(var(--ec-page-text-muted))]\">\n Node not found\n </div>\n );\n }\n\n return (\n <div\n className=\"h-full w-full focus-mode-container\"\n style={{ opacity: isReady ? 1 : 0 }}\n >\n <ReactFlow\n nodes={displayNodes}\n edges={edgesWithHover}\n nodeTypes={mergedNodeTypes}\n edgeTypes={edgeTypes}\n onNodeClick={handleNodeClick}\n onEdgeMouseEnter={handleEdgeMouseEnter}\n onEdgeMouseLeave={handleEdgeMouseLeave}\n onInit={handleInit}\n proOptions={HIDE_ATTRIBUTION}\n nodesDraggable={true}\n nodesConnectable={false}\n elementsSelectable={true}\n panOnDrag={true}\n zoomOnScroll={true}\n minZoom={0.3}\n maxZoom={2}\n >\n <Background color=\"rgb(var(--ec-page-border))\" gap={20} />\n <Controls showInteractive={false} />\n {displayNodes.map((node, index) => (\n <FocusModeNodeActions\n key={`actions-${node.id}-${index}`}\n node={node}\n isCenter={node.id === centerNodeId}\n onSwitch={handleSwitchNode}\n />\n ))}\n </ReactFlow>\n </div>\n );\n};\n\nexport default FocusModeContent;\n","import React, { memo } from \"react\";\nimport {\n NodeToolbar,\n Position,\n useStore,\n type Node,\n type ReactFlowState,\n} from \"@xyflow/react\";\nimport { ArrowRightLeft, FileText } from \"lucide-react\";\nimport { getNodeDocUrl } from \"./utils\";\nimport { buildUrl } from \"../../utils/url-builder\";\n\ninterface FocusModeNodeActionsProps {\n node: Node;\n isCenter: boolean;\n onSwitch: (nodeId: string, direction: \"left\" | \"right\") => void;\n}\n\n// Smaller when zoomed out (not below 40%): only the zoom, so panning doesn't re-render every node's actions\nconst selectScaleFactor = (state: ReactFlowState) =>\n Math.max(0.4, Math.min(1, state.transform[2]));\n\nconst FocusModeNodeActions: React.FC<FocusModeNodeActionsProps> = ({\n node,\n isCenter,\n onSwitch,\n}) => {\n const scaleFactor = useStore(selectScaleFactor);\n\n // Don't show actions for placeholder nodes\n if (node.type === \"placeholder\") return null;\n\n const docUrl = getNodeDocUrl(node);\n const direction = (node.position?.x ?? 0) < 0 ? \"left\" : \"right\";\n\n // Scale sizes based on zoom (inverse relationship - smaller when zoomed out)\n const baseButtonSize = 24;\n const baseIconSize = 12;\n const buttonSize = Math.round(baseButtonSize * scaleFactor);\n const iconSize = Math.round(baseIconSize * scaleFactor);\n\n const handleSwitch = (e: React.MouseEvent) => {\n e.stopPropagation();\n onSwitch(node.id, direction);\n };\n\n const handleDocClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (docUrl) {\n window.location.href = buildUrl(docUrl);\n }\n };\n\n // Center node only shows docs icon (if available)\n if (isCenter) {\n if (!docUrl) return null;\n return (\n <NodeToolbar\n nodeId={node.id}\n position={Position.Bottom}\n isVisible={true}\n offset={-16}\n >\n <div\n className=\"flex items-center gap-1 bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-lg shadow-md\"\n style={{ padding: Math.round(4 * scaleFactor) }}\n >\n <button\n onClick={handleDocClick}\n className=\"flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors\"\n style={{ width: buttonSize, height: buttonSize }}\n title=\"View documentation\"\n >\n <FileText style={{ width: iconSize, height: iconSize }} />\n </button>\n </div>\n </NodeToolbar>\n );\n }\n\n return (\n <NodeToolbar\n nodeId={node.id}\n position={Position.Bottom}\n isVisible={true}\n offset={-16}\n >\n <div\n className=\"flex items-center gap-1 bg-[rgb(var(--ec-card-bg,var(--ec-page-bg)))] border border-[rgb(var(--ec-page-border))] rounded-lg shadow-md\"\n style={{ padding: Math.round(4 * scaleFactor) }}\n >\n {docUrl && (\n <button\n onClick={handleDocClick}\n className=\"flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors\"\n style={{ width: buttonSize, height: buttonSize }}\n title=\"View documentation\"\n >\n <FileText style={{ width: iconSize, height: iconSize }} />\n </button>\n )}\n <button\n onClick={handleSwitch}\n className=\"flex items-center justify-center rounded-md text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))] transition-colors\"\n style={{ width: buttonSize, height: buttonSize }}\n title=\"Focus on this node\"\n >\n <ArrowRightLeft style={{ width: iconSize, height: iconSize }} />\n </button>\n </div>\n </NodeToolbar>\n );\n};\n\nexport default memo(FocusModeNodeActions);\n","import React from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\n\ninterface FocusModePlaceholderProps {\n data: {\n label: string;\n side: \"left\" | \"right\";\n };\n}\n\nconst FocusModePlaceholder: React.FC<FocusModePlaceholderProps> = ({\n data,\n}) => {\n const { label, side } = data;\n\n return (\n <div\n className=\"px-4 py-4 rounded-lg border-2 border-dashed border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.5)] max-w-[280px] flex items-center justify-center\"\n style={{ opacity: 0.6, minHeight: \"130px\" }}\n >\n {side === \"right\" && (\n <Handle\n type=\"target\"\n position={Position.Left}\n style={{ visibility: \"hidden\" }}\n />\n )}\n <div className=\"text-center text-sm text-[rgb(var(--ec-page-text-muted))] italic\">\n {label}\n </div>\n {side === \"left\" && (\n <Handle\n type=\"source\"\n position={Position.Right}\n style={{ visibility: \"hidden\" }}\n />\n )}\n </div>\n );\n};\n\nexport default FocusModePlaceholder;\n","import { memo } from \"react\";\nimport { Background } from \"@xyflow/react\";\n\n/**\n * A diagram's background: dots on the canvas colour (`.react-flow` in styles-core.css), the same wherever a\n * diagram is drawn (the visualiser and Studio)\n */\nconst DiagramBackground = memo(function DiagramBackground() {\n return <Background color=\"var(--ec-bg-dots)\" gap={16} />;\n});\n\nexport default DiagramBackground;\n","import { memo } from \"react\";\nimport { MiniMap, type MiniMapNodeProps } from \"@xyflow/react\";\nimport { getMiniMapNodeClassName } from \"../utils/minimap\";\n\nconst MINIMAP_STYLE = {\n backgroundColor: \"rgb(var(--ec-card-bg))\",\n border: \"1px solid rgb(var(--ec-page-border))\",\n borderRadius: \"8px\",\n} as const;\n\n/**\n * A node on the minimap: a rect coloured by its class names alone (`.ec-minimap-*` in styles-core.css and\n * styles.css), so a node's own style (e.g. a transparent background) doesn't hide it\n */\nconst DiagramMiniMapNode = memo(function DiagramMiniMapNode({\n x,\n y,\n width,\n height,\n className,\n shapeRendering,\n}: MiniMapNodeProps) {\n return (\n <rect\n className={className}\n x={x}\n y={y}\n rx={6}\n ry={6}\n width={width}\n height={height}\n shapeRendering={shapeRendering}\n />\n );\n});\n\n/**\n * A diagram's minimap: each node in its resource's colour, and domains and systems as outlined containers with\n * what's in them inside, as the diagram draws them. The same wherever a diagram is drawn (the visualiser and Studio).\n */\nconst DiagramMiniMap = memo(function DiagramMiniMap() {\n return (\n <MiniMap\n zoomable\n pannable\n style={MINIMAP_STYLE}\n nodeClassName={getMiniMapNodeClassName}\n nodeComponent={DiagramMiniMapNode}\n />\n );\n});\n\nexport default DiagramMiniMap;\n","import type { Node } from \"@xyflow/react\";\n\n/**\n * How the minimap draws each kind of node, so it looks like the diagram: each resource in its colour (the\n * `--ec-minimap-<kind>` variables in styles-core.css and styles.css, for light and dark), and containers (domains,\n * systems, groups) outlined in theirs, with what's in them drawn inside.\n *\n * The minimap re-renders while the diagram pans and nodes are dragged, so this is a static lookup by node type.\n */\n\nexport type MiniMapKind =\n | \"event\"\n | \"command\"\n | \"query\"\n | \"service\"\n | \"channel\"\n | \"data\"\n | \"agent\"\n | \"view\"\n | \"message-group\"\n | \"system\"\n | \"external\"\n | \"domain\"\n | \"actor\"\n | \"flow\"\n | \"entity\"\n | \"note\"\n | \"other\";\n\n// Node types as the visualiser's diagrams (singular and plural) and Studio's canvases name them\nconst KIND_BY_TYPE: Record<string, MiniMapKind> = {\n event: \"event\",\n events: \"event\",\n command: \"command\",\n commands: \"command\",\n query: \"query\",\n queries: \"query\",\n service: \"service\",\n services: \"service\",\n channel: \"channel\",\n channels: \"channel\",\n data: \"data\",\n container: \"data\",\n \"data-product\": \"data\",\n \"data-products\": \"data\",\n agent: \"agent\",\n agents: \"agent\",\n view: \"view\",\n agentTool: \"message-group\",\n \"agent-tool\": \"message-group\",\n messageGroup: \"message-group\",\n messageGroupExpanded: \"message-group\",\n system: \"system\",\n systems: \"system\",\n \"system-group\": \"system\",\n externalSystem: \"external\",\n \"external-system\": \"external\",\n domain: \"domain\",\n domains: \"domain\",\n \"context-domain\": \"domain\",\n \"domain-group\": \"domain\",\n actor: \"actor\",\n \"context-actor\": \"actor\",\n user: \"actor\",\n flow: \"flow\",\n flows: \"flow\",\n flowExpanded: \"flow\",\n entity: \"entity\",\n entities: \"entity\",\n field: \"entity\",\n note: \"note\",\n};\n\n// Nodes that hold others: outlined, so what's in them shows through\nconst CONTAINER_TYPES = new Set([\n \"domain-group\",\n \"system-group\",\n \"group\",\n \"swimlane\",\n \"messageGroupExpanded\",\n \"flowExpanded\",\n]);\n\nexport const getMiniMapKind = (type?: string): MiniMapKind =>\n (type && KIND_BY_TYPE[type]) || \"other\";\n\n// A system outside the organisation (a third party, e.g. Stripe): its card keeps it on `system.scope`, Studio on `scope`\nconst isExternal = (data: Node[\"data\"] | undefined) =>\n data?.scope === \"external\" ||\n (data?.system as { scope?: string } | undefined)?.scope === \"external\";\n\n/** The minimap's class names for a node: its kind, whether it's a container, and whether it's an external system */\nexport const getMiniMapNodeClassName = (\n node: Pick<Node, \"type\" | \"data\">,\n): string => {\n const { type } = node;\n let className = `ec-minimap-node ec-minimap-${getMiniMapKind(type)}`;\n if (type && CONTAINER_TYPES.has(type)) className += \" ec-minimap-container\";\n if (isExternal(node.data)) className += \" ec-minimap-external\";\n return className;\n};\n\n/** Where the person's choice to show the minimap is kept, so it stays on across levels and diagrams */\nexport const SHOW_MINIMAP_STORAGE_KEY = \"EventCatalog:showMinimap\";\n\n/** Whether the person last chose to show the minimap (hidden until they do, or when storage is blocked) */\nexport const getStoredShowMinimap = (): boolean => {\n try {\n return localStorage.getItem(SHOW_MINIMAP_STORAGE_KEY) === \"true\";\n } catch {\n return false;\n }\n};\n\nexport const storeShowMinimap = (show: boolean) => {\n try {\n localStorage.setItem(SHOW_MINIMAP_STORAGE_KEY, String(show));\n } catch {\n // Storage blocked: the minimap is shown or hidden until the diagram is left\n }\n};\n","import { memo } from \"react\";\nimport { Panel, type Node } from \"@xyflow/react\";\nimport {\n Zap,\n Bot,\n Wrench,\n ServerIcon,\n Workflow,\n MessageSquare,\n Search as SearchIcon,\n ArrowLeftRight,\n Group as GroupIcon,\n Globe,\n User,\n Database,\n Boxes,\n Box,\n type LucideIcon,\n} from \"lucide-react\";\n\n/**\n * A diagram's legend: how many of each kind of node it shows (and of each domain's, when steps are grouped by\n * domain), with the kind's icon. Clicking an entry hides or shows those nodes. Studio's canvases have the same one.\n */\n\nexport type LegendEntry = {\n count: number;\n colorClass: string;\n groupId?: string;\n};\n\n// Boundaries around other nodes, left out of the legend\nconst GROUP_NODE_TYPES = [\"group\", \"system-group\", \"domain-group\", \"swimlane\"];\n\n// Friendly labels for legend keys that differ from their raw node type (shown capitalised)\nconst LEGEND_LABELS: Record<string, string> = {\n \"context-actor\": \"Actors\",\n \"context-domain\": \"Domains\",\n // Studio's node types are singular: listed like the visualiser's\n service: \"services\",\n event: \"events\",\n command: \"commands\",\n query: \"queries\",\n channel: \"channels\",\n system: \"systems\",\n agent: \"agents\",\n actor: \"Actors\",\n view: \"views\",\n};\n\nconst getLegendLabel = (key: string) => LEGEND_LABELS[key] ?? key;\n\n// Icon + text colour per legend key, mirroring each collection's node styling.\n// When a key has no icon mapped, the legend falls back to its coloured square.\nconst LEGEND_ICONS: Record<string, { Icon: LucideIcon; colorClass: string }> = {\n events: { Icon: Zap, colorClass: \"text-orange-600\" },\n event: { Icon: Zap, colorClass: \"text-orange-600\" },\n agent: { Icon: Bot, colorClass: \"text-sky-600\" },\n agents: { Icon: Bot, colorClass: \"text-sky-600\" },\n agentTool: { Icon: Wrench, colorClass: \"text-violet-600\" },\n \"agent-tool\": { Icon: Wrench, colorClass: \"text-violet-600\" },\n services: { Icon: ServerIcon, colorClass: \"text-pink-600\" },\n service: { Icon: ServerIcon, colorClass: \"text-pink-600\" },\n flows: { Icon: Workflow, colorClass: \"text-teal-600\" },\n commands: { Icon: MessageSquare, colorClass: \"text-blue-600\" },\n command: { Icon: MessageSquare, colorClass: \"text-blue-600\" },\n queries: { Icon: SearchIcon, colorClass: \"text-green-600\" },\n query: { Icon: SearchIcon, colorClass: \"text-green-600\" },\n channels: { Icon: ArrowLeftRight, colorClass: \"text-gray-600\" },\n channel: { Icon: ArrowLeftRight, colorClass: \"text-gray-600\" },\n externalSystem: { Icon: Globe, colorClass: \"text-pink-600\" },\n systems: { Icon: GroupIcon, colorClass: \"text-purple-600\" },\n system: { Icon: GroupIcon, colorClass: \"text-purple-600\" },\n actor: { Icon: User, colorClass: \"text-yellow-500\" },\n \"context-actor\": { Icon: User, colorClass: \"text-yellow-500\" },\n \"context-domain\": { Icon: Boxes, colorClass: \"text-yellow-500\" },\n data: { Icon: Database, colorClass: \"text-blue-600\" },\n \"data-products\": { Icon: Boxes, colorClass: \"text-indigo-600\" },\n field: { Icon: Box, colorClass: \"text-cyan-600\" },\n};\n\n// The coloured square for kinds without an icon\nconst LEGEND_COLORS: Record<string, string> = {\n events: \"bg-orange-600\",\n agent: \"bg-sky-600\",\n agents: \"bg-sky-600\",\n agentTool: \"bg-violet-600\",\n \"agent-tool\": \"bg-violet-600\",\n services: \"bg-pink-600\",\n flows: \"bg-teal-600\",\n commands: \"bg-blue-600\",\n queries: \"bg-green-600\",\n channels: \"bg-gray-600\",\n externalSystem: \"bg-pink-600\",\n systems: \"bg-purple-600\",\n system: \"bg-purple-600\",\n actor: \"bg-yellow-500\",\n \"context-actor\": \"bg-yellow-500\",\n step: \"bg-gray-700\",\n data: \"bg-blue-600\",\n \"data-products\": \"bg-indigo-600\",\n field: \"bg-cyan-600\",\n messageGroup: \"bg-violet-600\",\n messageGroupExpanded: \"bg-violet-600\",\n};\n\n/** The legend for some nodes: each domain's steps (when grouped by domain), then each kind of node */\nexport const getLegend = (nodes: Node<any>[]): Record<string, LegendEntry> => {\n const legend: Record<string, LegendEntry> = {};\n const domainGroups = [\n ...new Set(\n nodes\n .filter((node) => node.data.group?.type === \"Domain\")\n .map((node) => node.data.group?.id),\n ),\n ];\n domainGroups.forEach((groupId) => {\n legend[`${groupId} (Domain)`] = {\n count: nodes.filter((node) => node.data.group?.id === groupId).length,\n colorClass: \"bg-yellow-600\",\n groupId,\n };\n });\n for (const { type } of nodes) {\n // Group boundaries aren't something to count or hide\n if (!type || GROUP_NODE_TYPES.includes(type)) continue;\n const entry = legend[type];\n if (entry) entry.count += 1;\n else\n legend[type] = {\n count: 1,\n colorClass: LEGEND_COLORS[type] || \"bg-black\",\n };\n }\n return legend;\n};\n\nconst LEGEND_PANEL_STYLE_WITH_MINIMAP = { marginRight: \"230px\" } as const;\n\n/** The legend, bottom right */\nexport const LegendPanel = memo(function LegendPanel({\n legend,\n hiddenKeys,\n showMinimap = false,\n onLegendClick,\n}: {\n legend: Record<string, LegendEntry>;\n /** Entries whose nodes are hidden, shown faded */\n hiddenKeys: string[];\n showMinimap?: boolean;\n onLegendClick: (key: string) => void;\n}) {\n if (Object.keys(legend).length === 0) return null;\n\n return (\n <Panel\n position=\"bottom-right\"\n style={showMinimap ? LEGEND_PANEL_STYLE_WITH_MINIMAP : undefined}\n >\n <div className=\"bg-[rgb(var(--ec-card-bg))] border border-[rgb(var(--ec-page-border))] font-light px-4 text-[12px] shadow-md py-1 rounded-md\">\n <ul className=\"m-0 p-0 \">\n {Object.entries(legend).map(([key, { count, colorClass }]) => {\n const legendIcon = LEGEND_ICONS[key];\n const hidden = hiddenKeys.includes(key);\n return (\n <li\n key={key}\n title={`${hidden ? \"Show\" : \"Hide\"} ${getLegendLabel(key)}`}\n className={`flex space-x-2 items-center text-[10px] cursor-pointer text-[rgb(var(--ec-page-text))] hover:text-[rgb(var(--ec-accent))] hover:underline transition-opacity ${hidden ? \"opacity-40\" : \"\"}`}\n onClick={() => onLegendClick(key)}\n >\n {legendIcon ? (\n <legendIcon.Icon\n className={`w-3 h-3 shrink-0 ${legendIcon.colorClass}`}\n strokeWidth={2}\n aria-hidden=\"true\"\n />\n ) : (\n <span className={`w-2 h-2 block ${colorClass}`} />\n )}\n <span className=\"block capitalize\">\n {getLegendLabel(key)} ({count})\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n </Panel>\n );\n});\n","/**\n * How a diagram is fitted to the screen: all of it, filling the view with the same room around it at any size (clear\n * of the title and menus at the top, and the bar at the bottom), never zoomed in past full size (e.g. a graph with\n * one small node). Studio fits its canvases the same way.\n */\nexport const DIAGRAM_FIT_VIEW_OPTIONS = {\n padding: { top: \"100px\", right: \"60px\", bottom: \"80px\", left: \"60px\" },\n maxZoom: 1,\n} as const;\n","import {\n useState,\n useEffect,\n useLayoutEffect,\n useRef,\n useCallback,\n useId,\n} from \"react\";\nimport {\n CheckIcon,\n ClipboardIcon,\n Maximize,\n ZoomIn,\n ZoomOut,\n} from \"lucide-react\";\nimport type { Node, Edge } from \"@xyflow/react\";\nimport { convertToMermaid } from \"../utils/export-mermaid\";\nimport { copyToClipboard } from \"../utils/clipboard\";\nimport { usePanZoom, type PanZoomView } from \"../hooks/use-pan-zoom\";\nimport {\n LevelButtons,\n MermaidToggle,\n Toolbar,\n ToolbarButton,\n ToolbarDivider,\n type CanvasLevel,\n} from \"./CanvasToolbar\";\n\ninterface MermaidViewProps {\n nodes: Node[];\n edges: Edge[];\n maxTextSize?: number;\n /** The diagram's levels of detail, shown in the toolbar as on the diagram */\n levels?: CanvasLevel[];\n /** Zoom with the wheel; otherwise only with Ctrl or Cmd held (or a pinch), as on the diagram */\n zoomOnScroll?: boolean;\n /** Goes back to the diagram (the toolbar's Mermaid toggle, which is on here) */\n onShowDiagram?: () => void;\n}\n\n// The diagram's dotted background (see DiagramBackground), moved and scaled\n// with the diagram as React Flow does it: dots 1px across, 16px apart\nconst BACKGROUND_GAP = 16;\nconst BACKGROUND_DOT_SIZE = 1;\n\nconst MermaidView = ({\n nodes,\n edges,\n maxTextSize = 100000,\n levels = [],\n zoomOnScroll = true,\n onShowDiagram,\n}: MermaidViewProps) => {\n const [copySuccess, setCopySuccess] = useState(false);\n // How far the diagram is zoomed in, as a percentage (as the diagram's\n // toolbar shows it). Written straight into the label, so zooming doesn't\n // render the view again\n const zoomLabelRef = useRef<HTMLDivElement>(null);\n const handleZoomChange = useCallback((percent: number) => {\n if (zoomLabelRef.current) zoomLabelRef.current.textContent = `${percent}%`;\n }, []);\n // Drawn as React Flow's Background draws it, updated in the same frame as the diagram\n const patternRef = useRef<SVGPatternElement>(null);\n const dotRef = useRef<SVGCircleElement>(null);\n // Without the colons React puts in ids, for `url(#...)`\n const patternId = `mermaid-dots-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n const handleViewChange = useCallback(({ x, y, scale }: PanZoomView) => {\n const pattern = patternRef.current;\n const dot = dotRef.current;\n if (!pattern || !dot) return;\n const gap = BACKGROUND_GAP * scale || 1;\n const radius = (BACKGROUND_DOT_SIZE * scale) / 2;\n pattern.setAttribute(\"x\", String(x % gap));\n pattern.setAttribute(\"y\", String(y % gap));\n pattern.setAttribute(\"width\", String(gap));\n pattern.setAttribute(\"height\", String(gap));\n pattern.setAttribute(\n \"patternTransform\",\n `translate(-${gap / 2},-${gap / 2})`,\n );\n dot.setAttribute(\"cx\", String(radius));\n dot.setAttribute(\"cy\", String(radius));\n dot.setAttribute(\"r\", String(radius));\n }, []);\n const { viewportRef, contentRef, setContentSize, fitView, zoomIn, zoomOut } =\n usePanZoom({\n zoomOnScroll,\n onZoomChange: handleZoomChange,\n onViewChange: handleViewChange,\n });\n const [mermaidCode, setMermaidCode] = useState(\"\");\n const [previewSvg, setPreviewSvg] = useState<string | null>(null);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [isRendering, setIsRendering] = useState(true);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Generate mermaid code\n useEffect(() => {\n const code = convertToMermaid(nodes, edges, {\n includeStyles: true,\n direction: \"LR\",\n });\n setMermaidCode(code);\n }, [nodes, edges]);\n\n // Render mermaid preview\n useEffect(() => {\n if (!mermaidCode) return;\n\n let cancelled = false;\n setIsRendering(true);\n setPreviewError(null);\n\n const renderMermaid = async () => {\n try {\n const { default: mermaid } = await import(\"mermaid\");\n\n // Detect current theme\n const isDarkMode =\n document.documentElement.getAttribute(\"data-theme\") === \"dark\";\n const currentTheme = isDarkMode ? \"dark\" : \"default\";\n\n mermaid.initialize({\n maxTextSize: maxTextSize,\n startOnLoad: false,\n theme: currentTheme,\n flowchart: {\n curve: \"basis\",\n padding: 20,\n },\n securityLevel: \"loose\",\n });\n\n const id = \"mermaid-view-\" + Math.random().toString(36).substring(2, 9);\n const { svg } = await mermaid.render(id, mermaidCode);\n\n if (!cancelled) {\n setPreviewSvg(svg);\n setPreviewError(null);\n }\n } catch (error) {\n if (!cancelled) {\n console.error(\"Mermaid render error:\", error);\n setPreviewError(\n error instanceof Error ? error.message : \"Failed to render diagram\",\n );\n setPreviewSvg(null);\n }\n } finally {\n if (!cancelled) {\n setIsRendering(false);\n }\n }\n };\n\n renderMermaid();\n\n return () => {\n cancelled = true;\n };\n }, [mermaidCode]);\n\n // Each diagram drawn at its own size, fitted to the view (as the diagram is\n // fitted after switching levels)\n useLayoutEffect(() => {\n const svgElement = contentRef.current?.querySelector(\"svg\");\n if (!svgElement) return;\n const { width, height } = svgElement.viewBox.baseVal;\n svgElement.style.maxWidth = \"none\";\n svgElement.setAttribute(\"width\", String(width));\n svgElement.setAttribute(\"height\", String(height));\n setContentSize(width, height);\n // Each diagram (e.g. another level) fades in, as there's no animating\n // between two Mermaid diagrams\n svgElement.animate([{ opacity: 0 }, { opacity: 1 }], {\n duration: 200,\n easing: \"ease-out\",\n });\n }, [previewSvg, setContentSize]);\n\n const handleCopyToClipboard = useCallback(async () => {\n await copyToClipboard(mermaidCode);\n setCopySuccess(true);\n setTimeout(() => setCopySuccess(false), 2000);\n }, [mermaidCode]);\n\n return (\n <div\n ref={containerRef}\n className=\"absolute inset-0 bg-[rgb(var(--ec-page-bg))]\"\n style={{ animation: \"fadeIn 200ms ease-out\" }}\n >\n <svg\n className=\"absolute inset-0 w-full h-full pointer-events-none\"\n aria-hidden=\"true\"\n >\n <pattern\n ref={patternRef}\n id={patternId}\n width={BACKGROUND_GAP}\n height={BACKGROUND_GAP}\n patternUnits=\"userSpaceOnUse\"\n >\n <circle ref={dotRef} style={{ fill: \"var(--ec-bg-dots)\" }} />\n </pattern>\n <rect width=\"100%\" height=\"100%\" fill={`url(#${patternId})`} />\n </svg>\n <style>{`\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n `}</style>\n\n {/* Mermaid diagram container: drag to pan, scroll or pinch to zoom */}\n <div\n ref={viewportRef}\n className=\"absolute inset-0 overflow-hidden cursor-grab select-none touch-none\"\n >\n {/* Only before the first diagram: switching levels keeps the last one until the next is drawn */}\n {isRendering && !previewSvg && (\n <div className=\"w-full h-full flex items-center justify-center\">\n <div className=\"relative\">\n <div className=\"flex items-center gap-4 opacity-40\">\n <div className=\"w-24 h-10 bg-[rgb(var(--ec-page-border))] rounded animate-pulse\" />\n <div className=\"w-12 h-0.5 bg-[rgb(var(--ec-page-border))] animate-pulse\" />\n <div\n className=\"w-20 h-10 bg-[rgb(var(--ec-page-border))] rounded-full animate-pulse\"\n style={{ animationDelay: \"75ms\" }}\n />\n <div\n className=\"w-12 h-0.5 bg-[rgb(var(--ec-page-border))] animate-pulse\"\n style={{ animationDelay: \"150ms\" }}\n />\n <div\n className=\"w-24 h-10 bg-[rgb(var(--ec-page-border))] rounded animate-pulse\"\n style={{ animationDelay: \"225ms\" }}\n />\n </div>\n <p className=\"text-center text-sm text-[rgb(var(--ec-page-text-muted))] mt-4\">\n Rendering diagram...\n </p>\n </div>\n </div>\n )}\n\n {previewError && !isRendering && (\n <div className=\"w-full h-full flex flex-col items-center justify-center p-4\">\n <div className=\"text-red-500 text-sm mb-2\">\n Failed to render diagram\n </div>\n <div className=\"text-[rgb(var(--ec-page-text-muted))] text-xs font-mono bg-[rgb(var(--ec-code-bg))] p-2 rounded max-w-lg overflow-auto\">\n {previewError}\n </div>\n <div className=\"mt-4 text-sm text-[rgb(var(--ec-page-text-muted))]\">\n <p>You can still copy the Mermaid code and paste it into</p>\n <a\n href=\"https://mermaid.live\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-[rgb(var(--ec-accent))] hover:underline\"\n >\n mermaid.live\n </a>\n </div>\n </div>\n )}\n\n {previewSvg && !previewError && (\n <div\n ref={contentRef}\n className=\"absolute left-0 top-0 origin-top-left\"\n dangerouslySetInnerHTML={{ __html: previewSvg }}\n />\n )}\n </div>\n\n {/* The diagram's toolbar: the view, its levels and copying the Mermaid code */}\n <div className=\"absolute bottom-[15px] left-1/2 -translate-x-1/2 z-20\">\n <Toolbar>\n <ToolbarButton label=\"Fit view\" onClick={() => fitView()}>\n <Maximize className=\"w-4 h-4\" />\n </ToolbarButton>\n <ToolbarButton label=\"Zoom out\" onClick={zoomOut}>\n <ZoomOut className=\"w-4 h-4\" />\n </ToolbarButton>\n <div\n ref={zoomLabelRef}\n className=\"w-12 text-center text-xs font-medium tabular-nums text-[rgb(var(--ec-page-text-muted))]\"\n >\n 100%\n </div>\n <ToolbarButton label=\"Zoom in\" onClick={zoomIn}>\n <ZoomIn className=\"w-4 h-4\" />\n </ToolbarButton>\n {levels.length > 0 && (\n <>\n <ToolbarDivider />\n <LevelButtons levels={levels} />\n </>\n )}\n {onShowDiagram && (\n <>\n <ToolbarDivider />\n <MermaidToggle active onClick={onShowDiagram} />\n </>\n )}\n <ToolbarDivider />\n <ToolbarButton\n label={copySuccess ? \"Copied!\" : \"Copy Mermaid code\"}\n active={copySuccess}\n onClick={handleCopyToClipboard}\n >\n {copySuccess ? (\n <CheckIcon className=\"w-4 h-4\" />\n ) : (\n <ClipboardIcon className=\"w-4 h-4\" />\n )}\n </ToolbarButton>\n </Toolbar>\n </div>\n </div>\n );\n};\n\nexport default MermaidView;\n","/**\n * Utility to copy text to clipboard\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n try {\n if (navigator?.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return true;\n }\n // Fallback for older browsers\n const textArea = document.createElement(\"textarea\");\n textArea.value = text;\n textArea.style.position = \"fixed\";\n textArea.style.left = \"-999999px\";\n document.body.appendChild(textArea);\n textArea.select();\n const success = document.execCommand(\"copy\");\n document.body.removeChild(textArea);\n return success;\n } catch (error) {\n console.error(\"Failed to copy to clipboard:\", error);\n return false;\n }\n}\n","import { useCallback, useEffect, useRef } from \"react\";\n\nexport type PanZoomView = { x: number; y: number; scale: number };\ntype View = PanZoomView;\n\nconst MIN_SCALE = 0.05;\nconst MAX_SCALE = 4;\n/**\n * Space left around the content when it's fitted: more above and below, for\n * the title and toolbar over it\n */\nconst FIT_PADDING = { x: 40, y: 80 };\n/** How long the buttons (and double-click) take to zoom, as the diagram's do */\nconst ANIMATION_MS = 200;\n/** How long after the last pan or zoom the content is drawn sharp again */\nconst SETTLE_MS = 150;\n\nconst clampScale = (scale: number) =>\n Math.min(MAX_SCALE, Math.max(MIN_SCALE, scale));\n\nconst easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);\n\n/**\n * Zoom factor for a wheel event, as React Flow works it out, so zooming feels\n * the same as on the diagram: proportional to how far the wheel or trackpad\n * moved (a pinch is a wheel event with ctrlKey), not a fixed step per event\n */\nexport const wheelZoomFactor = (event: WheelEvent) => {\n const factor = event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002;\n return Math.pow(2, -event.deltaY * factor * (event.ctrlKey ? 10 : 1));\n};\n\ninterface PanZoomOptions {\n /**\n * Zoom with the wheel. Otherwise the wheel scrolls the page, and zooms only\n * with Ctrl or Cmd held (or a trackpad pinch), as on the diagram.\n */\n zoomOnScroll?: boolean;\n /** Called with the zoom as a percentage whenever it changes */\n onZoomChange?: (percent: number) => void;\n /** Called in the same frame as the view is drawn (e.g. to move a background with it) */\n onViewChange?: (view: PanZoomView) => void;\n}\n\n/**\n * Pans and zooms content (e.g. a rendered SVG) inside a viewport with a CSS\n * transform, applied at most once a frame. While moving, the content is a\n * composited layer (`will-change`), so the browser moves it without drawing it\n * again; once it settles, it's drawn sharp at its new size.\n *\n * Drag to pan, wheel or pinch to zoom around the pointer, double-click to zoom in.\n */\nexport const usePanZoom = ({\n zoomOnScroll = true,\n onZoomChange,\n onViewChange,\n}: PanZoomOptions = {}) => {\n const viewportRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const view = useRef<View>({ x: 0, y: 0, scale: 1 });\n const size = useRef({ width: 0, height: 0 });\n const frame = useRef<number | null>(null);\n const animation = useRef<number | null>(null);\n const settleTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastPercent = useRef<number | null>(null);\n const onZoomChangeRef = useRef(onZoomChange);\n onZoomChangeRef.current = onZoomChange;\n const onViewChangeRef = useRef(onViewChange);\n onViewChangeRef.current = onViewChange;\n\n const draw = useCallback(() => {\n const content = contentRef.current;\n if (!content) return;\n const { x, y, scale } = view.current;\n content.style.transform = `translate3d(${x}px, ${y}px, 0) scale(${scale})`;\n onViewChangeRef.current?.(view.current);\n const percent = Math.round(scale * 100);\n if (percent !== lastPercent.current) {\n lastPercent.current = percent;\n onZoomChangeRef.current?.(percent);\n }\n }, []);\n\n // Draws the view on the next frame (once, however many events come in before it)\n const apply = useCallback(() => {\n if (frame.current !== null) return;\n frame.current = requestAnimationFrame(() => {\n frame.current = null;\n draw();\n });\n }, [draw]);\n\n // Keeps the content a layer while it moves, and draws it sharp once it stops\n const moving = useCallback(() => {\n const content = contentRef.current;\n if (!content) return;\n content.style.willChange = \"transform\";\n if (settleTimer.current) clearTimeout(settleTimer.current);\n settleTimer.current = setTimeout(() => {\n content.style.willChange = \"\";\n }, SETTLE_MS);\n }, []);\n\n const stopAnimation = useCallback(() => {\n if (animation.current !== null) cancelAnimationFrame(animation.current);\n animation.current = null;\n }, []);\n\n const setView = useCallback(\n (next: View, animate = false) => {\n stopAnimation();\n moving();\n if (!animate) {\n view.current = next;\n apply();\n return;\n }\n const from = { ...view.current };\n const start = performance.now();\n const step = (now: number) => {\n const t = easeOutCubic(Math.min(1, (now - start) / ANIMATION_MS));\n view.current = {\n x: from.x + (next.x - from.x) * t,\n y: from.y + (next.y - from.y) * t,\n scale: from.scale + (next.scale - from.scale) * t,\n };\n apply();\n moving();\n animation.current = t < 1 ? requestAnimationFrame(step) : null;\n };\n animation.current = requestAnimationFrame(step);\n },\n [apply, moving, stopAnimation],\n );\n\n /** The view zoomed by a factor around a point in the viewport (keeping it where it is) */\n const zoomedAt = useCallback(\n (factor: number, px: number, py: number, from = view.current): View => {\n const scale = clampScale(from.scale * factor);\n const ratio = scale / from.scale;\n return {\n x: px - (px - from.x) * ratio,\n y: py - (py - from.y) * ratio,\n scale,\n };\n },\n [],\n );\n\n const viewportCenter = () => {\n const rect = viewportRef.current?.getBoundingClientRect();\n return rect ? { x: rect.width / 2, y: rect.height / 2 } : { x: 0, y: 0 };\n };\n\n const zoomBy = useCallback(\n (factor: number) => {\n const center = viewportCenter();\n // From where an animation in progress is going, so clicks add up\n setView(zoomedAt(factor, center.x, center.y), true);\n },\n [setView, zoomedAt],\n );\n const zoomIn = useCallback(() => zoomBy(1.2), [zoomBy]);\n const zoomOut = useCallback(() => zoomBy(1 / 1.2), [zoomBy]);\n\n /** Fits the content in the viewport, no larger than its own size */\n const fitView = useCallback(\n (animate = true) => {\n const rect = viewportRef.current?.getBoundingClientRect();\n const { width, height } = size.current;\n if (!rect || !width || !height) return;\n const scale = clampScale(\n Math.min(\n (rect.width - FIT_PADDING.x * 2) / width,\n (rect.height - FIT_PADDING.y * 2) / height,\n 1,\n ),\n );\n setView(\n {\n x: (rect.width - width * scale) / 2,\n y: (rect.height - height * scale) / 2,\n scale,\n },\n animate,\n );\n },\n [setView],\n );\n\n /**\n * Sets the size of the content (e.g. a new diagram) and fits it straight\n * away, so it's never drawn where the last one was\n */\n const setContentSize = useCallback(\n (width: number, height: number) => {\n size.current = { width, height };\n fitView(false);\n if (frame.current !== null) cancelAnimationFrame(frame.current);\n frame.current = null;\n draw();\n },\n [fitView, draw],\n );\n\n useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n\n const pointers = new Map<number, { x: number; y: number }>();\n let pinchDistance = 0;\n const local = (event: { clientX: number; clientY: number }) => {\n const rect = viewport.getBoundingClientRect();\n return { x: event.clientX - rect.left, y: event.clientY - rect.top };\n };\n\n const handleWheel = (event: WheelEvent) => {\n if (!zoomOnScroll && !event.ctrlKey && !event.metaKey) return;\n event.preventDefault();\n const point = local(event);\n setView(zoomedAt(wheelZoomFactor(event), point.x, point.y));\n };\n\n const handlePointerDown = (event: PointerEvent) => {\n if (event.button !== 0) return;\n stopAnimation();\n viewport.setPointerCapture(event.pointerId);\n pointers.set(event.pointerId, local(event));\n viewport.style.cursor = \"grabbing\";\n if (pointers.size === 2) {\n const [a, b] = [...pointers.values()];\n pinchDistance = Math.hypot(a.x - b.x, a.y - b.y);\n }\n };\n\n const handlePointerMove = (event: PointerEvent) => {\n const previous = pointers.get(event.pointerId);\n if (!previous) return;\n const point = local(event);\n pointers.set(event.pointerId, point);\n if (pointers.size === 1) {\n const { x, y, scale } = view.current;\n setView({\n x: x + point.x - previous.x,\n y: y + point.y - previous.y,\n scale,\n });\n return;\n }\n // Two fingers: zoom around the point between them\n const [a, b] = [...pointers.values()];\n const distance = Math.hypot(a.x - b.x, a.y - b.y);\n if (pinchDistance > 0) {\n setView(\n zoomedAt(distance / pinchDistance, (a.x + b.x) / 2, (a.y + b.y) / 2),\n );\n }\n pinchDistance = distance;\n };\n\n const handlePointerUp = (event: PointerEvent) => {\n pointers.delete(event.pointerId);\n pinchDistance = 0;\n if (pointers.size === 0) viewport.style.cursor = \"\";\n };\n\n const handleDoubleClick = (event: MouseEvent) => {\n const point = local(event);\n setView(zoomedAt(2, point.x, point.y), true);\n };\n\n // Not passive, so zooming doesn't scroll the page too\n viewport.addEventListener(\"wheel\", handleWheel, { passive: false });\n viewport.addEventListener(\"pointerdown\", handlePointerDown);\n viewport.addEventListener(\"pointermove\", handlePointerMove);\n viewport.addEventListener(\"pointerup\", handlePointerUp);\n viewport.addEventListener(\"pointercancel\", handlePointerUp);\n viewport.addEventListener(\"dblclick\", handleDoubleClick);\n return () => {\n viewport.removeEventListener(\"wheel\", handleWheel);\n viewport.removeEventListener(\"pointerdown\", handlePointerDown);\n viewport.removeEventListener(\"pointermove\", handlePointerMove);\n viewport.removeEventListener(\"pointerup\", handlePointerUp);\n viewport.removeEventListener(\"pointercancel\", handlePointerUp);\n viewport.removeEventListener(\"dblclick\", handleDoubleClick);\n };\n }, [zoomOnScroll, setView, zoomedAt, stopAnimation]);\n\n // Fits again when the viewport changes size (e.g. going full screen), as the diagram does\n useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || typeof ResizeObserver === \"undefined\") return;\n let last = { width: viewport.clientWidth, height: viewport.clientHeight };\n const observer = new ResizeObserver(() => {\n const width = viewport.clientWidth;\n const height = viewport.clientHeight;\n if (width === last.width && height === last.height) return;\n last = { width, height };\n fitView(false);\n });\n observer.observe(viewport);\n return () => observer.disconnect();\n }, [fitView]);\n\n useEffect(\n () => () => {\n if (frame.current !== null) cancelAnimationFrame(frame.current);\n if (animation.current !== null) cancelAnimationFrame(animation.current);\n if (settleTimer.current) clearTimeout(settleTimer.current);\n },\n [],\n );\n\n return {\n viewportRef,\n contentRef,\n setContentSize,\n fitView,\n zoomIn,\n zoomOut,\n };\n};\n","import { memo, useEffect, type ReactNode } from \"react\";\nimport { Code, Image, X } from \"lucide-react\";\n\ninterface ExportModalProps {\n onClose: () => void;\n onExportImage: () => void;\n onExportMermaid: () => void;\n}\n\nconst ExportOption = ({\n icon,\n title,\n description,\n onClick,\n}: {\n icon: ReactNode;\n title: string;\n description: string;\n onClick: () => void;\n}) => (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"w-full flex items-start gap-3 p-3 rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] text-left transition-colors hover:border-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--ec-accent))]\"\n >\n <span className=\"flex items-center justify-center w-9 h-9 shrink-0 rounded-md bg-[rgb(var(--ec-accent-subtle)/0.5)] text-[rgb(var(--ec-accent))]\">\n {icon}\n </span>\n <span className=\"flex flex-col gap-0.5\">\n <span className=\"text-sm font-medium text-[rgb(var(--ec-page-text))]\">\n {title}\n </span>\n <span className=\"text-xs text-[rgb(var(--ec-page-text-muted))]\">\n {description}\n </span>\n </span>\n </button>\n);\n\n/** Picks how to export the diagram: as an image, or as a Mermaid file */\nconst ExportModal = memo(function ExportModal({\n onClose,\n onExportImage,\n onExportMermaid,\n}: ExportModalProps) {\n // Closes on Escape, as the menus do\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [onClose]);\n\n const choose = (exportDiagram: () => void) => () => {\n onClose();\n exportDiagram();\n };\n\n return (\n <>\n <div\n className=\"absolute inset-0 bg-black/20 z-40\"\n onClick={onClose}\n style={{ animation: \"fadeIn 150ms ease-out\" }}\n />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"export-modal-title\"\n className=\"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-[rgb(var(--ec-page-bg))] rounded-lg shadow-xl z-50 w-[calc(100%-2rem)] max-w-md p-6 border border-[rgb(var(--ec-page-border))]\"\n style={{ animation: \"slideInCenter 250ms ease-out\" }}\n >\n {/* Only a short rise: the -translate-x/y-1/2 classes centre the modal\n with the translate property, which a transform here would add to */}\n <style>{`\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes slideInCenter {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: none; }\n }\n `}</style>\n\n <div className=\"flex justify-between items-start mb-4\">\n <h3\n id=\"export-modal-title\"\n className=\"text-lg font-semibold text-[rgb(var(--ec-page-text))]\"\n >\n Export\n </h3>\n <button\n onClick={onClose}\n className=\"text-[rgb(var(--ec-page-text-muted))] hover:text-[rgb(var(--ec-page-text))] transition-colors\"\n aria-label=\"Close\"\n >\n <X className=\"w-5 h-5\" />\n </button>\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <ExportOption\n icon={<Image className=\"w-5 h-5\" />}\n title=\"Export as image\"\n description=\"Download the diagram as a PNG image.\"\n onClick={choose(onExportImage)}\n />\n <ExportOption\n icon={<Code className=\"w-5 h-5\" />}\n title=\"Export as Mermaid\"\n description=\"Download the diagram as a Mermaid (.mmd) file, to use in docs, wikis or other tools.\"\n onClick={choose(onExportMermaid)}\n />\n </div>\n </div>\n </>\n );\n});\n\nexport default ExportModal;\n","import {\n useCallback,\n useState,\n useEffect,\n useLayoutEffect,\n useRef,\n type Dispatch,\n type SetStateAction,\n} from \"react\";\nimport { type Edge, type Node, useReactFlow } from \"@xyflow/react\";\nimport {\n createEdge,\n getEdgeLabelForMessageAsSource,\n getEdgeLabelForServiceAsTarget,\n} from \"../utils/utils/utils\";\nimport { layoutWithElk } from \"../utils/elk-layout\";\nimport { DIAGRAM_FIT_VIEW_OPTIONS } from \"../utils/fit-view\";\nimport {\n hideMessageNodes,\n hideNodes,\n isMessageNode,\n} from \"../utils/hide-messages\";\nimport {\n animateLayout,\n getSystemMorphs,\n getLayoutBounds,\n LAYOUT_ANIMATION_DURATION,\n type GraphTransition,\n} from \"../utils/animate-layout\";\n\n// Keeps `?level=` in the URL so shared links open at the same level of detail\nexport const setLevelInUrl = (level: number) => {\n const url = new URL(window.location.href);\n url.searchParams.set(\"level\", String(level));\n window.history.replaceState(window.history.state, \"\", url);\n};\n\ninterface NodeVisibilityProps {\n nodes: Node[];\n edges: Edge[];\n setNodes: (nodes: Node[]) => void;\n setEdges: Dispatch<SetStateAction<Edge[]>>;\n hasChannels: boolean;\n hasMessages: boolean;\n /** The graph switched away from to show this one, to animate from */\n transitionFrom?: GraphTransition;\n /** React Flow's node origin, to line up nodes when animating */\n nodeOrigin?: [number, number];\n /**\n * Go straight to each graph rather than animating to it, e.g. while the\n * graph is shown as Mermaid, which would draw every step of the animation\n */\n disableAnimation?: boolean;\n /** The graph laid out with messages and channels hidden, if precomputed */\n hiddenMessagesGraph?: { nodes: Node[]; edges: Edge[] };\n /** Prepares the edges of each graph shown (e.g. animating messages) */\n prepareEdges?: (edges: Edge[]) => Edge[];\n /** Whether a node is one a legend entry lists, to hide it from the legend */\n matchesLegendKey?: (node: Node, key: string) => boolean;\n /** Legend entries hidden to start with (e.g. kept when switching graphs) */\n initialHiddenLegendKeys?: string[];\n /** Called when legend entries are hidden or shown */\n onHiddenLegendKeysChange?: (keys: string[]) => void;\n /**\n * The kind of diagram (e.g. \"services\"), so the level is remembered for each\n * kind rather than one level for every diagram\n */\n preferenceScope?: string;\n /**\n * Levels don't apply to this graph (e.g. a flow), so it always opens with\n * everything shown, whatever level was last picked\n */\n ignoreSavedLevel?: boolean;\n /**\n * The level to open at (2 or 3; level 1 is an overview graph shown instead),\n * rather than the URL's or the saved one, e.g. the level an MCP client asked for\n */\n initialLevel?: 2 | 3;\n /**\n * Called on a graph before it's laid out again (e.g. taking it out of\n * swimlanes, which the layout doesn't know about), and on each graph before\n * it's shown (e.g. putting it back in them)\n */\n beforeLayout?: (graph: { nodes: Node[]; edges: Edge[] }) => {\n nodes: Node[];\n edges: Edge[];\n };\n afterLayout?: (graph: { nodes: Node[]; edges: Edge[] }) => {\n nodes: Node[];\n edges: Edge[];\n };\n}\n\nconst identity = <T>(graph: T) => graph;\n\nconst matchesType = (node: Node, key: string) => node.type === key;\n\nconst hideChannelNodes = (nodes: Node[], edges: Edge[]) => {\n const channelIds = new Set(\n nodes.filter((node) => node.type === \"channels\").map((node) => node.id),\n );\n\n // By id, keeping the first edge with each id\n const newEdges = new Map<string, Edge>();\n const add = (edge: Edge) => {\n if (!newEdges.has(edge.id)) newEdges.set(edge.id, edge);\n };\n for (const edge of edges) {\n const { source, target, data } = edge;\n if (!channelIds.has(source) && !channelIds.has(target)) {\n add(edge);\n continue;\n }\n\n const rootSourceAndTarget = data?.rootSourceAndTarget as {\n source: { id: string; collection: string };\n target: { id: string; collection: string };\n };\n if (!rootSourceAndTarget) {\n add(edge);\n continue;\n }\n\n // is target a service-like resource?\n const targetIsService =\n rootSourceAndTarget?.target?.collection === \"services\" ||\n rootSourceAndTarget?.target?.collection === \"agents\";\n const edgeLabel = targetIsService\n ? getEdgeLabelForMessageAsSource(rootSourceAndTarget.source as any)\n : getEdgeLabelForServiceAsTarget(rootSourceAndTarget.target as any);\n\n add(\n createEdge({\n id: `${rootSourceAndTarget.source.id}-${rootSourceAndTarget.target.id}`,\n source: rootSourceAndTarget.source.id,\n target: rootSourceAndTarget.target.id,\n label: edgeLabel,\n ...(data?.crossDomain ? { data: { crossDomain: true } } : {}),\n }),\n );\n }\n\n return {\n nodes: nodes.filter((node) => !channelIds.has(node.id)),\n edges: Array.from(newEdges.values()),\n };\n};\n\nexport const useNodeVisibility = ({\n nodes,\n edges,\n setNodes,\n setEdges,\n hasChannels,\n hasMessages,\n transitionFrom,\n nodeOrigin,\n disableAnimation = false,\n hiddenMessagesGraph,\n prepareEdges = (edges) => edges,\n matchesLegendKey = matchesType,\n initialHiddenLegendKeys = [],\n onHiddenLegendKeysChange,\n preferenceScope,\n ignoreSavedLevel = false,\n initialLevel,\n beforeLayout = identity,\n afterLayout = identity,\n}: NodeVisibilityProps) => {\n const hideMessagesKey = `EventCatalog:hideMessages${preferenceScope ? `:${preferenceScope}` : \"\"}`;\n const hideChannelsKey = `EventCatalog:hideChannels${preferenceScope ? `:${preferenceScope}` : \"\"}`;\n // Start from the URL (`?level=`), falling back to the saved preference, so\n // the first render is already at the right level. Level 1 is an overview\n // graph shown instead of this one, so without one this graph opens at level 2.\n const [urlLevel] = useState(() => {\n if (ignoreSavedLevel) return 3;\n if (initialLevel) return initialLevel;\n const level = Number(\n new URLSearchParams(window.location.search).get(\"level\"),\n );\n if (level === 1 || level === 2) return 2;\n return level === 3 ? 3 : undefined;\n });\n const [hideChannels, setHideChannels] = useState(\n () =>\n !ignoreSavedLevel &&\n !urlLevel &&\n localStorage.getItem(hideChannelsKey) === \"true\",\n );\n const [hideMessages, setHideMessages] = useState(() =>\n urlLevel\n ? urlLevel === 2\n : localStorage.getItem(hideMessagesKey) === \"true\",\n );\n // The full graph, to restore when showing everything again\n const fullGraph = useRef({ nodes, edges });\n const { fitView, fitBounds } = useReactFlow();\n // Changes the user makes animate; restoring saved settings on load doesn't\n const animateNextChange = useRef(false);\n const isAnimating = useRef(false);\n const cancelAnimation = useRef<(() => void) | undefined>(undefined);\n\n // Only hide things that actually exist in the graph.\n // Channels carry messages, so hiding messages hides channels too.\n const messagesHidden = hideMessages && hasMessages;\n const channelsHidden = hasChannels && (hideChannels || messagesHidden);\n\n // Legend entries whose nodes are hidden (clicking an entry hides or shows them)\n const [hiddenLegendKeys, setHiddenLegendKeys] = useState(\n initialHiddenLegendKeys,\n );\n const onHiddenLegendKeysChangeRef = useRef(onHiddenLegendKeysChange);\n onHiddenLegendKeysChangeRef.current = onHiddenLegendKeysChange;\n const toggleLegendKey = useCallback(\n (key: string) => {\n animateNextChange.current = true;\n const keys = hiddenLegendKeys.includes(key)\n ? hiddenLegendKeys.filter((hiddenKey) => hiddenKey !== key)\n : [...hiddenLegendKeys, key];\n setHiddenLegendKeys(keys);\n onHiddenLegendKeysChangeRef.current?.(keys);\n },\n [hiddenLegendKeys],\n );\n const matchesLegendKeyRef = useRef(matchesLegendKey);\n matchesLegendKeyRef.current = matchesLegendKey;\n const isHiddenByLegend = (node: Node) =>\n hiddenLegendKeys.some((key) => matchesLegendKeyRef.current(node, key));\n // Only when this graph has nodes to hide (entries can be hidden on another)\n const legendHidden = fullGraph.current.nodes.some(isHiddenByLegend);\n\n // Highlighting cross-domain communication picks out the edges crossing\n // domains on the graph shown (it doesn't change what's shown). Kept between visits.\n const [highlightCrossDomain, setHighlightCrossDomain] = useState(\n () => localStorage.getItem(\"EventCatalog:highlightCrossDomain\") === \"true\",\n );\n const toggleHighlightCrossDomain = useCallback(() => {\n const highlight = !highlightCrossDomain;\n setHighlightCrossDomain(highlight);\n localStorage.setItem(\n \"EventCatalog:highlightCrossDomain\",\n JSON.stringify(highlight),\n );\n }, [highlightCrossDomain]);\n // Keep a snapshot of the full graph so it can be restored when toggling back.\n // Only runs on graph changes: a graph that still contains hidden node types\n // was set from outside this hook (e.g. message group expansion).\n useEffect(() => {\n // Mid-animation graphs are in between layouts, never a snapshot\n if (isAnimating.current) return;\n const containsHiddenNodes = nodes.some(\n (node) =>\n (channelsHidden && node.type === \"channels\") ||\n (messagesHidden && isMessageNode(node)) ||\n (legendHidden && isHiddenByLegend(node)),\n );\n if (\n (!channelsHidden && !messagesHidden && !legendHidden) ||\n containsHiddenNodes\n ) {\n fullGraph.current = { nodes, edges };\n }\n }, [nodes, edges]);\n\n const toggleChannelsVisibility = useCallback(() => {\n animateNextChange.current = true;\n const hide = !hideChannels;\n setHideChannels(hide);\n localStorage.setItem(hideChannelsKey, JSON.stringify(hide));\n }, [hideChannels]);\n\n const toggleMessagesVisibility = useCallback(() => {\n animateNextChange.current = true;\n const hide = !hideMessages;\n setHideMessages(hide);\n localStorage.setItem(hideMessagesKey, JSON.stringify(hide));\n setLevelInUrl(hide ? 2 : 3);\n }, [hideMessages]);\n\n // Level 2: services and data stores. Level 3: add messages and channels.\n const setDetailLevel = useCallback((level: 2 | 3) => {\n animateNextChange.current = true;\n const hide = level === 2;\n setHideMessages(hide);\n localStorage.setItem(hideMessagesKey, JSON.stringify(hide));\n if (!hide) {\n setHideChannels(false);\n localStorage.setItem(hideChannelsKey, \"false\");\n }\n setLevelInUrl(level);\n }, []);\n\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n const edgesRef = useRef(edges);\n edgesRef.current = edges;\n // The latest, as layouts can finish after it changes\n const prepareEdgesRef = useRef(prepareEdges);\n prepareEdgesRef.current = prepareEdges;\n const beforeLayoutRef = useRef(beforeLayout);\n beforeLayoutRef.current = beforeLayout;\n const afterLayoutRef = useRef(afterLayout);\n afterLayoutRef.current = afterLayout;\n // Relayouts are async (ELK), so only the latest one is applied\n const latestRun = useRef(0);\n // While the first layout of a graph opening at a hidden level is worked out,\n // the graph stays out of sight rather than showing everything first\n const [isLayingOut, setIsLayingOut] = useState(false);\n\n // Read when the level changes, not a reason to lay the graph out again\n const disableAnimationRef = useRef(disableAnimation);\n disableAnimationRef.current = disableAnimation;\n\n // A layout effect, so the graph is at the right level before it's painted\n // (when its layout is already known)\n const isFirstRun = useRef(true);\n useLayoutEffect(() => {\n const firstRun = isFirstRun.current;\n isFirstRun.current = false;\n // Switched to this graph from another (e.g. its overview): animate from it\n const from = firstRun ? transitionFrom : undefined;\n // Otherwise the graph starts with everything shown\n if (\n firstRun &&\n !from &&\n !channelsHidden &&\n !messagesHidden &&\n !legendHidden\n )\n return;\n\n const run = ++latestRun.current;\n const animate =\n !disableAnimationRef.current && (!!from || animateNextChange.current);\n animateNextChange.current = false;\n cancelAnimation.current?.();\n\n const apply = (\n { nodes: toNodes, edges: toEdges }: { nodes: Node[]; edges: Edge[] },\n laidOutLater = false,\n ) => {\n if (run !== latestRun.current) return;\n const shown = afterLayoutRef.current({ nodes: toNodes, edges: toEdges });\n const target = {\n nodes: shown.nodes,\n edges: prepareEdgesRef.current(shown.edges),\n };\n\n if (!animate) {\n setNodes(target.nodes);\n setEdges(target.edges);\n // React Flow fits the view on first render itself. Otherwise called\n // straight after setNodes so React Flow queues the fit until the new\n // nodes are measured (deferring it would fit the previous graph)\n if (!firstRun || laidOutLater)\n fitView({ ...DIAGRAM_FIT_VIEW_OPTIONS, duration: 800 });\n return;\n }\n\n // Move from the current layout to the new one, fitting the view to where\n // the graph ends up while it moves\n const fromNodes = from?.nodes ?? nodesRef.current;\n isAnimating.current = true;\n const bounds = getLayoutBounds(target.nodes, fromNodes);\n if (bounds) {\n fitBounds(bounds, {\n padding: 0.2,\n duration: LAYOUT_ANIMATION_DURATION,\n });\n }\n cancelAnimation.current = animateLayout({\n fromNodes,\n fromEdges: from?.edges ?? edgesRef.current,\n toNodes: target.nodes,\n toEdges: target.edges,\n setNodes,\n setEdges,\n getCurrentNodes: () => nodesRef.current,\n // When switching graphs, systems expand into their group (or back), e.g.\n // a system in its context diagram\n morphs: from ? getSystemMorphs(from.nodes, target.nodes) : [],\n nodeOrigin,\n onDone: () => {\n isAnimating.current = false;\n // Fit to the final graph now every node has its real size. Only its\n // nodes: React Flow can still have the nodes that faded out\n fitView({\n ...DIAGRAM_FIT_VIEW_OPTIONS,\n duration: 400,\n nodes: target.nodes,\n });\n },\n });\n };\n\n // Graphs already laid out\n if (!legendHidden) {\n if (messagesHidden && hiddenMessagesGraph)\n return apply(hiddenMessagesGraph);\n if (!channelsHidden && !messagesHidden) return apply(fullGraph.current);\n }\n\n // Lay the graph out again without the hidden nodes: the level's, then\n // the legend's\n const full = beforeLayoutRef.current(fullGraph.current);\n const level = messagesHidden\n ? (hiddenMessagesGraph ?? hideMessageNodes(full.nodes, full.edges))\n : channelsHidden\n ? hideChannelNodes(full.nodes, full.edges)\n : full;\n const graph = legendHidden\n ? hideNodes(level.nodes, level.edges, isHiddenByLegend)\n : level;\n if (firstRun) setIsLayingOut(true);\n layoutWithElk(graph).then((target) => {\n apply(target, true);\n if (firstRun) setIsLayingOut(false);\n });\n }, [channelsHidden, messagesHidden, hiddenLegendKeys]);\n\n return {\n hideChannels,\n toggleChannelsVisibility,\n hideMessages,\n toggleMessagesVisibility,\n setDetailLevel,\n hiddenLegendKeys,\n toggleLegendKey,\n highlightCrossDomain,\n toggleHighlightCrossDomain,\n isLayingOut,\n };\n};\n","import type { Dispatch, SetStateAction } from \"react\";\nimport type { Edge, Node, Viewport } from \"@xyflow/react\";\n\n/** A graph being switched away from, for the next graph to animate from */\nexport type GraphTransition = {\n nodes: Node[];\n edges: Edge[];\n viewport: Viewport;\n};\n\nconst SYSTEM_GROUP_PREFIX = \"system-group-\";\n\n/**\n * Systems that change between being a node and being expanded into a group of\n * everything inside them (`system-group-<system node id>`), when switching\n * from one graph to another.\n */\nexport const getSystemMorphs = (fromNodes: Node[], toNodes: Node[]) => {\n const fromIds = new Set(fromNodes.map((node) => node.id));\n const toIds = new Set(toNodes.map((node) => node.id));\n const morphs: { from: string; to: string }[] = [];\n const pair = (groups: Node[], nodeIds: Set<string>, grows: boolean) =>\n groups\n .filter((node) => node.type === \"system-group\")\n .forEach((group) => {\n const systemId = group.id.slice(SYSTEM_GROUP_PREFIX.length);\n if (!nodeIds.has(systemId)) return;\n morphs.push(\n grows\n ? { from: systemId, to: group.id }\n : { from: group.id, to: systemId },\n );\n });\n pair(toNodes, fromIds, true);\n pair(fromNodes, toIds, false);\n return morphs.filter(\n (morph) => !toIds.has(morph.from) && !fromIds.has(morph.to),\n );\n};\n\nexport const LAYOUT_ANIMATION_DURATION = 500;\n\nconst easeInOut = (t: number) =>\n t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\n\nconst lerp = (from: number, to: number, t: number) => from + (to - from) * t;\n\nconst size = (node: Node) => ({\n width: node.style?.width,\n height: node.style?.height,\n});\n\n// Size a node that hasn't been rendered yet is assumed to be\nconst ESTIMATED_NODE_SIZE = { width: 250, height: 120 };\n\ntype Rect = { x: number; y: number; width: number; height: number };\n\n/** A node's rendered box: its position is offset into it by its origin */\nconst getRect = (node: Node, nodeOrigin: [number, number]): Rect => {\n const width =\n (typeof node.style?.width === \"number\" ? node.style.width : undefined) ??\n node.measured?.width ??\n ESTIMATED_NODE_SIZE.width;\n const height =\n (typeof node.style?.height === \"number\" ? node.style.height : undefined) ??\n node.measured?.height ??\n ESTIMATED_NODE_SIZE.height;\n const [originX, originY] = node.origin ?? nodeOrigin;\n return {\n x: node.position.x - originX * width,\n y: node.position.y - originY * height,\n width,\n height,\n };\n};\n\n/** Position that puts a node's rendered box at `rect` */\nconst getPositionForRect = (\n node: Node,\n rect: Rect,\n nodeOrigin: [number, number],\n) => {\n const [originX, originY] = node.origin ?? nodeOrigin;\n return {\n x: rect.x + originX * rect.width,\n y: rect.y + originY * rect.height,\n };\n};\n\n/**\n * Animates from one layout of the graph to another. Nodes in both layouts\n * move (and groups resize) to their new place, frame by frame so edges follow\n * them. Nodes and edges only in the new layout fade in, and ones only in the\n * old layout fade out.\n *\n * `morphs` pair nodes in the old layout with different ones in the new\n * layout, e.g. a system node and the group of everything inside the system:\n * the group grows out of the system node, or shrinks back into it.\n *\n * Returns a function that cancels the animation.\n */\nexport const animateLayout = ({\n fromNodes,\n fromEdges,\n toNodes,\n toEdges,\n setNodes,\n setEdges,\n getCurrentNodes,\n morphs = [],\n nodeOrigin = [0, 0],\n onDone,\n}: {\n fromNodes: Node[];\n fromEdges: Edge[];\n toNodes: Node[];\n toEdges: Edge[];\n setNodes: (nodes: Node[]) => void;\n setEdges: Dispatch<SetStateAction<Edge[]>>;\n /** The nodes React Flow currently has, with the sizes it measured */\n getCurrentNodes: () => Node[];\n morphs?: { from: string; to: string }[];\n nodeOrigin?: [number, number];\n onDone?: () => void;\n}) => {\n const fromNodesById = new Map(fromNodes.map((node) => [node.id, node]));\n const toNodeIds = new Set(toNodes.map((node) => node.id));\n const fromEdgeIds = new Set(fromEdges.map((edge) => edge.id));\n const toEdgeIds = new Set(toEdges.map((edge) => edge.id));\n\n // Morphing: a group (sized by its style) grows out of the old node, or the\n // old group shrinks to where the new node will be while it fades in\n const shrinking: { node: Node; from: Rect; to: Rect }[] = [];\n morphs.forEach((morph) => {\n const morphFrom = fromNodesById.get(morph.from);\n const morphTo = toNodes.find((node) => node.id === morph.to);\n if (!morphFrom || !morphTo) return;\n const fromRect = getRect(morphFrom, nodeOrigin);\n if (typeof morphTo.style?.width === \"number\") {\n fromNodesById.set(morphTo.id, {\n ...morphTo,\n position: getPositionForRect(morphTo, fromRect, nodeOrigin),\n style: {\n ...morphTo.style,\n width: fromRect.width,\n height: fromRect.height,\n },\n });\n } else {\n shrinking.push({\n node: { ...morphFrom, origin: [0, 0], className: \"ec-morph-exit\" },\n from: fromRect,\n to: getRect(morphTo, nodeOrigin),\n });\n }\n });\n const shrinkingIds = new Set(shrinking.map(({ node }) => node.id));\n\n const exitingNodes = fromNodes\n .filter((node) => !toNodeIds.has(node.id) && !shrinkingIds.has(node.id))\n .map((node) => ({ ...node, className: \"ec-exit\" }));\n\n const frame = (t: number): Node[] => {\n const nodes = toNodes.map((node) => {\n const from = fromNodesById.get(node.id);\n if (!from) return { ...node, className: \"ec-enter\" };\n\n const next: Node = {\n ...node,\n position: {\n x: lerp(from.position.x, node.position.x, t),\n y: lerp(from.position.y, node.position.y, t),\n },\n };\n // Groups grow or shrink to their new size\n const fromSize = size(from);\n const toSize = size(node);\n if (\n typeof fromSize.width === \"number\" &&\n typeof toSize.width === \"number\" &&\n typeof fromSize.height === \"number\" &&\n typeof toSize.height === \"number\"\n ) {\n next.style = {\n ...node.style,\n width: lerp(fromSize.width, toSize.width, t),\n height: lerp(fromSize.height, toSize.height, t),\n };\n }\n return next;\n });\n\n shrinking.forEach(({ node, from, to }) =>\n nodes.push({\n ...node,\n position: { x: lerp(from.x, to.x, t), y: lerp(from.y, to.y, t) },\n style: {\n ...node.style,\n width: lerp(from.width, to.width, t),\n height: lerp(from.height, to.height, t),\n },\n }),\n );\n // Exiting nodes stay (fading out) until the animation ends\n return [...nodes, ...exitingNodes];\n };\n\n // React Flow keeps a node's measured size only when the node passed in has\n // it. Without it, every node would render and be measured again each frame.\n const setNodesKeepingSize = (nodes: Node[]) => {\n const measured = new Map(\n getCurrentNodes().map((node) => [node.id, node.measured]),\n );\n setNodes(\n nodes.map((node) => {\n const measuredSize = measured.get(node.id);\n return measuredSize ? { ...node, measured: measuredSize } : node;\n }),\n );\n };\n\n // Start straight away so the new layout is never painted before it animates\n setNodesKeepingSize(frame(0));\n setEdges([\n ...toEdges.map((edge) =>\n fromEdgeIds.has(edge.id) ? edge : { ...edge, className: \"ec-enter\" },\n ),\n ...fromEdges\n .filter((edge) => !toEdgeIds.has(edge.id))\n .map((edge) => ({ ...edge, className: \"ec-exit\" })),\n ]);\n\n const start = performance.now();\n let animationFrame = requestAnimationFrame(function tick(now) {\n const t = Math.min(1, (now - start) / LAYOUT_ANIMATION_DURATION);\n if (t < 1) {\n setNodesKeepingSize(frame(easeInOut(t)));\n animationFrame = requestAnimationFrame(tick);\n return;\n }\n setNodesKeepingSize(toNodes);\n // Drop the faded out edges. Updated in place rather than replaced, so any\n // changes made to the edges since the start (e.g. animation) are kept.\n setEdges((edges) =>\n edges\n .filter((edge) => toEdgeIds.has(edge.id))\n .map((edge) =>\n edge.className === \"ec-enter\"\n ? { ...edge, className: undefined }\n : edge,\n ),\n );\n onDone?.();\n });\n\n return () => cancelAnimationFrame(animationFrame);\n};\n\n/**\n * Bounds of a laid out graph, for fitting the view to it before it's rendered\n * (none for an empty graph)\n */\nexport const getLayoutBounds = (nodes: Node[], currentNodes: Node[]) => {\n const currentById = new Map(currentNodes.map((node) => [node.id, node]));\n const topLevel = nodes.filter((node) => !node.parentId);\n if (topLevel.length === 0) return undefined;\n const rects = topLevel.map((node) => {\n const measured = currentById.get(node.id)?.measured ?? node.measured;\n const width =\n (typeof node.style?.width === \"number\" ? node.style.width : undefined) ??\n measured?.width ??\n 150;\n const height =\n (typeof node.style?.height === \"number\"\n ? node.style.height\n : undefined) ??\n measured?.height ??\n 100;\n return { ...node.position, width, height };\n });\n const x = Math.min(...rects.map((rect) => rect.x));\n const y = Math.min(...rects.map((rect) => rect.y));\n return {\n x,\n y,\n width: Math.max(...rects.map((rect) => rect.x + rect.width)) - x,\n height: Math.max(...rects.map((rect) => rect.y + rect.height)) - y,\n };\n};\n","import type { Edge } from \"@xyflow/react\";\n\n/**\n * Sets whether each edge simulates messages flowing along it. Only message\n * edges can animate; the rest keep their type.\n */\nexport const applyMessageAnimation = (\n edges: Edge[],\n animateMessages: boolean,\n): Edge[] =>\n edges.map((edge) => {\n // Decided once per edge: toggling animation off changes the type to\n // \"smoothstep\", which would otherwise stop it animating again.\n const canAnimate =\n (edge.data?.canAnimate as boolean | undefined) ??\n !(\n edge.type === \"flow-edge\" ||\n edge.type === \"multiline\" ||\n edge.type === \"default\" ||\n edge.type === \"step\" ||\n edge.type === \"smoothstep\" ||\n edge.data?.animated === false\n );\n\n return {\n ...edge,\n animated: canAnimate ? animateMessages : false,\n type: !canAnimate\n ? edge.type || \"default\"\n : animateMessages\n ? \"animated\"\n : \"smoothstep\",\n data: {\n ...edge.data,\n canAnimate,\n animateMessages: canAnimate ? animateMessages : false,\n animated: canAnimate ? animateMessages : false,\n },\n };\n });\n\n/** Graphs with more nodes than this don't simulate messages unless asked to, to keep the canvas responsive */\nexport const LARGE_GRAPH_NODE_THRESHOLD = 30;\n/** Where the person's choice (the \"Simulate messages\" toggle) is kept */\nexport const ANIMATE_MESSAGES_STORAGE_KEY = \"EventCatalog:animateMessages\";\n\n/**\n * Whether a graph simulates messages, in order: never for graphs that aren't message flows (`disabled`), as the\n * `animated` prop or the `?animate=` URL parameter say, else as the person last chose, except that large graphs\n * only do when asked (a choice made on a small graph would otherwise make every large one slow: each animated\n * edge repaints on every frame).\n */\nexport const shouldAnimateMessages = ({\n disabled,\n animated,\n nodeCount,\n}: {\n disabled?: boolean;\n animated?: boolean;\n nodeCount: number;\n}): boolean => {\n if (disabled) return false;\n if (animated !== undefined) return animated;\n const param = new URLSearchParams(window.location.search).get(\"animate\");\n if (param === \"true\" || param === \"false\") return param === \"true\";\n let stored: string | null = null;\n try {\n stored = localStorage.getItem(ANIMATE_MESSAGES_STORAGE_KEY);\n } catch {\n // Storage blocked: decided by the graph's size\n }\n return stored !== \"false\" && nodeCount <= LARGE_GRAPH_NODE_THRESHOLD;\n};\n","import React, { type RefObject, useState, memo } from \"react\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport {\n Code,\n Share2,\n Search,\n Grid3x3,\n Maximize,\n Map,\n Sparkles,\n Zap,\n EyeOff,\n Save,\n RotateCcw,\n Loader2,\n MessageCircle,\n SquareDashedMousePointer,\n} from \"lucide-react\";\nimport {\n DocumentArrowDownIcon,\n PresentationChartLineIcon,\n} from \"@heroicons/react/24/outline\";\nimport type { VisualiserSearchRef } from \"./VisualiserSearch\";\nimport {\n DIAGRAM_MENU_ITEM,\n DIAGRAM_MENU_ITEM_ICON,\n DIAGRAM_MENU_SEPARATOR,\n} from \"./diagram-menu\";\n\ninterface VisualizerDropdownContentProps {\n isMermaidView: boolean;\n setIsMermaidView: (value: boolean) => void;\n animateMessages: boolean;\n toggleAnimateMessages: () => void;\n /** Hide the \"Simulate Messages\" toggle entirely (e.g. on the Context Diagram). */\n hideAnimateMessages?: boolean;\n hideChannels: boolean;\n toggleChannelsVisibility: () => void;\n hasChannels: boolean;\n hideMessages: boolean;\n toggleMessagesVisibility: () => void;\n hasMessages: boolean;\n showMinimap: boolean;\n setShowMinimap: (value: boolean) => void;\n handleFitView: () => void;\n searchRef: RefObject<VisualiserSearchRef | null>;\n isChatEnabled: boolean;\n openChat: () => void;\n handleCopyArchitectureCode: () => void;\n /** Opens the choice of exports (an image, or Mermaid) */\n onOpenExport: () => void;\n setIsShareModalOpen: (value: boolean) => void;\n toggleFullScreen: () => void;\n isDevMode?: boolean;\n onSaveLayout?: () => Promise<boolean>;\n onResetLayout?: () => Promise<boolean>;\n notesCount?: number;\n onOpenNotes?: () => void;\n /** Starts a Studio canvas from the diagram (the app asks what to call it, then opens it) */\n onOpenInStudio?: () => void;\n}\n\nconst VisualizerDropdownContent: React.FC<VisualizerDropdownContentProps> =\n memo(\n ({\n isMermaidView,\n setIsMermaidView,\n animateMessages,\n toggleAnimateMessages,\n hideAnimateMessages = false,\n hideChannels,\n toggleChannelsVisibility,\n hasChannels,\n hideMessages,\n toggleMessagesVisibility,\n hasMessages,\n showMinimap,\n setShowMinimap,\n handleFitView,\n searchRef,\n isChatEnabled,\n openChat,\n handleCopyArchitectureCode,\n onOpenExport,\n setIsShareModalOpen,\n toggleFullScreen,\n isDevMode = false,\n onSaveLayout,\n onResetLayout,\n notesCount = 0,\n onOpenNotes,\n onOpenInStudio,\n }) => {\n const [layoutStatus, setLayoutStatus] = useState<\n \"idle\" | \"saving\" | \"resetting\"\n >(\"idle\");\n const portalContainer = usePortalContainer();\n\n const handleSaveLayout = async () => {\n if (!onSaveLayout) return;\n setLayoutStatus(\"saving\");\n await onSaveLayout();\n setLayoutStatus(\"idle\");\n };\n\n const handleResetLayout = async () => {\n if (!onResetLayout) return;\n if (\n !window.confirm(\n \"Reset layout to auto-positioning? This will delete your saved layout.\",\n )\n ) {\n return;\n }\n setLayoutStatus(\"resetting\");\n const success = await onResetLayout();\n if (success) {\n window.location.reload();\n } else {\n setLayoutStatus(\"idle\");\n }\n };\n\n return (\n <>\n {/* Canvas Settings Submenu */}\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger className=\"flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2 outline-none\">\n <Grid3x3 className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Canvas</span>\n <svg\n className=\"w-3 h-3 text-[rgb(var(--ec-page-text-muted))]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </DropdownMenu.SubTrigger>\n <DropdownMenu.Portal container={portalContainer}>\n <DropdownMenu.SubContent\n className=\"min-w-[200px] bg-[rgb(var(--ec-card-bg))] rounded-lg shadow-xl border border-[rgb(var(--ec-page-border))] py-1.5 z-[60]\"\n sideOffset={8}\n alignOffset={-8}\n >\n <DropdownMenu.CheckboxItem\n checked={isMermaidView}\n onCheckedChange={setIsMermaidView}\n className={DIAGRAM_MENU_ITEM}\n >\n <Code className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Render as mermaid</span>\n <div\n className={`w-7 h-4 rounded-full transition-all duration-200 flex-shrink-0 relative ${isMermaidView ? \"bg-[rgb(var(--ec-accent))]\" : \"bg-[rgb(var(--ec-page-border))]\"}`}\n >\n <div\n className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow-sm transition-all duration-200 ${isMermaidView ? \"left-3.5\" : \"left-0.5\"}`}\n />\n </div>\n </DropdownMenu.CheckboxItem>\n\n {!hideAnimateMessages && (\n <>\n <DropdownMenu.Separator\n className={DIAGRAM_MENU_SEPARATOR}\n />\n\n <DropdownMenu.CheckboxItem\n checked={animateMessages}\n onCheckedChange={toggleAnimateMessages}\n className={DIAGRAM_MENU_ITEM}\n >\n <Zap className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">\n Simulate Messages\n </span>\n <div\n className={`w-7 h-4 rounded-full transition-all duration-200 flex-shrink-0 relative ${animateMessages ? \"bg-[rgb(var(--ec-accent))]\" : \"bg-[rgb(var(--ec-page-border))]\"}`}\n >\n <div\n className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow-sm transition-all duration-200 ${animateMessages ? \"left-3.5\" : \"left-0.5\"}`}\n />\n </div>\n </DropdownMenu.CheckboxItem>\n </>\n )}\n\n {hasChannels && (\n <DropdownMenu.CheckboxItem\n checked={hideChannels || hideMessages}\n onCheckedChange={toggleChannelsVisibility}\n disabled={hideMessages}\n className=\"flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2 data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed\"\n >\n <EyeOff className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Hide channels</span>\n <div\n className={`w-7 h-4 rounded-full transition-all duration-200 flex-shrink-0 relative ${hideChannels || hideMessages ? \"bg-[rgb(var(--ec-accent))]\" : \"bg-[rgb(var(--ec-page-border))]\"}`}\n >\n <div\n className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow-sm transition-all duration-200 ${hideChannels || hideMessages ? \"left-3.5\" : \"left-0.5\"}`}\n />\n </div>\n </DropdownMenu.CheckboxItem>\n )}\n\n {hasMessages && (\n <DropdownMenu.CheckboxItem\n checked={hideMessages}\n onCheckedChange={toggleMessagesVisibility}\n className={DIAGRAM_MENU_ITEM}\n >\n <EyeOff className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Hide messages</span>\n <div\n className={`w-7 h-4 rounded-full transition-all duration-200 flex-shrink-0 relative ${hideMessages ? \"bg-[rgb(var(--ec-accent))]\" : \"bg-[rgb(var(--ec-page-border))]\"}`}\n >\n <div\n className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow-sm transition-all duration-200 ${hideMessages ? \"left-3.5\" : \"left-0.5\"}`}\n />\n </div>\n </DropdownMenu.CheckboxItem>\n )}\n\n <DropdownMenu.CheckboxItem\n checked={showMinimap}\n onCheckedChange={setShowMinimap}\n className={DIAGRAM_MENU_ITEM}\n >\n <Map className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Show minimap</span>\n <div\n className={`w-7 h-4 rounded-full transition-all duration-200 flex-shrink-0 relative ${showMinimap ? \"bg-[rgb(var(--ec-accent))]\" : \"bg-[rgb(var(--ec-page-border))]\"}`}\n >\n <div\n className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow-sm transition-all duration-200 ${showMinimap ? \"left-3.5\" : \"left-0.5\"}`}\n />\n </div>\n </DropdownMenu.CheckboxItem>\n\n <DropdownMenu.Separator className={DIAGRAM_MENU_SEPARATOR} />\n\n <DropdownMenu.Item\n onClick={handleFitView}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <Maximize className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Fit view</span>\n </DropdownMenu.Item>\n\n <DropdownMenu.Item\n onClick={() => {\n searchRef.current?.hideSuggestions();\n setTimeout(() => {\n const searchInput = document.querySelector(\n 'input[placeholder=\"Search nodes...\"]',\n ) as HTMLInputElement;\n searchInput?.focus();\n }, 50);\n }}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <Search className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Find on canvas</span>\n </DropdownMenu.Item>\n </DropdownMenu.SubContent>\n </DropdownMenu.Portal>\n </DropdownMenu.Sub>\n\n {/* Notes */}\n {notesCount > 0 && onOpenNotes && (\n <DropdownMenu.Item\n onClick={onOpenNotes}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <MessageCircle className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">\n View notes ({notesCount})\n </span>\n </DropdownMenu.Item>\n )}\n\n {/* Dev Mode: Layout Submenu */}\n {isDevMode && onSaveLayout && (\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger className=\"flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2 outline-none\">\n <Save className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Layout</span>\n <span className=\"text-[10px] text-amber-600 font-medium\">\n DEV\n </span>\n <svg\n className=\"w-3 h-3 text-[rgb(var(--ec-page-text-muted))]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </DropdownMenu.SubTrigger>\n <DropdownMenu.Portal container={portalContainer}>\n <DropdownMenu.SubContent\n className=\"min-w-[180px] bg-[rgb(var(--ec-card-bg))] rounded-lg shadow-xl border border-[rgb(var(--ec-page-border))] py-1.5 z-[60]\"\n sideOffset={8}\n alignOffset={-8}\n >\n <DropdownMenu.Item\n onClick={handleSaveLayout}\n disabled={layoutStatus !== \"idle\"}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {layoutStatus === \"saving\" ? (\n <Loader2 className=\"w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 animate-spin\" />\n ) : (\n <Save className={DIAGRAM_MENU_ITEM_ICON} />\n )}\n <span className=\"flex-1 font-normal\">\n {layoutStatus === \"saving\" ? \"Saving...\" : \"Save Layout\"}\n </span>\n </DropdownMenu.Item>\n <DropdownMenu.Item\n onClick={handleResetLayout}\n disabled={layoutStatus !== \"idle\"}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {layoutStatus === \"resetting\" ? (\n <Loader2 className=\"w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 animate-spin\" />\n ) : (\n <RotateCcw className={DIAGRAM_MENU_ITEM_ICON} />\n )}\n <span className=\"flex-1 font-normal\">\n {layoutStatus === \"resetting\"\n ? \"Resetting...\"\n : \"Reset Layout\"}\n </span>\n </DropdownMenu.Item>\n </DropdownMenu.SubContent>\n </DropdownMenu.Portal>\n </DropdownMenu.Sub>\n )}\n\n {/* Ask AI */}\n {isChatEnabled && (\n <>\n <DropdownMenu.Separator className={DIAGRAM_MENU_SEPARATOR} />\n <DropdownMenu.Item\n onClick={openChat}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <Sparkles className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Ask a question</span>\n </DropdownMenu.Item>\n </>\n )}\n\n {/* Export Items */}\n <DropdownMenu.Separator className={DIAGRAM_MENU_SEPARATOR} />\n <DropdownMenu.Item\n onClick={handleCopyArchitectureCode}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <Code className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Copy as mermaid</span>\n </DropdownMenu.Item>\n\n <DropdownMenu.Item\n onClick={onOpenExport}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <DocumentArrowDownIcon className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Export</span>\n </DropdownMenu.Item>\n\n {/* Share Link */}\n <DropdownMenu.Item\n onClick={() => setIsShareModalOpen(true)}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <Share2 className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Share Link</span>\n </DropdownMenu.Item>\n\n {/* Start Presentation */}\n <DropdownMenu.Separator className={DIAGRAM_MENU_SEPARATOR} />\n <DropdownMenu.Item\n onClick={toggleFullScreen}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <PresentationChartLineIcon className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Start Presentation</span>\n </DropdownMenu.Item>\n\n {/* Open in Studio */}\n {onOpenInStudio && (\n <>\n <DropdownMenu.Separator className={DIAGRAM_MENU_SEPARATOR} />\n <DropdownMenu.Item\n onSelect={onOpenInStudio}\n className=\"px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer flex items-center gap-2 transition-colors\"\n >\n <SquareDashedMousePointer className={DIAGRAM_MENU_ITEM_ICON} />\n <span className=\"flex-1 font-normal\">Open in Studio</span>\n </DropdownMenu.Item>\n </>\n )}\n </>\n );\n },\n );\n\nVisualizerDropdownContent.displayName = \"VisualizerDropdownContent\";\n\nexport default VisualizerDropdownContent;\n","/**\n * How a diagram's menu looks (the button at the top left, with the diagram's title, and the menu it opens). Studio's\n * canvas menu uses the same, so the two feel the same.\n */\n\n/** The button: the title, then the menu icon (DIAGRAM_MENU_BUTTON_ICON) */\nexport const DIAGRAM_MENU_BUTTON =\n \"py-2.5 px-4 bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-accent-subtle))] border border-[rgb(var(--ec-page-border))] rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[rgb(var(--ec-accent))] flex items-center gap-3 transition-colors duration-150 hover:border-[rgb(var(--ec-accent)/0.3)] group whitespace-nowrap\";\n/** The button without a title: just the icon */\nexport const DIAGRAM_MENU_BUTTON_COMPACT =\n \"h-9 w-9 p-0 bg-[rgb(var(--ec-card-bg))] hover:bg-[rgb(var(--ec-accent-subtle))] border border-[rgb(var(--ec-page-border))] rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[rgb(var(--ec-accent))] flex items-center justify-center transition-colors duration-150 hover:border-[rgb(var(--ec-accent)/0.3)] group\";\nexport const DIAGRAM_MENU_TITLE =\n \"text-base font-medium text-[rgb(var(--ec-page-text))] leading-tight\";\nexport const DIAGRAM_MENU_BUTTON_ICON =\n \"h-5 w-5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 group-hover:text-[rgb(var(--ec-accent))] transition-colors duration-150\";\nexport const DIAGRAM_MENU_BUTTON_ICON_COMPACT =\n \"h-4 w-4 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0 group-hover:text-[rgb(var(--ec-accent))] transition-colors duration-150\";\n\n/** The menu, its items (an icon, then the label), and the lines between groups of them */\nexport const DIAGRAM_MENU =\n \"min-w-56 bg-[rgb(var(--ec-page-bg))] border border-[rgb(var(--ec-page-border))] rounded-lg shadow-xl z-50 py-1.5\";\nexport const DIAGRAM_MENU_ITEM =\n \"flex items-center px-3 py-2 text-xs text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-accent-subtle)/0.3)] cursor-pointer transition-colors gap-2\";\nexport const DIAGRAM_MENU_ITEM_ICON =\n \"w-3.5 h-3.5 text-[rgb(var(--ec-page-text-muted))] flex-shrink-0\";\nexport const DIAGRAM_MENU_SEPARATOR =\n \"my-1 h-px bg-[rgb(var(--ec-page-border))]\";\n","import { memo } from \"react\";\nimport * as ContextMenu from \"@radix-ui/react-context-menu\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport type { ContextMenuItem } from \"../types\";\n\ninterface NodeContextMenuProps {\n items: ContextMenuItem[];\n children: React.ReactNode;\n}\n\nexport default memo(function NodeContextMenu({\n items,\n children,\n}: NodeContextMenuProps) {\n const portalContainer = usePortalContainer();\n\n if (!items || items.length === 0) return <>{children}</>;\n\n return (\n <ContextMenu.Root>\n <ContextMenu.Trigger>{children}</ContextMenu.Trigger>\n <ContextMenu.Portal container={portalContainer}>\n <ContextMenu.Content\n className=\"min-w-[220px] bg-white rounded-md p-1 shadow-md border border-gray-200 z-50\"\n onClick={(e) => e.stopPropagation()}\n >\n {items.map((item, index) => (\n <div key={index}>\n {item.separator && index > 0 && (\n <ContextMenu.Separator className=\"h-[1px] bg-gray-200 m-1\" />\n )}\n <ContextMenu.Item\n asChild\n className=\"text-sm px-2 py-1.5 outline-none cursor-pointer hover:bg-orange-100 rounded-sm flex items-center text-gray-900 hover:text-gray-900 visited:text-gray-900 no-underline hover:no-underline visited:no-underline\"\n >\n <a\n href={item.href}\n {...(item.download ? { download: item.download } : {})}\n {...(item.external\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : {})}\n >\n {item.label}\n </a>\n </ContextMenu.Item>\n </div>\n ))}\n </ContextMenu.Content>\n </ContextMenu.Portal>\n </ContextMenu.Root>\n );\n});\n","import { memo, type ComponentType } from \"react\";\n\n// React Flow gives every custom node its position, which changes on every frame\n// while a layout animates (e.g. switching levels). It moves nodes with its\n// wrapper's transform, so no node renders differently for its position.\nconst POSITION_PROPS = new Set([\"positionAbsoluteX\", \"positionAbsoluteY\"]);\n\nconst equalExceptPosition = <P extends object>(\n previous: Readonly<P>,\n next: Readonly<P>,\n) => {\n const keys = new Set([...Object.keys(previous), ...Object.keys(next)]);\n for (const key of keys) {\n if (POSITION_PROPS.has(key)) continue;\n if (\n !Object.is(\n (previous as Record<string, unknown>)[key],\n (next as Record<string, unknown>)[key],\n )\n )\n return false;\n }\n return true;\n};\n\n/** Memoizes a custom node so it renders again only when something besides its position changes. */\nexport const memoNode = <P extends object>(Component: ComponentType<P>) =>\n memo(Component, equalExceptPosition);\n","/**\n * Pauses (or resumes) the SMIL animations of a canvas's edges: the message envelopes moving along them. Hiding\n * them doesn't stop them (SMIL keeps running, with a style recalc and layout every frame), so while the canvas\n * is panned, zoomed or dragged they're paused. Each edge is its own <svg>, with its own timeline.\n */\nexport const pauseEdgeAnimations = (canvas: Element | null, paused: boolean) =>\n canvas\n ?.querySelectorAll<SVGSVGElement>(\".react-flow__edges > svg\")\n .forEach((svg) =>\n paused ? svg.pauseAnimations() : svg.unpauseAnimations(),\n );\n","import { getViewportForBounds, type Rect, type Viewport } from \"@xyflow/react\";\nimport logoSvg from \"../studio/eventcatalog-logo.svg?raw\";\n\nconst MIN_IMAGE_WIDTH = 1024;\nconst MIN_IMAGE_HEIGHT = 768;\n\n// Nodes render decorations outside their measured rects (type badges at\n// -top-2.5, actor icons at -top-4, box shadows), so the exported image needs\n// breathing room around getNodesBounds() or edge nodes get clipped.\nexport const EXPORT_PADDING = 40;\n\nexport function getExportImageDimensions(nodesBounds: Rect): {\n width: number;\n height: number;\n viewport: Viewport;\n} {\n const paddedBounds = {\n x: nodesBounds.x - EXPORT_PADDING,\n y: nodesBounds.y - EXPORT_PADDING,\n width: nodesBounds.width + EXPORT_PADDING * 2,\n height: nodesBounds.height + EXPORT_PADDING * 2,\n };\n\n const width = Math.max(MIN_IMAGE_WIDTH, Math.ceil(paddedBounds.width));\n const height = Math.max(MIN_IMAGE_HEIGHT, Math.ceil(paddedBounds.height));\n\n const viewport = getViewportForBounds(paddedBounds, width, height, 0.5, 2, 0);\n\n return { width, height, viewport };\n}\n\n// html-to-image deep-clones <svg> subtrees without inlining computed styles,\n// so var()-based fills (edge label pills, label text) and stylesheet rules\n// (.react-flow__edge-path) resolve to nothing in the capture — labels render\n// black and edges lose their color. Injecting a <style> that pins the resolved\n// theme variables and mirrors the edge rules fixes the capture in both themes.\n\nexport function extractEcVarNames(cssText: string): string[] {\n return Array.from(new Set(cssText.match(/--ec-[a-z0-9-]+/g) ?? []));\n}\n\nexport function buildExportCss(themeVars: Record<string, string>): string {\n const varDeclarations = Object.entries(themeVars)\n .map(([name, value]) => `${name}: ${value};`)\n .join(\" \");\n\n return [\n // Applied to every element so the variables reach the cloned SVG subtree\n `* { ${varDeclarations} }`,\n // Mirrors .react-flow__edge-path in styles.css, which is lost in the clone\n `.react-flow__edge-path { stroke: var(--ec-edge-stroke, #6b7280); stroke-width: 1.5; fill: none; }`,\n ].join(\"\\n\");\n}\n\nfunction collectThemeCssVars(scope: Element): Record<string, string> {\n const names = new Set<string>();\n for (const sheet of Array.from(document.styleSheets)) {\n let rules: CSSRuleList;\n try {\n rules = sheet.cssRules;\n } catch {\n continue; // cross-origin stylesheet\n }\n for (const rule of Array.from(rules)) {\n for (const name of extractEcVarNames(rule.cssText)) {\n names.add(name);\n }\n }\n }\n\n const computed = window.getComputedStyle(scope);\n const vars: Record<string, string> = {};\n for (const name of names) {\n const value = computed.getPropertyValue(name).trim();\n if (value) vars[name] = value;\n }\n return vars;\n}\n\n// html-to-image deep-clones <svg> elements via cloneNode(true) and skips\n// computed-style inlining for everything inside them (cloneChildren returns\n// early for SVG). Styles that SVG content gets from stylesheets or var()-based\n// presentation attributes are therefore lost in the capture. Inlining the\n// resolved values directly onto each SVG element before capture is the only\n// approach that survives the clone in every browser.\nconst SVG_EXPORT_STYLE_PROPERTIES = [\n \"fill\",\n \"fill-opacity\",\n \"stroke\",\n \"stroke-width\",\n \"stroke-dasharray\",\n \"stroke-linecap\",\n \"stroke-linejoin\",\n \"opacity\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"letter-spacing\",\n \"text-anchor\",\n \"dominant-baseline\",\n];\n\nfunction inlineSvgComputedStyles(viewport: HTMLElement): () => void {\n const restores: Array<() => void> = [];\n const svgElements = viewport.querySelectorAll(\"svg, svg *\");\n svgElements.forEach((element) => {\n if (!(element instanceof SVGElement)) return;\n const computed = window.getComputedStyle(element);\n const originalStyle = element.getAttribute(\"style\");\n for (const property of SVG_EXPORT_STYLE_PROPERTIES) {\n const value = computed.getPropertyValue(property);\n if (value) element.style.setProperty(property, value);\n }\n restores.push(() => {\n if (originalStyle === null) {\n element.removeAttribute(\"style\");\n } else {\n element.setAttribute(\"style\", originalStyle);\n }\n });\n });\n return () => restores.forEach((restore) => restore());\n}\n\n// Returns a cleanup function that removes the injected styles.\nexport function injectExportStyles(viewport: HTMLElement): () => void {\n const styleElement = document.createElement(\"style\");\n styleElement.textContent = buildExportCss(collectThemeCssVars(viewport));\n viewport.appendChild(styleElement);\n const restoreSvgStyles = inlineSvgComputedStyles(viewport);\n return () => {\n restoreSvgStyles();\n styleElement.remove();\n };\n}\n\nconst loadImage = (src: string) =>\n new Promise<HTMLImageElement>((resolve, reject) => {\n const image = new Image();\n image.onload = () => resolve(image);\n image.onerror = reject;\n image.src = src;\n });\n\n/** A theme colour, from EventCatalog's variables (e.g. --ec-card-bg is \"255 255 255\") */\nconst themeColor = (name: string, alpha = 1) => {\n const value =\n getComputedStyle(document.documentElement).getPropertyValue(name).trim() ||\n getComputedStyle(document.body).getPropertyValue(name).trim();\n return value\n ? `rgb(${value} / ${alpha})`\n : alpha === 1\n ? \"#0f172a\"\n : `rgb(15 23 42 / ${alpha})`;\n};\n\ntype BrandingOptions = {\n /** Space to add around the image, in CSS pixels (e.g. for an image cropped to what's drawn) */\n padding?: number;\n /** The background around the image, when its own edges aren't background */\n background?: string;\n};\n\nasync function drawBranding(\n dataUrl: string,\n pixelRatio: number,\n { padding = 0, background }: BrandingOptions,\n): Promise<string> {\n const image = await loadImage(dataUrl);\n // Sized to the image, so it reads the same on a small diagram or a very wide one\n const r = Math.max(\n pixelRatio,\n Math.min(image.width / 1200, image.height / 500),\n );\n const height = 30 * r;\n const margin = 20 * r;\n\n const pad = padding * pixelRatio;\n\n // The badge goes in a strip under the image, so it never covers the diagram\n const canvas = document.createElement(\"canvas\");\n canvas.width = image.width + pad * 2;\n canvas.height = image.height + pad * 2 + height + margin;\n const context = canvas.getContext(\"2d\");\n if (!context) return dataUrl;\n context.drawImage(image, pad, pad);\n // The space around it in the image's background (its corner is padding,\n // never the diagram), filled in behind it\n const [red, green, blue, alpha] = context.getImageData(\n pad,\n pad + image.height - 1,\n 1,\n 1,\n ).data;\n context.globalCompositeOperation = \"destination-over\";\n context.fillStyle =\n background ?? `rgba(${red}, ${green}, ${blue}, ${alpha / 255})`;\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.globalCompositeOperation = \"source-over\";\n await document.fonts?.ready;\n\n const text = themeColor(\"--ec-page-text\");\n const muted = themeColor(\"--ec-page-text-muted\");\n const font = (weight: number) =>\n `${weight} ${12 * r}px Inter, ui-sans-serif, system-ui, sans-serif`;\n const parts = [\n { label: \"Made with \", weight: 400, color: muted },\n { label: \"EventCatalog\", weight: 600, color: text },\n { label: \" · eventcatalog.dev\", weight: 400, color: muted },\n ];\n const widths = parts.map((part) => {\n context.font = font(part.weight);\n return context.measureText(part.label).width;\n });\n const logoSize = 16 * r;\n const paddingX = 12 * r;\n const gap = 7 * r;\n const width =\n paddingX * 2 + logoSize + gap + widths.reduce((sum, w) => sum + w, 0);\n const x = canvas.width - width - margin;\n const y = image.height + pad * 2;\n\n // The pill\n context.fillStyle = themeColor(\"--ec-card-bg\", 0.96);\n context.strokeStyle = themeColor(\"--ec-page-border\");\n context.lineWidth = r;\n context.beginPath();\n context.roundRect(x, y, width, height, height / 2);\n context.fill();\n context.stroke();\n\n // The logo, in the text colour\n const logo = await loadImage(\n `data:image/svg+xml;charset=utf-8,${encodeURIComponent(logoSvg.replace(/currentColor/g, text))}`,\n );\n context.drawImage(\n logo,\n x + paddingX,\n y + (height - logoSize) / 2,\n logoSize,\n logoSize,\n );\n\n // Made with EventCatalog · eventcatalog.dev\n let textX = x + paddingX + logoSize + gap;\n context.textBaseline = \"middle\";\n parts.forEach((part, index) => {\n context.font = font(part.weight);\n context.fillStyle = part.color;\n context.fillText(part.label, textX, y + height / 2 + r);\n textX += widths[index];\n });\n return canvas.toDataURL(\"image/png\");\n}\n\n/**\n * An exported image with \"Made with EventCatalog · eventcatalog.dev\" in its\n * bottom right corner: a small pill with the logo, in the diagram's theme.\n * Diagrams and Studio canvases are exported with it.\n */\nexport async function addExportBranding(\n dataUrl: string,\n pixelRatio: number,\n options: BrandingOptions = {},\n): Promise<string> {\n try {\n return await drawBranding(dataUrl, pixelRatio, options);\n } catch {\n // Exported without the badge rather than not at all\n return dataUrl;\n }\n}\n","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"58 54 1133 1133\" aria-hidden=\"true\" fill=\"currentColor\">\n<path fill-rule=\"evenodd\" d=\"M 445 55 c -174.6 0.5 -188.1 0.7 -196.5 2.3 -20.7 4.1 -35.3 8.5 -51 15.3 -66.7 28.8 -114.7 86.9 -130.3 157.9 l -2.6 12 -0.4 371 c -0.2 261 0 373.8 0.8 380.5 4.6 40.7 21.8 79.6 49.8 113 36.8 43.9 89.5 72.4 144.2 77.9 5.9 0.6 148.2 1.1 372.5 1.3 345.2 0.3 363.5 0.2 373 -1.5 32.1 -5.7 58.7 -16.4 85.5 -34.2 53.2 -35.3 89.1 -93.6 96 -156 0.8 -7.2 1 -114.8 0.8 -381.5 l -0.3 -371.5 -2.2 -10.4 c -7.7 -35.9 -18.8 -61.1 -38.9 -88.2 -9.5 -12.8 -30.7 -34.1 -43.4 -43.5 -34.4 -25.6 -73.7 -40.9 -113.5 -44.3 -12.5 -1.1 -182.7 -1.1 -543.5 -0.1 z m -26.3 152.5 c 30.7 11.6 86.7 67 122.9 121.6 l 8.4 12.6 9.7 -2.3 c 13.3 -3.3 30.3 -6.1 44.8 -7.5 15.1 -1.5 51.8 -0.6 67.5 1.6 10.1 1.4 37.1 6.8 40.5 8.1 0.7 0.3 3.6 -3.4 7.1 -8.8 18.3 -29.1 37.9 -53.5 64.7 -80.7 31.8 -32.2 53.3 -47 68.5 -47.1 10.5 -0 16.2 4.1 22.3 16.1 11.6 23 17.3 80.8 15 153.1 l -1 33.7 6 14.7 c 3.2 8 7.8 20.4 10 27.5 2.3 7.1 4.5 12.9 4.9 12.9 0.4 -0 5 -1.5 10.1 -3.4 29.8 -10.8 61.4 -20.5 89.6 -27.5 20 -5.1 21.5 -5.1 25.9 -0.7 2.9 2.9 3.4 4.1 3.4 7.9 0 3.4 -0.6 5.3 -2.5 7.5 -2.9 3.5 -4.7 4.3 -18 7.7 -23.9 6.3 -83.7 25.2 -103 32.5 -2 0.8 -2 1.2 -1 10.6 0.5 5.3 1.5 9.9 2 10 0.6 0.2 16.8 2.4 36 4.9 69.6 9.1 85.9 11.5 89.4 13.3 10.1 5.1 7.6 20.4 -3.6 21.9 -3.7 0.5 -26.4 -2.1 -63.3 -7.2 -18.4 -2.6 -56.7 -7.5 -58 -7.5 -0.4 -0 -1 0.8 -1.2 1.8 -0.4 1.4 -2.9 2.3 -11.4 4.1 -50.2 10.3 -130.1 33.1 -167.9 47.8 -35.1 13.6 -69.4 33.4 -96.1 55.6 -6.6 5.4 -10.1 7.7 -10.9 7.1 -0.7 -0.5 -5.8 -4.6 -11.5 -9.2 -25 -20.2 -55.1 -37.5 -88.5 -50.7 -39.3 -15.6 -111.9 -36.5 -170.7 -49.1 -15.1 -3.2 -17.8 -4.1 -17.8 -5.6 0 -2.4 0.4 -2.4 -35 2.2 -16.8 2.2 -42.6 5.7 -57.5 7.6 -14.8 2 -28.8 3.3 -31 3 -5.9 -0.7 -9.5 -5.1 -9.5 -11.5 0 -5.7 2.4 -9.4 7.3 -11 3.2 -1.1 62.2 -9.4 103.2 -14.6 11.6 -1.5 21.3 -3 21.7 -3.3 0.3 -0.4 0.9 -5 1.3 -10.3 l 0.7 -9.6 -30.3 -10.1 c -24.9 -8.3 -73.2 -22.8 -85.2 -25.6 -1.5 -0.4 -4.1 -1.9 -5.8 -3.4 -2.6 -2.3 -3.3 -3.8 -3.7 -8 -0.4 -4.7 -0.2 -5.4 2.5 -8.1 1.7 -1.6 4.3 -3.3 5.8 -3.7 5.8 -1.4 46 9.3 88.5 23.7 16.2 5.5 30.3 10.3 31.2 10.6 1 0.3 2 -0.1 2.2 -0.8 4.6 -14.9 9 -27.2 14 -39.4 l 6.2 -15 -1 -32.5 c -1.5 -48.5 0.9 -93.8 6.4 -122.4 5 -25.8 12 -40.4 21.9 -45.6 5.4 -2.9 15.3 -2.6 23.8 0.5 z m -67.6 364.4 c 81.9 16.7 161.5 40.4 199.3 59.3 11.7 5.9 29.8 16.7 34.1 20.3 l 3 2.6 -9.5 -0.4 c -8.7 -0.4 -15.5 -2.1 -78.5 -19.7 -37.9 -10.6 -76 -21.2 -84.5 -23.5 -56.6 -15.7 -123.4 -34.6 -123.8 -35 -0.6 -0.6 13.5 -2.8 37.3 -5.8 6.4 -0.8 8.6 -0.6 22.6 2.2 z m 589.5 -0.4 c 10.4 1.4 20.4 2.8 22.3 3.2 3.4 0.6 -40.5 13.5 -170.9 50.2 -20.1 5.7 -42.6 12 -50 14.1 -50.1 14.2 -53.5 15 -60.8 15 -4 -0 -7.2 -0.3 -7.2 -0.8 0 -2.1 28.9 -19.2 45.8 -27.1 36.1 -16.7 110.6 -38.3 193.2 -55.9 6.6 -1.4 7.1 -1.4 27.6 1.3 z m -672.2 33.1 c 13.2 3.6 31.1 8.5 39.6 10.9 8.5 2.4 35.3 9.8 59.5 16.4 52.5 14.3 120.5 33 167.5 46.1 22.9 6.3 23.5 6.6 24.9 9.6 0.8 1.8 1.1 45.6 1.1 162.2 0 175.7 0.4 164.2 -5.9 164.2 -1.5 -0 -12.4 -2.7 -24.2 -6.1 -20.6 -5.8 -66.3 -18.6 -188.9 -52.7 -31.6 -8.8 -63.1 -17.5 -70 -19.2 -13 -3.3 -16.3 -4.8 -17.9 -7.8 -1.1 -2.1 -7.2 -104.7 -15.6 -262.7 -1.3 -25.9 -2.7 -50.5 -3.1 -54.7 -0.6 -7.3 -0.5 -7.8 2 -10.2 1.4 -1.5 3.5 -2.6 4.7 -2.6 1.2 -0 13 3 26.3 6.6 z m 748.1 -5.6 c 3.9 1.5 4.4 4.2 3.4 19.5 -0.8 12.4 -4.2 70.9 -15 256 -2.6 46 -3.3 53.3 -4.8 55.5 -1.9 2.6 1.3 1.6 -78.6 23.9 -9.9 2.8 -34.2 9.6 -54 15.1 -19.8 5.6 -50.4 14.1 -68 19 -17.6 4.9 -45.7 12.8 -62.5 17.5 -16.7 4.7 -31.7 8.5 -33.2 8.5 -6.3 -0 -5.9 11.3 -5.6 -165.1 0.2 -88.2 0.7 -161.2 1.2 -162.1 0.9 -1.9 4.6 -3.1 32.6 -10.7 10.2 -2.8 25.9 -7.1 35 -9.6 9.1 -2.5 32 -8.9 51 -14.1 47.4 -13.1 124.2 -34.5 168.5 -46.9 14.3 -4 26.3 -7.4 26.7 -7.4 0.4 -0.1 1.8 0.3 3.3 0.9 z m -351.7 95.3 c 0.9 0.7 1.2 35.1 1.2 166.7 l 0 165.9 -2.2 1.3 c -1.8 1 -10.2 1.3 -35.1 1.3 -31.4 -0 -32.9 -0.1 -34.3 -1.9 -2.1 -2.9 -2.1 -330.7 0 -332.8 1.1 -1.2 7.6 -1.4 35.2 -1.4 18.7 0.1 34.5 0.5 35.2 0.9 z\"/>\n</svg>\n","import { MarkerType, type Node, type Edge } from \"@xyflow/react\";\nimport type { GraphNode, GraphEdge } from \"../types\";\nimport { layoutWithElk } from \"./elk-layout\";\n\nconst EMPTY_GROUP_WIDTH = 200;\nconst EMPTY_GROUP_HEIGHT = 80;\n\nconst defaultSizes: Record<string, { width: number; height: number }> = {\n service: { width: 300, height: 140 },\n agent: { width: 300, height: 140 },\n \"agent-tool\": { width: 260, height: 120 },\n agentTool: { width: 260, height: 120 },\n event: { width: 240, height: 140 },\n command: { width: 300, height: 120 },\n query: { width: 300, height: 120 },\n channel: { width: 300, height: 140 },\n container: { width: 300, height: 140 },\n \"data-product\": { width: 300, height: 140 },\n data: { width: 320, height: 120 },\n domain: { width: 300, height: 120 },\n flow: { width: 300, height: 140 },\n actor: { width: 240, height: 100 },\n \"external-system\": { width: 300, height: 100 },\n step: { width: 280, height: 100 },\n \"message-group\": { width: 350, height: 200 },\n group: { width: EMPTY_GROUP_WIDTH, height: EMPTY_GROUP_HEIGHT },\n};\nconst fallbackSize = { width: 280, height: 100 };\n\nconst getNodeSize = (node: Node) =>\n defaultSizes[node.type || \"\"] || fallbackSize;\n\nexport function buildNodeData(\n node: GraphNode,\n style?: string,\n): Record<string, unknown> {\n const notes =\n (node.metadata.notes as Array<{\n content: string;\n author?: string;\n priority?: string;\n }>) || [];\n const owners = (node.metadata.owners as string[]) || [];\n const base = {\n name: node.label,\n version: (node.metadata.version as string) || \"\",\n summary: (node.metadata.summary as string) || \"\",\n deprecated: node.metadata.deprecated === true,\n draft: node.metadata.draft === true,\n ...(notes.length > 0 ? { notes } : {}),\n ...(owners.length > 0 ? { owners } : {}),\n };\n\n switch (node.type) {\n case \"service\":\n return { mode: \"full\", style, service: base };\n case \"agent\":\n return {\n mode: \"full\",\n style,\n agent: {\n ...base,\n ...(node.metadata.model ? { model: node.metadata.model } : {}),\n ...(Array.isArray(node.metadata.tools)\n ? { tools: node.metadata.tools }\n : {}),\n },\n };\n case \"agent-tool\":\n case \"agentTool\":\n return {\n mode: \"full\",\n style,\n agentTool: {\n id: node.id,\n name: node.label,\n type: (node.metadata.type as string) || \"\",\n icon: (node.metadata.icon as string) || \"\",\n url: (node.metadata.url as string) || \"\",\n description: (node.metadata.description as string) || \"\",\n },\n };\n case \"event\":\n case \"command\":\n case \"query\":\n return {\n mode: \"full\",\n style,\n message: {\n ...base,\n schema: (node.metadata.schema as string) || \"\",\n ...(node.metadata.method\n ? { method: node.metadata.method as string }\n : {}),\n ...(node.metadata.path ? { path: node.metadata.path as string } : {}),\n ...(Array.isArray(node.metadata.statusCodes) &&\n node.metadata.statusCodes.length > 0\n ? { statusCodes: node.metadata.statusCodes as number[] }\n : {}),\n },\n };\n case \"channel\":\n return {\n mode: \"full\",\n style,\n channel: {\n ...base,\n protocols: (node.metadata.protocols as string[]) || [],\n address: (node.metadata.address as string) || \"\",\n ...(node.metadata.deliveryGuarantee\n ? { deliveryGuarantee: node.metadata.deliveryGuarantee as string }\n : {}),\n },\n };\n case \"container\":\n return {\n mode: \"full\",\n style,\n data: {\n ...base,\n type: (node.metadata.containerType as string) || \"Database\",\n },\n };\n case \"data-product\":\n return { mode: \"full\", style, dataProduct: base };\n case \"data\":\n return {\n mode: \"full\",\n style,\n data: {\n ...base,\n type: (node.metadata.containerType as string) || \"Database\",\n },\n };\n case \"domain\":\n return {\n mode: \"full\",\n style,\n domain: { data: { ...base, id: node.id } },\n };\n case \"flow\":\n return {\n mode: \"full\",\n style,\n flow: { data: { ...base, id: node.id } },\n };\n case \"actor\":\n return { ...base, label: node.label, mode: \"full\", style, id: node.id };\n case \"external-system\":\n return {\n mode: \"full\",\n style,\n externalSystem: { label: node.label, ...base, id: node.id },\n };\n case \"step\":\n return {\n mode: \"full\",\n style,\n step: { ...base, title: node.label, id: node.id },\n };\n default:\n return { ...base, style, resourceType: node.type };\n }\n}\n\n/**\n * Lays a DSL graph out (left to right), as React Flow nodes and edges. Domains,\n * and nodes other nodes sit in, become groups sized to fit their children.\n */\nexport async function layoutGraph(\n nodes: GraphNode[],\n edges: GraphEdge[],\n { style }: { style?: string } = {},\n): Promise<{ nodes: Node[]; edges: Edge[] }> {\n if (nodes.length === 0) {\n return { nodes: [], edges: [] };\n }\n\n const nodeById = new Map(nodes.map((n) => [n.id, n]));\n const groupIds = new Set(\n nodes\n .filter(\n (n) => n.type === \"domain\" || nodes.some((c) => c.parentId === n.id),\n )\n .map((n) => n.id),\n );\n\n const layoutNodes: Node[] = nodes.map((node) => {\n const parentId =\n node.parentId && node.parentId !== node.id && groupIds.has(node.parentId)\n ? node.parentId\n : undefined;\n const placement = {\n id: node.id,\n position: { x: 0, y: 0 },\n ...(parentId ? { parentId, extent: \"parent\" as const } : {}),\n };\n if (!groupIds.has(node.id)) {\n return {\n ...placement,\n type: node.type,\n data: buildNodeData(node, style),\n };\n }\n return {\n ...placement,\n type: \"group\",\n data: {\n mode: \"full\",\n domain: {\n name: node.label,\n version: (node.metadata.version as string) || \"\",\n summary: (node.metadata.summary as string) || \"\",\n },\n },\n // Groups with children are sized to fit them when laid out\n style: {\n width: EMPTY_GROUP_WIDTH,\n height: EMPTY_GROUP_HEIGHT,\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n },\n };\n });\n\n const layoutEdges: Edge[] = edges\n .filter((edge) => !groupIds.has(edge.source) && !groupIds.has(edge.target))\n .map((edge) => {\n const collection = getMessageCollection(edge, nodeById);\n const isFlowStep = edge.type === \"flow-step\";\n const isCalls = edge.type === \"calls\";\n const isBidirectional = edge.type === \"reads-writes\";\n const arrowMarker = {\n type: MarkerType.ArrowClosed,\n width: 20,\n height: 20,\n color: \"rgb(var(--ec-page-text-muted))\",\n };\n return {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n label: isBidirectional\n ? \"reads/writes\"\n : isFlowStep\n ? edge.label || undefined\n : edge.label || edge.type,\n type: isFlowStep ? \"flow-edge\" : isCalls ? \"step\" : \"animated\",\n markerEnd: arrowMarker,\n ...(isBidirectional ? { markerStart: arrowMarker } : {}),\n data: { edgeType: edge.type, message: { collection } },\n };\n });\n\n return layoutWithElk(\n { nodes: layoutNodes, edges: layoutEdges },\n { sizeOf: getNodeSize },\n );\n}\n\nconst MESSAGE_TYPES = new Set([\"event\", \"command\", \"query\"]);\n\nfunction getMessageCollection(\n edge: GraphEdge,\n nodeById: Map<string, GraphNode>,\n): string | undefined {\n const targetNode = nodeById.get(edge.target);\n if (targetNode && MESSAGE_TYPES.has(targetNode.type)) {\n return `${targetNode.type}s`;\n }\n const sourceNode = nodeById.get(edge.source);\n if (sourceNode && MESSAGE_TYPES.has(sourceNode.type)) {\n return `${sourceNode.type}s`;\n }\n return targetNode ? `${targetNode.type}s` : undefined;\n}\n","export type Position = {\n x: number;\n y: number;\n};\n\nexport type Rect = Position & {\n width: number;\n height: number;\n};\n\nexport type PackableNode = {\n id: string;\n parentId?: string;\n position: Position;\n style?: {\n width?: number | string;\n height?: number | string;\n };\n measured?: {\n width?: number;\n height?: number;\n };\n width?: number;\n height?: number;\n};\n\nconst toNumber = (value: unknown) => {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n};\n\nexport const getPackableNodeSize = (node: PackableNode) => ({\n width:\n toNumber(node.measured?.width) ??\n toNumber(node.width) ??\n toNumber(node.style?.width) ??\n 260,\n height:\n toNumber(node.measured?.height) ??\n toNumber(node.height) ??\n toNumber(node.style?.height) ??\n 140,\n});\n\nexport const rectsIntersect = (a: Rect, b: Rect, gap = 0) =>\n a.x < b.x + b.width + gap &&\n a.x + a.width + gap > b.x &&\n a.y < b.y + b.height + gap &&\n a.y + a.height + gap > b.y;\n\nconst toRect = (node: PackableNode, y = node.position.y): Rect => {\n const size = getPackableNodeSize(node);\n return {\n x: node.position.x,\n y,\n width: size.width,\n height: size.height,\n };\n};\n\nexport const packNodesAroundBounds = ({\n nodes,\n movableNodeIds,\n protectedBounds,\n groupNodeId,\n gap = 40,\n}: {\n nodes: PackableNode[];\n movableNodeIds: Set<string>;\n protectedBounds: Rect;\n groupNodeId: string;\n gap?: number;\n}) => {\n const movableNodes = nodes\n .filter((node) => movableNodeIds.has(node.id))\n .sort((a, b) => a.position.y - b.position.y);\n const movableIds = new Set(movableNodes.map((node) => node.id));\n const occupiedRects: Rect[] = [\n protectedBounds,\n ...nodes\n .filter(\n (node) =>\n !node.parentId && node.id !== groupNodeId && !movableIds.has(node.id),\n )\n .map((node) => toRect(node)),\n ];\n const plannedPositions = new Map<string, Position>();\n const groupCenterY = protectedBounds.y + protectedBounds.height / 2;\n\n const placeNode = (node: PackableNode) => {\n const size = getPackableNodeSize(node);\n const nodeCenterY = node.position.y + size.height / 2;\n const moveDirection = nodeCenterY >= groupCenterY ? 1 : -1;\n let y =\n moveDirection > 0\n ? Math.max(\n node.position.y,\n protectedBounds.y + protectedBounds.height + gap,\n )\n : Math.min(node.position.y, protectedBounds.y - size.height - gap);\n let attempts = 0;\n\n while (attempts < occupiedRects.length + 8) {\n const rect = {\n x: node.position.x,\n y,\n width: size.width,\n height: size.height,\n };\n const collision = occupiedRects.find((occupied) =>\n rectsIntersect(rect, occupied, gap),\n );\n if (!collision) {\n occupiedRects.push(rect);\n plannedPositions.set(node.id, { ...node.position, y });\n return;\n }\n\n y =\n moveDirection > 0\n ? collision.y + collision.height + gap\n : collision.y - size.height - gap;\n attempts += 1;\n }\n\n occupiedRects.push({\n x: node.position.x,\n y,\n width: size.width,\n height: size.height,\n });\n plannedPositions.set(node.id, { ...node.position, y });\n };\n\n const below = movableNodes.filter((node) => {\n const size = getPackableNodeSize(node);\n return node.position.y + size.height / 2 >= groupCenterY;\n });\n const belowIds = new Set(below.map((node) => node.id));\n const above = movableNodes.filter((node) => !belowIds.has(node.id)).reverse();\n\n below.forEach(placeNode);\n above.forEach(placeNode);\n\n return plannedPositions;\n};\n","export type GraphNode = {\n id: string;\n type?: string;\n parentId?: string;\n position: {\n x: number;\n y: number;\n };\n style?: {\n width?: number | string;\n height?: number | string;\n };\n [key: string]: unknown;\n};\n\nexport const getExpandedMessageGroupNode = (\n nodes: GraphNode[],\n groupNodeId: string,\n) =>\n nodes.find(\n (node) => node.id === groupNodeId && node.type === \"messageGroupExpanded\",\n );\n\nexport const buildMessageGroupExpansionNodes = ({\n currentNodes,\n groupNodeId,\n expandedContainerNode,\n childNodes,\n downstreamNodes,\n getDownstreamPosition,\n}: {\n currentNodes: GraphNode[];\n groupNodeId: string;\n expandedContainerNode: GraphNode;\n childNodes: GraphNode[];\n downstreamNodes: GraphNode[];\n getDownstreamPosition: (\n node: GraphNode,\n index: number,\n ) => GraphNode[\"position\"];\n}) => {\n const withoutExistingGroup = currentNodes.filter(\n (node) => node.id !== groupNodeId && node.parentId !== groupNodeId,\n );\n const existingIds = new Set(withoutExistingGroup.map((node) => node.id));\n const newDownstream = downstreamNodes\n .filter((node) => !existingIds.has(node.id))\n .map((node, index) => ({\n ...node,\n position: getDownstreamPosition(node, index),\n }));\n\n return [\n ...withoutExistingGroup,\n expandedContainerNode,\n ...childNodes,\n ...newDownstream,\n ];\n};\n","import { useState, useCallback } from \"react\";\nimport {\n MessageCircle,\n AlertTriangle,\n X,\n Locate,\n ChevronRight,\n ServerIcon,\n Bot,\n Zap,\n MessageSquare,\n Search,\n ArrowRightLeft,\n Database,\n Package,\n Globe,\n User,\n MonitorIcon,\n BoxesIcon,\n type LucideIcon,\n} from \"lucide-react\";\nimport { useReactFlow, type Node } from \"@xyflow/react\";\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { usePortalContainer } from \"../context/PortalContainerContext\";\nimport type { Note } from \"../types\";\n\n/* ------------------------------------------------------------------ */\n/* Node type → icon + color mapping */\n/* ------------------------------------------------------------------ */\n\nconst NODE_TYPE_META: Record<\n string,\n { icon: LucideIcon; color: string; label: string }\n> = {\n service: { icon: ServerIcon, color: \"#ec4899\", label: \"Service\" },\n services: { icon: ServerIcon, color: \"#ec4899\", label: \"Service\" },\n agent: { icon: Bot, color: \"#0ea5e9\", label: \"Agent\" },\n agents: { icon: Bot, color: \"#0ea5e9\", label: \"Agent\" },\n event: { icon: Zap, color: \"#f97316\", label: \"Event\" },\n events: { icon: Zap, color: \"#f97316\", label: \"Event\" },\n command: { icon: MessageSquare, color: \"#3b82f6\", label: \"Command\" },\n commands: { icon: MessageSquare, color: \"#3b82f6\", label: \"Command\" },\n query: { icon: Search, color: \"#22c55e\", label: \"Query\" },\n queries: { icon: Search, color: \"#22c55e\", label: \"Query\" },\n channel: { icon: ArrowRightLeft, color: \"#6b7280\", label: \"Channel\" },\n channels: { icon: ArrowRightLeft, color: \"#6b7280\", label: \"Channel\" },\n data: { icon: Database, color: \"#3b82f6\", label: \"Data\" },\n \"data-products\": { icon: Package, color: \"#6366f1\", label: \"Data Product\" },\n externalSystem: { icon: Globe, color: \"#ec4899\", label: \"External System\" },\n actor: { icon: User, color: \"#eab308\", label: \"Actor\" },\n view: { icon: MonitorIcon, color: \"#8b5cf6\", label: \"View\" },\n domain: { icon: BoxesIcon, color: \"#14b8a6\", label: \"Domain\" },\n domains: { icon: BoxesIcon, color: \"#14b8a6\", label: \"Domain\" },\n};\n\nfunction getNodeMeta(nodeType?: string) {\n if (!nodeType) return null;\n return NODE_TYPE_META[nodeType] || null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Extract notes from any node type */\n/* ------------------------------------------------------------------ */\n\nexport function getNotesFromNode(\n node: Node<any>,\n): { name: string; notes: Note[]; nodeType: string } | null {\n const d = node.data;\n const containers = [\n d?.service,\n d?.message,\n d?.channel,\n d?.data,\n d?.dataProduct,\n d?.externalSystem,\n d?.actor,\n ];\n for (const container of containers) {\n if (container?.notes && container.notes.length > 0) {\n return {\n name: container.name || node.id,\n notes: container.notes,\n nodeType: node.type || \"unknown\",\n };\n }\n }\n if (d?.notes && d.notes.length > 0) {\n return {\n name: d.name || node.id,\n notes: d.notes,\n nodeType: node.type || \"unknown\",\n };\n }\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Constants */\n/* ------------------------------------------------------------------ */\n\nconst AMBER = {\n 50: \"#fffbeb\",\n 100: \"#fef3c7\",\n 200: \"#fde68a\",\n 400: \"#fbbf24\",\n 500: \"#f59e0b\",\n 600: \"#d97706\",\n 700: \"#b45309\",\n 800: \"#92400e\",\n} as const;\n\nconst PRIORITY: Record<\n string,\n { bg: string; fg: string; border: string; label: string; accent: string }\n> = {\n high: {\n bg: \"#fef2f2\",\n fg: \"#b91c1c\",\n border: \"#fecaca\",\n label: \"High\",\n accent: \"#ef4444\",\n },\n critical: {\n bg: \"#fef2f2\",\n fg: \"#991b1b\",\n border: \"#fecaca\",\n label: \"Critical\",\n accent: \"#dc2626\",\n },\n low: {\n bg: \"#f0fdf4\",\n fg: \"#15803d\",\n border: \"#bbf7d0\",\n label: \"Low\",\n accent: \"#22c55e\",\n },\n};\n\nconst AVATAR_PALETTES = [\n [\"#7c3aed\", \"#a78bfa\"],\n [\"#2563eb\", \"#60a5fa\"],\n [\"#0891b2\", \"#22d3ee\"],\n [\"#059669\", \"#34d399\"],\n [\"#d97706\", \"#fbbf24\"],\n [\"#dc2626\", \"#f87171\"],\n [\"#db2777\", \"#f472b6\"],\n [\"#4f46e5\", \"#818cf8\"],\n];\n\nfunction hashStr(s: string): number {\n let h = 0;\n for (let i = 0; i < s.length; i++) {\n h = (h * 31 + s.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nfunction Avatar({ name, size = 28 }: { name: string; size?: number }) {\n const initials = name\n .split(/\\s+/)\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n const [c1, c2] = AVATAR_PALETTES[hashStr(name) % AVATAR_PALETTES.length];\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: `linear-gradient(135deg, ${c1}, ${c2})`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <span\n style={{\n fontSize: Math.round(size * 0.42),\n fontWeight: 700,\n color: \"white\",\n lineHeight: 1,\n }}\n >\n {initials}\n </span>\n </div>\n );\n}\n\nfunction PriorityBadge({ priority }: { priority: string }) {\n const p = PRIORITY[priority.toLowerCase()];\n if (!p) return null;\n const isUrgent = priority === \"high\" || priority === \"critical\";\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 3,\n fontSize: 10,\n fontWeight: 600,\n color: p.fg,\n background: p.bg,\n border: `1px solid ${p.border}`,\n borderRadius: 99,\n padding: \"2px 7px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.03em\",\n lineHeight: 1.4,\n }}\n >\n {isUrgent && (\n <AlertTriangle style={{ width: 9, height: 9 }} strokeWidth={2.5} />\n )}\n {p.label}\n </span>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Note card for the right panel */\n/* ------------------------------------------------------------------ */\n\nfunction NoteCard({ note, index }: { note: Note; index: number }) {\n const prioStyle = note.priority\n ? PRIORITY[note.priority.toLowerCase()]\n : null;\n\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #e2e8f0\",\n borderRadius: 10,\n padding: \"14px 16px\",\n position: \"relative\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.04)\",\n }}\n >\n {/* Priority accent stripe */}\n {prioStyle && (\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 10,\n bottom: 10,\n width: 3,\n borderRadius: \"0 2px 2px 0\",\n background: prioStyle.accent,\n }}\n />\n )}\n\n {/* Header: author + priority */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 8,\n }}\n >\n {note.author ? (\n <Avatar name={note.author} size={24} />\n ) : (\n <div\n style={{\n width: 24,\n height: 24,\n borderRadius: \"50%\",\n background: \"#f1f5f9\",\n border: `2px solid ${AMBER[200]}`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <span style={{ fontSize: 10, fontWeight: 700, color: AMBER[700] }}>\n {index + 1}\n </span>\n </div>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>\n {note.author && (\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: \"#0f172a\",\n lineHeight: 1,\n }}\n >\n {note.author}\n </span>\n )}\n </div>\n {note.priority && <PriorityBadge priority={note.priority} />}\n </div>\n\n {/* Content */}\n <p\n style={{\n fontSize: 13,\n lineHeight: 1.6,\n color: \"#334155\",\n margin: 0,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n paddingLeft: prioStyle ? 6 : 0,\n }}\n >\n {note.content}\n </p>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* All Notes Modal — split layout */\n/* ------------------------------------------------------------------ */\n\ninterface NoteGroup {\n nodeId: string;\n name: string;\n notes: Note[];\n nodeType: string;\n}\n\nexport function AllNotesModal({\n noteGroups,\n isOpen,\n onClose,\n nodes,\n}: {\n noteGroups: NoteGroup[];\n isOpen: boolean;\n onClose: () => void;\n nodes: Node<any>[];\n}) {\n const { setCenter, getZoom } = useReactFlow();\n const [selectedIdx, setSelectedIdx] = useState(0);\n const portalContainer = usePortalContainer();\n\n const totalNotes = noteGroups.reduce((sum, g) => sum + g.notes.length, 0);\n const selected = noteGroups[selectedIdx] || noteGroups[0];\n\n const handleNavigate = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const zoom = Math.max(getZoom(), 1);\n setCenter(node.position.x + 100, node.position.y + 50, {\n zoom,\n duration: 600,\n });\n onClose();\n },\n [nodes, setCenter, getZoom, onClose],\n );\n\n if (totalNotes === 0) return null;\n\n return (\n <Dialog.Root\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) {\n onClose();\n setSelectedIdx(0);\n }\n }}\n >\n <Dialog.Portal container={portalContainer}>\n <div\n className=\"fixed inset-0 z-[99999]\"\n style={{ isolation: \"isolate\" }}\n >\n <Dialog.Overlay\n style={{\n position: \"fixed\",\n inset: 0,\n background: \"rgba(15, 23, 42, 0.55)\",\n backdropFilter: \"blur(6px)\",\n }}\n />\n\n <Dialog.Content\n style={{\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"94vw\",\n maxWidth: 720,\n height: \"78vh\",\n maxHeight: 560,\n background: \"white\",\n borderRadius: 14,\n boxShadow:\n \"0 0 0 1px rgba(0,0,0,0.06), 0 20px 50px rgba(0,0,0,0.2)\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n outline: \"none\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"14px 20px\",\n borderBottom: \"1px solid #e2e8f0\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n flexShrink: 0,\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: 8,\n background: \"#f1f5f9\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <MessageCircle\n style={{ width: 16, height: 16, color: \"#64748b\" }}\n strokeWidth={2.5}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <Dialog.Title\n style={{\n fontSize: 15,\n fontWeight: 700,\n color: \"#0f172a\",\n margin: 0,\n lineHeight: 1.25,\n }}\n >\n Notes\n </Dialog.Title>\n <Dialog.Description\n style={{\n fontSize: 12,\n color: \"#64748b\",\n margin: 0,\n marginTop: 1,\n }}\n >\n {totalNotes} note{totalNotes !== 1 ? \"s\" : \"\"} across{\" \"}\n {noteGroups.length} resource\n {noteGroups.length !== 1 ? \"s\" : \"\"}\n </Dialog.Description>\n </div>\n <Dialog.Close asChild>\n <button\n style={{\n width: 30,\n height: 30,\n borderRadius: 8,\n border: \"none\",\n background: \"rgba(0,0,0,0.04)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: \"#94a3b8\",\n flexShrink: 0,\n }}\n aria-label=\"Close\"\n >\n <X style={{ width: 15, height: 15 }} />\n </button>\n </Dialog.Close>\n </div>\n\n {/* Split body */}\n <div style={{ display: \"flex\", flex: 1, overflow: \"hidden\" }}>\n {/* Left: resource list */}\n <div\n style={{\n width: 240,\n flexShrink: 0,\n borderRight: \"1px solid #e2e8f0\",\n overflowY: \"auto\",\n background: \"#f8fafc\",\n }}\n >\n {noteGroups.map((group, i) => {\n const isActive = i === selectedIdx;\n const meta = getNodeMeta(group.nodeType);\n const IconComp = meta?.icon || MessageCircle;\n const iconColor = meta?.color || \"#64748b\";\n\n return (\n <button\n key={group.nodeId}\n onClick={() => setSelectedIdx(i)}\n style={{\n width: \"100%\",\n padding: \"12px 16px\",\n background: isActive ? \"white\" : \"transparent\",\n border: \"none\",\n borderBottom: \"1px solid #f1f5f9\",\n borderRight: isActive\n ? `2px solid ${iconColor}`\n : \"2px solid transparent\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n textAlign: \"left\",\n transition: \"background 0.1s\",\n }}\n >\n {/* Resource type icon */}\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n background: isActive ? iconColor : `${iconColor}14`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n transition: \"background 0.15s\",\n }}\n >\n <IconComp\n style={{\n width: 14,\n height: 14,\n color: isActive ? \"white\" : iconColor,\n transition: \"color 0.15s\",\n }}\n strokeWidth={2}\n />\n </div>\n\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontSize: 12,\n fontWeight: isActive ? 600 : 500,\n color: isActive ? \"#0f172a\" : \"#475569\",\n lineHeight: 1.3,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {group.name}\n </div>\n <div\n style={{\n fontSize: 10,\n color: \"#94a3b8\",\n lineHeight: 1.3,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n marginTop: 2,\n }}\n >\n {meta?.label || group.nodeType} &middot;{\" \"}\n {group.notes.length} note\n {group.notes.length !== 1 ? \"s\" : \"\"}\n </div>\n </div>\n\n <ChevronRight\n style={{\n width: 14,\n height: 14,\n color: isActive ? iconColor : \"#cbd5e1\",\n flexShrink: 0,\n }}\n strokeWidth={2}\n />\n </button>\n );\n })}\n </div>\n\n {/* Right: notes for selected resource */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {selected && (\n <>\n {/* Selected resource header */}\n <div\n style={{\n padding: \"14px 20px\",\n borderBottom: \"1px solid #f1f5f9\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n flexShrink: 0,\n background: \"#fafbfc\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n }}\n >\n {(() => {\n const meta = getNodeMeta(selected.nodeType);\n const Icon = meta?.icon || MessageCircle;\n const color = meta?.color || \"#64748b\";\n return (\n <div\n style={{\n width: 30,\n height: 30,\n borderRadius: 8,\n background: `${color}14`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Icon\n style={{\n width: 15,\n height: 15,\n color,\n }}\n strokeWidth={2}\n />\n </div>\n );\n })()}\n <div>\n <div\n style={{\n fontSize: 14,\n fontWeight: 600,\n color: \"#0f172a\",\n lineHeight: 1.3,\n }}\n >\n {selected.name}\n </div>\n <div\n style={{\n fontSize: 11,\n color: \"#94a3b8\",\n marginTop: 2,\n }}\n >\n {getNodeMeta(selected.nodeType)?.label ||\n selected.nodeType}{\" \"}\n &middot; {selected.notes.length} note\n {selected.notes.length !== 1 ? \"s\" : \"\"}\n </div>\n </div>\n </div>\n <button\n onClick={() => handleNavigate(selected.nodeId)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 5,\n padding: \"5px 10px\",\n borderRadius: 6,\n border: \"1px solid #e2e8f0\",\n background: \"white\",\n cursor: \"pointer\",\n fontSize: 11,\n fontWeight: 500,\n color: \"#475569\",\n transition: \"all 0.12s\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.borderColor = AMBER[400];\n e.currentTarget.style.color = AMBER[700];\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.borderColor = \"#e2e8f0\";\n e.currentTarget.style.color = \"#475569\";\n }}\n >\n <Locate style={{ width: 12, height: 12 }} />\n Find on canvas\n </button>\n </div>\n\n {/* Notes list */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px 20px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n }}\n >\n {selected.notes.map((note, i) => (\n <NoteCard key={i} note={note} index={i} />\n ))}\n </div>\n </>\n )}\n </div>\n </div>\n </Dialog.Content>\n </div>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","/**\n * Node components for EventCatalog Visualizer\n */\n\n// Studio-2 nodes (organized in directories) - import for nodeComponents\nimport { Event, eventConfig } from \"./event\";\nimport { Command } from \"./command\";\nimport { Query } from \"./query\";\nimport { Service } from \"./service\";\nimport AgentNode from \"./Agent\";\nimport AgentToolNode from \"./AgentTool\";\nimport { Channel } from \"./channel\";\nimport { Note } from \"./note\";\nimport { Data, dataNodeConfig } from \"./data\";\nimport { View } from \"./view\";\nimport { Actor, actorConfig } from \"./actor\";\nimport { ExternalSystem, externalSystemConfig } from \"./external-system\";\nimport { Field, fieldConfig } from \"./field\";\n\n// Re-export studio-2 nodes\nexport { Event, eventConfig };\nexport type { EventNode } from \"./event\";\n\nexport { Command };\nexport type { CommandNode } from \"./command\";\n\nexport { Query };\nexport type { QueryNode } from \"./query\";\n\nexport { Service };\nexport type { ServiceNode } from \"./service\";\n\nexport type { AgentToolNode as AgentToolNodeType } from \"./AgentTool\";\n\nexport { Channel };\nexport type { ChannelNode } from \"./channel\";\n\nexport { Note };\nexport type { NoteNode } from \"./note\";\n\nexport { Data, dataNodeConfig };\nexport type { DataNode } from \"./data\";\n\nexport { View };\nexport type { ViewNode } from \"./view\";\n\nexport { Actor, actorConfig };\nexport type { ActorNode } from \"./actor\";\n\nexport { ExternalSystem, externalSystemConfig };\nexport type { ExternalSystemNode } from \"./external-system\";\n\nexport { Field, fieldConfig };\nexport type { FieldNodeType } from \"./field\";\n\n// Shared components\nexport { NotesIndicator } from \"./NotesIndicator\";\nexport { OwnerIndicator, normalizeOwners } from \"./OwnerIndicator\";\nexport {\n ENTITY_TARGET_HANDLE_ID,\n getNestedEntityProperties,\n getPropertyTypeLabel,\n} from \"./Entity\";\nexport type { EntityProperty } from \"./Entity\";\n\n// Core nodes (single files) - import then re-export for nodeComponents\nimport CustomNode from \"./Custom\";\nimport DomainNode from \"./Domain\";\nimport DomainCardNode from \"./DomainCard\";\nimport SystemNode from \"./System\";\nimport ContextActorNode from \"./ContextActor\";\nimport SystemGroupNode from \"./SystemGroupNode\";\nimport EntityNode from \"./Entity\";\nimport FlowNode from \"./Flow\";\nimport FlowExpandedNode from \"./FlowExpandedNode\";\nimport GroupNode from \"./GroupNode\";\nimport StepNode from \"./Step\";\nimport UserNode from \"./User\";\nimport DataProductNode from \"./DataProduct\";\nimport ExternalSystem2Node from \"./ExternalSystem2\";\nimport { MessageGroupNode, MessageGroupExpandedNode } from \"./message-group\";\n\nexport {\n CustomNode,\n DomainNode,\n DomainCardNode,\n SystemNode,\n ContextActorNode,\n SystemGroupNode,\n EntityNode,\n FlowNode,\n FlowExpandedNode,\n GroupNode,\n StepNode,\n UserNode,\n DataProductNode,\n AgentNode,\n AgentToolNode,\n ExternalSystem2Node,\n MessageGroupNode,\n MessageGroupExpandedNode,\n};\n\nexport type {\n MessageGroupNodeType,\n MessageGroupNodeData,\n} from \"./message-group\";\n\nexport type { MessageGroupExpandedNodeData } from \"./message-group\";\n\n// Node type constants\nexport {\n SERVICE,\n AGENT,\n AGENT_TOOL,\n EVENT,\n QUERY,\n COMMAND,\n CHANNEL,\n ACTOR,\n MESSAGE,\n DATA,\n VIEW,\n} from \"./node-types\";\n\nexport { diagramNodeComponents } from \"./diagram-nodes\";\n\n// Re-export for convenience (studio-2 nodes only)\nexport const nodeComponents = {\n event: Event,\n command: Command,\n query: Query,\n service: Service,\n agent: AgentNode,\n agentTool: AgentToolNode,\n \"agent-tool\": AgentToolNode,\n channel: Channel,\n note: Note,\n externalSystem: ExternalSystem,\n data: Data,\n view: View,\n actor: Actor,\n field: Field,\n // Core nodes are available via individual imports\n custom: CustomNode,\n domain: DomainNode,\n system: SystemNode,\n \"context-actor\": ContextActorNode,\n \"system-group\": SystemGroupNode,\n entity: EntityNode,\n flow: FlowNode,\n flowExpanded: FlowExpandedNode,\n group: GroupNode,\n step: StepNode,\n user: UserNode,\n dataProduct: DataProductNode,\n externalSystem2: ExternalSystem2Node,\n messageGroup: MessageGroupNode,\n messageGroupExpanded: MessageGroupExpandedNode,\n};\n\nexport const nodeConfigs: Record<string, import(\"../types\").NodeConfiguration> =\n {\n event: eventConfig,\n data: dataNodeConfig,\n actor: actorConfig,\n externalSystem: externalSystemConfig,\n field: fieldConfig,\n };\n","/**\n * Edge components for EventCatalog Visualizer\n */\n\n// Import for edgeTypes object\nimport AnimatedMessageEdge from \"./AnimatedMessageEdge\";\nimport FlowEdge from \"./FlowEdge\";\nimport MultilineEdgeLabel from \"./MultilineEdgeLabel\";\nimport {\n LabelledDefaultEdge,\n LabelledSmoothStepEdge,\n LabelledStepEdge,\n} from \"./LabelledEdge\";\n\n// Re-export\nexport {\n AnimatedMessageEdge,\n FlowEdge,\n MultilineEdgeLabel,\n LabelledDefaultEdge,\n LabelledSmoothStepEdge,\n LabelledStepEdge,\n};\n\n// Re-export for convenience\nexport const edgeTypes = {\n animated: AnimatedMessageEdge,\n \"flow-edge\": FlowEdge,\n multiline: MultilineEdgeLabel,\n default: LabelledDefaultEdge,\n smoothstep: LabelledSmoothStepEdge,\n step: LabelledStepEdge,\n};\n","import type { Node, ReactFlowJsonObject, Edge } from \"@xyflow/react\";\n\n// Define the structure of resource data that can be found in nodes\ninterface ResourceData {\n id?: string;\n name?: string;\n summary?: string;\n version?: string;\n}\n\n// Define the possible node data structure\ninterface NodeDataWithResources {\n [key: string]: any;\n channel?: ResourceData;\n custom?: ResourceData;\n data?: ResourceData;\n domain?: ResourceData;\n entity?: ResourceData;\n message?: ResourceData;\n flow?: ResourceData;\n agent?: ResourceData;\n agentTool?: ResourceData;\n service?: ResourceData;\n step?: ResourceData;\n user?: ResourceData;\n}\n\nexport const exportNodeGraphForStudio = (\n data: ReactFlowJsonObject,\n): ReactFlowJsonObject => {\n const dataTypes: (keyof NodeDataWithResources)[] = [\n \"channel\",\n \"custom\",\n \"data\",\n \"domain\",\n \"entity\",\n \"message\",\n \"flow\",\n \"agent\",\n \"agentTool\",\n \"service\",\n \"step\",\n \"user\",\n ];\n\n // try and remove unwanted data for studio\n const nodes = data.nodes.map((node: Node) => {\n let nodeData = node.data as NodeDataWithResources;\n const dataProperties = Object.keys(\n nodeData,\n ) as (keyof NodeDataWithResources)[];\n\n // If we find a match.....\n const hasCustomDataType = dataProperties.find((property) =>\n dataTypes.includes(property),\n );\n\n if (hasCustomDataType && nodeData[hasCustomDataType]) {\n const resourceData = nodeData[hasCustomDataType] as ResourceData;\n nodeData = {\n ...nodeData,\n [hasCustomDataType]: {\n id: resourceData?.id,\n name: resourceData?.name,\n summary: resourceData?.summary,\n version: resourceData?.version,\n },\n };\n }\n\n return {\n ...node,\n data: {\n ...nodeData,\n // We dont need these for studio\n source: undefined,\n target: undefined,\n // Studio wants all nodes in full mode\n mode: \"full\",\n },\n };\n });\n\n const edges = data.edges.map((edge: Edge) => {\n return {\n ...edge,\n data: undefined,\n type: \"animatedMessage\",\n };\n });\n\n return {\n ...data,\n nodes,\n edges,\n };\n};\n"],"mappings":"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","names":["useEffect","useMemo","useState","useCallback","useRef","createPortal","ReactFlow","Controls","Panel","ReactFlowProvider","useNodesState","useEdgesState","useReactFlow","getViewportForBounds","MarkerType","ExternalLink","CheckIcon","ClipboardIcon","DropdownMenu","memo","useMemo","memo","jsx","memo","CustomIcon","memo","jsx","jsxs","memo","OwnerIndicator","Handle","Position","useCallback","useState","useCallback","memo","Fragment","jsx","jsxs","size","memo","NotesIndicator","useState","useCallback","useEffect","useRef","useState","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","memo","SpecBadges","useMemo","MiniEnvelope","ServiceMessageFlow","GlowHandle","classNames","Handle","Position","memo","useMemo","Handle","Position","jsx","jsxs","classNames","GlowHandle","useMemo","Handle","Position","memo","memo","Handle","Position","jsx","jsxs","classNames","GlowHandle","Handle","Position","memo","memo","useMemo","Handle","Position","memo","jsx","MethodBadge","StatusCodes","ApiPath","jsx","jsxs","GlowHandle","memo","classNames","Handle","Position","useMemo","Zap","Zap","memo","useMemo","Handle","Position","jsx","jsxs","GlowHandle","memo","classNames","Handle","Position","useMemo","memo","useMemo","Handle","Position","jsx","jsxs","GlowHandle","memo","classNames","Handle","Position","useMemo","Handle","Position","memo","useMemo","jsx","jsxs","size","GlowHandle","classNames","Handle","Position","memo","useMemo","Handle","Position","jsx","jsxs","GlowHandle","classNames","Handle","Position","useMemo","memo","MarkerType","Database","config_default","Database","MarkerType","memo","useMemo","Handle","Position","jsx","jsxs","GlowHandle","memo","useMemo","Handle","Position","memo","Handle","Position","jsx","jsxs","GlowHandle","classNames","Handle","Position","memo","MarkerType","User","config_default","User","MarkerType","memo","Database","Handle","Position","jsx","jsxs","GlowHandle","classNames","memo","Handle","Position","Database","MarkerType","Database","config_default","memo","Globe","Handle","Position","jsx","jsxs","GlowHandle","classNames","Handle","Position","Globe","memo","MarkerType","Globe","config_default","Globe","MarkerType","memo","Handle","Position","User","jsx","jsxs","memo","Handle","Position","User","memo","Handle","Position","jsx","jsxs","memo","Handle","Position","Handle","Position","BoxesIcon","GroupIcon","ServerIcon","memo","jsx","jsxs","GlowHandle","memo","GroupIcon","ServerIcon","Handle","Position","BoxesIcon","memo","useMemo","Handle","Globe","jsx","jsxs","Fragment","jsx","jsxs","classNames","memo","useMemo","Handle","memo","jsx","jsxs","CONTAINER_STYLE","HEADER_STYLE","BADGE_STYLE","VERSION_STYLE","memo","Handle","Position","ContextMenu","memo","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","classNames","memo","useMemo","useState","useRef","useCallback","useEffect","Handle","Position","memo","UserIcon","Handle","jsx","jsxs","classNames","memo","UserIcon","Handle","memo","Handle","Position","jsx","jsxs","classNames","memo","Handle","Position","Handle","Position","ContextMenu","memo","useState","useCallback","useMemo","jsx","jsxs","memo","useState","useMemo","ServerIcon","useCallback","id","Handle","Position","Handle","Position","GroupIcon","ServerIcon","BoxIcon","memo","jsx","jsxs","classNames","memo","isExternal","ServerIcon","BoxIcon","Handle","Position","GroupIcon","memo","BoxesIcon","jsx","jsxs","memo","BoxesIcon","memo","useMemo","Handle","Position","ContextMenu","jsx","jsxs","classNames","GlowHandle","memo","useMemo","Handle","Position","memo","Handle","Position","jsx","jsxs","memo","Handle","Position","memo","Handle","Position","jsx","jsxs","GlowHandle","classNames","Handle","Position","memo","memo","Globe","jsx","jsxs","memo","Globe","memo","useMemo","Zap","HelpCircle","Maximize2","Handle","Position","jsx","jsxs","Zap","HelpCircle","CARD_STYLE","memo","useMemo","Handle","Position","Maximize2","memo","Layers","Minimize2","jsx","jsxs","CONTAINER_STYLE","HEADER_STYLE","BADGE_STYLE","HEADER_CONTENT_STYLE","COLLAPSE_BUTTON_STYLE","memo","jsx","CONTAINER_STYLE","jsxs","HEADER_STYLE","BADGE_STYLE","Layers","HEADER_CONTENT_STYLE","Minimize2","memo","useMemo","useStore","jsx","useCallback","Position","useStore","a","b","zIndex","domainEnds","memo","Fragment","jsx","jsxs","Dot","Fragment","jsx","jsxs","memo","useMemo","memo","getSmoothStepPath","Fragment","jsx","jsxs","memo","getSmoothStepPath","memo","useMemo","BaseEdge","getSmoothStepPath","Fragment","jsx","jsxs","messageColor","memo","getSmoothStepPath","useMemo","BaseEdge","BaseEdge","memo","Fragment","jsx","jsxs","BaseEdge","memo","LabelledDefaultEdge","LabelledSmoothStepEdge","LabelledStepEdge","useState","useCallback","useRef","useEffect","memo","Bot","Database","Group","Layers","MessageSquare","Server","User","Workflow","Wrench","Zap","jsx","jsxs","suggestions","useState","useEffect","useCallback","useMemo","useRef","memo","jsx","jsxs","memo","useState","useRef","useMemo","useEffect","start","useCallback","next","memo","jsx","memo","Badge","Fragment","memo","useReactFlow","useStore","Map","Zap","jsx","jsxs","Fragment","jsx","jsxs","memo","ZoomLevel","useStore","CanvasToolbar","useReactFlow","Zap","Map","memo","useEffect","useState","Group","Layers","X","jsx","jsxs","Layers","memo","useState","useEffect","Group","X","useState","useCallback","useEffect","Dialog","XIcon","useMemo","useCallback","useEffect","useState","useRef","useReactFlow","memo","Position","useStore","ArrowRightLeft","jsx","jsxs","useStore","Position","ArrowRightLeft","memo","Handle","Position","jsx","jsxs","jsx","jsxs","edgeTypes","useReactFlow","useState","useRef","useEffect","useCallback","useMemo","jsx","jsxs","edgeTypes","useState","useEffect","useCallback","XIcon","memo","Background","jsx","DiagramBackground","memo","jsx","memo","DiagramMiniMapNode","DiagramMiniMap","memo","Panel","Zap","Bot","Wrench","ServerIcon","Workflow","MessageSquare","SearchIcon","GroupIcon","Globe","User","Database","Boxes","jsx","jsxs","LegendPanel","useState","useEffect","useLayoutEffect","useRef","useCallback","Maximize","ZoomIn","ZoomOut","useCallback","useEffect","useRef","size","Fragment","jsx","jsxs","useState","useRef","useCallback","useEffect","useLayoutEffect","Maximize","ZoomOut","ZoomIn","memo","useEffect","Code","Image","X","Fragment","jsx","jsxs","ExportModal","useCallback","useState","useEffect","useLayoutEffect","useRef","useReactFlow","add","edges","useState","useRef","useReactFlow","useCallback","useEffect","useLayoutEffect","useState","memo","DropdownMenu","Code","Search","Maximize","Map","Zap","RotateCcw","MessageCircle","Fragment","jsx","jsxs","memo","useState","Code","Zap","Map","Maximize","Search","MessageCircle","RotateCcw","memo","ContextMenu","Fragment","jsx","jsxs","memo","memo","MarkerType","getNodeSize","MarkerType","size","useState","useCallback","MessageCircle","AlertTriangle","X","ChevronRight","ServerIcon","Bot","Zap","MessageSquare","Search","ArrowRightLeft","Database","Package","Globe","User","MonitorIcon","BoxesIcon","useReactFlow","Dialog","Fragment","jsx","jsxs","ServerIcon","Bot","Zap","MessageSquare","Search","ArrowRightLeft","Database","Package","Globe","User","MonitorIcon","BoxesIcon","AMBER","PRIORITY","AVATAR_PALETTES","hashStr","Avatar","size","AlertTriangle","NoteCard","useReactFlow","useState","useCallback","MessageCircle","X","ChevronRight","Fragment","jsx","jsxs","HIDE_ATTRIBUTION","MarkerType","useEffect","useMemo","edgeTypes","useState","useCallback","useNodesState","useEdgesState","useReactFlow","useRef","nodes","animateLayout","m","edges","getViewportForBounds","link","Panel","ReactFlow","Controls","ExternalLink","CheckIcon","ClipboardIcon","createPortal","ReactFlowProvider","config_default"]}