@mp70/react-networks 0.1.0-alpha → 0.1.4-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/RackNode.tsx","../src/components/FiberNode.tsx","../src/components/FiberEdge.tsx","../src/components/PowerEdge.tsx","../src/types/index.ts","../src/utils/power-connectors.ts","../src/components/DeviceNode.tsx","../src/components/VerticalPDU.tsx","../src/utils/u-positioning.ts","../src/core/store.ts","../src/core/hooks.ts","../src/components/NetworkDiagram.tsx","../src/utils/netbox.ts","../src/utils/rack-schema.ts"],"names":["RackNode","data","selected","id","onViewChange","onRackFaceChange","label","ports","status","uHeight","uPosition","face","getNodes","setNodes","useReactFlow","nodes","showUMarkers","setShowUMarkers","useState","toggleFace","next","n","child","getStatusColor","renderUPositions","positions","startY","i","yPos","jsx","jsxs","Handle","Position","e","FiberNode","FiberEdge","sourceX","sourceY","targetX","targetY","sourcePosition","targetPosition","style","edgePath","labelX","labelY","getBezierPath","bandwidth","length","color","edgeStyle","Fragment","EdgeLabelRenderer","PowerEdge","markerEnd","connectorType","BaseEdge","baseStyle","Width","POWER_CONNECTORS","getPowerPortStyle","connector","isHighPower","width","height","cornerStyle","getConnectorConfig","isHighPowerConnector","getPDUPortType","portIndex","getDeviceConnectorType","deviceName","name","DeviceNode","deviceType","manufacturer","role","_uPosition","rearPorts","view","_powerSide","currentFace","handleSideMap","portBlock","port","handleId","deviceHeight","rackDeviceWidth","rackDeviceLeft","renderPortsFromArray","portBlocks","position","handles","portWidth","portHeight","blockIndex","isPower","isConnected","portColor","handlePosition","handleStyle","baseTop","spacing","portStyle","handleType","renderHandles","renderAGGSwitchHandles","isSwitch","isPatchPanel","port1Top","port2Top","handle","bottomIndex","uplinkWidth","uplinkHeight","VerticalPDU","heightCm","powerPorts","portTypes","widthPx","mgmt_unit","heightPx","renderPowerHandles","nCycles","portsPerCycle","_","c","idx","headerHeight","portSpacing","renderMgmtUnit","portType","leftPx","snapToUPosition","device","rack","newPosition","allNodes","relativeY","calculatedUPosition","snappedUPosition","isUPositionAvailable","availablePosition","findNextAvailableUPosition","snappedY","deviceUHeight","rackUHeight","rackDevices","node","otherDevice","otherUPosition","otherUHeight","newDeviceStart","newDeviceEnd","otherDeviceStart","otherDeviceEnd","startFrom","u","calculateDevicePositionFromU","updateDeviceUPosition","newUPosition","validateAndSnapDevice","currentUPosition","validUPosition","defaultValidateConnection","params","ctx","sourceAlready","targetAlready","getHandleSide","frontBlocks","rearBlocks","block","createNetworkDiagramStore","initial","options","state","listeners","partial","l","listener","edge","targetNode","deviceView","side","targetHandle","isPowerHandle","isNetworkHandle","useNetworkDiagram","store","subscribe","cb","getSnapshot","useSyncExternalStore","useNodes","useEdges","useSelectEdgeZIndex","createNodeTypes","props","edgeTypes","NetworkDiagramInner","edges","initialNodes","initialEdges","externalOnNodesChange","externalOnEdgesChange","debug","onNodeClick","onEdgeClick","className","alignRacksToBottom","isControlled","localStore","React","storeNodes","storeEdges","reactFlowNodes","onNodesChange","useNodesState","reactFlowEdges","setEdges","onEdgesChange","useEdgesState","selectEdgeZIndex","memoizedNodeTypes","useMemo","memoizedEdgeTypes","latestNodesRef","useRef","useEffect","latestEdgesRef","racks","rackBottoms","r","minBottom","maxBottom","baselineBottom","nextNodes","currentBottom","delta","getNodeById","useCallback","targetNodeId","handleSide","zIndex","eds","newZIndex","updatedNodes","parentRack","calculatedPosition","index","handleNodesChange","changes","updatedChanges","change","snappedResult","updatedNode","nearestRack","minDistance","rackNode","distance","rackWidth","rackHeight","rackLeft","rackRight","rackTop","rackBottom","relativeX","absoluteX","absoluteY","connection","sourceHandleId","targetHandleId","sourceAlreadyConnected","targetAlreadyConnected","onConnect","isPduSource","looksLikePowerTarget","existingTargetEdge","edgeToAdd","filtered","addEdge","validation","existingSourceEdge","handleNodeClick","event","currentView","nextView","handleNodeDoubleClick","handleEdgeClick","selectedNode","setSelectedNode","useOnSelectionChange","toggleSelectedFace","hasRear","hasFront","ReactFlow","acc","Background","Controls","MiniMap","NetworkDiagram","ReactFlowProvider","netboxRackToNetworkNode","netboxDeviceToNetworkNode","netboxCableToNetworkEdge","cable","netboxToNetworkDiagram","calculateUPositions","devices","usedPositions","d","a","b","generateLayout","rackNodes","deviceNodes","otherNodes","DevicePlacementError","rackId","deviceId","conflictWith","validateRackDevicePlacements","conflictPolicy","conflicts","outOfBounds","deviceA","deviceAStart","deviceAEnd","j","deviceB","deviceBStart","deviceBEnd","createDeviceNode","deviceTypeMapping","nodeType","createRackNode","buildNodesFromRackConfig","validatePlacements","errors","conflict","bound","deviceNode","error","adjustedDevice","createRackConfigFromNodes","addDeviceToRack","removeDeviceFromRack"],"mappings":"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","file":"index.js","sourcesContent":["import React, { useState } from 'react';\nimport { Handle, Position, NodeProps, useReactFlow } from 'reactflow';\nimport { NetworkNode } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from '../utils/constants';\n\ninterface RackNodeProps extends NodeProps<NetworkNode['data']> {\n onViewChange?: (nodeId: string, view: 'front' | 'rear') => void;\n onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void;\n}\n\nexport const RackNode: React.FC<RackNodeProps> = ({ data, selected, id, onViewChange, onRackFaceChange }) => {\n const { \n label, \n ports = 0, \n status = 'active',\n uHeight = 42, // Standard rack height\n uPosition = 1,\n face = 'front'\n } = data;\n \n const { getNodes, setNodes } = useReactFlow();\n const nodes = getNodes();\n const [showUMarkers, setShowUMarkers] = useState(true);\n \n const toggleFace = () => {\n const next = face === 'front' ? 'rear' : 'front';\n \n if (onRackFaceChange) {\n onRackFaceChange(id, next);\n // Also update child devices via onViewChange if provided\n if (onViewChange) {\n const childNodes = nodes.filter(n => n.parentId === id);\n childNodes.forEach(child => {\n onViewChange(child.id, next);\n });\n }\n } else if (onViewChange) {\n // Use external onViewChange for devices\n const childNodes = nodes.filter(n => n.parentId === id);\n childNodes.forEach(child => {\n onViewChange(child.id, next);\n });\n } else {\n // Fallback to internal state management\n setNodes(nodes => nodes.map(n => \n n.id === id \n ? { ...n, data: { ...n.data, face: next } }\n : n.parentId === id \n ? { ...n, data: { ...n.data, view: next } } // Use 'view' for devices\n : n\n ));\n }\n };\n \n const getStatusColor = (status: string) => {\n switch (status) {\n case 'active':\n return '#10b981';\n case 'inactive':\n return '#6b7280';\n case 'maintenance':\n return '#f59e0b';\n default:\n return '#6b7280';\n }\n };\n\n // Generate U position markers aligned to rack origin\n const renderUPositions = () => {\n const positions = [];\n const startY = RACK_HEADER_HEIGHT; // Start after header from rack origin\n \n for (let i = 1; i <= uHeight; i++) {\n const yPos = startY + (i - 1) * U_HEIGHT_PX - 4; // Align with device positioning, shifted up 3px\n positions.push(\n <div\n key={i}\n style={{\n position: 'absolute',\n left: '-35px',\n top: `${yPos}px`,\n background: '#374151',\n color: '#9ca3af',\n padding: '2px 4px',\n borderRadius: '2px',\n fontSize: '8px',\n fontWeight: 'bold',\n width: '28px',\n textAlign: 'center',\n border: '1px solid #4b5563',\n zIndex: 10,\n height: `${U_HEIGHT_PX}px`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 1,\n }}\n >\n {i}\n </div>\n );\n }\n return positions;\n };\n\n\n return (\n <div\n className={`rack-node ${selected ? 'selected' : ''}`}\n style={{\n background: 'transparent',\n border: `2px solid ${getStatusColor(status)}`,\n borderRadius: '8px',\n padding: 0,\n width: '300px', // Fixed width for parent node\n height: `${RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX}px`, // Header + exact U area\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '12px',\n boxShadow: selected ? '0 0 0 2px #3b82f6' : '0 2px 4px rgba(0,0,0,0.1)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <Handle type=\"target\" position={Position.Top} />\n {/* Only top handle for rack nodes */}\n \n {/* Rack Header */}\n <div style={{ \n textAlign: 'center', \n marginBottom: 0, \n zIndex: 2, \n background: '#1f2937', \n padding: '8px',\n position: 'relative',\n height: `${RACK_HEADER_HEIGHT}px`, // Fixed header height\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n }}>\n <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{label}</div>\n <div style={{ fontSize: '10px', color: '#9ca3af' }}>\n {typeof ports === 'number' ? ports : 0} ports • {uHeight}U • {face}\n </div>\n <div style={{ display: 'flex', gap: '4px', position: 'absolute', top: '4px', right: '4px' }}>\n <button\n onPointerDown={(e) => { e.stopPropagation(); }}\n onMouseDown={(e) => { e.stopPropagation(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); setShowUMarkers(!showUMarkers); }}\n style={{\n background: showUMarkers ? '#10b981' : '#374151',\n color: showUMarkers ? '#ffffff' : '#9ca3af',\n border: '1px solid #4b5563',\n borderRadius: '2px',\n padding: '2px 6px',\n fontSize: '8px',\n cursor: 'pointer',\n fontFamily: 'monospace',\n }}\n title={`${showUMarkers ? 'Hide' : 'Show'} U markers`}\n >\n U\n </button>\n <button\n onPointerDown={(e) => { e.stopPropagation(); }}\n onMouseDown={(e) => { e.stopPropagation(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); toggleFace(); }}\n style={{\n background: '#374151',\n color: '#9ca3af',\n border: '1px solid #4b5563',\n borderRadius: '2px',\n padding: '2px 6px',\n fontSize: '8px',\n cursor: 'pointer',\n fontFamily: 'monospace',\n }}\n title={`Switch to ${face === 'front' ? 'rear' : 'front'} view`}\n >\n {face === 'front' ? '⇄ Rear' : '⇄ Front'}\n </button>\n </div>\n </div>\n \n {/* Rack Body - transparent background; devices are positioned relative to rack origin */}\n <div\n style={{\n flex: 1,\n background: 'transparent',\n // no borders to avoid pixel offsets\n position: 'relative',\n minHeight: `${uHeight * U_HEIGHT_PX}px`,\n overflow: 'hidden',\n }}\n />\n\n {/* Overlay for U markers aligned to rack origin */}\n {showUMarkers && (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}\n >\n {renderUPositions()}\n </div>\n )}\n \n </div>\n );\n};\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode } from '../types';\n\nexport const FiberNode: React.FC<NodeProps<NetworkNode['data']>> = ({ data, selected }) => {\n const { label, status = 'active' } = data;\n \n const getStatusColor = (status: string) => {\n switch (status) {\n case 'active':\n return '#10b981';\n case 'inactive':\n return '#6b7280';\n case 'maintenance':\n return '#f59e0b';\n default:\n return '#6b7280';\n }\n };\n\n return (\n <div\n className={`fiber-node ${selected ? 'selected' : ''}`}\n style={{\n background: '#1f2937',\n border: `2px solid ${getStatusColor(status)}`,\n borderRadius: '50%',\n width: '60px',\n height: '60px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '10px',\n fontWeight: 'bold',\n boxShadow: selected ? '0 0 0 2px #3b82f6' : '0 2px 4px rgba(0,0,0,0.1)',\n position: 'relative',\n }}\n >\n <Handle type=\"target\" position={Position.Top} />\n <Handle type=\"source\" position={Position.Bottom} />\n <Handle type=\"target\" position={Position.Left} />\n <Handle type=\"source\" position={Position.Right} />\n \n <div style={{ textAlign: 'center' }}>\n <div style={{ fontSize: '8px', lineHeight: '1.2' }}>{label}</div>\n </div>\n \n <div\n style={{\n position: 'absolute',\n bottom: '4px',\n left: '50%',\n transform: 'translateX(-50%)',\n width: '8px',\n height: '8px',\n background: getStatusColor(status),\n borderRadius: '50%',\n }}\n />\n </div>\n );\n};\n","import React from 'react';\nimport { EdgeProps, getBezierPath, EdgeLabelRenderer } from 'reactflow';\nimport { NetworkEdge } from '../types';\n\nexport const FiberEdge: React.FC<EdgeProps<NetworkEdge['data']>> = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n selected,\n style,\n}) => {\n const [edgePath, labelX, labelY] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const { bandwidth, length, color = '#10b981' } = data || {};\n\n // Use style prop from React Flow (includes zIndex)\n const edgeStyle = {\n stroke: color,\n strokeWidth: selected ? 3 : 2,\n strokeDasharray: data?.type === 'fiber' ? '5,5' : 'none',\n fill: 'none',\n ...style, // This includes zIndex from React Flow\n };\n\n\n return (\n <>\n <path\n id={id}\n className=\"react-flow__edge-path\"\n d={edgePath}\n stroke={color}\n strokeWidth={selected ? 3 : 2}\n strokeDasharray={data?.type === 'fiber' ? '5,5' : 'none'}\n fill=\"none\"\n style={edgeStyle}\n />\n <EdgeLabelRenderer>\n {data && (bandwidth || length) && (\n <div\n style={{\n position: 'absolute',\n transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,\n background: '#1f2937',\n padding: '4px 8px',\n borderRadius: '4px',\n fontSize: '10px',\n color: 'white',\n fontFamily: 'monospace',\n border: `1px solid ${color}`,\n pointerEvents: 'none',\n }}\n >\n {bandwidth && <div>{bandwidth}</div>}\n {length && <div>{length}m</div>}\n </div>\n )}\n </EdgeLabelRenderer>\n </>\n );\n};\n","import React from 'react';\nimport { EdgeProps, getBezierPath, EdgeLabelRenderer, BaseEdge } from 'reactflow';\n\nexport const PowerEdge: React.FC<EdgeProps> = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n style = {},\n data,\n markerEnd,\n}) => {\n const [edgePath, labelX, labelY] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n // Determine connector type based on data\n const connectorType = data?.connectorType || 'C13';\n const voltage = data?.voltage || 'AC';\n const amperage = data?.amperage || (connectorType === 'C19' ? '16A' : '10A');\n\n // Different styling for different connector types\n const getEdgeStyle = () => {\n const baseStyle = {\n stroke: data?.color || '#f59e0b',\n strokeWidth: connectorType === 'C19' ? 5 : 3, // Thicker for C19 (higher power)\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n ...style, // This includes zIndex from React Flow\n };\n\n\n // C19 (16A) gets solid line, C13 (10A) gets dashed\n if (connectorType === 'C19') {\n return {\n ...baseStyle,\n strokeDasharray: 'none', // Solid line for high power\n };\n } else {\n return {\n ...baseStyle,\n strokeDasharray: '6,3', // Dashed line for standard power\n };\n }\n };\n\n return (\n <BaseEdge\n id={id}\n path={edgePath}\n markerEnd={markerEnd}\n style={getEdgeStyle()}\n />\n );\n};\n","/**\n * Rack device width configuration\n * @public\n */\nexport enum Width {\n /** Full width device (19\" rack width) */\n FULL = 'full',\n /** Half width device (9.5\" rack width) */\n HALF = 'half'\n}\n\n/**\n * Port configuration for network devices\n * @public\n */\nexport interface Port {\n /** Display label for the port */\n label: string;\n /** Whether the port is currently connected */\n connected: boolean;\n /** Type of port for styling and validation */\n type?: 'ethernet' | 'fiber' | 'console' | 'mgmt' | 'usb' | 'power_ac' | 'power_c13' | 'power_c19';\n /** Cable type for connection validation */\n cableType?: 'smf' | 'cat6' | 'om3' | 'om4' | 'om5' | 'cat5e' | 'cat6a' | 'cat7' | 'fiber' | 'ethernet';\n}\n\n/**\n * Group of related ports on a device\n * @public\n */\nexport interface PortBlock {\n /** Name of the port group */\n name: string;\n /** Array of ports in this group */\n ports: Port[];\n}\n\n/**\n * Network node types supported by the diagram\n * @public\n */\nexport type NetworkNodeType = \n | 'rack' \n | 'switch' \n | 'router' \n | 'server' \n | 'fiber' \n | 'patch-panel' \n | 'device' \n | 'vertical-pdu';\n\n/**\n * Device status states\n * @public\n */\nexport type DeviceStatus = 'active' | 'inactive' | 'maintenance';\n\n/**\n * Device view orientations\n * @public\n */\nexport type DeviceView = 'front' | 'rear';\n\n/**\n * Power port side configuration\n * @public\n */\nexport type PowerSide = 'left' | 'right';\n\n/**\n * Network node data structure\n * @public\n */\nexport interface NetworkNode {\n /** Unique identifier for the node */\n id: string;\n /** Type of network node */\n type: NetworkNodeType;\n /** Position coordinates in the diagram */\n position: { x: number; y: number };\n /** Parent node ID for React Flow sub-flows */\n parentId?: string;\n /** Node extent for sub-flows */\n extent?: 'parent' | [[number, number], [number, number]];\n /** Node data and configuration */\n data: {\n /** Display label for the node */\n label: string;\n /** Port configurations for the device */\n ports?: PortBlock[];\n /** List of connected node IDs */\n connections?: string[];\n /** Current status of the device */\n status?: DeviceStatus;\n /** NetBox integration ID */\n netboxId?: number;\n /** NetBox object type */\n netboxType?: 'device' | 'rack' | 'interface' | 'cable';\n /** Rack height in U units */\n uHeight?: number;\n /** Device position within rack in U units */\n uPosition?: number;\n /** Current view orientation */\n view?: DeviceView;\n /** Device type specification */\n deviceType?: string;\n /** Device manufacturer */\n manufacturer?: string;\n /** Device role in network */\n role?: string;\n /** Device width configuration */\n width?: Width;\n /** Rear port configurations */\n rearPorts?: PortBlock[];\n /** Power port side for rear view */\n powerSide?: PowerSide;\n /** Vertical PDU height in centimeters */\n heightCm?: number;\n /** Number of AC power ports */\n powerPorts?: number;\n /** Additional custom properties */\n [key: string]: any;\n };\n}\n\n/**\n * Network edge types\n * @public\n */\nexport type NetworkEdgeType = 'fiber' | 'ethernet' | 'power';\n\n/**\n * Network edge data structure\n * @public\n */\nexport interface NetworkEdge {\n /** Unique identifier for the edge */\n id: string;\n /** Source node ID */\n source: string;\n /** Target node ID */\n target: string;\n /** Source handle/port ID */\n sourceHandle?: string;\n /** Target handle/port ID */\n targetHandle?: string;\n /** Type of network connection */\n type?: NetworkEdgeType;\n /** Edge data and configuration */\n data?: {\n /** Connection bandwidth */\n bandwidth?: string;\n /** Cable length */\n length?: number;\n /** Edge color for styling */\n color?: string;\n /** Edge kind for styling/validation */\n kind?: 'fiber' | 'power' | 'network';\n /** Additional custom properties */\n [key: string]: any;\n };\n}\n\n/**\n * Rack device types\n * @public\n */\nexport type RackDeviceType = 'server' | 'switch' | 'router' | 'patch-panel' | 'ups';\n\n/**\n * Rack configuration structure\n * @public\n */\nexport interface RackConfig {\n /** Unique rack identifier */\n id: string;\n /** Rack display name */\n name: string;\n /** Rack position coordinates */\n position: { x: number; y: number };\n /** Rack height in U units */\n units: number;\n /** Devices mounted in the rack */\n devices: RackDevice[];\n}\n\n/**\n * Device mounted in a rack\n * @public\n */\nexport interface RackDevice {\n /** Unique device identifier */\n id: string;\n /** Device display name */\n name: string;\n /** Starting U position in rack */\n unit: number;\n /** Device height in U units */\n height: number;\n /** Device type */\n type: RackDeviceType;\n /** Device width configuration */\n width?: Width;\n /** Device role in network */\n role?: string;\n /** Front port configurations */\n ports?: PortBlock[];\n /** Rear port configurations */\n rearPorts?: PortBlock[];\n /** Power port side for rear view */\n powerSide?: PowerSide;\n /** Connected device IDs */\n connections?: string[];\n}\n\n/**\n * Fiber cable types\n * @public\n */\nexport type FiberCableType = 'single-mode' | 'multi-mode';\n\n/**\n * Fiber cable configuration\n * @public\n */\nexport interface FiberCable {\n /** Unique cable identifier */\n id: string;\n /** Cable display name */\n name: string;\n /** Fiber cable type */\n type: FiberCableType;\n /** Cable length */\n length: number;\n /** Cable color for visualization */\n color: string;\n /** Connection endpoints */\n connections: {\n /** Source connection point */\n from: string;\n /** Target connection point */\n to: string;\n };\n}\n\n// Re-export NetBox types\nexport * from './netbox';\nimport { NetBoxRack, NetBoxDevice, NetBoxCable } from './netbox';\n\n/**\n * Network diagram component props\n * @public\n */\nexport interface NetworkDiagramProps {\n /** Controlled nodes array */\n nodes?: NetworkNode[];\n /** Controlled edges array */\n edges?: NetworkEdge[];\n /** Callback when nodes change (controlled mode) */\n onNodesChange?: (nodes: NetworkNode[]) => void;\n /** Callback when edges change (controlled mode) */\n onEdgesChange?: (edges: NetworkEdge[]) => void;\n /** Initial nodes for uncontrolled mode */\n initialNodes?: NetworkNode[];\n /** Initial edges for uncontrolled mode */\n initialEdges?: NetworkEdge[];\n /** Headless store injection */\n store?: any;\n /** Enable debug mode */\n debug?: boolean;\n /** Callback when a node is clicked */\n onNodeClick?: (node: NetworkNode) => void;\n /** Callback when an edge is clicked */\n onEdgeClick?: (edge: NetworkEdge) => void;\n /** Callback when device view changes */\n onViewChange?: (nodeId: string, view: DeviceView) => void;\n /** Callback when rack face changes */\n onRackFaceChange?: (rackId: string, face: DeviceView) => void;\n /** CSS class name */\n className?: string;\n /** Inline styles */\n style?: React.CSSProperties;\n /** If true, vertically align rack bottoms to the same baseline */\n alignRacksToBottom?: boolean;\n}\n\n/**\n * NetBox integration props\n * @public\n */\nexport interface NetBoxNetworkDiagramProps extends NetworkDiagramProps {\n /** NetBox data for integration */\n netboxData?: {\n /** NetBox racks */\n racks: NetBoxRack[];\n /** NetBox devices */\n devices: NetBoxDevice[];\n /** NetBox cables */\n cables: NetBoxCable[];\n };\n /** Callback when NetBox data is updated */\n onNetBoxUpdate?: (data: any) => void;\n}\n","/**\n * Power connector utilities for consistent styling across devices and PDUs\n */\n\nexport interface PowerConnectorConfig {\n type: 'C13' | 'C14' | 'C19' | 'C20';\n color: string;\n borderColor: string;\n amperage: number;\n voltage: number;\n phases: number;\n}\n\nexport const POWER_CONNECTORS: Record<string, PowerConnectorConfig> = {\n C13: {\n type: 'C13',\n color: '#f59e0b', // Orange\n borderColor: '#d97706',\n amperage: 10,\n voltage: 230,\n phases: 1\n },\n C14: {\n type: 'C14',\n color: '#f59e0b', // Orange\n borderColor: '#d97706',\n amperage: 10,\n voltage: 230,\n phases: 1\n },\n C19: {\n type: 'C19',\n color: '#fbbf24', // Amber\n borderColor: '#d97706',\n amperage: 16,\n voltage: 230,\n phases: 1\n },\n C20: {\n type: 'C20',\n color: '#fbbf24', // Amber\n borderColor: '#d97706',\n amperage: 16,\n voltage: 230,\n phases: 1\n }\n};\n\nexport interface PowerPortStyle {\n width: number;\n height: number;\n borderRadius?: string;\n clipPath?: string;\n color: string;\n borderColor: string;\n fontSize: string;\n}\n\n/**\n * Get consistent power port styling for any connector type\n */\nexport function getPowerPortStyle(connectorType: string): PowerPortStyle {\n const connector = POWER_CONNECTORS[connectorType];\n if (!connector) {\n throw new Error(`Unknown connector type: ${connectorType}`);\n }\n\n const isHighPower = connector.amperage === 16; // C19/C20 are 16A\n const isLowPower = connector.amperage === 10; // C13/C14 are 10A\n\n // Size: High power connectors are bigger\n const width = isHighPower ? 12 : 8; // C19/C20 bigger; C13/C14 smaller\n const height = isHighPower ? 10 : 5; // C19/C20 bigger; C13/C14 smaller\n\n // Shape: C13/C14 have chamfered corners, C19/C20 have rounded corners\n const cornerStyle = isHighPower \n ? { borderRadius: '3px' } // C19/C20: rounded corners\n : { \n clipPath: `polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)`,\n borderRadius: '0px'\n };\n\n return {\n width,\n height,\n color: connector.color,\n borderColor: connector.borderColor,\n fontSize: isHighPower ? '3px' : '4px',\n ...cornerStyle\n };\n}\n\n/**\n * Get connector configuration by type\n */\nexport function getConnectorConfig(connectorType: string): PowerConnectorConfig {\n const connector = POWER_CONNECTORS[connectorType];\n if (!connector) {\n throw new Error(`Unknown connector type: ${connectorType}`);\n }\n return connector;\n}\n\n/**\n * Determine if a connector is high power (16A)\n */\nexport function isHighPowerConnector(connectorType: string): boolean {\n const connector = getConnectorConfig(connectorType);\n return connector.amperage === 16;\n}\n\n/**\n * Get PDU port type based on position in cycle\n * PDU cycle: [8xC13, 2xC19] = 10 ports per cycle\n */\nexport function getPDUPortType(portIndex: number): string {\n const cyclePosition = portIndex % 10; // 10 ports per cycle\n return cyclePosition < 8 ? 'C13' : 'C19';\n}\n\n/**\n * Get device connector type based on device name\n */\nexport function getDeviceConnectorType(deviceName: string): string {\n const name = deviceName.toLowerCase();\n \n // High power devices use C20\n if (name.includes('mx304') || name.includes('mx480') || name.includes('mx960')) {\n return 'C20';\n }\n \n // Standard devices use C14\n return 'C14';\n}\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode, Width, PortBlock } from '../types';\nimport { U_HEIGHT_PX } from '../utils/constants';\nimport { getPowerPortStyle, getConnectorConfig, getDeviceConnectorType } from '../utils/power-connectors';\n\n// Power connector styling is now handled by shared utility\n\nexport const DeviceNode: React.FC<NodeProps<NetworkNode['data']>> = ({ data, selected }) => {\n const { \n label, \n status = 'active', \n deviceType = 'server',\n manufacturer,\n role,\n uHeight = 1,\n uPosition: _uPosition = 1,\n width = Width.FULL, // Default to full width\n ports = [], // Array of port configurations\n rearPorts = [],\n view, // Optional view override\n powerSide: _powerSide = 'left' // Default power side for rear view\n } = data;\n\n // Determine view: prefer explicit view; if both front and rear ports exist, default to 'front'\n const currentFace = view || ((rearPorts.length > 0 && ports.length === 0) ? 'rear' : 'front');\n\n // Debug logging removed in production build; keep component silent by default\n\n // Create handle-to-side mapping for zIndex calculation\n const handleSideMap: Record<string, 'front' | 'rear'> = {};\n \n // Map ALL handles to their sides (both front and rear) for proper zIndex calculation\n // This should be independent of the current view - handles have fixed positions\n \n // Front view handles (always on front regardless of current view)\n handleSideMap['net-top'] = 'front';\n handleSideMap['net-bottom'] = 'front';\n // Add any custom front handles from ports array\n if (ports.length > 0) {\n ports.forEach(portBlock => {\n portBlock.ports.forEach(port => {\n const handleId = port.type?.includes('power') ? port.label : `${portBlock.name}-${port.label}`;\n handleSideMap[handleId] = 'front';\n });\n });\n }\n \n // Rear view handles (always on rear regardless of current view)\n handleSideMap['pwr-left-1'] = 'rear';\n handleSideMap['pwr-left-2'] = 'rear';\n handleSideMap['net-right-1'] = 'rear';\n handleSideMap['net-right-2'] = 'rear';\n // Add any custom rear handles from rearPorts array\n if (rearPorts.length > 0) {\n rearPorts.forEach(portBlock => {\n portBlock.ports.forEach(port => {\n const handleId = port.type?.includes('power') ? port.label : `${portBlock.name}-${port.label}`;\n handleSideMap[handleId] = 'rear';\n });\n });\n }\n \n\n // Removed data mutation; z-index is derived in headless selectors\n\n // Calculate device height based on U height\n const deviceHeight = uHeight * U_HEIGHT_PX;\n \n // Calculate rackDevice width based on width setting\n // Rack width is 300px, so full width = 300px, half width = 150px\n const rackDeviceWidth = width === Width.HALF ? '150px' : '304px';\n const rackDeviceLeft = width === Width.HALF ? '150px' : undefined;\n \n const getStatusColor = (status: string) => {\n switch (status) {\n case 'active':\n return '#10b981';\n case 'inactive':\n return '#6b7280';\n case 'maintenance':\n return '#f59e0b';\n default:\n return '#6b7280';\n }\n };\n\n const getDeviceTypeColor = (type: string) => {\n switch (type.toLowerCase()) {\n case 'server':\n return '#3b82f6';\n case 'switch':\n return '#8b5cf6';\n case 'router':\n return '#f59e0b';\n case 'patch-panel':\n return '#10b981';\n case 'ups':\n return '#ef4444';\n default:\n return '#6b7280';\n }\n };\n\n // Render ports from port arrays\n const renderPortsFromArray = (portBlocks: PortBlock[], position: 'front' | 'rear') => {\n const handles: React.ReactElement[] = [];\n \n if (portBlocks.length === 0) return handles;\n \n // Calculate port dimensions based on device height\n const portWidth = Math.max(4, Math.floor(deviceHeight * 0.4)); // 40% of device height, minimum 4px\n const portHeight = Math.max(2, Math.floor(deviceHeight * 0.2)); // 20% of device height, minimum 2px\n \n portBlocks.forEach((portBlock, blockIndex) => {\n portBlock.ports.forEach((port: any, portIndex: number) => {\n const isPower = !!port.type && port.type.includes('power');\n // Remove front-facing power connections: skip power ports on front face\n if (position === 'front' && isPower) {\n return;\n }\n const handleId = isPower ? `${port.label}` : `${portBlock.name}-${port.label}`;\n const isConnected = port.connected;\n \n // Determine port color based on type and cable medium\n let portColor = '#6b7280'; // Default grey for empty/disconnected\n if (isConnected) {\n if (port.type?.includes('power')) {\n portColor = port.type === 'power_c19' ? '#fbbf24' : '#f59e0b'; // Amber for C19, orange for C13\n } else if (port.type === 'console' || port.type === 'mgmt') {\n portColor = '#8b5cf6'; // Purple for management\n } else if (port.type === 'usb') {\n portColor = '#10b981'; // Green for USB\n } else {\n // Network port colors based on cable/transceiver type\n switch (port.cableType) {\n case 'smf': // Single Mode Fiber\n portColor = '#fbbf24'; // Yellow\n break;\n case 'cat6': // Category 6 Ethernet\n portColor = '#8b5cf6'; // Purple\n break;\n case 'om3': // OM3 Multimode Fiber\n portColor = '#06b6d4'; // Aqua/Cyan\n break;\n case 'om4': // OM4 Multimode Fiber\n portColor = '#8b5cf6'; // Violet\n break;\n case 'om5': // OM5 Multimode Fiber\n portColor = '#84cc16'; // Lime Green\n break;\n case 'cat5e': // Category 5e Ethernet\n portColor = '#3b82f6'; // Blue\n break;\n case 'cat6a': // Category 6A Ethernet\n portColor = '#ef4444'; // Red\n break;\n case 'cat7': // Category 7 Ethernet\n portColor = '#f97316'; // Orange\n break;\n case 'fiber': // Generic fiber\n portColor = '#3b82f6'; // Blue\n break;\n case 'ethernet': // Generic ethernet\n portColor = '#10b981'; // Green\n break;\n default:\n portColor = '#10b981'; // Default green for connected\n }\n }\n }\n \n // Determine position based on port type and face\n let handlePosition = Position.Top;\n let handleStyle: React.CSSProperties = {\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: isConnected ? portColor : '#6b7280',\n border: `1px solid ${isConnected ? portColor : '#374151'}`,\n borderRadius: '1px',\n cursor: 'pointer',\n };\n \n if (position === 'front') {\n // Front view: network ports on top/bottom\n if (portIndex % 2 === 0) {\n handlePosition = Position.Top;\n handleStyle.transform = 'translateY(50%)';\n handleStyle.left = `${(portIndex / 2) * (portWidth + 2)}px`;\n } else {\n handlePosition = Position.Bottom;\n handleStyle.transform = 'translateY(-50%)';\n handleStyle.left = `${((portIndex - 1) / 2) * (portWidth + 2)}px`;\n }\n } else {\n // Rear view: power ports on left, network on right\n if (port.type?.includes('power')) {\n handlePosition = Position.Left;\n handleStyle.transform = 'translateX(50%)'; // Move inside device boundary\n // Better spacing for 1U devices - start at top and space appropriately\n const baseTop = deviceHeight <= 20 ? 10 : 20;\n const spacing = deviceHeight <= 20 ? 30 : 50;\n handleStyle.top = `${baseTop + (portIndex * spacing)}%`;\n \n // Use shared utility for consistent power port styling\n const connectorType = getDeviceConnectorType(label);\n const portStyle = getPowerPortStyle(connectorType);\n \n handleStyle = {\n ...handleStyle,\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n };\n } else {\n handlePosition = Position.Right;\n handleStyle.transform = 'translateX(50%)';\n handleStyle.top = `${25 + (portIndex * 50)}%`;\n }\n }\n \n const handleType = isPower ? 'target' : (isConnected ? 'source' : 'target');\n\n handles.push(\n <Handle\n key={handleId}\n id={handleId}\n type={handleType as any}\n position={handlePosition}\n style={handleStyle}\n title={`${portBlock.name} - ${port.label} ${isConnected ? '(connected)' : '(disconnected)'}`}\n >\n {isPower ? portIndex + 1 : undefined}\n </Handle>\n );\n });\n });\n \n return handles;\n };\n\n // Render handles based on face orientation\n const renderHandles = () => {\n const handles: React.ReactElement[] = [];\n \n // Calculate port dimensions based on device height\n const portMargin = Math.max(1, Math.floor(deviceHeight * 0.1)); // 10% of device height, minimum 1px\n const portWidth = Math.max(4, Math.floor(deviceHeight * 0.4)); // 40% of device height, minimum 4px\n const portHeight = Math.max(2, Math.floor(deviceHeight * 0.2)); // 20% of device height, minimum 2px\n \n if (currentFace === 'front') {\n // Front view\n // Front view: render from ports array if provided, else fall back to defaults\n if (ports.length > 0) {\n // Render ports from provided configuration\n return renderPortsFromArray(ports, 'front');\n }\n\n // Check if this is an AGG/core switch\n const isAGGSwitch = deviceType === 'switch' && (label.toLowerCase().includes('agg') || label.toLowerCase().includes('core') || role === 'agg' || role === 'core');\n if (isAGGSwitch) {\n return renderAGGSwitchHandles();\n }\n\n // Standard network ports on top and bottom (target - receives network from switches)\n // Standard device fallbacks\n handles.push(\n <Handle\n key=\"net-top\"\n id=\"net-top\"\n type=\"target\"\n position={Position.Top}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateY(50%)',\n }}\n title=\"Network Port (Top)\"\n />\n );\n\n handles.push(\n <Handle\n key=\"net-bottom\"\n id=\"net-bottom\"\n type=\"target\"\n position={Position.Bottom}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateY(-50%)',\n }}\n title=\"Network Port (Bottom)\"\n />\n );\n \n } else if (currentFace === 'rear') {\n // Rear view\n // Rear view: render from rearPorts array if provided, else fall back to defaults\n if (rearPorts.length > 0) {\n // Render ports from provided configuration\n return renderPortsFromArray(rearPorts, 'rear');\n }\n\n const isSwitch = deviceType === 'switch';\n const isPatchPanel = deviceType === 'patch-panel';\n\n // Power ports on left side (all devices except patch panels)\n if (!isPatchPanel) {\n // Get connector type and styling using shared utility\n const connectorType = getDeviceConnectorType(label);\n const connector = getConnectorConfig(connectorType);\n const portStyle = getPowerPortStyle(connectorType);\n\n // Power port 1 - position based on device height\n const port1Top = deviceHeight <= 20 ? '10%' : '25%'; // Start at top for 1U devices\n \n handles.push(\n <Handle\n key=\"pwr-1\"\n id=\"pwr-left-1\"\n type=\"target\"\n position={Position.Left}\n style={{\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n transform: 'translateX(50%)', // Move inside the device boundary\n top: port1Top,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port 1 (${connector.type}) - ${connector.voltage}V, ${connector.amperage}A`}\n >\n 1\n </Handle>\n );\n\n // Power port 2 - position based on device height with proper spacing\n const port2Top = deviceHeight <= 20 ? '50%' : '75%'; // Position second port lower for 1U devices\n \n handles.push(\n <Handle\n key=\"pwr-2\"\n id=\"pwr-left-2\"\n type=\"target\"\n position={Position.Left}\n style={{\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n transform: 'translateX(50%)', // Move inside the device boundary\n top: port2Top,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port 2 (${connector.type}) - ${connector.voltage}V, ${connector.amperage}A`}\n >\n 2\n </Handle>\n );\n }\n\n // Network ports on right side (for non-switch, non-patch-panel devices)\n if (!isSwitch && !isPatchPanel) {\n handles.push(\n <Handle\n key=\"net-right-1\"\n id=\"net-right-1\"\n type=\"target\"\n position={Position.Right}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateX(50%)',\n top: '25%',\n }}\n title=\"Network Port 1 (Right)\"\n />\n );\n\n handles.push(\n <Handle\n key=\"net-right-2\"\n id=\"net-right-2\"\n type=\"target\"\n position={Position.Right}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateX(50%)',\n top: '75%',\n }}\n title=\"Network Port 2 (Right)\"\n />\n );\n }\n }\n\n return handles;\n };\n\n // Render AGG switch handles: 48 ports on front, 4 uplinks on right\n const renderAGGSwitchHandles = () => {\n // AGG/core switch ports and uplinks\n const handles: React.ReactElement[] = [];\n \n // Calculate port dimensions - middle size for good visibility\n const portMargin = Math.max(1, Math.floor(deviceHeight * 0.08)); // 8% of device height, minimum 1px\n const portWidth = Math.max(10, Math.floor(deviceHeight * 0.45)); // 45% of device height, minimum 10px\n const portHeight = Math.max(5, Math.floor(deviceHeight * 0.25)); // 25% of device height, minimum 5px\n const portSpacing = Math.max(2, Math.floor(deviceHeight * 0.25)); // 25% of device height, minimum 2px\n \n // 32 ports arranged in grid pattern: 16 on top, 16 on bottom\n // Create 32 front ports\n \n // Top row: 16 ports\n for (let i = 1; i <= 16; i++) {\n const handle = (\n <Handle\n key={`port-${i}`}\n id={`port-${i}`}\n type=\"source\"\n position={Position.Top}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '1px solid #059669', // Thinner border for cleaner look\n borderRadius: '2px',\n cursor: 'pointer',\n transform: 'translateY(50%)', // Pull handle into node\n zIndex: 1000,\n // Position ports across the top edge\n left: `${(i - 1) * (portWidth + 2)}px`, // Space ports across the width\n }}\n title={`Port ${i}`}\n />\n );\n \n \n \n handles.push(handle);\n }\n \n // Bottom row: 16 ports\n for (let i = 17; i <= 32; i++) {\n const bottomIndex = i - 16; // 1-16 for bottom row positioning\n const handle = (\n <Handle\n key={`port-${i}`}\n id={`port-${i}`}\n type=\"source\"\n position={Position.Bottom}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '1px solid #059669', // Thinner border for cleaner look\n borderRadius: '2px',\n cursor: 'pointer',\n transform: 'translateY(-50%)', // Pull handle into node\n zIndex: 1000,\n // Position ports across the bottom edge\n left: `${(bottomIndex - 1) * (portWidth + 2)}px`, // Space ports across the width\n }}\n title={`Port ${i}`}\n />\n );\n \n \n \n handles.push(handle);\n }\n \n // 4 uplink ports on the right edge (larger, different color)\n for (let i = 1; i <= 4; i++) {\n const uplinkWidth = Math.max(4, Math.floor(deviceHeight * 0.3)); // Larger uplink ports\n const uplinkHeight = Math.max(3, Math.floor(deviceHeight * 0.15)); // Taller uplink ports\n \n handles.push(\n <Handle\n key={`uplink-${i}`}\n id={`uplink-${i}`}\n type=\"source\"\n position={Position.Right}\n style={{\n width: `${uplinkWidth}px`,\n height: `${uplinkHeight}px`,\n background: '#8b5cf6', // Purple color for uplinks\n border: '0.5px solid #7c3aed',\n borderRadius: '0.5px',\n cursor: 'pointer',\n transform: 'translateX(-50%)', // Pull handle into node\n }}\n title={`Uplink ${i}`}\n />\n );\n }\n\n return handles;\n };\n\n return (\n <div\n className={`device-node ${selected ? 'selected' : ''}`}\n style={{\n background: '#1f2937',\n border: `1px solid ${getStatusColor(status)}`,\n borderRadius: '2px',\n padding: '0px', // Remove padding to fix alignment\n width: rackDeviceWidth, // Width based on width setting\n ...(rackDeviceLeft && { left: rackDeviceLeft }), // Only set left for HALF width rackDevices\n height: `${deviceHeight}px`, // Exact U height (20px per U)\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '8px',\n boxShadow: selected ? '0 0 0 1px #3b82f6' : '0 1px 2px rgba(0,0,0,0.1)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n cursor: 'grab',\n marginBottom: '0px', // No gap - devices should be exactly U height\n boxSizing: 'border-box',\n marginTop: '0px',\n marginLeft: '0px',\n marginRight: '0px',\n }}\n >\n {/* Standard handles are now always rendered */}\n \n {/* U Position will be calculated dynamically based on position */}\n \n \n <div style={{ \n textAlign: 'center', \n flex: 1, \n display: 'flex', \n flexDirection: 'column', \n justifyContent: 'center',\n overflow: 'hidden',\n padding: '2px', // Add small padding for text readability\n }}>\n <div style={{ \n fontWeight: 'bold', \n fontSize: '7px',\n lineHeight: '1.1',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {label}\n </div>\n {uHeight > 1 && (\n <div style={{ \n fontSize: '6px', \n color: '#9ca3af',\n lineHeight: '1',\n }}>\n {manufacturer}\n </div>\n )}\n </div>\n \n {/* U Height indicator */}\n {uHeight > 1 && (\n <div\n style={{\n position: 'absolute',\n bottom: '1px',\n right: '1px',\n background: '#374151',\n color: '#9ca3af',\n padding: '1px 2px',\n borderRadius: '1px',\n fontSize: '6px',\n lineHeight: '1',\n }}\n >\n {uHeight}U\n </div>\n )}\n \n {/* Status indicator */}\n <div\n style={{\n position: 'absolute',\n bottom: '1px',\n left: '1px',\n width: '4px',\n height: '4px',\n background: getStatusColor(status),\n borderRadius: '50%',\n }}\n />\n \n {/* React Flow edge handles based on face orientation */}\n {renderHandles()}\n </div>\n );\n};\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode } from '../types';\nimport { getPowerPortStyle, getPDUPortType } from '../utils/power-connectors';\n\nexport enum MgmtUnitPosition {\n TOP = 'top',\n MIDDLE = 'middle',\n BOTTOM = 'bottom'\n}\n\n// Reduce header height further to minimize top gap\nconst PDU_HEADER_HEIGHT = 13; // px\nconst PDU_BODY_BOTTOM_PADDING = 1; // px\n\nexport const VerticalPDU: React.FC<NodeProps<NetworkNode['data']>> = ({\n data,\n selected,\n id,\n}) => {\n const {\n label,\n status = 'active',\n heightCm = 100,\n powerPorts = 36, // Default number of AC power ports (10 C13 + 2 C19) × 3\n portTypes = [],\n widthPx = 15,\n mgmt_unit, // Optional management unit position\n } = data;\n\n const getStatusColor = (status: string) => {\n switch (status) {\n case 'active':\n return '#10b981';\n case 'inactive':\n return '#6b7280';\n case 'maintenance':\n return '#f59e0b';\n default:\n return '#6b7280';\n }\n };\n\n // Convert cm to pixels (1cm = 4.2px)\n const heightPx = heightCm * 4.2;\n\n // Completely custom vertical positioning for C13/C19/sets\n const renderPowerHandles = () => {\n // CYCLE = [8xC13, 2xC19], three times (for 30 ports)\n // Strategy:\n // - Use minimal/gapless \"start\" offset (header), so first port right beneath header.\n // - C13 ports: minimal gap (tight)\n // - C19 ports: even tighter gap than C13 (or zero)\n // - After last C19 of set: add a MUCH bigger gap before the new cycle (visual break).\n // - Ensure total height, including all ports and gaps, fits exactly into the available drawing area, and cycles are visually distinct.\n const cycleLength = 10; // 8 C13, 2 C19\n const nCycles = Math.ceil(powerPorts / cycleLength);\n const portsPerCycle = Array(cycleLength).fill(0).map((_, i) => (i < 8 ? '10A' : '16A'));\n\n // Sizing\n const C13_HEIGHT = 5;\n const C19_HEIGHT = 7;\n // Reduce these gaps by 30%\n const C13_GAP = 0.7 * 0.7; // 0.49, very tight\n const C19_GAP = 0.2 * 0.7; // 0.14, nearly none\n const CYCLE_GAP = 8 * 0.7; // 5.6, much wider than normal (but 30% less)\n const totalHeaderAndBottomGaps = PDU_HEADER_HEIGHT + PDU_BODY_BOTTOM_PADDING;\n\n // Build metadata of port types and port heights\n const portMeta = [];\n for (let c = 0, idx = 0; c < nCycles; ++c) {\n for (let i = 0; i < cycleLength && idx < powerPorts; ++i, ++idx) {\n const portType = portsPerCycle[i];\n const is16A = portType === '16A';\n portMeta.push({\n portType,\n is16A,\n idx,\n isLastInCycle: i === cycleLength - 1,\n // For gap calculation\n isC19: is16A,\n portHeight: is16A ? C19_HEIGHT : C13_HEIGHT,\n });\n }\n }\n\n // Calculate the \"cycle\" indices (where to add the larger cycle gap)\n const handles = [];\n // Account for header height (20px) and add minimal padding\n const headerHeight = 15;\n const availableHeight = heightPx - headerHeight - 3; // 5px padding at bottom\n\n // REDUCE vertical spacing: 30% less spacing between ports\n // So multiply the calculated spacing by 0.7\n const rawPortSpacing = availableHeight / (powerPorts - 9);\n const portSpacing = rawPortSpacing * 0.5; // Even tighter spacing\n \n for (let i = 0; i < powerPorts; i++) {\n const yPos = headerHeight - 2 + (portSpacing * i); // Start slightly above header\n const handleId = `${i + 1}`;\n \n // Check if this position should be the management unit\n const isMgmtPosition = mgmt_unit && (\n (mgmt_unit === 'top' && i === 0) ||\n (mgmt_unit === 'middle' && i === Math.floor(powerPorts / 2)) ||\n (mgmt_unit === 'bottom' && i === powerPorts - 1)\n );\n \n if (isMgmtPosition) {\n handles.push(renderMgmtUnit(yPos));\n continue;\n }\n \n // Get port type and styling using shared utility\n const portType = getPDUPortType(i);\n const portStyle = getPowerPortStyle(portType);\n \n // Fix: Center the port more accurately (add -1px shift for visual center).\n const leftPx = Math.round((widthPx - portStyle.width) / 2 -1) ;\n\n handles.push(\n <Handle\n key={`handle-${handleId}`}\n type=\"source\"\n position={Position.Right}\n id={handleId}\n style={{\n position: 'absolute',\n left: `${leftPx}px`,\n top: `${yPos - (portStyle.height / 2)}px`,\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port ${i + 1} (${portType})`}\n >\n {i + 1}\n </Handle>\n );\n }\n return handles;\n };\n\n // Render management unit as a power port in the sequence\n const renderMgmtUnit = (yPos: number) => {\n const mgmtWidth = 16;\n const mgmtHeight = 12;\n\n return (\n <div\n key=\"mgmt-unit\"\n style={{\n position: 'absolute',\n left: `${(widthPx - mgmtWidth) / 2}px`,\n top: `${yPos - (mgmtHeight / 2)}px`,\n width: `${mgmtWidth}px`,\n height: `${mgmtHeight}px`,\n background: '#1a1a1a',\n border: '1px solid #374151',\n borderRadius: '1px',\n display: 'flex',\n flexDirection: 'column',\n padding: '1px',\n zIndex: 10,\n }}\n >\n {/* Screen positioned on the left */}\n <div\n style={{\n position: 'absolute',\n left: '-10px',\n top: '1px',\n background: '#ffffff',\n border: '0.5px solid #6b7280',\n borderRadius: '0.5px',\n width: '8px',\n height: '10px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '3px',\n color: '#10b981',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n transform: 'rotate(90deg)',\n transformOrigin: 'center',\n }}\n >\n APC\n </div>\n \n {/* Single Network Port Handle */}\n <Handle\n key=\"mgmt-net-1\"\n type=\"source\"\n position={Position.Right}\n id=\"mgmt-net-1\"\n style={{\n width: '70%',\n height: '6px',\n background: '#10b981',\n border: '1px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n zIndex: 11,\n margin: '0 auto',\n }}\n title=\"Management Network Port\"\n />\n </div>\n );\n };\n\n return (\n <div\n className={`vertical-pdu-node ${selected ? 'selected' : ''}`}\n style={{\n background: 'linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)',\n border: `1px solid ${getStatusColor(status)}`,\n borderRadius: '2px',\n padding: 0,\n width: `${widthPx}px`,\n height: `${heightPx}px`,\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '12px',\n boxShadow: selected ? '0 0 0 2px #3b82f6' : '0 1px 3px rgba(0,0,0,0.3)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n \n {/* PDU Header */}\n <div style={{ \n textAlign: 'center', \n marginBottom: 0, \n zIndex: 2, \n background: 'linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)', \n padding: '2px',\n position: 'relative',\n height: '20px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n borderBottom: '1px solid #4a5568',\n }}>\n <div style={{ fontWeight: 'bold', fontSize: '6px', color: '#e2e8f0' }}>{label}</div>\n </div>\n \n {/* PDU Body with power ports */}\n <div\n style={{\n flex: 1,\n background: 'linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)',\n position: 'relative',\n minHeight: `${heightPx - 20}px`,\n overflow: 'hidden',\n }}\n >\n {renderPowerHandles()}\n </div>\n </div>\n );\n};\n","import { NetworkNode } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from './constants';\n\n/**\n * Calculate U position from device Y coordinate within a rack\n */\nexport const calculateUPositionFromY = (\n deviceY: number,\n rackY: number,\n rackUHeight: number = 42\n): number => {\n const startY = RACK_HEADER_HEIGHT; // Start at top of rack body\n const relativeY = deviceY - rackY - startY;\n const uPosition = Math.max(1, Math.min(rackUHeight, Math.round(relativeY / U_HEIGHT_PX) + 1));\n return uPosition;\n};\n\n/**\n * Snap a device position to the nearest U position within a rack\n */\nexport const snapToUPosition = (\n device: NetworkNode,\n rack: NetworkNode,\n newPosition: { x: number; y: number },\n allNodes: NetworkNode[]\n): { x: number; y: number; uPosition?: number } => {\n if (!device.parentId || device.parentId !== rack.id) {\n return newPosition;\n }\n\n const uHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n // Calculate U position based on Y coordinate\n const startY = RACK_HEADER_HEIGHT; // After header\n \n // Calculate which U position this corresponds to\n const relativeY = newPosition.y - startY; // child position is already parent-relative\n const calculatedUPosition = Math.round(relativeY / U_HEIGHT_PX) + 1;\n let snappedUPosition = Math.max(1, calculatedUPosition); // Don't constrain here, let availability check handle it\n \n // Debug logging (commented out for tests)\n // console.log('SnapToUPosition Debug:', {\n // deviceId: device.id,\n // newPosition,\n // rackPosition: rack.position,\n // startY,\n // relativeY,\n // calculatedUPosition,\n // snappedUPosition,\n // uHeight,\n // rackUHeight\n // });\n \n // Check if the calculated position is available, if not find the nearest available position\n if (!isUPositionAvailable(rack, device, snappedUPosition, allNodes)) {\n // Try to find the nearest available position\n const availablePosition = findNextAvailableUPosition(rack, device, allNodes, snappedUPosition);\n if (availablePosition !== snappedUPosition) {\n snappedUPosition = availablePosition;\n }\n }\n \n // Snap to exact U position - ensure devices are exactly on U boundaries\n // Account for device border (1px) to align properly with U grid\n const snappedY = startY + (snappedUPosition - 1) * U_HEIGHT_PX - 1; // return parent-relative y, offset by border\n \n return {\n x: newPosition.x,\n y: snappedY,\n uPosition: snappedUPosition,\n };\n};\n\n/**\n * Check if a U position is available in a rack\n */\nexport const isUPositionAvailable = (\n rack: NetworkNode,\n device: NetworkNode,\n uPosition: number,\n allNodes: NetworkNode[]\n): boolean => {\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n // Check bounds\n if (uPosition < 1 || uPosition + deviceUHeight - 1 > rackUHeight) {\n return false;\n }\n \n // Check for conflicts with other devices in the same rack\n const rackDevices = allNodes.filter(node => \n node.type === 'device' && \n node.parentId === rack.id && \n node.id !== device.id\n );\n \n for (const otherDevice of rackDevices) {\n const otherUPosition = otherDevice.data.uPosition || 1;\n const otherUHeight = otherDevice.data.uHeight || 1;\n \n // Check if the new device would overlap with existing device\n const newDeviceStart = uPosition;\n const newDeviceEnd = uPosition + deviceUHeight - 1;\n const otherDeviceStart = otherUPosition;\n const otherDeviceEnd = otherUPosition + otherUHeight - 1;\n \n if (newDeviceStart <= otherDeviceEnd && newDeviceEnd >= otherDeviceStart) {\n return false; // Overlap detected\n }\n }\n \n return true;\n};\n\n/**\n * Find the next available U position in a rack\n */\nexport const findNextAvailableUPosition = (\n rack: NetworkNode,\n device: NetworkNode,\n allNodes: NetworkNode[],\n startFrom: number = 1\n): number => {\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n for (let u = startFrom; u <= rackUHeight - deviceUHeight + 1; u++) {\n if (isUPositionAvailable(rack, device, u, allNodes)) {\n return u;\n }\n }\n \n return 1; // Fallback to position 1\n};\n\n/**\n * Calculate device position based on U position within a rack\n */\nexport const calculateDevicePositionFromU = (\n rack: NetworkNode,\n uPosition: number\n): { x: number; y: number } => {\n const startY = RACK_HEADER_HEIGHT; // After header\n \n // For React Flow sub-flows, child positions are relative to parent\n // So we return the position relative to the rack origin\n return {\n x: 0, // Align with rack left edge (relative to parent)\n y: startY + (uPosition - 1) * U_HEIGHT_PX - 1, // Relative to rack top, account for device border\n };\n};\n\n/**\n * Update device U position and recalculate position\n */\nexport const updateDeviceUPosition = (\n device: NetworkNode,\n rack: NetworkNode,\n newUPosition: number\n): NetworkNode => {\n const newPosition = calculateDevicePositionFromU(rack, newUPosition);\n \n return {\n ...device,\n position: newPosition,\n data: {\n ...device.data,\n uPosition: newUPosition,\n },\n };\n};\n\n/**\n * Validate and snap device to valid U position\n */\nexport const validateAndSnapDevice = (\n device: NetworkNode,\n rack: NetworkNode\n): NetworkNode => {\n const currentUPosition = device.data.uPosition || 1;\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n // Ensure U position is within bounds\n const validUPosition = Math.max(1, Math.min(rackUHeight - deviceUHeight + 1, currentUPosition));\n \n if (validUPosition !== currentUPosition) {\n return updateDeviceUPosition(device, rack, validUPosition);\n }\n \n return device;\n};\n","import type { NetworkEdge, NetworkNode } from '../types';\n\nexport type ViewFace = 'front' | 'rear';\n\nexport interface NetworkDiagramState {\n nodes: NetworkNode[];\n edges: NetworkEdge[];\n debug?: boolean;\n}\n\nexport interface ValidateConnectionParams {\n source: string | null;\n target: string | null;\n sourceHandle?: string | null;\n targetHandle?: string | null;\n}\n\nexport interface ValidationResult { valid: boolean; reason?: string }\n\nexport interface NetworkDiagramOptions {\n validateConnection?: (params: ValidateConnectionParams, ctx: NetworkDiagramState) => ValidationResult;\n}\n\nexport interface NetworkDiagramStore {\n getState: () => NetworkDiagramState;\n setState: (partial: Partial<NetworkDiagramState>) => void;\n subscribe: (listener: (state: NetworkDiagramState) => void) => () => void;\n // selectors\n selectEdgeZIndex: (edge: NetworkEdge) => number;\n validateConnection: (params: ValidateConnectionParams) => ValidationResult;\n}\n\nfunction defaultValidateConnection(params: ValidateConnectionParams, ctx: NetworkDiagramState): ValidationResult {\n if (!params.source || !params.target || !params.sourceHandle || !params.targetHandle) return { valid: true };\n\n const sourceAlready = ctx.edges.some(e => e.source === params.source && e.sourceHandle === params.sourceHandle);\n const targetAlready = ctx.edges.some(e => e.target === params.target && e.targetHandle === params.targetHandle);\n if (sourceAlready) return { valid: false, reason: 'Source port is already connected' };\n if (targetAlready) return { valid: false, reason: 'Target port is already connected' };\n return { valid: true };\n}\n\n// Determine which face a given handle belongs to, based on node data\nexport function getHandleSide(handleId: string, node: NetworkNode | undefined): ViewFace | undefined {\n if (!node) return undefined;\n const data = node.data || {} as any;\n \n // Check handleSideMap first if available\n if (data.handleSideMap && data.handleSideMap[handleId]) {\n return data.handleSideMap[handleId];\n }\n \n // Known defaults\n if (handleId === 'net-top' || handleId === 'net-bottom') return 'front';\n if (handleId === 'pwr-left-1' || handleId === 'pwr-left-2' || handleId === 'net-right-1' || handleId === 'net-right-2') return 'rear';\n\n // Ports from arrays\n const frontBlocks: any[] = Array.isArray((data as any).ports) ? (data as any).ports : [];\n const rearBlocks: any[] = Array.isArray((data as any).rearPorts) ? (data as any).rearPorts : [];\n\n // If the handleId matches a power label, treat as rear by default\n const looksLikePower = handleId.startsWith('pwr') || handleId.includes('power');\n if (looksLikePower) return 'rear';\n\n // Try to match against front port blocks\n if (frontBlocks.length > 0) {\n for (const block of frontBlocks) {\n for (const port of block.ports || []) {\n const expected = port.type && String(port.type).includes('power') ? port.label : `${block.name}-${port.label}`;\n if (expected === handleId) return 'front';\n }\n }\n }\n // Try to match against rear port blocks\n if (rearBlocks.length > 0) {\n for (const block of rearBlocks) {\n for (const port of block.ports || []) {\n const expected = port.type && String(port.type).includes('power') ? port.label : `${block.name}-${port.label}`;\n if (expected === handleId) return 'rear';\n }\n }\n }\n\n return undefined;\n}\n\nexport function createNetworkDiagramStore(initial: Partial<NetworkDiagramState> = {}, options: NetworkDiagramOptions = {}): NetworkDiagramStore {\n let state: NetworkDiagramState = {\n nodes: initial.nodes ?? [],\n edges: initial.edges ?? [],\n debug: initial.debug ?? false,\n };\n const listeners = new Set<(s: NetworkDiagramState) => void>();\n\n const getState = () => state;\n const setState = (partial: Partial<NetworkDiagramState>) => {\n state = { ...state, ...partial };\n listeners.forEach(l => l(state));\n };\n const subscribe = (listener: (s: NetworkDiagramState) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n\n const selectEdgeZIndex = (edge: NetworkEdge): number => {\n const targetNode = state.nodes.find(n => n.id === edge.target);\n if (!targetNode || targetNode.type !== 'device') return 1000;\n const deviceView: ViewFace = (targetNode.data?.view as ViewFace) || 'front';\n const side = getHandleSide(edge.targetHandle || '', targetNode);\n if (side) return deviceView === side ? 1000 : 500;\n\n const targetHandle = edge.targetHandle || '';\n const isPowerHandle = targetHandle.startsWith('pwr') || targetHandle.startsWith('power');\n const isNetworkHandle = targetHandle.startsWith('net-') || targetHandle.startsWith('port-') || targetHandle.startsWith('uplink-') || targetHandle.includes('Fiber') || targetHandle.includes('Ports');\n if (isPowerHandle) return deviceView === 'rear' ? 1000 : 500;\n if (isNetworkHandle) return deviceView === 'front' ? 1000 : 500;\n return 1000;\n };\n\n const validate = (params: ValidateConnectionParams): ValidationResult => {\n const fn = options.validateConnection || defaultValidateConnection;\n return fn(params, state);\n };\n\n return { getState, setState, subscribe, selectEdgeZIndex, validateConnection: validate };\n}\n\n\n","import { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport type { NetworkEdge, NetworkNode } from '../types';\nimport type { NetworkDiagramStore, ValidateConnectionParams, ValidationResult } from './store';\n\nexport function useNetworkDiagram(store: NetworkDiagramStore) {\n const subscribe = (cb: () => void) => store.subscribe(cb as any);\n const getSnapshot = () => store.getState();\n const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return state;\n}\n\nexport function useNodes(store: NetworkDiagramStore): NetworkNode[] {\n const subscribe = (cb: () => void) => store.subscribe(cb as any);\n const getSnapshot = () => store.getState().nodes;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport function useEdges(store: NetworkDiagramStore): NetworkEdge[] {\n const subscribe = (cb: () => void) => store.subscribe(cb as any);\n const getSnapshot = () => store.getState().edges;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport function useConnectionValidation(store: NetworkDiagramStore) {\n return (params: ValidateConnectionParams): ValidationResult => store.validateConnection(params);\n}\n\nexport function useSelectEdgeZIndex(store: NetworkDiagramStore) {\n return store.selectEdgeZIndex;\n}\n\n\n","import React, { useCallback, useMemo, useState, useEffect, useRef } from 'react';\nimport {\n ReactFlow,\n Background,\n Controls,\n MiniMap,\n useNodesState,\n useEdgesState,\n addEdge,\n Connection,\n Edge,\n Node,\n NodeTypes,\n EdgeTypes,\n useReactFlow,\n NodeChange,\n useOnSelectionChange,\n ReactFlowProvider,\n} from 'reactflow';\nimport { NetworkDiagramProps, NetworkNode, NetworkEdge } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from '../utils/constants';\nimport { RackNode } from './RackNode';\nimport { FiberNode } from './FiberNode';\nimport { FiberEdge } from './FiberEdge';\nimport { PowerEdge } from './PowerEdge';\nimport { DeviceNode } from './DeviceNode';\nimport { VerticalPDU } from './VerticalPDU';\nimport { snapToUPosition, validateAndSnapDevice, calculateDevicePositionFromU } from '../utils/u-positioning';\nimport { createNetworkDiagramStore } from '../core/store';\nimport { useEdges, useNodes, useSelectEdgeZIndex } from '../core/hooks';\n\n// Create nodeTypes with onViewChange prop - memoized outside component\nconst createNodeTypes = (\n onViewChange?: (nodeId: string, view: 'front' | 'rear') => void,\n onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void\n): NodeTypes => ({\n rack: (props: any) => <RackNode {...props} onViewChange={onViewChange} onRackFaceChange={onRackFaceChange} />,\n fiber: FiberNode,\n device: DeviceNode,\n 'vertical-pdu': VerticalPDU,\n});\n\nconst edgeTypes: EdgeTypes = {\n fiber: FiberEdge,\n power: PowerEdge,\n};\n\nconst NetworkDiagramInner: React.FC<NetworkDiagramProps> = ({\n nodes,\n edges,\n initialNodes,\n initialEdges,\n onNodesChange: externalOnNodesChange,\n onEdgesChange: externalOnEdgesChange,\n store,\n debug,\n onNodeClick,\n onEdgeClick,\n onViewChange,\n onRackFaceChange,\n className,\n style,\n alignRacksToBottom,\n}) => {\n // Decide controlled vs uncontrolled\n const isControlled = Array.isArray(nodes) && Array.isArray(edges);\n const localStore = React.useMemo(() => {\n if (store) return store;\n return createNetworkDiagramStore({\n nodes: isControlled ? nodes : (initialNodes || nodes || []),\n edges: isControlled ? edges : (initialEdges || edges || []),\n debug,\n });\n }, [store, isControlled, nodes, edges, initialNodes, initialEdges, debug]);\n\n // Local React Flow states mirror store state for rendering\n const storeNodes = useNodes(localStore);\n const storeEdges = useEdges(localStore);\n const [reactFlowNodes, setNodes, onNodesChange] = useNodesState(storeNodes);\n const [reactFlowEdges, setEdges, onEdgesChange] = useEdgesState(storeEdges);\n const selectEdgeZIndex = useSelectEdgeZIndex(localStore);\n // Memoize nodeTypes to avoid recreating object every render (prevents node remounts)\n const memoizedNodeTypes = useMemo(() => createNodeTypes(onViewChange, onRackFaceChange), [onViewChange, onRackFaceChange]);\n \n // Memoize edgeTypes to prevent recreation warnings\n const memoizedEdgeTypes = useMemo(() => edgeTypes, []);\n\n\n // Maintain the latest nodes in a ref for always-current lookups in callbacks\n const latestNodesRef = useRef<Node[]>(reactFlowNodes);\n useEffect(() => { latestNodesRef.current = reactFlowNodes; }, [reactFlowNodes]);\n\n // Maintain the latest edges in a ref for always-current lookups in callbacks\n const latestEdgesRef = useRef<Edge[]>(reactFlowEdges);\n useEffect(() => { latestEdgesRef.current = reactFlowEdges; }, [reactFlowEdges]);\n\n // Sync store -> RF state updates\n useEffect(() => { setNodes(storeNodes); }, [storeNodes, setNodes]);\n useEffect(() => { setEdges(storeEdges); }, [storeEdges, setEdges]);\n // Sync controlled props -> store (if controlled)\n useEffect(() => {\n if (isControlled) {\n localStore.setState({ nodes: nodes || [] });\n }\n }, [isControlled, nodes, localStore]);\n useEffect(() => {\n if (isControlled) {\n localStore.setState({ edges: edges || [] });\n }\n }, [isControlled, edges, localStore]);\n\n // Optionally align rack bottoms to a common baseline\n useEffect(() => {\n if (!alignRacksToBottom) return;\n if (!reactFlowNodes || reactFlowNodes.length === 0) return;\n\n const racks = reactFlowNodes.filter(n => n.type === 'rack');\n if (racks.length === 0) return;\n\n // Compute each rack's bottom (y + header + uHeight * U_HEIGHT_PX)\n const rackBottoms = racks.map(r => {\n const uHeight = (r.data && (r.data as any).uHeight) || 42;\n const heightPx = RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX;\n return (r.position?.y || 0) + heightPx;\n });\n \n // Find the range of bottom positions\n const minBottom = Math.min(...rackBottoms);\n const maxBottom = Math.max(...rackBottoms);\n const range = maxBottom - minBottom;\n \n // Only align if there's a significant difference (more than 20px)\n // This prevents constant micro-adjustments during dragging\n if (range < 20) return;\n \n // Use the highest bottom as the baseline (floor level)\n const baselineBottom = maxBottom;\n\n // Align all racks to the baseline - move them up or down as needed\n const nextNodes = reactFlowNodes.map(n => {\n if (n.type !== 'rack') return n;\n const uHeight = (n.data && (n.data as any).uHeight) || 42;\n const heightPx = RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX;\n const currentBottom = (n.position?.y || 0) + heightPx;\n const delta = baselineBottom - currentBottom;\n if (Math.abs(delta) < 5) return n; // Don't make tiny adjustments\n return {\n ...n,\n position: {\n x: n.position?.x || 0,\n y: (n.position?.y || 0) + delta,\n },\n } as Node;\n });\n\n const changed = nextNodes.some((n, i) => n.position !== reactFlowNodes[i].position);\n if (changed) setNodes(nextNodes);\n }, [alignRacksToBottom, reactFlowNodes, setNodes]);\n\n // Helper: always get current version of a node (beyond closure scope issue)\n const getNodeById = useCallback((id: string) => {\n return latestNodesRef.current.find(n => n.id === id);\n }, []);\n\n // Calculate zIndex based on target device view and handle metadata\n // -- Use always-current nodes to avoid closure/stale state bugs\n const calculateEdgeZIndex = useCallback((targetNodeId: string, targetHandle: string) => {\n const targetNode = getNodeById(targetNodeId);\n\n if (!targetNode || targetNode.type !== 'device') {\n return 1000; // Default high zIndex for non-device targets\n }\n\n // Use always-current data for .data and .handleSideMap\n const deviceView = targetNode.data?.view || 'front';\n const handleSideMap = (targetNode.data as any)?.handleSideMap || {};\n const handleSide = handleSideMap[targetHandle];\n\n let zIndex;\n if (handleSide) {\n // Use the actual handle side mapping from DeviceNode\n zIndex = deviceView === handleSide ? 1000 : 500;\n } else {\n // Fallback to simple logic for unknown handles\n const isPowerHandle = targetHandle.startsWith('pwr-left') || targetHandle.startsWith('power');\n const isNetworkHandle = targetHandle.startsWith('net-') || targetHandle.startsWith('port-') || targetHandle.startsWith('uplink-') || targetHandle.includes('Fiber') || targetHandle.includes('Ports');\n\n if (isPowerHandle) {\n zIndex = deviceView === 'rear' ? 1000 : 500;\n } else if (isNetworkHandle) {\n zIndex = deviceView === 'front' ? 1000 : 500;\n } else {\n zIndex = 1000;\n }\n }\n return zIndex;\n }, [getNodeById]);\n\n // Update edges zIndex when nodes change\n useEffect(() => {\n setEdges((eds) =>\n eds.map(edge => {\n const newZIndex = selectEdgeZIndex(edge as NetworkEdge);\n return {\n ...edge,\n zIndex: newZIndex,\n style: { ...edge.style, zIndex: newZIndex }\n };\n })\n );\n }, [reactFlowNodes, setEdges, selectEdgeZIndex]);\n\n useEffect(() => {\n const updatedNodes = reactFlowNodes.map(node => {\n if (\n node.type === 'device' &&\n node.parentId &&\n node.data.uPosition &&\n (!node.position || (node.position.x === 0 && node.position.y === 0))\n ) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const calculatedPosition = calculateDevicePositionFromU(parentRack as NetworkNode, node.data.uPosition);\n return {\n ...node,\n position: calculatedPosition,\n };\n }\n }\n return node;\n });\n\n const hasChanges = updatedNodes.some((node, index) =>\n node.position !== reactFlowNodes[index].position\n );\n if (hasChanges) {\n setNodes(updatedNodes);\n }\n }, [reactFlowNodes, setNodes, getNodeById]);\n\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n const updatedChanges = changes.map((change) => {\n if (change.type === 'position' && change.position) {\n const node = getNodeById(change.id);\n\n if (node && node.type === 'device' && node.parentId) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const snappedResult = snapToUPosition(\n node as NetworkNode,\n parentRack as NetworkNode,\n change.position,\n latestNodesRef.current as NetworkNode[]\n );\n\n if (snappedResult.uPosition !== undefined) {\n const updatedNode = {\n ...node,\n data: {\n ...node.data,\n uPosition: snappedResult.uPosition,\n },\n };\n\n setNodes((nodes) =>\n nodes.map(n => n.id === node.id ? updatedNode : n)\n );\n }\n\n return { ...change, position: { x: snappedResult.x, y: snappedResult.y } };\n }\n }\n\n if (node && node.type === 'device' && !node.parentId) {\n // Find the nearest rack\n const racks = latestNodesRef.current.filter(n => n.type === 'rack');\n let nearestRack: NetworkNode | null = null;\n let minDistance = Infinity;\n\n for (const rack of racks) {\n const rackNode = rack as NetworkNode;\n const distance = Math.sqrt(\n Math.pow(change.position.x - rackNode.position.x, 2) +\n Math.pow(change.position.y - rackNode.position.y, 2)\n );\n const rackWidth = 300;\n const rackHeight = (rackNode.data.uHeight || 42) * 20;\n const rackLeft = rackNode.position.x;\n const rackRight = rackNode.position.x + rackWidth;\n const rackTop = rackNode.position.y;\n const rackBottom = rackNode.position.y + rackHeight;\n\n if (\n change.position.x >= rackLeft && change.position.x <= rackRight &&\n change.position.y >= rackTop && change.position.y <= rackBottom\n ) {\n if (distance < minDistance) {\n minDistance = distance;\n nearestRack = rackNode;\n }\n }\n }\n\n if (nearestRack) {\n const updatedNode = {\n ...node,\n parentId: nearestRack.id,\n extent: 'parent' as const,\n data: {\n ...node.data,\n uPosition: 1,\n },\n };\n setNodes((nodes) =>\n nodes.map(n => n.id === node.id ? updatedNode : n)\n );\n const relativeX = change.position.x - nearestRack.position.x;\n const relativeY = change.position.y - nearestRack.position.y;\n return { ...change, position: { x: relativeX, y: relativeY } };\n }\n }\n\n if (node && node.type === 'device' && node.parentId) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const rackNode = parentRack as NetworkNode;\n const rackWidth = 300;\n const rackHeight = (rackNode.data.uHeight || 42) * 20;\n const rackLeft = rackNode.position.x;\n const rackRight = rackNode.position.x + rackWidth;\n const rackTop = rackNode.position.y;\n const rackBottom = rackNode.position.y + rackHeight;\n\n if (\n change.position.x < rackLeft || change.position.x > rackRight ||\n change.position.y < rackTop || change.position.y > rackBottom\n ) {\n const absoluteX = change.position.x + rackNode.position.x;\n const absoluteY = change.position.y + rackNode.position.y;\n const updatedNode = {\n ...node,\n parentId: undefined,\n extent: undefined,\n data: {\n ...node.data,\n uPosition: undefined,\n },\n };\n setNodes((nodes) =>\n nodes.map(n => n.id === node.id ? updatedNode : n)\n );\n return { ...change, position: { x: absoluteX, y: absoluteY } };\n }\n }\n }\n }\n return change;\n });\n\n onNodesChange(updatedChanges);\n }, [onNodesChange, setNodes, getNodeById]);\n\n // Connection validation - enforce single connection per handle and allow PDU → device power\n const isValidConnection = useCallback((connection: Connection): { valid: boolean; reason?: string } => {\n if (!connection.source || !connection.target || !connection.sourceHandle || !connection.targetHandle) {\n return { valid: true };\n }\n\n const sourceHandleId = connection.sourceHandle;\n const targetHandleId = connection.targetHandle;\n\n const sourceAlreadyConnected = latestEdgesRef.current.some(edge =>\n edge.source === connection.source && edge.sourceHandle === sourceHandleId\n );\n\n const targetAlreadyConnected = latestEdgesRef.current.some(edge =>\n edge.target === connection.target && edge.targetHandle === targetHandleId\n );\n\n if (sourceAlreadyConnected) {\n return { valid: false, reason: 'Source port is already connected' };\n }\n\n if (targetAlreadyConnected) {\n return { valid: false, reason: 'Target port is already connected' };\n }\n\n return { valid: true };\n }, []);\n\n const onConnect = useCallback(\n (params: Connection) => {\n const sourceNode = getNodeById(params.source!);\n const isPduSource = sourceNode?.type === 'vertical-pdu';\n const looksLikePowerTarget = !!params.targetHandle && (params.targetHandle.startsWith('pwr') || params.targetHandle.startsWith('power'));\n\n if (isPduSource && looksLikePowerTarget && params.target && params.targetHandle) {\n const existingTargetEdge = latestEdgesRef.current.find(e => e.target === params.target && e.targetHandle === params.targetHandle);\n if (existingTargetEdge) {\n const edgeToAdd = {\n ...params,\n type: 'power',\n zIndex: selectEdgeZIndex({ ...(params as any), id: 'temp-id' } as NetworkEdge)\n } as Connection;\n setEdges((eds) => {\n const filtered = eds.filter(e => e.id !== existingTargetEdge.id);\n return addEdge(edgeToAdd, filtered);\n });\n return;\n }\n }\n\n const validation = localStore.validateConnection({\n source: params.source ?? null,\n target: params.target ?? null,\n sourceHandle: params.sourceHandle ?? null,\n targetHandle: params.targetHandle ?? null,\n });\n if (!validation.valid) {\n if (isPduSource && params.source && params.sourceHandle) {\n const existingSourceEdge = latestEdgesRef.current.find(e => e.source === params.source && e.sourceHandle === params.sourceHandle);\n if (existingSourceEdge) {\n const edgeToAdd = {\n ...params,\n type: looksLikePowerTarget ? 'power' : 'fiber',\n zIndex: selectEdgeZIndex({ ...(params as any), id: 'temp-id' } as NetworkEdge)\n } as Connection;\n setEdges((eds) => {\n const filtered = eds.filter(e => e.id !== existingSourceEdge.id);\n return addEdge(edgeToAdd, filtered);\n });\n return;\n }\n }\n console.warn(`Connection rejected: ${validation.reason}`);\n return;\n }\n\n const edgeToAdd = {\n ...params,\n type: (isPduSource && looksLikePowerTarget) ? 'power' : 'fiber',\n zIndex: selectEdgeZIndex({ ...(params as any), id: 'temp-id' } as NetworkEdge),\n } as Connection;\n\n setEdges((eds) => addEdge(edgeToAdd, eds));\n },\n [setEdges, localStore, selectEdgeZIndex, getNodeById]\n );\n\n const handleNodeClick = useCallback(\n (event: React.MouseEvent, node: Node) => {\n const isCommandClick = event.metaKey || event.ctrlKey;\n\n if (isCommandClick && node.type === 'device') {\n const data = node.data || {};\n const currentView: 'front' | 'rear' = data.view || (Array.isArray(data.rearPorts) && data.rearPorts.length > 0 ? 'rear' : 'front');\n const nextView: 'front' | 'rear' = currentView === 'front' ? 'rear' : 'front';\n\n console.log(`Command+click: Toggling device ${node.id} from ${currentView} to ${nextView}`);\n\n // Use external onViewChange instead of internal state management\n if (onViewChange) {\n onViewChange(node.id, nextView);\n }\n\n onNodeClick && onNodeClick(node as NetworkNode);\n } else if (node.type !== 'device') {\n onNodeClick && onNodeClick(node as NetworkNode);\n }\n // Regular click on device: do nothing (let double-click handle it)\n },\n [onViewChange, onNodeClick]\n );\n\n // Double-click no longer removes edges to avoid accidental disconnects during interactions\n const handleNodeDoubleClick = useCallback(() => {}, []);\n\n const handleEdgeClick = useCallback(\n (event: React.MouseEvent, edge: Edge) => {\n if (onEdgeClick) {\n onEdgeClick(edge as NetworkEdge);\n }\n },\n [onEdgeClick]\n );\n\n // Track selection to show a toggle UI\n const [selectedNode, setSelectedNode] = useState<Node | null>(null);\n useOnSelectionChange({\n onChange: ({ nodes }) => {\n if (nodes && nodes.length === 1) {\n setSelectedNode(nodes[0]);\n } else {\n setSelectedNode(null);\n }\n },\n });\n\n const toggleSelectedFace = useCallback(() => {\n if (!selectedNode) return;\n const node = getNodeById(selectedNode.id);\n if (!node) return;\n\n if (node.type === 'rack') {\n const currentFace: 'front' | 'rear' = (node.data && (node.data as any).face) || 'front';\n const next: 'front' | 'rear' = currentFace === 'front' ? 'rear' : 'front';\n if (onRackFaceChange) {\n onRackFaceChange(node.id, next);\n } else {\n // Fallback: update rack face and propagate to child devices' view\n setNodes((nodes) => nodes.map(n => {\n if (n.id === node.id) {\n return { ...n, data: { ...n.data, face: next } } as any;\n }\n if (n.parentId === node.id) {\n return { ...n, data: { ...n.data, view: next } } as any;\n }\n return n;\n }));\n }\n return;\n }\n\n if (node.type === 'device') {\n const data: any = node.data || {};\n const hasRear = Array.isArray(data.rearPorts) && data.rearPorts.length > 0;\n const hasFront = Array.isArray(data.ports) && data.ports.length > 0;\n const currentView: 'front' | 'rear' = data.view || (hasRear && !hasFront ? 'rear' : 'front');\n const next: 'front' | 'rear' = currentView === 'front' ? 'rear' : 'front';\n if (onViewChange) {\n onViewChange(node.id, next);\n } else {\n setNodes((nodes) => nodes.map(n => n.id === node.id ? ({ ...n, data: { ...n.data, view: next } } as any) : n));\n }\n }\n }, [selectedNode, getNodeById, onRackFaceChange, onViewChange, setNodes]);\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n <ReactFlow\n nodes={reactFlowNodes}\n edges={reactFlowEdges}\n onNodesChange={(changes) => {\n handleNodesChange(changes);\n const next = changes.reduce((acc, change) => {\n if (change.type === 'add' || change.type === 'remove') return acc; // ignore adds/removes here\n return acc;\n }, null as null);\n if (!isControlled) {\n localStore.setState({ nodes: (latestNodesRef.current as any) });\n } else {\n externalOnNodesChange && externalOnNodesChange(latestNodesRef.current as any);\n }\n }}\n onEdgesChange={(changes) => {\n onEdgesChange(changes);\n if (!isControlled) {\n localStore.setState({ edges: (latestEdgesRef.current as any) });\n } else {\n externalOnEdgesChange && externalOnEdgesChange(latestEdgesRef.current as any);\n }\n }}\n onConnect={onConnect}\n onNodeClick={handleNodeClick}\n onNodeDoubleClick={handleNodeDoubleClick}\n onEdgeClick={handleEdgeClick}\n nodeTypes={memoizedNodeTypes}\n edgeTypes={memoizedEdgeTypes}\n defaultEdgeOptions={{\n zIndex: 1000,\n reconnectable: true\n }}\n fitView\n attributionPosition=\"bottom-left\"\n >\n <Background />\n <Controls />\n <MiniMap />\n </ReactFlow>\n {selectedNode && (selectedNode.type === 'rack' || selectedNode.type === 'device') && (\n <div\n style={{\n position: 'absolute',\n top: 12,\n right: 12,\n display: 'flex',\n gap: 8,\n zIndex: 2000,\n }}\n >\n <button\n onClick={(e) => { e.preventDefault(); toggleSelectedFace(); }}\n style={{\n background: '#374151',\n color: '#e5e7eb',\n border: '1px solid #4b5563',\n borderRadius: 4,\n padding: '6px 10px',\n fontSize: 11,\n fontFamily: 'monospace',\n cursor: 'pointer',\n }}\n title={(selectedNode.type === 'rack' ? (((selectedNode.data as any)?.face || 'front') === 'front' ? 'Switch to rear' : 'Switch to front') : ((((selectedNode.data as any)?.view) || ((Array.isArray((selectedNode.data as any)?.rearPorts) && (selectedNode.data as any).rearPorts.length > 0 && !(Array.isArray((selectedNode.data as any)?.ports) && (selectedNode.data as any).ports.length > 0)) ? 'rear' : 'front')) === 'front' ? 'Switch to rear' : 'Switch to front'))}\n >\n {selectedNode.type === 'rack'\n ? ((((selectedNode.data as any)?.face) || 'front') === 'front' ? '⇄ Rear' : '⇄ Front')\n : (((((selectedNode.data as any)?.view) || ((Array.isArray((selectedNode.data as any)?.rearPorts) && (selectedNode.data as any).rearPorts.length > 0 && !(Array.isArray((selectedNode.data as any)?.ports) && (selectedNode.data as any).ports.length > 0)) ? 'rear' : 'front'))) === 'front' ? '⇄ Rear' : '⇄ Front')}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const NetworkDiagram: React.FC<NetworkDiagramProps> = (props) => {\n return (\n <ReactFlowProvider>\n <NetworkDiagramInner {...props} />\n </ReactFlowProvider>\n );\n};\n","import { NetworkNode, NetworkEdge, NetBoxDevice, NetBoxRack, NetBoxCable } from '../types';\n\n/**\n * Convert NetBox rack data to NetworkNode\n */\nexport const netboxRackToNetworkNode = (rack: NetBoxRack): NetworkNode => {\n return {\n id: `rack-${rack.id}`,\n type: 'rack',\n position: { x: 0, y: 0 }, // Will be set by layout\n data: {\n label: rack.name,\n status: rack.status.value as 'active' | 'inactive' | 'maintenance',\n uHeight: rack.u_height,\n netboxId: rack.id,\n netboxType: 'rack',\n // Additional NetBox data\n facilityId: rack.facility_id,\n serial: rack.serial,\n assetTag: rack.asset_tag,\n site: rack.site.name,\n role: rack.role?.name,\n tenant: rack.tenant?.name,\n },\n };\n};\n\n/**\n * Convert NetBox device data to NetworkNode\n */\nexport const netboxDeviceToNetworkNode = (device: NetBoxDevice): NetworkNode => {\n return {\n id: `device-${device.id}`,\n type: 'device',\n position: { x: 0, y: 0 }, // Will be set by layout\n parentId: device.rack ? `rack-${device.rack.id}` : undefined,\n extent: device.rack ? 'parent' : undefined,\n data: {\n label: device.name,\n status: device.status.value as 'active' | 'inactive' | 'maintenance',\n deviceType: device.device_type.model,\n manufacturer: device.device_type.manufacturer.name,\n role: device.device_role.name,\n uHeight: 1, // Default, should be from device type\n uPosition: device.position || 1,\n face: device.face || 'front',\n netboxId: device.id,\n netboxType: 'device',\n // Additional NetBox data\n primaryIp4: device.primary_ip4?.address,\n primaryIp6: device.primary_ip6?.address,\n site: device.site.name,\n rack: device.rack?.name,\n },\n };\n};\n\n/**\n * Convert NetBox cable data to NetworkEdge\n */\nexport const netboxCableToNetworkEdge = (cable: NetBoxCable): NetworkEdge => {\n return {\n id: `cable-${cable.id}`,\n source: `device-${cable.termination_a.device.name}`,\n target: `device-${cable.termination_b.device.name}`,\n type: 'fiber',\n data: {\n bandwidth: cable.type.label,\n length: cable.length || 0,\n color: cable.color,\n netboxId: cable.id,\n netboxType: 'cable',\n status: cable.status.value,\n terminationA: cable.termination_a.name,\n terminationB: cable.termination_b.name,\n },\n };\n};\n\n/**\n * Convert NetBox data to network diagram format\n */\nexport const netboxToNetworkDiagram = (data: {\n racks: NetBoxRack[];\n devices: NetBoxDevice[];\n cables: NetBoxCable[];\n}): { nodes: NetworkNode[]; edges: NetworkEdge[] } => {\n const nodes: NetworkNode[] = [];\n const edges: NetworkEdge[] = [];\n\n // Convert racks\n data.racks.forEach(rack => {\n nodes.push(netboxRackToNetworkNode(rack));\n });\n\n // Convert devices\n data.devices.forEach(device => {\n nodes.push(netboxDeviceToNetworkNode(device));\n });\n\n // Convert cables\n data.cables.forEach(cable => {\n edges.push(netboxCableToNetworkEdge(cable));\n });\n\n return { nodes, edges };\n};\n\n/**\n * Calculate U position for devices in a rack\n */\nexport const calculateUPositions = (devices: NetBoxDevice[], rackHeight: number): Map<number, number> => {\n const positions = new Map<number, number>();\n const usedPositions = new Set<number>();\n\n // Sort devices by position\n const sortedDevices = devices\n .filter(d => d.position !== null)\n .sort((a, b) => (a.position || 0) - (b.position || 0));\n\n sortedDevices.forEach(device => {\n if (device.position) {\n positions.set(device.id, device.position);\n usedPositions.add(device.position);\n }\n });\n\n return positions;\n};\n\n/**\n * Generate layout positions for nodes\n */\nexport const generateLayout = (nodes: NetworkNode[]): NetworkNode[] => {\n const rackNodes = nodes.filter(n => n.type === 'rack');\n const deviceNodes = nodes.filter(n => n.type === 'device');\n const otherNodes = nodes.filter(n => !['rack', 'device'].includes(n.type));\n\n // Position racks\n rackNodes.forEach((rack, index) => {\n rack.position = { x: index * 300, y: 100 };\n });\n\n // Position devices relative to their parent racks\n deviceNodes.forEach(device => {\n if (device.parentId) {\n const parentRack = rackNodes.find(r => r.id === device.parentId);\n if (parentRack) {\n const uPosition = device.data.uPosition || 1;\n const uHeight = device.data.uHeight || 1;\n device.position = {\n x: parentRack.position.x + 50,\n y: parentRack.position.y + (uPosition * 20) - (uHeight * 10),\n };\n }\n } else {\n // Position orphaned devices\n device.position = { x: Math.random() * 400 + 100, y: Math.random() * 200 + 50 };\n }\n });\n\n // Position other nodes\n otherNodes.forEach((node, index) => {\n node.position = { x: index * 150 + 100, y: 300 };\n });\n\n return nodes;\n};\n","import { NetworkNode, RackConfig, RackDevice, Width } from '../types';\nimport { calculateDevicePositionFromU, isUPositionAvailable, findNextAvailableUPosition } from './u-positioning';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from './constants';\n\n/**\n * Configuration options for building nodes from rack schema\n */\nexport interface RackSchemaOptions {\n /** How to handle device placement conflicts */\n conflictPolicy?: 'strict' | 'nearest';\n /** Whether to validate all placements before creating nodes */\n validatePlacements?: boolean;\n /** Custom device type mapping from schema to NetworkNode type */\n deviceTypeMapping?: Record<string, NetworkNode['type']>;\n}\n\n/**\n * Error thrown when device placement conflicts occur in strict mode\n */\nexport class DevicePlacementError extends Error {\n constructor(\n public rackId: string,\n public deviceId: string,\n public uPosition: number,\n public uHeight: number,\n public conflictWith?: string\n ) {\n super(\n `Device placement conflict: ${deviceId} at U${uPosition}-${uPosition + uHeight - 1} in rack ${rackId}${\n conflictWith ? ` conflicts with ${conflictWith}` : ''\n }`\n );\n this.name = 'DevicePlacementError';\n }\n}\n\n/**\n * Validation result for device placement\n */\nexport interface DevicePlacementValidation {\n isValid: boolean;\n conflicts: Array<{\n deviceId: string;\n uPosition: number;\n uHeight: number;\n conflictWith: string;\n }>;\n outOfBounds: Array<{\n deviceId: string;\n uPosition: number;\n uHeight: number;\n rackUHeight: number;\n }>;\n}\n\n/**\n * Validate device placements within a rack schema\n */\nexport function validateRackDevicePlacements(\n rack: RackConfig,\n options: RackSchemaOptions = {}\n): DevicePlacementValidation {\n const { conflictPolicy = 'strict' } = options;\n const conflicts: DevicePlacementValidation['conflicts'] = [];\n const outOfBounds: DevicePlacementValidation['outOfBounds'] = [];\n \n // Check for out-of-bounds placements\n for (const device of rack.devices) {\n const deviceEnd = device.unit + device.height - 1;\n if (deviceEnd > rack.units) {\n outOfBounds.push({\n deviceId: device.id,\n uPosition: device.unit,\n uHeight: device.height,\n rackUHeight: rack.units,\n });\n }\n }\n \n // Check for device-to-device conflicts\n for (let i = 0; i < rack.devices.length; i++) {\n const deviceA = rack.devices[i];\n const deviceAStart = deviceA.unit;\n const deviceAEnd = deviceA.unit + deviceA.height - 1;\n \n for (let j = i + 1; j < rack.devices.length; j++) {\n const deviceB = rack.devices[j];\n const deviceBStart = deviceB.unit;\n const deviceBEnd = deviceB.unit + deviceB.height - 1;\n \n // Check for overlap using 1a rule (start to start+height-1)\n if (deviceAStart <= deviceBEnd && deviceAEnd >= deviceBStart) {\n conflicts.push({\n deviceId: deviceA.id,\n uPosition: deviceA.unit,\n uHeight: deviceA.height,\n conflictWith: deviceB.id,\n });\n }\n }\n }\n \n return {\n isValid: conflicts.length === 0 && outOfBounds.length === 0,\n conflicts,\n outOfBounds,\n };\n}\n\n/**\n * Convert a RackDevice to NetworkNode with proper U positioning\n */\nfunction createDeviceNode(\n device: RackDevice,\n rack: NetworkNode,\n options: RackSchemaOptions = {}\n): NetworkNode {\n const { deviceTypeMapping = {} } = options;\n \n // Map device type to NetworkNode type\n const nodeType = deviceTypeMapping[device.type] || 'device';\n \n // Calculate pixel position from U position\n const position = calculateDevicePositionFromU(rack, device.unit);\n \n \n return {\n id: device.id,\n type: nodeType,\n position,\n parentId: rack.id,\n extent: 'parent',\n data: {\n label: device.name,\n status: 'active', // Default status\n deviceType: device.type,\n uHeight: device.height,\n uPosition: device.unit,\n width: device.width || Width.FULL,\n // view is controlled at node-level; default computed in DeviceNode when absent\n role: device.role, // Pass through the role property\n ports: device.ports,\n rearPorts: device.rearPorts,\n connections: device.connections,\n },\n };\n}\n\n/**\n * Convert a RackConfig to NetworkNode\n */\nfunction createRackNode(rack: RackConfig): NetworkNode {\n return {\n id: rack.id,\n type: 'rack',\n position: rack.position,\n data: {\n label: rack.name,\n status: 'active',\n uHeight: rack.units,\n ports: [], // Default empty array, can be overridden\n },\n };\n}\n\n/**\n * Build NetworkNode array from RackConfig array with comprehensive validation\n */\nexport function buildNodesFromRackConfig(\n racks: RackConfig[],\n options: RackSchemaOptions = {}\n): NetworkNode[] {\n const { conflictPolicy = 'strict', validatePlacements = true } = options;\n const nodes: NetworkNode[] = [];\n const deviceNodes: NetworkNode[] = [];\n \n // Validate all racks first if requested\n if (validatePlacements) {\n for (const rack of racks) {\n const validation = validateRackDevicePlacements(rack, options);\n \n if (!validation.isValid) {\n if (conflictPolicy === 'strict') {\n // Report all conflicts and out-of-bounds\n const errors: string[] = [];\n \n validation.conflicts.forEach(conflict => {\n errors.push(\n `Device ${conflict.deviceId} at U${conflict.uPosition}-${conflict.uPosition + conflict.uHeight - 1} conflicts with ${conflict.conflictWith}`\n );\n });\n \n validation.outOfBounds.forEach(bound => {\n errors.push(\n `Device ${bound.deviceId} at U${bound.uPosition}-${bound.uPosition + bound.uHeight - 1} exceeds rack height (${bound.rackUHeight}U)`\n );\n });\n \n throw new DevicePlacementError(\n rack.id,\n validation.conflicts[0]?.deviceId || validation.outOfBounds[0]?.deviceId || 'unknown',\n validation.conflicts[0]?.uPosition || validation.outOfBounds[0]?.uPosition || 1,\n validation.conflicts[0]?.uHeight || validation.outOfBounds[0]?.uHeight || 1\n );\n }\n }\n }\n }\n \n // Create rack nodes first (required for device parent references)\n for (const rack of racks) {\n const rackNode = createRackNode(rack);\n nodes.push(rackNode);\n \n // Create device nodes for this rack\n for (const device of rack.devices) {\n try {\n const deviceNode = createDeviceNode(device, rackNode, options);\n deviceNodes.push(deviceNode);\n } catch (error) {\n if (conflictPolicy === 'strict') {\n throw error;\n } else if (conflictPolicy === 'nearest') {\n // Try to find nearest available position\n const availablePosition = findNextAvailableUPosition(\n rackNode,\n { id: device.id, type: 'device', position: { x: 0, y: 0 }, data: { label: device.name, uHeight: device.height } } as NetworkNode,\n deviceNodes,\n device.unit\n );\n \n if (availablePosition !== device.unit) {\n console.warn(\n `Device ${device.id} moved from U${device.unit} to U${availablePosition} due to conflict`\n );\n \n const adjustedDevice = { ...device, unit: availablePosition };\n const deviceNode = createDeviceNode(adjustedDevice, rackNode, options);\n deviceNodes.push(deviceNode);\n } else {\n throw new DevicePlacementError(rack.id, device.id, device.unit, device.height);\n }\n }\n }\n }\n }\n \n // Add device nodes after all rack nodes\n nodes.push(...deviceNodes);\n \n return nodes;\n}\n\n/**\n * Create a RackConfig from existing NetworkNode data (reverse operation)\n */\nexport function createRackConfigFromNodes(nodes: NetworkNode[]): RackConfig[] {\n const racks: RackConfig[] = [];\n const rackNodes = nodes.filter(node => node.type === 'rack');\n \n for (const rackNode of rackNodes) {\n const deviceNodes = nodes.filter(\n node => node.type === 'device' && node.parentId === rackNode.id\n );\n \n const devices: RackDevice[] = deviceNodes.map(deviceNode => ({\n id: deviceNode.id,\n name: deviceNode.data.label,\n unit: deviceNode.data.uPosition || 1,\n height: deviceNode.data.uHeight || 1,\n type: (deviceNode.data.deviceType as RackDevice['type']) || 'server',\n width: deviceNode.data.width,\n ports: deviceNode.data.ports,\n connections: deviceNode.data.connections,\n }));\n \n racks.push({\n id: rackNode.id,\n name: rackNode.data.label,\n position: rackNode.position,\n units: rackNode.data.uHeight || 42,\n devices,\n });\n }\n \n return racks;\n}\n\n/**\n * Update device U position in a rack schema\n */\nexport function updateDeviceUPosition(\n racks: RackConfig[],\n rackId: string,\n deviceId: string,\n newUPosition: number\n): RackConfig[] {\n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n return {\n ...rack,\n devices: rack.devices.map(device => {\n if (device.id !== deviceId) return device;\n return { ...device, unit: newUPosition };\n }),\n };\n });\n}\n\n/**\n * Add a device to a rack schema\n */\nexport function addDeviceToRack(\n racks: RackConfig[],\n rackId: string,\n device: RackDevice,\n options: RackSchemaOptions = {}\n): RackConfig[] {\n const { conflictPolicy = 'strict' } = options;\n \n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n // Check for conflicts if in strict mode\n if (conflictPolicy === 'strict') {\n const validation = validateRackDevicePlacements(\n { ...rack, devices: [...rack.devices, device] },\n options\n );\n \n if (!validation.isValid) {\n throw new DevicePlacementError(rackId, device.id, device.unit, device.height);\n }\n }\n \n return {\n ...rack,\n devices: [...rack.devices, device],\n };\n });\n}\n\n/**\n * Remove a device from a rack schema\n */\nexport function removeDeviceFromRack(\n racks: RackConfig[],\n rackId: string,\n deviceId: string\n): RackConfig[] {\n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n return {\n ...rack,\n devices: rack.devices.filter(device => device.id !== deviceId),\n };\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/u-positioning.ts","../src/utils/status-colors.ts","../src/components/RackNode.tsx","../src/components/FiberNode.tsx","../src/components/FiberEdge.tsx","../src/components/PowerEdge.tsx","../src/types/index.ts","../src/utils/power-connectors.ts","../src/components/DeviceNode.tsx","../src/components/VerticalPDU.tsx","../src/core/store.ts","../src/core/hooks.ts","../src/utils/rack-geometry.ts","../src/utils/edge-connection.ts","../src/components/NetworkDiagram.tsx","../src/utils/inventory.ts","../src/utils/rack-schema.ts"],"names":["getDefaultUNumberingDirection","getRackUNumberingDirection","rack","convertUPositionForDirection","uPosition","rackUHeight","direction","convertUPositionFromDirection","snapToUPosition","device","newPosition","allNodes","uHeight","startY","relativeY","physicalUPosition","calculatedUPosition","maxUPosition","snappedUPosition","isUPositionAvailable","availablePosition","findNextAvailableUPosition","snappedY","topLogicalUPosition","topPhysicalUPosition","snappedPhysicalUPosition","deviceUHeight","rackDevices","node","otherDevice","otherUPosition","otherUHeight","newDeviceStart","newDeviceEnd","otherDeviceStart","otherDeviceEnd","startFrom","u","calculateDevicePositionFromU","deviceHeight","deviceY","updateDeviceUPosition","newUPosition","validateAndSnapDevice","currentUPosition","validUPosition","getStatusColor","status","RackNode","data","selected","id","onViewChange","onRackFaceChange","isDragOver","label","ports","face","customHeaderText","getNodes","setNodes","useReactFlow","nodes","showUMarkers","setShowUMarkers","useState","toggleUNumberingDirection","newDirection","n","toggleFace","next","child","renderUPositions","positions","i","yPos","displayNumber","jsx","jsxs","e","FiberNode","Handle","Position","FiberEdge","sourceX","sourceY","targetX","targetY","sourcePosition","targetPosition","style","edgePath","labelX","labelY","getBezierPath","bandwidth","length","color","edgeStyle","Fragment","BaseEdge","EdgeLabelRenderer","PowerEdge","markerEnd","connectorType","baseStyle","Width","POWER_CONNECTORS","getPowerPortStyle","connector","isHighPower","width","height","cornerStyle","getConnectorConfig","isHighPowerConnector","getPDUPortType","portIndex","getDeviceConnectorType","deviceName","name","DeviceNode","deviceType","manufacturer","role","rearPorts","view","currentFace","handleSideMap","portBlock","port","handleId","rackDeviceWidth","rackDeviceLeft","renderPortsFromArray","portBlocks","position","handles","portWidth","portHeight","_blockIndex","isPower","isConnected","portColor","handlePosition","handleStyle","baseTop","spacing","portStyle","isPatchPanel","handleType","oppositeType","renderHandles","renderAGGSwitchHandles","isSwitch","port1Top","port2Top","handle","bottomIndex","uplinkWidth","uplinkHeight","VerticalPDU","heightCm","powerPorts","widthPx","mgmt_unit","heightPx","renderPowerHandles","nCycles","portsPerCycle","_","c","idx","headerHeight","portSpacing","renderMgmtUnit","portType","leftPx","defaultValidateConnection","params","ctx","sourceAlready","targetAlready","sourceHandleId","targetHandleId","sourceNode","targetNode","isPowerHandle","h","looksLikeDevicePower","isPduPower","isNetworkHandle","looksLikeNetwork","isCustomPortName","sourceIsPower","targetIsPower","sourceIsNetwork","targetIsNetwork","isPduSource","isPduTarget","deviceNode","pduNode","eSourceIsPower","eTargetIsPower","involvesDevice","getHandleSide","frontBlocks","rearBlocks","block","createNetworkDiagramStore","initial","options","state","listeners","partial","l","listener","edge","deviceView","side","targetHandle","targetHandleLc","isStandardNetworkHandle","nodeId","useNetworkDiagram","store","subscribe","cb","getSnapshot","useSyncExternalStore","useNodes","useEdges","useSelectEdgeZIndex","getRackBounds","rackWidth","rackHeight","rackLeft","rackRight","rackTop","rackBottom","isPointInRack","point","bounds","findNearestRack","racks","nearestRack","minDistance","distance","replaceEdge","edges","connection","edgeType","selectEdgeZIndex","findBy","existingEdge","filtered","edgeFromAddEdge","addEdge","newEdge","edgeWithMetadata","createNodeTypes","dragOverRackId","props","edgeTypes","NetworkDiagramInner","initialNodes","initialEdges","externalOnNodesChange","externalOnEdgesChange","debug","onNodeClick","onEdgeClick","className","alignRacksToBottom","colorMode","onInit","onFlowMethods","showDownloadButton","downloadButtonPosition","downloadButtonText","downloadButtonStyle","isControlled","localStore","React","storeNodes","storeEdges","reactFlowNodes","onNodesChange","useNodesState","reactFlowEdges","setEdges","onEdgesChange","useEdgesState","reactFlowWrapper","useRef","toObject","setViewport","setReactFlowNodes","setReactFlowEdges","useEffect","toPng","onDownload","useCallback","dataUrl","link","error","setDragOverRackId","memoizedNodeTypes","useMemo","memoizedEdgeTypes","latestNodesRef","latestEdgesRef","rackBottoms","r","minBottom","maxBottom","baselineBottom","nextNodes","currentBottom","delta","getNodeById","eds","newZIndex","updatedNodes","parentRack","calculatedPosition","index","handleNodesChange","changes","updatedChanges","change","snappedResult","updatedNode","rackNode","absoluteX","absoluteY","handleNodeDragStart","_event","_node","handleNodeDrag","_nodes","handleNodeDragStop","relativeX","sourceAlreadyConnected","targetAlreadyConnected","onConnect","sourceNodeData","isSwitchSource","looksLikePowerTarget","looksLikeNetworkTarget","newEdges","validation","edgeToAdd","handleNodeClick","event","currentView","nextView","handleNodeDoubleClick","handleEdgeClick","selectedNode","setSelectedNode","useOnSelectionChange","toggleSelectedFace","nodeData","hasRear","hasFront","ReactFlow","Background","Controls","MiniMap","Panel","NetworkDiagram","ReactFlowProvider","inventoryRackToNetworkNode","inventoryDeviceToNetworkNode","inventoryCableToNetworkEdge","cable","getDeviceId","term","dev","termADeviceId","termBDeviceId","inventoryToNetworkDiagram","generateLayout","rackNodes","deviceNodes","otherNodes","DevicePlacementError","rackId","deviceId","conflictWith","validateRackDevicePlacements","_options","conflicts","outOfBounds","deviceA","deviceAStart","deviceAEnd","j","deviceB","deviceBStart","deviceBEnd","createDeviceNode","deviceTypeMapping","nodeType","createRackNode","buildNodesFromRackConfig","conflictPolicy","validatePlacements","errors","conflict","bound","adjustedDevice","createRackConfigFromNodes","devices","addDeviceToRack","removeDeviceFromRack"],"mappings":"mQAMO,IAAMA,EAAAA,CAAgC,IAA2B,WAAA,CAK3DC,EAAAA,CAA8BC,CAAAA,EAClCA,CAAAA,CAAK,IAAA,CAAK,mBAAA,EAAuBF,EAAAA,EAA8B,CAQ3DG,EAAAA,CAA+B,CAC1CC,EACAC,CAAAA,CACAC,CAAAA,GAEIA,CAAAA,GAAc,WAAA,CAETD,CAAAA,CAAcD,CAAAA,CAAY,CAAA,CAG5BA,CAAAA,CAMIG,EAAAA,CAAgC,CAC3CH,CAAAA,CACAC,CAAAA,CACAC,CAAAA,GAEIA,CAAAA,GAAc,WAAA,CAETD,CAAAA,CAAcD,CAAAA,CAAY,CAAA,CAG5BA,CAAAA,CAuBF,IAAMI,EAAAA,CAAkB,CAC7BC,CAAAA,CACAP,CAAAA,CACAQ,CAAAA,CACAC,CAAAA,GACiD,CACjD,GAAI,CAACF,CAAAA,CAAO,QAAA,EAAYA,CAAAA,CAAO,WAAaP,CAAAA,CAAK,EAAA,CAC/C,OAAOQ,CAAAA,CAGT,IAAME,CAAAA,CAAUH,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACjCJ,CAAAA,CAAcH,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,CACnCI,CAAAA,CAAYL,EAAAA,CAA2BC,CAAI,CAAA,CAG3CW,CAAAA,CAAS,EAAA,CAITC,CAAAA,CAAYJ,CAAAA,CAAY,CAAA,CAAIG,CAAAA,CAC5BE,CAAAA,CAAoB,IAAA,CAAK,KAAA,CAAMD,CAAAA,CAAY,EAAW,CAAA,CAAI,CAAA,CAK5DE,EACAV,CAAAA,GAAc,WAAA,CAKhBU,CAAAA,CADwBb,EAAAA,CAA6BY,CAAAA,CAAmBV,CAAAA,CAAaC,CAAS,CAAA,CACtDM,CAAAA,CAAU,CAAA,CAIlDI,CAAAA,CADwBb,EAAAA,CAA6BY,CAAAA,CAAmBV,CAAAA,CAAaC,CAAS,CAAA,CAMhG,IAAMW,CAAAA,CAAeZ,CAAAA,CAAcO,CAAAA,CAAU,CAAA,CACzCM,CAAAA,CAAmB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,GAAA,CAAID,CAAAA,CAAcD,CAAmB,CAAC,CAAA,CAuB9E,GApBIV,IAAc,UAAA,EAAcU,CAAAA,EAAuB,CAAA,GACrDE,CAAAA,CAAmB,CAAA,CAAA,CAmBjB,CAACC,EAAAA,CAAqBjB,CAAAA,CAAMO,CAAAA,CAAQS,CAAAA,CAAkBP,CAAQ,CAAA,CAAG,CAEnE,IAAMS,CAAAA,CAAoBC,EAAAA,CAA2BnB,CAAAA,CAAMO,CAAAA,CAAQE,CAAAA,CAAUO,CAAgB,CAAA,CACzFE,CAAAA,GAAsBF,CAAAA,GACxBA,CAAAA,CAAmBE,CAAAA,EAEvB,CAMA,IAAIE,CAAAA,CACJ,GAAIhB,CAAAA,GAAc,WAAA,CAAa,CAG7B,IAAMiB,CAAAA,CAAsBL,CAAAA,CAAmBN,CAAAA,CAAU,CAAA,CACnDY,CAAAA,CAAuBjB,EAAAA,CAA8BgB,CAAAA,CAAqBlB,CAAAA,CAAaC,CAAS,CAAA,CACtGgB,CAAAA,CAAWT,CAAAA,CAAAA,CAAUW,CAAAA,CAAuB,CAAA,EAAK,EAAA,CAAc,EACjE,CAAA,KAAO,CAEL,IAAMC,CAAAA,CAA2BlB,EAAAA,CAA8BW,CAAAA,CAAkBb,CAAAA,CAAaC,CAAS,CAAA,CACvGgB,CAAAA,CAAWT,CAAAA,CAAAA,CAAUY,CAAAA,CAA2B,CAAA,EAAK,EAAA,CAAc,EACrE,CAEA,OAAO,CACL,CAAA,CAAGf,CAAAA,CAAY,CAAA,CACf,CAAA,CAAGY,CAAAA,CACH,SAAA,CAAWJ,CACb,CACF,CAAA,CAKaC,EAAAA,CAAuB,CAClCjB,CAAAA,CACAO,CAAAA,CACAL,CAAAA,CACAO,CAAAA,GACY,CACZ,IAAMe,CAAAA,CAAgBjB,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACvCJ,CAAAA,CAAcH,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,CAGzC,GAAIE,CAAAA,CAAY,CAAA,EAAKA,CAAAA,CAAYsB,EAAgB,CAAA,CAAIrB,CAAAA,CACnD,OAAO,MAAA,CAIT,IAAMsB,CAAAA,CAAchB,CAAAA,CAAS,MAAA,CAAOiB,CAAAA,EAClCA,CAAAA,CAAK,IAAA,GAAS,QAAA,EACdA,CAAAA,CAAK,QAAA,GAAa1B,CAAAA,CAAK,EAAA,EACvB0B,CAAAA,CAAK,EAAA,GAAOnB,CAAAA,CAAO,EACrB,CAAA,CAEA,IAAA,IAAWoB,CAAAA,IAAeF,CAAAA,CAAa,CACrC,IAAMG,CAAAA,CAAiBD,CAAAA,CAAY,IAAA,CAAK,SAAA,EAAa,CAAA,CAC/CE,CAAAA,CAAeF,EAAY,IAAA,CAAK,OAAA,EAAW,CAAA,CAG3CG,CAAAA,CAAiB5B,CAAAA,CACjB6B,CAAAA,CAAe7B,CAAAA,CAAYsB,CAAAA,CAAgB,CAAA,CAC3CQ,CAAAA,CAAmBJ,CAAAA,CACnBK,CAAAA,CAAiBL,CAAAA,CAAiBC,CAAAA,CAAe,CAAA,CAEvD,GAAIC,CAAAA,EAAkBG,CAAAA,EAAkBF,CAAAA,EAAgBC,CAAAA,CACtD,OAAO,MAEX,CAEA,OAAO,KACT,CAAA,CAKab,EAAAA,CAA6B,CACxCnB,CAAAA,CACAO,CAAAA,CACAE,CAAAA,CACAyB,CAAAA,CAAoB,IACT,CACX,IAAMV,CAAAA,CAAgBjB,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACvCJ,CAAAA,CAAcH,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,CAEzC,IAAA,IAASmC,CAAAA,CAAID,CAAAA,CAAWC,CAAAA,EAAKhC,CAAAA,CAAcqB,CAAAA,CAAgB,CAAA,CAAGW,CAAAA,EAAAA,CAC5D,GAAIlB,EAAAA,CAAqBjB,CAAAA,CAAMO,CAAAA,CAAQ4B,CAAAA,CAAG1B,CAAQ,CAAA,CAChD,OAAO0B,CAAAA,CAIX,OAAO,CACT,CAAA,CAKaC,GAA+B,CAC1CpC,CAAAA,CACAE,CAAAA,CACAmC,CAAAA,CAAuB,CAAA,GACM,CAC7B,IAAM1B,CAAAA,CAAS,EAAA,CACTP,CAAAA,CAAYL,EAAAA,CAA2BC,CAAI,CAAA,CAC3CG,CAAAA,CAAcH,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,CAGnCa,CAAAA,CAAoBR,EAAAA,CAA8BH,CAAAA,CAAWC,CAAAA,CAAaC,CAAS,CAAA,CAIrFkC,CAAAA,CACJ,GAAIlC,CAAAA,GAAc,WAAA,CAAa,CAG7B,IAAMiB,CAAAA,CAAsBnB,CAAAA,CAAYmC,EAAe,CAAA,CACjDf,CAAAA,CAAuBjB,EAAAA,CAA8BgB,CAAAA,CAAqBlB,CAAAA,CAAaC,CAAS,CAAA,CACtGkC,CAAAA,CAAU3B,CAAAA,CAAAA,CAAUW,CAAAA,CAAuB,CAAA,EAAK,EAAA,CAAc,EAChE,CAAA,KAEEgB,CAAAA,CAAU3B,CAAAA,CAAAA,CAAUE,CAAAA,CAAoB,CAAA,EAAK,EAAA,CAAc,CAAA,CAG7D,OAAO,CACL,CAAA,CAAG,CAAA,CACH,CAAA,CAAGyB,CACL,CACF,CAAA,CAKaC,EAAAA,CAAwB,CACnChC,CAAAA,CACAP,CAAAA,CACAwC,IACgB,CAChB,IAAMH,CAAAA,CAAe9B,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACtCC,CAAAA,CAAc4B,EAAAA,CAA6BpC,CAAAA,CAAMwC,CAAAA,CAAcH,CAAY,CAAA,CAEjF,OAAO,CACL,GAAG9B,CAAAA,CACH,QAAA,CAAUC,CAAAA,CACV,IAAA,CAAM,CACJ,GAAGD,CAAAA,CAAO,IAAA,CACV,SAAA,CAAWiC,CACb,CACF,CACF,CAAA,CAKaC,EAAAA,CAAwB,CACnClC,CAAAA,CACAP,IACgB,CAChB,IAAM0C,CAAAA,CAAmBnC,CAAAA,CAAO,IAAA,CAAK,SAAA,EAAa,CAAA,CAC5CiB,CAAAA,CAAgBjB,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACvCJ,CAAAA,CAAcH,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,CAGnC2C,CAAAA,CAAiB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,GAAA,CAAIxC,CAAAA,CAAcqB,CAAAA,CAAgB,CAAA,CAAGkB,CAAgB,CAAC,CAAA,CAE9F,OAAIC,CAAAA,GAAmBD,CAAAA,CACdH,GAAsBhC,CAAAA,CAAQP,CAAAA,CAAM2C,CAAc,CAAA,CAGpDpC,CACT,ECvSO,SAASqC,CAAAA,CAAeC,CAAAA,CAAuC,CACpE,OAAQA,CAAAA,EACN,KAAK,QAAA,CACH,OAAO,SAAA,CACT,KAAK,UAAA,CACH,OAAO,SAAA,CACT,KAAK,aAAA,CACH,OAAO,SAAA,CACT,QACE,OAAO,SACX,CACF,CCNO,IAAMC,EAAAA,CAAoC,CAAC,CAAE,IAAA,CAAAC,CAAAA,CAAM,QAAA,CAAAC,CAAAA,CAAU,EAAA,CAAAC,CAAAA,CAAI,YAAA,CAAAC,CAAAA,CAAc,gBAAA,CAAAC,CAAAA,CAAkB,UAAA,CAAAC,CAAAA,CAAa,KAAM,CAAA,GAAM,CAC/H,GAAM,CACJ,KAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CAAQ,CAAA,CACR,MAAA,CAAAT,CAAAA,CAAS,QAAA,CACT,OAAA,CAAAnC,EAAU,EAAA,CACV,IAAA,CAAA6C,CAAAA,CAAO,OAAA,CACP,gBAAA,CAAAC,CACF,CAAA,CAAIT,CAAAA,CAEE,CAAE,QAAA,CAAAU,CAAAA,CAAU,QAAA,CAAAC,CAAS,CAAA,CAAIC,sBAAAA,EAAa,CACtCC,CAAAA,CAAQH,CAAAA,EAAS,CACjB,CAACI,CAAAA,CAAcC,CAAe,CAAA,CAAIC,WAAAA,CAAS,IAAI,CAAA,CAE/CC,CAAAA,CAA4B,IAAM,CAEtC,IAAMC,CAAAA,CADmBlE,EAAAA,CAA2B,CAAE,IAAA,CAAAgD,CAAK,CAAgB,CAAA,GACZ,WAAA,CAAc,UAAA,CAAa,WAAA,CAE1FW,CAAAA,CAASE,CAAAA,EAASA,CAAAA,CAAM,GAAA,CAAIM,CAAAA,EAC1BA,CAAAA,CAAE,EAAA,GAAOjB,CAAAA,CACL,CAAE,GAAGiB,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,mBAAA,CAAqBD,CAAa,CAAE,CAAA,CAC/DC,CACN,CAAC,EACH,CAAA,CAGMC,CAAAA,CAAa,IAAM,CACvB,IAAMC,CAAAA,CAAOb,CAAAA,GAAS,OAAA,CAAU,MAAA,CAAS,OAAA,CAErCJ,CAAAA,EACFA,CAAAA,CAAiBF,CAAAA,CAAImB,CAAI,CAAA,CAErBlB,CAAAA,EACiBU,CAAAA,CAAM,MAAA,CAAOM,CAAAA,EAAKA,CAAAA,CAAE,QAAA,GAAajB,CAAE,CAAA,CAC3C,OAAA,CAAQoB,CAAAA,EAAS,CAC1BnB,CAAAA,CAAamB,CAAAA,CAAM,EAAA,CAAID,CAAI,EAC7B,CAAC,CAAA,EAEMlB,CAAAA,CAEUU,CAAAA,CAAM,OAAOM,CAAAA,EAAKA,CAAAA,CAAE,QAAA,GAAajB,CAAE,CAAA,CAC3C,OAAA,CAAQoB,CAAAA,EAAS,CAC1BnB,CAAAA,CAAamB,CAAAA,CAAM,EAAA,CAAID,CAAI,EAC7B,CAAC,CAAA,CAGDV,CAAAA,CAASE,CAAAA,EAASA,CAAAA,CAAM,GAAA,CAAIM,CAAAA,EAC1BA,CAAAA,CAAE,EAAA,GAAOjB,CAAAA,CACL,CAAE,GAAGiB,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,IAAA,CAAME,CAAK,CAAE,CAAA,CACxCF,CAAAA,CAAE,QAAA,GAAajB,CAAAA,CACb,CAAE,GAAGiB,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,IAAA,CAAME,CAAK,CAAE,CAAA,CACxCF,CACR,CAAC,EAEL,CAAA,CAGMI,CAAAA,CAAmB,IAAM,CAC7B,IAAMC,CAAAA,CAAY,EAAC,CACb5D,CAAAA,CAAS,EAAA,CACTP,CAAAA,CAAYL,EAAAA,CAA2B,CAAE,IAAA,CAAAgD,CAAK,CAAgB,CAAA,CAEpE,IAAA,IAASyB,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAK9D,CAAAA,CAAS8D,CAAAA,EAAAA,CAAK,CACjC,IAAMC,CAAAA,CAAO9D,CAAAA,CAAAA,CAAU6D,CAAAA,CAAI,CAAA,EAAK,EAAA,CAAc,CAAA,CAExCE,CAAAA,CAAgBzE,EAAAA,CAA6BuE,CAAAA,CAAG9D,CAAAA,CAASN,CAAS,CAAA,CAExEmE,CAAAA,CAAU,IAAA,CACRI,cAAAA,CAAC,KAAA,CAAA,CAEC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,KAAM,OAAA,CACN,GAAA,CAAK,CAAA,EAAGF,CAAI,CAAA,EAAA,CAAA,CACZ,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,SAAA,CACP,OAAA,CAAS,SAAA,CACT,YAAA,CAAc,KAAA,CACd,QAAA,CAAU,KAAA,CACV,UAAA,CAAY,MAAA,CACZ,KAAA,CAAO,MAAA,CACP,SAAA,CAAW,QAAA,CACX,MAAA,CAAQ,mBAAA,CACR,MAAA,CAAQ,EAAA,CACR,MAAA,CAAQ,CAAA,EAAG,EAAW,CAAA,EAAA,CAAA,CACtB,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,UAAA,CAAY,CACd,CAAA,CAEC,QAAA,CAAAC,CAAAA,CAAAA,CAtBIF,CAuBP,CACF,EACF,CACA,OAAOD,CACT,CAAA,CAGA,OACEK,eAAAA,CAAC,KAAA,CAAA,CACC,SAAA,CAAW,CAAA,UAAA,EAAa5B,CAAAA,CAAW,UAAA,CAAa,EAAE,CAAA,CAAA,EAAII,CAAAA,CAAa,WAAA,CAAc,EAAE,CAAA,CAAA,CACnF,KAAA,CAAO,CACL,UAAA,CAAY,aAAA,CACZ,MAAA,CAAQ,aAAaR,CAAAA,CAAeC,CAAM,CAAC,CAAA,CAAA,CAC3C,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,CAAA,CACT,KAAA,CAAO,CAAA,EAAG,GAAa,CAAA,EAAA,CAAA,CACvB,MAAA,CAAQ,CAAA,EAAG,EAAA,CAAqBnC,CAAAA,CAAU,EAAW,CAAA,EAAA,CAAA,CACrD,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,WAAA,CACZ,QAAA,CAAU,MAAA,CACV,SAAA,CAAW0C,CAAAA,CACP,sDAAA,CACAJ,CAAAA,CACE,mBAAA,CACA,2BAAA,CACN,QAAA,CAAU,UAAA,CACV,QAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,UAAA,CAAY,6BACd,CAAA,CAGA,QAAA,CAAA,CAAA4B,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CACV,SAAA,CAAW,QAAA,CACX,YAAA,CAAc,CAAA,CACd,MAAA,CAAQ,CAAA,CACR,UAAA,CAAY,SAAA,CACZ,OAAA,CAAS,KAAA,CACT,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,CAAA,EAAG,EAAkB,CAAA,EAAA,CAAA,CAC7B,OAAA,CAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,cAAA,CAAgB,QAClB,CAAA,CACE,QAAA,CAAA,CAAAD,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CAAE,UAAA,CAAY,MAAA,CAAQ,YAAA,CAAc,KAAM,CAAA,CAAI,QAAA,CAAAtB,CAAAA,CAAM,CAAA,CAChEuB,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CAAE,QAAA,CAAU,MAAA,CAAQ,KAAA,CAAO,SAAU,CAAA,CAC9C,QAAA,CAAA,CAAApB,CAAAA,CACCmB,cAAAA,CAAC,MAAA,CAAA,CAAK,KAAA,CAAO,CAAE,KAAA,CAAO,SAAA,CAAW,UAAA,CAAY,MAAO,CAAA,CAAI,QAAA,CAAAnB,CAAAA,CAAiB,CAAA,CAEzEoB,eAAAA,CAAC,MAAA,CAAA,CAAM,QAAA,CAAA,CAAA,OAAOtB,CAAAA,EAAU,QAAA,CAAWA,CAAAA,CAAQ,CAAA,CAAE,QAAA,CAAA,CAAM,CAAA,CACnD,UAAA,CAAI5C,CAAAA,CAAQ,WAAA,CAAK6C,CAAAA,CAAAA,CACrB,CAAA,CACAqB,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CAAE,OAAA,CAAS,MAAA,CAAQ,GAAA,CAAK,KAAA,CAAO,QAAA,CAAU,UAAA,CAAY,GAAA,CAAK,KAAA,CAAO,KAAA,CAAO,KAAM,EACxF,QAAA,CAAA,CAAAD,cAAAA,CAAC,QAAA,CAAA,CACC,aAAA,CAAgBE,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC7C,WAAA,CAAcA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC3C,OAAA,CAAUA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,EAAgB,CAAGA,CAAAA,CAAE,cAAA,EAAe,CAAGf,CAAAA,CAAgB,CAACD,CAAY,EAAG,CAAA,CAC3F,KAAA,CAAO,CACL,UAAA,CAAYA,CAAAA,CAAe,SAAA,CAAY,SAAA,CACvC,KAAA,CAAOA,CAAAA,CAAe,SAAA,CAAY,SAAA,CAClC,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,KAAA,CACV,MAAA,CAAQ,SAAA,CACR,UAAA,CAAY,WACd,CAAA,CACA,KAAA,CAAO,CAAA,EAAGA,CAAAA,CAAe,MAAA,CAAS,MAAM,CAAA,UAAA,CAAA,CACzC,QAAA,CAAA,GAAA,CAED,CAAA,CACAc,cAAAA,CAAC,QAAA,CAAA,CACC,aAAA,CAAgBE,GAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC7C,WAAA,CAAcA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC3C,OAAA,CAAUA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,iBAAgB,CAAGA,CAAAA,CAAE,cAAA,EAAe,CAAGb,CAAAA,GAA6B,CAAA,CACxF,KAAA,CAAO,CACL,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,SAAA,CACP,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,MACd,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,KAAA,CACV,MAAA,CAAQ,SAAA,CACR,UAAA,CAAY,WACd,CAAA,CACA,KAAA,CAAO,CAAA,sBAAA,EAAyBjE,EAAAA,CAA2B,CAAE,IAAA,CAAAgD,CAAK,CAAgB,CAAA,GAAM,WAAA,CAAc,UAAA,CAAa,WAAW,CAAA,CAAA,CAE7H,QAAA,CAAAhD,EAAAA,CAA2B,CAAE,IAAA,CAAAgD,CAAK,CAAgB,CAAA,GAAM,WAAA,CAAc,cAAA,CAAO,cAAA,CAChF,CAAA,CACA4B,eAAC,QAAA,CAAA,CACC,aAAA,CAAgBE,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC7C,WAAA,CAAcA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,GAAmB,CAAA,CAC3C,OAAA,CAAUA,CAAAA,EAAM,CAAEA,CAAAA,CAAE,eAAA,EAAgB,CAAGA,CAAAA,CAAE,cAAA,EAAe,CAAGV,CAAAA,GAAc,CAAA,CACzE,KAAA,CAAO,CACL,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,UACP,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,KAAA,CACV,MAAA,CAAQ,SAAA,CACR,UAAA,CAAY,WACd,CAAA,CACA,KAAA,CAAO,CAAA,UAAA,EAAaZ,CAAAA,GAAS,OAAA,CAAU,MAAA,CAAS,OAAO,CAAA,KAAA,CAAA,CAEtD,QAAA,CAAAA,CAAAA,GAAS,OAAA,CAAU,aAAA,CAAW,cAAA,CACjC,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAGAoB,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,KAAM,CAAA,CACN,UAAA,CAAY,aAAA,CAEZ,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,CAAA,EAAGjE,CAAAA,CAAU,EAAW,CAAA,EAAA,CAAA,CACnC,QAAA,CAAU,QACZ,CAAA,CACF,CAAA,CAGCmD,CAAAA,EACCc,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,GAAA,CAAK,CAAA,CACL,IAAA,CAAM,CAAA,CACN,KAAA,CAAO,CAAA,CACP,MAAA,CAAQ,CAAA,CACR,aAAA,CAAe,MACjB,CAAA,CAEC,SAAAL,CAAAA,EAAiB,CACpB,CAAA,CAAA,CAGJ,CAEJ,EChPO,IAAMQ,EAAAA,CAAsD,CAAC,CAAE,IAAA,CAAA/B,CAAAA,CAAM,QAAA,CAAAC,CAAS,CAAA,GAAM,CACzF,GAAM,CAAE,KAAA,CAAAK,CAAAA,CAAO,MAAA,CAAAR,EAAS,QAAS,CAAA,CAAIE,CAAAA,CAErC,OACE6B,eAAAA,CAAC,KAAA,CAAA,CACC,SAAA,CAAW,CAAA,WAAA,EAAc5B,CAAAA,CAAW,UAAA,CAAa,EAAE,CAAA,CAAA,CACnD,KAAA,CAAO,CACL,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,CAAA,UAAA,EAAaJ,CAAAA,CAAeC,CAAM,CAAC,CAAA,CAAA,CAC3C,YAAA,CAAc,KAAA,CACd,KAAA,CAAO,MAAA,CACP,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,QAAA,CACZ,eAAgB,QAAA,CAChB,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,WAAA,CACZ,QAAA,CAAU,MAAA,CACV,UAAA,CAAY,MAAA,CACZ,SAAA,CAAWG,CAAAA,CAAW,mBAAA,CAAsB,2BAAA,CAC5C,QAAA,CAAU,UACZ,CAAA,CAEA,QAAA,CAAA,CAAA2B,cAAAA,CAACI,gBAAAA,CAAA,CAAO,IAAA,CAAK,QAAA,CAAS,QAAA,CAAUC,kBAAAA,CAAS,GAAA,CAAK,CAAA,CAC9CL,cAAAA,CAACI,gBAAAA,CAAA,CAAO,IAAA,CAAK,QAAA,CAAS,QAAA,CAAUC,mBAAS,MAAA,CAAQ,CAAA,CACjDL,cAAAA,CAACI,gBAAAA,CAAA,CAAO,IAAA,CAAK,QAAA,CAAS,QAAA,CAAUC,kBAAAA,CAAS,IAAA,CAAM,CAAA,CAC/CL,cAAAA,CAACI,gBAAAA,CAAA,CAAO,IAAA,CAAK,QAAA,CAAS,QAAA,CAAUC,kBAAAA,CAAS,KAAA,CAAO,CAAA,CAEhDL,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CAAE,SAAA,CAAW,QAAS,CAAA,CAChC,QAAA,CAAAA,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CAAE,SAAU,KAAA,CAAO,UAAA,CAAY,KAAM,CAAA,CAAI,QAAA,CAAAtB,CAAAA,CAAM,CAAA,CAC7D,CAAA,CAEAsB,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,KAAA,CACR,IAAA,CAAM,KAAA,CACN,SAAA,CAAW,kBAAA,CACX,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,KAAA,CACR,UAAA,CAAY/B,CAAAA,CAAeC,CAAM,CAAA,CACjC,YAAA,CAAc,KAChB,CAAA,CACF,CAAA,CAAA,CACF,CAEJ,EC/CO,IAAMoC,EAAAA,CAAsD,CAAC,CAClE,EAAA,CAAAhC,CAAAA,CACA,OAAA,CAAAiC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CACA,eAAAC,CAAAA,CACA,IAAA,CAAAxC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,KAAA,CAAAwC,CAAAA,CAAQ,EACV,CAAA,GAAM,CACJ,GAAM,CAACC,CAAAA,CAAUC,CAAAA,CAAQC,CAAM,CAAA,CAAIC,uBAAAA,CAAc,CAC/C,OAAA,CAAAV,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAG,CAAAA,CACA,OAAA,CAAAF,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAE,CACF,CAAC,EAEK,CAAE,SAAA,CAAAM,CAAAA,CAAW,MAAA,CAAAC,CAAAA,CAAQ,KAAA,CAAAC,CAAAA,CAAQ,SAAU,CAAA,CAAIhD,CAAAA,EAAQ,EAAC,CAIpDiD,CAAAA,CAAY,CAChB,GAAGR,CAAAA,CACH,MAAA,CAAQO,CAAAA,CACR,WAAA,CAAa/C,CAAAA,CAAW,CAAA,CAAI,CAAA,CAC5B,eAAA,CAAiB,MACnB,CAAA,CAGA,OACE4B,eAAAA,CAAAqB,mBAAAA,CAAA,CACE,QAAA,CAAA,CAAAtB,cAAAA,CAACuB,kBAAAA,CAAA,CAAS,EAAA,CAAIjD,CAAAA,CAAI,IAAA,CAAMwC,CAAAA,CAAU,KAAA,CAAOO,CAAAA,CAAW,CAAA,CACpDrB,cAAAA,CAACwB,2BAAAA,CAAA,CACE,QAAA,CAAAnD,CAAAA,EAAYD,CAAAA,GAAS8C,CAAAA,EAAaC,CAAAA,CAAAA,EACjClB,eAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,CAAA,gCAAA,EAAmCc,CAAM,CAAA,GAAA,EAAMC,CAAM,CAAA,GAAA,CAAA,CAChE,UAAA,CAAY,SAAA,CACZ,OAAA,CAAS,SAAA,CACT,YAAA,CAAc,MACd,QAAA,CAAU,MAAA,CACV,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,WAAA,CACZ,MAAA,CAAQ,CAAA,UAAA,EAAaI,CAAK,CAAA,CAAA,CAC1B,aAAA,CAAe,MAAA,CACf,MAAA,CAAQ,IACV,CAAA,CAEC,QAAA,CAAA,CAAAF,CAAAA,EAAalB,cAAAA,CAAC,KAAA,CAAA,CAAK,QAAA,CAAAkB,CAAAA,CAAU,CAAA,CAC7BC,CAAAA,EAAUlB,eAAAA,CAAC,KAAA,CAAA,CAAK,QAAA,CAAA,CAAAkB,CAAAA,CAAO,GAAA,CAAA,CAAC,CAAA,CAAA,CAC3B,CAAA,CAEJ,CAAA,CAAA,CACF,CAEJ,EC7DO,IAAMM,EAAAA,CAAiC,CAAC,CAC7C,EAAA,CAAAnD,CAAAA,CACA,OAAA,CAAAiC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CAAQ,EAAC,CACT,IAAA,CAAAzC,EACA,SAAA,CAAAsD,CACF,CAAA,GAAM,CACJ,GAAM,CAACZ,CAAQ,CAAA,CAAIG,uBAAAA,CAAc,CAC/B,OAAA,CAAAV,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAG,CAAAA,CACA,QAAAF,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,cAAA,CAAAE,CACF,CAAC,CAAA,CAGKe,CAAAA,CAAgBvD,CAAAA,EAAM,aAAA,EAAiB,KAAA,CA2B7C,OACE4B,cAAAA,CAACuB,kBAAAA,CAAA,CACC,EAAA,CAAIjD,EACJ,IAAA,CAAMwC,CAAAA,CACN,SAAA,CAAWY,CAAAA,CACX,KAAA,CAAA,CA7BiB,IAAM,CACzB,IAAME,CAAAA,CAAY,CAChB,MAAA,CAAQxD,CAAAA,EAAM,KAAA,EAAS,SAAA,CACvB,WAAA,CAAauD,CAAAA,GAAkB,KAAA,CAAQ,CAAA,CAAI,CAAA,CAC3C,aAAA,CAAe,OAAA,CACf,cAAA,CAAgB,OAAA,CAChB,GAAGd,CACL,CAAA,CAIA,OAAIc,CAAAA,GAAkB,KAAA,CACb,CACL,GAAGC,CAAAA,CACH,gBAAiB,MACnB,CAAA,CAEO,CACL,GAAGA,CAAAA,CACH,eAAA,CAAiB,KACnB,CAEJ,CAAA,GAOwB,CACtB,CAEJ,ECxDO,IAAKC,EAAAA,CAAAA,CAAAA,CAAAA,GAEVA,CAAAA,CAAA,IAAA,CAAO,MAAA,CAEPA,CAAAA,CAAA,IAAA,CAAO,MAAA,CAJGA,CAAAA,CAAAA,EAAAA,EAAAA,EAAA,EAAA,ECSL,IAAMC,EAAAA,CAAyD,CACpE,GAAA,CAAK,CACH,IAAA,CAAM,KAAA,CACN,KAAA,CAAO,SAAA,CACP,WAAA,CAAa,SAAA,CACb,QAAA,CAAU,EAAA,CACV,OAAA,CAAS,GAAA,CACT,MAAA,CAAQ,CACV,CAAA,CACA,GAAA,CAAK,CACH,IAAA,CAAM,KAAA,CACN,KAAA,CAAO,SAAA,CACP,WAAA,CAAa,SAAA,CACb,QAAA,CAAU,EAAA,CACV,OAAA,CAAS,GAAA,CACT,MAAA,CAAQ,CACV,CAAA,CACA,GAAA,CAAK,CACH,IAAA,CAAM,KAAA,CACN,MAAO,SAAA,CACP,WAAA,CAAa,SAAA,CACb,QAAA,CAAU,EAAA,CACV,OAAA,CAAS,GAAA,CACT,MAAA,CAAQ,CACV,CAAA,CACA,GAAA,CAAK,CACH,IAAA,CAAM,KAAA,CACN,KAAA,CAAO,SAAA,CACP,WAAA,CAAa,SAAA,CACb,QAAA,CAAU,EAAA,CACV,OAAA,CAAS,GAAA,CACT,MAAA,CAAQ,CACV,CACF,EAeO,SAASC,EAAAA,CAAkBJ,CAAAA,CAAuC,CACvE,IAAMK,CAAAA,CAAYF,GAAiBH,CAAa,CAAA,CAChD,GAAI,CAACK,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2BL,CAAa,CAAA,CAAE,CAAA,CAG5D,IAAMM,CAAAA,CAAcD,CAAAA,CAAU,QAAA,GAAa,EAAA,CAGrCE,CAAAA,CAAQD,CAAAA,CAAc,EAAA,CAAK,CAAA,CAC3BE,CAAAA,CAASF,CAAAA,CAAc,EAAA,CAAK,CAAA,CAG5BG,CAAAA,CAAcH,CAAAA,CAChB,CAAE,YAAA,CAAc,KAAM,CAAA,CACtB,CACE,SAAU,wEAAA,CACV,YAAA,CAAc,KAChB,CAAA,CAEJ,OAAO,CACL,KAAA,CAAAC,CAAAA,CACA,MAAA,CAAAC,CAAAA,CACA,KAAA,CAAOH,CAAAA,CAAU,KAAA,CACjB,WAAA,CAAaA,CAAAA,CAAU,WAAA,CACvB,QAAA,CAAUC,CAAAA,CAAc,KAAA,CAAQ,KAAA,CAChC,GAAGG,CACL,CACF,CAKO,SAASC,EAAAA,CAAmBV,CAAAA,CAA6C,CAC9E,IAAMK,CAAAA,CAAYF,EAAAA,CAAiBH,CAAa,EAChD,GAAI,CAACK,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2BL,CAAa,CAAA,CAAE,CAAA,CAE5D,OAAOK,CACT,CAKO,SAASM,EAAAA,CAAqBX,CAAAA,CAAgC,CAEnE,OADkBU,EAAAA,CAAmBV,CAAa,CAAA,CACjC,QAAA,GAAa,EAChC,CAMO,SAASY,EAAAA,CAAeC,CAAAA,CAA2B,CAExD,OADsBA,CAAAA,CAAY,EAAA,CACX,CAAA,CAAI,MAAQ,KACrC,CAKO,SAASC,EAAAA,CAAuBC,CAAAA,CAA4B,CACjE,IAAMC,CAAAA,CAAOD,CAAAA,CAAW,WAAA,EAAY,CAGpC,OAAIC,CAAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAKA,CAAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAKA,CAAAA,CAAK,QAAA,CAAS,OAAO,CAAA,CACpE,KAAA,CAIF,KACT,KC3HaC,EAAAA,CAAuD,CAAC,CAAE,IAAA,CAAAxE,CAAAA,CAAM,QAAA,CAAAC,CAAS,CAAA,GAAM,CAC1F,GAAM,CACJ,KAAA,CAAAK,CAAAA,CACA,MAAA,CAAAR,CAAAA,CAAS,QAAA,CACT,UAAA,CAAA2E,CAAAA,CAAa,QAAA,CACb,YAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,OAAA,CAAAhH,CAAAA,CAAU,CAAA,CACV,KAAA,CAAAmG,CAAAA,CAAAA,MAAAA,CACA,KAAA,CAAAvD,CAAAA,CAAQ,EAAC,CACT,UAAAqE,CAAAA,CAAY,EAAC,CACb,IAAA,CAAAC,CACF,CAAA,CAAI7E,CAAAA,CAGE8E,CAAAA,CAAcD,CAAAA,GAAUD,CAAAA,CAAU,MAAA,CAAS,CAAA,EAAKrE,CAAAA,CAAM,MAAA,GAAW,CAAA,CAAK,MAAA,CAAS,OAAA,CAAA,CAK/EwE,CAAAA,CAAkD,EAAC,CAMzDA,CAAAA,CAAc,SAAS,CAAA,CAAI,OAAA,CAC3BA,CAAAA,CAAc,YAAY,CAAA,CAAI,OAAA,CAE1BxE,CAAAA,CAAM,MAAA,CAAS,CAAA,EACjBA,CAAAA,CAAM,QAAQyE,CAAAA,EAAa,CACzBA,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQC,CAAAA,EAAQ,CAC9B,IAAMC,CAAAA,CAAWD,CAAAA,CAAK,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,CAAIA,CAAAA,CAAK,KAAA,CAAQ,CAAA,EAAGD,CAAAA,CAAU,IAAI,CAAA,CAAA,EAAIC,CAAAA,CAAK,KAAK,CAAA,CAAA,CAC5FF,CAAAA,CAAcG,CAAQ,CAAA,CAAI,QAC5B,CAAC,EACH,CAAC,CAAA,CAIHH,CAAAA,CAAc,YAAY,CAAA,CAAI,MAAA,CAC9BA,CAAAA,CAAc,YAAY,CAAA,CAAI,MAAA,CAC9BA,CAAAA,CAAc,aAAa,CAAA,CAAI,MAAA,CAC/BA,CAAAA,CAAc,aAAa,CAAA,CAAI,MAAA,CAE3BH,CAAAA,CAAU,MAAA,CAAS,CAAA,EACrBA,CAAAA,CAAU,OAAA,CAAQI,CAAAA,EAAa,CAC7BA,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQC,CAAAA,EAAQ,CAC9B,IAAMC,CAAAA,CAAWD,CAAAA,CAAK,IAAA,EAAM,QAAA,CAAS,OAAO,EAAIA,CAAAA,CAAK,KAAA,CAAQ,CAAA,EAAGD,CAAAA,CAAU,IAAI,CAAA,CAAA,EAAIC,CAAAA,CAAK,KAAK,CAAA,CAAA,CAC5FF,CAAAA,CAAcG,CAAQ,CAAA,CAAI,OAC5B,CAAC,EACH,CAAC,CAAA,CAOH,IAAM5F,CAAAA,CAAe3B,CAAAA,CAAU,EAAA,CAIzBwH,CAAAA,CAAkBrB,CAAAA,GAAU,MAAA,CAAa,OAAA,CAAU,OAAA,CACnDsB,CAAAA,CAAiBtB,CAAAA,GAAU,MAAA,CAAa,OAAA,CAAU,MAAA,CAGlDuB,CAAAA,CAAuB,CAACC,CAAAA,CAAyBC,CAAAA,GAA+B,CACpF,IAAMC,CAAAA,CAAgC,EAAC,CAEvC,GAAIF,CAAAA,CAAW,MAAA,GAAW,CAAA,CAAG,OAAOE,CAAAA,CAGpC,IAAMC,CAAAA,CAAY,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMnG,CAAAA,CAAe,EAAG,CAAC,CAAA,CACtDoG,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMpG,CAAAA,CAAe,EAAG,CAAC,CAAA,CAE7D,OAAAgG,CAAAA,CAAW,OAAA,CAAQ,CAACN,CAAAA,CAAWW,CAAAA,GAAgB,CAC7CX,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQ,CAACC,CAAAA,CAAYb,CAAAA,GAAsB,CACzD,IAAMwB,CAAAA,CAAU,CAAC,CAACX,CAAAA,CAAK,IAAA,EAAQA,CAAAA,CAAK,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,CAEzD,GAAIM,CAAAA,GAAa,OAAA,EAAWK,CAAAA,CAC1B,OAEF,IAAMV,EAAWU,CAAAA,CAAU,CAAA,EAAGX,CAAAA,CAAK,KAAK,CAAA,CAAA,CAAK,CAAA,EAAGD,CAAAA,CAAU,IAAI,CAAA,CAAA,EAAIC,CAAAA,CAAK,KAAK,CAAA,CAAA,CACtEY,EAAAA,CAAcZ,CAAAA,CAAK,SAAA,CAGrBa,CAAAA,CAAY,UAChB,GAAID,EAAAA,CACF,GAAIZ,CAAAA,CAAK,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,CAC7Ba,CAAAA,CAAYb,CAAAA,CAAK,IAAA,GAAS,WAAA,CAAc,SAAA,CAAY,SAAA,CAAA,KAAA,GAC3CA,CAAAA,CAAK,IAAA,GAAS,WAAaA,CAAAA,CAAK,IAAA,GAAS,MAAA,CAClDa,CAAAA,CAAY,SAAA,CAAA,KAAA,GACHb,CAAAA,CAAK,IAAA,GAAS,KAAA,CACvBa,CAAAA,CAAY,SAAA,CAAA,KAGZ,OAAQb,CAAAA,CAAK,SAAA,EACX,KAAK,KAAA,CACHa,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,MAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,KAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,KAAA,CACHA,CAAAA,CAAY,UACZ,MACF,KAAK,KAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,OAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,OAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,MAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,OAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,KAAK,UAAA,CACHA,CAAAA,CAAY,SAAA,CACZ,MACF,QACEA,EAAY,UAChB,CAKJ,IAAIC,CAAAA,CAAiB9D,kBAAAA,CAAS,GAAA,CAC1B+D,CAAAA,CAAmC,CACrC,KAAA,CAAO,CAAA,EAAGP,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAYG,EAAAA,CAAcC,CAAAA,CAAY,SAAA,CACtC,MAAA,CAAQ,CAAA,UAAA,EAAaD,EAAAA,CAAcC,CAAAA,CAAY,SAAS,CAAA,CAAA,CACxD,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SACV,CAAA,CAEA,GAAIP,IAAa,OAAA,CAEXnB,CAAAA,CAAY,CAAA,GAAM,CAAA,EACpB2B,CAAAA,CAAiB9D,kBAAAA,CAAS,GAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,iBAAA,CACxBA,CAAAA,CAAY,IAAA,CAAO,CAAA,EAAI5B,CAAAA,CAAY,CAAA,EAAMqB,CAAAA,CAAY,CAAA,CAAE,CAAA,EAAA,CAAA,GAEvDM,CAAAA,CAAiB9D,kBAAAA,CAAS,MAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,kBAAA,CACxBA,CAAAA,CAAY,IAAA,CAAO,CAAA,EAAA,CAAK5B,CAAAA,CAAY,CAAA,EAAK,CAAA,EAAMqB,CAAAA,CAAY,CAAA,CAAE,eAKlChB,CAAAA,EAAY,WAAA,EAAY,CAAE,OAAA,CAAQ,IAAA,CAAM,GAAG,CAAA,EAAK,EAAA,IAChD,aAAA,CAEvBL,CAAAA,CAAY,CAAA,GAAM,CAAA,EACpB2B,CAAAA,CAAiB9D,kBAAAA,CAAS,GAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,iBAAA,CACxBA,CAAAA,CAAY,IAAA,CAAO,CAAA,EAAI5B,CAAAA,CAAY,CAAA,EAAMqB,CAAAA,CAAY,CAAA,CAAE,CAAA,EAAA,CAAA,GAEvDM,CAAAA,CAAiB9D,kBAAAA,CAAS,MAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,kBAAA,CACxBA,EAAY,IAAA,CAAO,CAAA,EAAA,CAAK5B,CAAAA,CAAY,CAAA,EAAK,CAAA,EAAMqB,CAAAA,CAAY,CAAA,CAAE,CAAA,EAAA,CAAA,CAAA,CAAA,KAAA,GAEtDR,CAAAA,CAAK,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,CAAG,CAEvCc,CAAAA,CAAiB9D,kBAAAA,CAAS,IAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,iBAAA,CAExB,IAAMC,EAAAA,CAAU3G,CAAAA,EAAgB,EAAA,CAAK,EAAA,CAAK,EAAA,CACpC4G,EAAAA,CAAU5G,CAAAA,EAAgB,EAAA,CAAK,EAAA,CAAK,EAAA,CAC1C0G,CAAAA,CAAY,IAAM,CAAA,EAAGC,EAAAA,CAAW7B,CAAAA,CAAY8B,EAAQ,CAAA,CAAA,CAAA,CAGpD,IAAM3C,EAAAA,CAAgBc,EAAAA,CAAuB/D,CAAK,CAAA,CAC5C6F,EAAAA,CAAYxC,EAAAA,CAAkBJ,EAAa,CAAA,CAEjDyC,CAAAA,CAAc,CACZ,GAAGA,CAAAA,CACH,KAAA,CAAO,CAAA,EAAGG,EAAAA,CAAU,KAAK,CAAA,EAAA,CAAA,CACzB,MAAA,CAAQ,CAAA,EAAGA,EAAAA,CAAU,MAAM,CAAA,EAAA,CAAA,CAC3B,MAAA,CAAQ,EAAA,CACR,OAAA,CAAS,MAAA,CACT,WAAY,QAAA,CACZ,cAAA,CAAgB,QAAA,CAChB,QAAA,CAAUA,EAAAA,CAAU,QAAA,CACpB,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,MAAA,CACZ,YAAA,CAAcA,EAAAA,CAAU,YAAA,CACxB,QAAA,CAAUA,EAAAA,CAAU,QACtB,EACF,CAAA,KAEEJ,CAAAA,CAAiB9D,kBAAAA,CAAS,KAAA,CAC1B+D,CAAAA,CAAY,SAAA,CAAY,kBAAA,CACxBA,CAAAA,CAAY,GAAA,CAAM,CAAA,EAAG,EAAA,CAAM5B,CAAAA,CAAY,EAAG,IAU9C,IAAMgC,EAAAA,CAAAA,CADuB3B,CAAAA,EAAY,WAAA,EAAY,CAAE,OAAA,CAAQ,IAAA,CAAM,GAAG,CAAA,EAAK,EAAA,IAC/B,aAAA,CAC1C4B,EAAAA,CACJ,GAAIT,CAAAA,CACFS,EAAAA,CAAa,QAAA,CAAA,KAAA,GACJ5B,CAAAA,GAAe,QAAA,EAAYA,CAAAA,GAAe,QAAA,CACnD4B,EAAAA,CAAa,QAAA,CAEbb,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAI,CAAA,EAAGkD,CAAQ,CAAA,OAAA,CAAA,CACf,IAAA,CAAK,SACL,QAAA,CAAUa,CAAAA,CACV,KAAA,CAAOC,CAAAA,CACP,KAAA,CAAO,CAAA,EAAGhB,CAAAA,CAAU,IAAI,CAAA,GAAA,EAAMC,CAAAA,CAAK,KAAK,CAAA,SAAA,EAAYY,EAAAA,CAAc,aAAA,CAAgB,gBAAgB,CAAA,CAAA,CAAA,CAL7F,CAAA,EAAGX,CAAQ,CAAA,OAAA,CAMlB,CACF,CAAA,CAAA,KAAA,GACSkB,EAAAA,CAAc,CAIvBC,EAAAA,CAAad,CAAAA,GAAa,MAAA,CAAS,QAAA,CAAW,QAAA,CAE9C,IAAMe,EAAAA,CAAef,CAAAA,GAAa,MAAA,CAAS,SAAW,QAAA,CACtDC,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAI,CAAA,EAAGkD,CAAQ,CAAA,CAAA,EAAIoB,EAAY,CAAA,CAAA,CAC/B,IAAA,CAAMA,EAAAA,CACN,QAAA,CAAUP,CAAAA,CACV,KAAA,CAAOC,CAAAA,CACP,KAAA,CAAO,CAAA,EAAGhB,CAAAA,CAAU,IAAI,CAAA,GAAA,EAAMC,CAAAA,CAAK,KAAK,CAAA,EAAA,EAAKqB,EAAY,CAAA,EAAA,EAAKT,EAAAA,CAAc,aAAA,CAAgB,gBAAgB,CAAA,CAAA,CAAA,CALvG,GAAGX,CAAQ,CAAA,CAAA,EAAIoB,EAAY,CAAA,CAMlC,CACF,EACF,CAAA,KACED,EAAAA,CAAaR,EAAAA,CAAc,QAAA,CAAW,QAAA,CAGxCL,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAIkD,CAAAA,CACJ,IAAA,CAAMmB,EAAAA,CACN,QAAA,CAAUN,CAAAA,CACV,KAAA,CAAOC,CAAAA,CACP,KAAA,CAAO,CAAA,EAAGhB,CAAAA,CAAU,IAAI,CAAA,GAAA,EAAMC,CAAAA,CAAK,KAAK,CAAA,CAAA,EAAIY,GAAc,aAAA,CAAgB,gBAAgB,CAAA,CAAA,CAEzF,QAAA,CAAAD,CAAAA,CAAUxB,CAAAA,CAAY,CAAA,CAAI,MAAA,CAAA,CAPtBc,CAQP,CACF,EACF,CAAC,EACH,CAAC,CAAA,CAEMM,CACT,CAAA,CAGMe,CAAAA,CAAgB,IAAM,CAC1B,IAAMf,CAAAA,CAAgC,EAAC,CAGjCC,CAAAA,CAAY,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMnG,CAAAA,CAAe,EAAG,CAAC,CAAA,CACtDoG,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMpG,CAAAA,CAAe,EAAG,CAAC,CAAA,CAE7D,GAAIwF,CAAAA,GAAgB,OAAA,CAAS,CAG3B,GAAIvE,CAAAA,CAAM,MAAA,CAAS,CAAA,CAEjB,OAAO8E,CAAAA,CAAqB9E,CAAAA,CAAO,OAAO,CAAA,CAK5C,GADoBkE,CAAAA,GAAe,QAAA,GAAanE,CAAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,KAAK,GAAKA,CAAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,CAAA,EAAKqE,CAAAA,GAAS,KAAA,EAASA,CAAAA,GAAS,MAAA,CAAA,CAExJ,OAAO6B,CAAAA,EAAuB,CAKhChB,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,SAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,GAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,GAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,iBACb,CAAA,CACA,KAAA,CAAM,oBAAA,CAAA,CAbF,SAcN,CACF,CAAA,CAEAF,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,YAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,MAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,GAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,kBACb,CAAA,CACA,KAAA,CAAM,uBAAA,CAAA,CAbF,YAcN,CACF,EAEF,CAAA,KAAA,GAAWZ,CAAAA,GAAgB,MAAA,CAAQ,CAGjC,GAAIF,CAAAA,CAAU,MAAA,CAAS,CAAA,CAErB,OAAOS,CAAAA,CAAqBT,EAAW,MAAM,CAAA,CAG/C,IAAM6B,CAAAA,CAAWhC,CAAAA,GAAe,QAAA,CAG1B2B,CAAAA,CAAAA,CADuB3B,CAAAA,EAAY,WAAA,EAAY,CAAE,OAAA,CAAQ,IAAA,CAAM,GAAG,CAAA,EAAK,EAAA,IAC/B,aAAA,CAG9C,GAAI,CAAC2B,CAAAA,CAAc,CAEjB,IAAM7C,CAAAA,CAAgBc,EAAAA,CAAuB/D,CAAK,CAAA,CAC5CsD,CAAAA,CAAYK,EAAAA,CAAmBV,CAAa,CAAA,CAC5C4C,CAAAA,CAAYxC,EAAAA,CAAkBJ,CAAa,EAG3CmD,CAAAA,CAAWpH,CAAAA,EAAgB,EAAA,CAAK,KAAA,CAAQ,KAAA,CAE9CkG,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,YAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,IAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGkE,CAAAA,CAAU,KAAK,CAAA,EAAA,CAAA,CACzB,MAAA,CAAQ,CAAA,EAAGA,CAAAA,CAAU,MAAM,CAAA,EAAA,CAAA,CAC3B,UAAA,CAAYA,CAAAA,CAAU,KAAA,CACtB,OAAQ,CAAA,UAAA,EAAaA,CAAAA,CAAU,WAAW,CAAA,CAAA,CAC1C,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,iBAAA,CACX,GAAA,CAAKO,CAAAA,CACL,MAAA,CAAQ,EAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,QAAA,CACZ,cAAA,CAAgB,QAAA,CAChB,QAAA,CAAUP,CAAAA,CAAU,QAAA,CACpB,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,MAAA,CACZ,YAAA,CAAcA,CAAAA,CAAU,YAAA,CACxB,QAAA,CAAUA,CAAAA,CAAU,QACtB,CAAA,CACA,KAAA,CAAO,CAAA,cAAA,EAAiBvC,CAAAA,CAAU,IAAI,CAAA,IAAA,EAAOA,CAAAA,CAAU,OAAO,CAAA,GAAA,EAAMA,CAAAA,CAAU,QAAQ,CAAA,CAAA,CAAA,CACvF,QAAA,CAAA,GAAA,CAAA,CAxBK,OA0BN,CACF,CAAA,CAGA,IAAM+C,CAAAA,CAAWrH,CAAAA,EAAgB,EAAA,CAAK,KAAA,CAAQ,KAAA,CAE9CkG,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,YAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,mBAAS,IAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGkE,CAAAA,CAAU,KAAK,CAAA,EAAA,CAAA,CACzB,MAAA,CAAQ,CAAA,EAAGA,CAAAA,CAAU,MAAM,CAAA,EAAA,CAAA,CAC3B,UAAA,CAAYA,CAAAA,CAAU,KAAA,CACtB,MAAA,CAAQ,CAAA,UAAA,EAAaA,CAAAA,CAAU,WAAW,CAAA,CAAA,CAC1C,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,iBAAA,CACX,GAAA,CAAKQ,CAAAA,CACL,MAAA,CAAQ,EAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,QAAA,CAAUR,CAAAA,CAAU,QAAA,CACpB,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,MAAA,CACZ,YAAA,CAAcA,CAAAA,CAAU,YAAA,CACxB,QAAA,CAAUA,CAAAA,CAAU,QACtB,CAAA,CACA,KAAA,CAAO,CAAA,cAAA,EAAiBvC,CAAAA,CAAU,IAAI,CAAA,IAAA,EAAOA,CAAAA,CAAU,OAAO,CAAA,GAAA,EAAMA,CAAAA,CAAU,QAAQ,CAAA,CAAA,CAAA,CACvF,QAAA,CAAA,GAAA,CAAA,CAxBK,OA0BN,CACF,EACF,CAGI,CAAC6C,CAAAA,EAAY,CAACL,CAAAA,GAChBZ,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,aAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,KAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,MACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,kBAAA,CACX,GAAA,CAAK,KACP,CAAA,CACA,KAAA,CAAM,wBAAA,CAAA,CAdF,aAeN,CACF,CAAA,CAEAF,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAG,aAAA,CACH,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,KAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,kBAAA,CACX,GAAA,CAAK,KACP,CAAA,CACA,KAAA,CAAM,wBAAA,CAAA,CAdF,aAeN,CACF,CAAA,EAEJ,CAEA,OAAOF,CACT,CAAA,CAGMgB,CAAAA,CAAyB,IAAM,CAEnC,IAAMhB,CAAAA,CAAgC,EAAC,CAGjCC,CAAAA,CAAY,IAAA,CAAK,IAAI,EAAA,CAAI,IAAA,CAAK,KAAA,CAAMnG,CAAAA,CAAe,GAAI,CAAC,CAAA,CACxDoG,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMpG,CAAAA,CAAe,GAAI,CAAC,CAAA,CAM9D,IAAA,IAASmC,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAK,EAAA,CAAIA,CAAAA,EAAAA,CAAK,CAC5B,IAAMmF,CAAAA,CACJhF,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAI,CAAA,KAAA,EAAQP,CAAC,GACb,IAAA,CAAK,QAAA,CACL,QAAA,CAAUQ,kBAAAA,CAAS,GAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,iBAAA,CACX,MAAA,CAAQ,GAAA,CAER,IAAA,CAAM,CAAA,EAAA,CAAIjE,CAAAA,CAAI,CAAA,GAAMgE,CAAAA,CAAY,EAAE,CAAA,EAAA,CACpC,CAAA,CACA,KAAA,CAAO,CAAA,KAAA,EAAQhE,CAAC,CAAA,CAAA,CAAA,CAhBX,CAAA,KAAA,EAAQA,CAAC,CAAA,CAiBhB,CAAA,CAKF+D,CAAAA,CAAQ,IAAA,CAAKoB,CAAM,EACrB,CAGA,IAAA,IAASnF,CAAAA,CAAI,EAAA,CAAIA,CAAAA,EAAK,EAAA,CAAIA,CAAAA,EAAAA,CAAK,CAC7B,IAAMoF,CAAAA,CAAcpF,CAAAA,CAAI,EAAA,CAClBmF,CAAAA,CACJhF,cAAAA,CAACI,gBAAAA,CAAA,CAEC,EAAA,CAAI,CAAA,KAAA,EAAQP,CAAC,CAAA,CAAA,CACb,IAAA,CAAK,QAAA,CACL,QAAA,CAAUQ,kBAAAA,CAAS,MAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAGwD,CAAS,CAAA,EAAA,CAAA,CACnB,MAAA,CAAQ,CAAA,EAAGC,CAAU,CAAA,EAAA,CAAA,CACrB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,kBAAA,CACX,MAAA,CAAQ,GAAA,CAER,IAAA,CAAM,CAAA,EAAA,CAAImB,CAAAA,CAAc,CAAA,GAAMpB,EAAY,CAAA,CAAE,CAAA,EAAA,CAC9C,CAAA,CACA,KAAA,CAAO,CAAA,KAAA,EAAQhE,CAAC,CAAA,CAAA,CAAA,CAhBX,CAAA,KAAA,EAAQA,CAAC,CAAA,CAiBhB,CAAA,CAKF+D,CAAAA,CAAQ,IAAA,CAAKoB,CAAM,EACrB,CAGA,IAAA,IAASnF,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAK,CAAA,CAAGA,CAAAA,EAAAA,CAAK,CAC3B,IAAMqF,CAAAA,CAAc,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMxH,CAAAA,CAAe,EAAG,CAAC,CAAA,CACxDyH,CAAAA,CAAe,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMzH,CAAAA,CAAe,GAAI,CAAC,CAAA,CAEhEkG,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,GAAI,CAAA,OAAA,EAAUP,CAAC,CAAA,CAAA,CACf,IAAA,CAAK,QAAA,CACL,QAAA,CAAUQ,kBAAAA,CAAS,KAAA,CACnB,KAAA,CAAO,CACL,KAAA,CAAO,CAAA,EAAG6E,CAAW,CAAA,EAAA,CAAA,CACrB,MAAA,CAAQ,CAAA,EAAGC,CAAY,CAAA,EAAA,CAAA,CACvB,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,OAAA,CACd,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,kBACb,CAAA,CACA,KAAA,CAAO,CAAA,OAAA,EAAUtF,CAAC,CAAA,CAAA,CAAA,CAbb,CAAA,OAAA,EAAUA,CAAC,CAAA,CAclB,CACF,EACF,CAEA,OAAO+D,CACT,CAAA,CAEA,OACE3D,eAAAA,CAAC,KAAA,CAAA,CACC,SAAA,CAAW,CAAA,YAAA,EAAe5B,CAAAA,CAAW,UAAA,CAAa,EAAE,CAAA,CAAA,CACpD,KAAA,CAAO,CACL,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,CAAA,UAAA,EAAaJ,CAAAA,CAAeC,CAAM,CAAC,CAAA,CAAA,CAC3C,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,KAAA,CACT,KAAA,CAAOqF,CAAAA,CACP,GAAIC,CAAAA,EAAkB,CAAE,IAAA,CAAMA,CAAe,CAAA,CAC7C,MAAA,CAAQ,CAAA,EAAG9F,CAAY,CAAA,EAAA,CAAA,CACvB,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,WAAA,CACZ,QAAA,CAAU,MACV,SAAA,CAAWW,CAAAA,CAAW,mBAAA,CAAsB,2BAAA,CAC5C,QAAA,CAAU,UAAA,CACV,OAAA,CAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,cAAA,CAAgB,QAAA,CAChB,MAAA,CAAQ,MAAA,CACR,YAAA,CAAc,KAAA,CACd,SAAA,CAAW,YAAA,CACX,SAAA,CAAW,KAAA,CACX,UAAA,CAAY,KAAA,CACZ,WAAA,CAAa,KACf,CAAA,CAOA,QAAA,CAAA,CAAA4B,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CACV,SAAA,CAAW,QAAA,CACX,KAAM,CAAA,CACN,OAAA,CAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,cAAA,CAAgB,QAAA,CAChB,QAAA,CAAU,QAAA,CACV,OAAA,CAAS,KACX,CAAA,CACE,QAAA,CAAA,CAAAD,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CACV,UAAA,CAAY,MAAA,CACZ,QAAA,CAAU,KAAA,CACV,UAAA,CAAY,KAAA,CACZ,UAAA,CAAY,QAAA,CACZ,QAAA,CAAU,QAAA,CACV,YAAA,CAAc,UAChB,CAAA,CACG,QAAA,CAAAtB,CAAAA,CACH,EACC3C,CAAAA,CAAU,CAAA,EACTiE,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CACV,QAAA,CAAU,KAAA,CACV,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,GACd,CAAA,CACG,QAAA,CAAA8C,CAAAA,CACH,CAAA,CAAA,CAEJ,CAAA,CAGC/G,CAAAA,CAAU,CAAA,EACTkE,eAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,KAAA,CACR,KAAA,CAAO,KAAA,CACP,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,UACP,OAAA,CAAS,SAAA,CACT,YAAA,CAAc,KAAA,CACd,QAAA,CAAU,KAAA,CACV,UAAA,CAAY,GACd,CAAA,CAEC,QAAA,CAAA,CAAAlE,CAAAA,CAAQ,GAAA,CAAA,CACX,CAAA,CAIFiE,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,KAAA,CACR,IAAA,CAAM,KAAA,CACN,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,KAAA,CACR,UAAA,CAAY/B,CAAAA,CAAeC,CAAM,CAAA,CACjC,YAAA,CAAc,KAChB,CAAA,CACF,CAAA,CAGCyG,CAAAA,EAAc,CAAA,CACjB,CAEJ,ECnpBO,IAAMS,EAAAA,CAAwD,CAAC,CACpE,IAAA,CAAAhH,CAAAA,CACA,QAAA,CAAAC,CACF,CAAA,GAAM,CACJ,GAAM,CACJ,KAAA,CAAAK,CAAAA,CACA,MAAA,CAAAR,EAAS,QAAA,CACT,QAAA,CAAAmH,CAAAA,CAAW,GAAA,CACX,UAAA,CAAAC,CAAAA,CAAa,EAAA,CACb,OAAA,CAAAC,CAAAA,CAAU,EAAA,CACV,SAAA,CAAAC,CACF,CAAA,CAAIpH,CAAAA,CAGEqH,CAAAA,CAAWJ,CAAAA,CAAW,GAAA,CAGtBK,CAAAA,CAAqB,IAAM,CAS/B,IAAMC,CAAAA,CAAU,IAAA,CAAK,IAAA,CAAKL,CAAAA,CAAa,EAAW,CAAA,CAC5CM,CAAAA,CAAgB,KAAA,CAAM,EAAW,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAACC,CAAAA,CAAGhG,CAAAA,GAAOA,CAAAA,CAAI,CAAA,CAAI,KAAA,CAAQ,KAAM,CAAA,CAQtF,IAAA,IAASiG,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAM,CAAA,CAAGD,CAAAA,CAAIH,CAAAA,CAAS,EAAEG,CAAAA,CACtC,IAAA,IAASjG,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAI,EAAA,EAAekG,CAAAA,CAAMT,EAAY,EAAEzF,CAAAA,CAAG,EAAEkG,CAAAA,CAAK,CAC9CH,CAAAA,CAAc/F,CAAC,CAAA,CAWlC,CAIF,IAAM+D,CAAAA,CAAU,EAAC,CAEXoC,CAAAA,CAAe,EAAA,CAMfC,CAAAA,CAAAA,CALkBR,CAAAA,CAAWO,CAAAA,CAAe,CAAA,GAIRV,CAAAA,CAAa,CAAA,CAAA,CAClB,EAAA,CAErC,IAAA,IAASzF,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIyF,CAAAA,CAAYzF,CAAAA,EAAAA,CAAK,CACnC,IAAMC,CAAAA,CAAOkG,CAAAA,CAAe,CAAA,CAAMC,CAAAA,CAAcpG,CAAAA,CAC1CyD,CAAAA,CAAW,CAAA,EAAGzD,CAAAA,CAAI,CAAC,CAAA,CAAA,CASzB,GANuB2F,CAAAA,GACpBA,CAAAA,GAAc,KAAA,EAAS3F,CAAAA,GAAM,CAAA,EAC7B2F,CAAAA,GAAc,QAAA,EAAY3F,CAAAA,GAAM,IAAA,CAAK,KAAA,CAAMyF,CAAAA,CAAa,CAAC,CAAA,EACzDE,CAAAA,GAAc,QAAA,EAAY3F,CAAAA,GAAMyF,CAAAA,CAAa,CAAA,CAAA,CAG5B,CAClB1B,CAAAA,CAAQ,IAAA,CAAKsC,CAAAA,CAAepG,CAAI,CAAC,CAAA,CACjC,QACF,CAGA,IAAMqG,CAAAA,CAAW5D,EAAAA,CAAe1C,CAAC,CAAA,CAC3B0E,EAAYxC,EAAAA,CAAkBoE,CAAQ,CAAA,CAGtCC,CAAAA,CAAS,IAAA,CAAK,KAAA,CAAA,CAAOb,CAAAA,CAAUhB,CAAAA,CAAU,KAAA,EAAS,CAAA,CAAG,CAAC,CAAA,CAE5DX,CAAAA,CAAQ,IAAA,CACN5D,cAAAA,CAACI,gBAAAA,CAAA,CAEC,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,KAAA,CACnB,EAAA,CAAIiD,CAAAA,CACJ,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,IAAA,CAAM,CAAA,EAAG8C,CAAM,CAAA,EAAA,CAAA,CACf,IAAK,CAAA,EAAGtG,CAAAA,CAAQyE,CAAAA,CAAU,MAAA,CAAS,CAAE,CAAA,EAAA,CAAA,CACrC,KAAA,CAAO,CAAA,EAAGA,CAAAA,CAAU,KAAK,CAAA,EAAA,CAAA,CACzB,MAAA,CAAQ,CAAA,EAAGA,CAAAA,CAAU,MAAM,CAAA,EAAA,CAAA,CAC3B,UAAA,CAAYA,CAAAA,CAAU,KAAA,CACtB,MAAA,CAAQ,CAAA,UAAA,EAAaA,CAAAA,CAAU,WAAW,CAAA,CAAA,CAC1C,MAAA,CAAQ,SAAA,CACR,MAAA,CAAQ,EAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,QAAA,CACZ,eAAgB,QAAA,CAChB,QAAA,CAAUA,CAAAA,CAAU,QAAA,CACpB,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,MAAA,CACZ,YAAA,CAAcA,CAAAA,CAAU,YAAA,CACxB,QAAA,CAAUA,CAAAA,CAAU,QACtB,CAAA,CACA,KAAA,CAAO,CAAA,WAAA,EAAc1E,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAKsG,CAAQ,CAAA,CAAA,CAAA,CAEtC,QAAA,CAAAtG,CAAAA,CAAI,CAAA,CAAA,CA1BA,CAAA,OAAA,EAAUyD,CAAQ,CAAA,CA2BzB,CACF,EACF,CACA,OAAOM,CACT,CAAA,CAGMsC,CAAAA,CAAkBpG,CAAAA,EAKpBG,eAAAA,CAAC,KAAA,CAAA,CAEC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,IAAA,CAAM,CAAA,EAAA,CAAIsF,CAAAA,CAAU,EAAA,EAAa,CAAC,KAClC,GAAA,CAAK,CAAA,EAAGzF,CAAAA,CAAQ,EAAA,CAAa,CAAE,CAAA,EAAA,CAAA,CAC/B,KAAA,CAAO,MAAA,CACP,MAAA,CAAQ,MAAA,CACR,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,QAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,OAAA,CAAS,KAAA,CACT,MAAA,CAAQ,EACV,CAAA,CAGA,QAAA,CAAA,CAAAE,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,IAAA,CAAM,OAAA,CACN,GAAA,CAAK,KAAA,CACL,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,qBAAA,CACR,YAAA,CAAc,OAAA,CACd,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,QAAA,CAAU,KAAA,CACV,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,MAAA,CACZ,SAAA,CAAW,eAAA,CACX,eAAA,CAAiB,QACnB,CAAA,CACD,QAAA,CAAA,KAAA,CAED,CAAA,CAGAA,cAAAA,CAACI,gBAAAA,CAAA,CAEC,IAAA,CAAK,QAAA,CACL,QAAA,CAAUC,kBAAAA,CAAS,KAAA,CACnB,EAAA,CAAG,YAAA,CACH,KAAA,CAAO,CACL,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,MACR,UAAA,CAAY,SAAA,CACZ,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,MAAA,CAAQ,SAAA,CACR,MAAA,CAAQ,EAAA,CACR,MAAA,CAAQ,QACV,CAAA,CACA,KAAA,CAAM,yBAAA,CAAA,CAdF,YAeN,CAAA,CAAA,CAAA,CA1DI,WA2DN,CAAA,CAIJ,OACEJ,eAAAA,CAAC,KAAA,CAAA,CACC,SAAA,CAAW,CAAA,kBAAA,EAAqB5B,CAAAA,CAAW,UAAA,CAAa,EAAE,CAAA,CAAA,CAC1D,KAAA,CAAO,CACL,UAAA,CAAY,+DAAA,CACZ,OAAQ,CAAA,UAAA,EAAaJ,CAAAA,CAAeC,CAAM,CAAC,CAAA,CAAA,CAC3C,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,CAAA,CACT,KAAA,CAAO,CAAA,EAAGqH,CAAO,CAAA,EAAA,CAAA,CACjB,MAAA,CAAQ,CAAA,EAAGE,CAAQ,CAAA,EAAA,CAAA,CACnB,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,WAAA,CACZ,QAAA,CAAU,MAAA,CACV,SAAA,CAAWpH,CAAAA,CAAW,mBAAA,CAAsB,2BAAA,CAC5C,QAAA,CAAU,UAAA,CACV,OAAA,CAAS,MAAA,CACT,aAAA,CAAe,QACjB,CAAA,CAIA,QAAA,CAAA,CAAA2B,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAO,CACV,SAAA,CAAW,QAAA,CACX,YAAA,CAAc,CAAA,CACd,MAAA,CAAQ,CAAA,CACR,UAAA,CAAY,+DAAA,CACZ,OAAA,CAAS,KAAA,CACT,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,MAAA,CACT,aAAA,CAAe,QAAA,CACf,cAAA,CAAgB,QAAA,CAChB,YAAA,CAAc,mBAChB,CAAA,CACE,QAAA,CAAAA,cAAAA,CAAC,KAAA,CAAA,CAAI,MAAO,CAAE,UAAA,CAAY,MAAA,CAAQ,QAAA,CAAU,KAAA,CAAO,KAAA,CAAO,SAAU,CAAA,CAAI,QAAA,CAAAtB,CAAAA,CAAM,CAAA,CAChF,CAAA,CAGAsB,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,IAAA,CAAM,CAAA,CACN,UAAA,CAAY,gEAAA,CACZ,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,CAAA,EAAGyF,CAAAA,CAAW,EAAE,CAAA,EAAA,CAAA,CAC3B,QAAA,CAAU,QACZ,CAAA,CAEC,QAAA,CAAAC,CAAAA,GACH,CAAA,CAAA,CACF,CAEJ,EC3NA,SAASW,EAAAA,CAA0BC,CAAAA,CAAkCC,CAAAA,CAA4C,CAC/G,GAAI,CAACD,CAAAA,CAAO,MAAA,EAAU,CAACA,CAAAA,CAAO,MAAA,EAAU,CAACA,CAAAA,CAAO,YAAA,EAAgB,CAACA,CAAAA,CAAO,YAAA,CAAc,OAAO,CAAE,KAAA,CAAO,IAAK,CAAA,CAE3G,IAAME,CAAAA,CAAgBD,CAAAA,CAAI,KAAA,CAAM,IAAA,CAAKrG,CAAAA,EAAKA,EAAE,MAAA,GAAWoG,CAAAA,CAAO,MAAA,EAAUpG,CAAAA,CAAE,YAAA,GAAiBoG,CAAAA,CAAO,YAAY,CAAA,CACxGG,CAAAA,CAAgBF,CAAAA,CAAI,KAAA,CAAM,IAAA,CAAKrG,CAAAA,EAAKA,CAAAA,CAAE,MAAA,GAAWoG,CAAAA,CAAO,MAAA,EAAUpG,CAAAA,CAAE,YAAA,GAAiBoG,CAAAA,CAAO,YAAY,CAAA,CAC9G,GAAIE,CAAAA,CAAe,OAAO,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,kCAAmC,CAAA,CACrF,GAAIC,EAAe,OAAO,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,kCAAmC,CAAA,CAGrF,IAAMC,CAAAA,CAAiBJ,CAAAA,CAAO,YAAA,CACxBK,CAAAA,CAAiBL,CAAAA,CAAO,YAAA,CAGxBM,CAAAA,CAAaL,CAAAA,CAAI,KAAA,CAAM,IAAA,CAAKhH,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAO+G,CAAAA,CAAO,MAAM,CAAA,CAEvDO,CAAAA,CAAaN,CAAAA,CAAI,KAAA,CAAM,IAAA,CAAKhH,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAO+G,CAAAA,CAAO,MAAM,CAAA,CAIvDQ,CAAAA,CAAgB,CAACC,CAAAA,CAAWhK,CAAAA,GAAe,CAC/C,GAAI,CAACgK,CAAAA,CAAG,OAAO,MAAA,CACf,IAAMC,CAAAA,CAAuBD,CAAAA,CAAE,UAAA,CAAW,KAAK,CAAA,EAAKA,CAAAA,CAAE,UAAA,CAAW,OAAO,CAAA,CAClEE,CAAAA,CAAalK,CAAAA,EAAM,IAAA,GAAS,cAAA,EAAkBgK,CAAAA,GAAM,YAAA,CAC1D,OAAOC,CAAAA,EAAwBC,CACjC,CAAA,CAEMC,CAAAA,CAAkB,CAACH,CAAAA,CAAWhK,CAAAA,GAAe,CACjD,GAAI,CAACgK,CAAAA,CAAG,OAAO,MAAA,CACf,GAAIhK,CAAAA,EAAM,IAAA,GAAS,cAAA,EAAkBgK,CAAAA,GAAM,YAAA,CAAc,OAAO,KAAA,CAEhE,IAAMI,CAAAA,CAAmBJ,CAAAA,CAAE,UAAA,CAAW,MAAM,CAAA,EAAKA,CAAAA,CAAE,UAAA,CAAW,OAAO,CAAA,EAAKA,CAAAA,CAAE,UAAA,CAAW,SAAS,CAAA,EAAKA,CAAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAKA,CAAAA,CAAE,QAAA,CAAS,OAAO,CAAA,CAGxIK,CAAAA,CAAmB,iBAAA,CAAkB,IAAA,CAAKL,CAAC,CAAA,EAAK,CAACA,CAAAA,CAAE,UAAA,CAAW,KAAK,CAAA,EAAK,CAACA,CAAAA,CAAE,UAAA,CAAW,OAAO,CAAA,CACnG,OAAOI,CAAAA,EAAoBC,CAC7B,CAAA,CAEMC,CAAAA,CAAgBP,CAAAA,CAAcJ,CAAAA,CAAgBE,CAAU,CAAA,CACxDU,CAAAA,CAAgBR,CAAAA,CAAcH,CAAAA,CAAgBE,CAAU,CAAA,CACxDU,CAAAA,CAAkBL,CAAAA,CAAgBR,CAAAA,CAAgBE,CAAU,CAAA,CAC5DY,CAAAA,CAAkBN,CAAAA,CAAgBP,CAAAA,CAAgBE,CAAU,CAAA,CAGlE,GAAKQ,CAAAA,EAAiBG,CAAAA,EAAqBF,CAAAA,EAAiBC,CAAAA,CAC1D,OAAO,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,4CAA6C,CAAA,CAI9E,GAAKF,CAAAA,EAAiB,CAACC,CAAAA,EAAmBA,CAAAA,EAAiB,CAACD,CAAAA,CAC1D,OAAO,CAAE,MAAO,KAAA,CAAO,MAAA,CAAQ,oDAAqD,CAAA,CAKtF,IAAMI,CAAAA,CAAcb,CAAAA,EAAY,IAAA,GAAS,cAAA,CACnCc,CAAAA,CAAcb,CAAAA,EAAY,IAAA,GAAS,cAAA,CAEzC,GAAIQ,CAAAA,EAAiBC,CAAAA,CAAe,CAClC,IAAMK,CAAAA,CAAaF,CAAAA,CAAcZ,CAAAA,CAAaa,CAAAA,CAAcd,CAAAA,CAAa,IAAA,CACnEgB,CAAAA,CAAUH,CAAAA,CAAcb,CAAAA,CAAac,CAAAA,CAAcb,CAAAA,CAAa,IAAA,CAGtE,GAAIc,CAAAA,EAAcC,GAESrB,CAAAA,CAAI,KAAA,CAAM,MAAA,CAAOrG,CAAAA,EAAK,CAC7C,IAAM2H,CAAAA,CAAiBf,CAAAA,CAAc5G,CAAAA,CAAE,YAAA,EAAgB,EAAE,CAAA,CACnD4H,CAAAA,CAAiBhB,CAAAA,CAAc5G,CAAAA,CAAE,YAAA,EAAgB,EAAE,CAAA,CACnD6H,CAAAA,CAAiB7H,CAAAA,CAAE,MAAA,GAAWyH,CAAAA,CAAW,EAAA,EAAMzH,CAAAA,CAAE,MAAA,GAAWyH,CAAAA,CAAW,EAAA,CAC7E,OAAA,CAAQE,CAAAA,EAAkBC,CAAAA,GAAmBC,CAC/C,CAAC,EAGuC,IAAA,CAAK7H,CAAAA,EAAKA,CAAAA,CAAE,MAAA,GAAW0H,CAAAA,CAAQ,EAAA,EAAM1H,CAAAA,CAAE,MAAA,GAAW0H,CAAAA,CAAQ,EAAE,CAAA,CAGlG,OAAO,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,6DAA8D,CAGnG,CAEA,OAAO,CAAE,KAAA,CAAO,IAAK,CACvB,CAGO,SAASI,EAAAA,CAAc1E,CAAAA,CAAkBvG,CAAAA,CAAqD,CACnG,GAAI,CAACA,CAAAA,CAAM,OACX,IAAMqB,CAAAA,CAAOrB,CAAAA,CAAK,IAAA,EAAQ,EAAC,CAGrBoG,CAAAA,CAAiB/E,CAAAA,CAAsD,aAAA,CAC7E,GAAI+E,CAAAA,EAAiBA,CAAAA,CAAcG,CAAQ,CAAA,CACzC,OAAOH,CAAAA,CAAcG,CAAQ,CAAA,CAI/B,GAAIA,CAAAA,GAAa,SAAA,EAAaA,CAAAA,GAAa,YAAA,CAAc,OAAO,OAAA,CAChE,GAAIA,CAAAA,GAAa,YAAA,EAAgBA,CAAAA,GAAa,YAAA,EAAgBA,CAAAA,GAAa,aAAA,EAAiBA,IAAa,aAAA,CAAe,OAAO,MAAA,CAG/H,IAAM2E,CAAAA,CAAc,KAAA,CAAM,OAAA,CAAS7J,CAAAA,CAA8F,KAAK,CAAA,CACjIA,CAAAA,CAA8F,KAAA,CAC/F,EAAC,CACC8J,CAAAA,CAAa,KAAA,CAAM,OAAA,CAAS9J,CAAAA,CAAkG,SAAS,CAAA,CACxIA,CAAAA,CAAkG,SAAA,CACnG,EAAC,CAIL,GADuBkF,CAAAA,CAAS,UAAA,CAAW,KAAK,CAAA,EAAKA,CAAAA,CAAS,QAAA,CAAS,OAAO,EAC1D,OAAO,MAAA,CAG3B,IAAA,IAAW6E,CAAAA,IAASF,CAAAA,CAClB,IAAA,IAAW5E,CAAAA,IAAQ8E,CAAAA,CAAM,KAAA,EAAS,EAAC,CAGjC,GAAA,CAFoB,CAAC,CAAC9E,CAAAA,CAAK,IAAA,EAAQ,MAAA,CAAOA,CAAAA,CAAK,IAAI,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,CACtCA,CAAAA,CAAK,KAAA,CAAQ,CAAA,EAAG8E,CAAAA,CAAM,IAAI,CAAA,CAAA,EAAI9E,CAAAA,CAAK,KAAK,CAAA,CAAA,IACtDC,EAAU,OAAO,OAAA,CAItC,IAAA,IAAW6E,CAAAA,IAASD,CAAAA,CAClB,IAAA,IAAW7E,CAAAA,IAAQ8E,CAAAA,CAAM,KAAA,EAAS,EAAC,CAGjC,GAAA,CAFoB,CAAC,CAAC9E,CAAAA,CAAK,IAAA,EAAQ,MAAA,CAAOA,CAAAA,CAAK,IAAI,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,CACtCA,CAAAA,CAAK,KAAA,CAAQ,CAAA,EAAG8E,CAAAA,CAAM,IAAI,CAAA,CAAA,EAAI9E,CAAAA,CAAK,KAAK,CAAA,CAAA,IACtDC,EAAU,OAAO,MAKxC,CAEO,SAAS8E,EAAAA,CAA0BC,CAAAA,CAAwC,EAAC,CAAGC,CAAAA,CAAiC,EAAC,CAAwB,CAC9I,IAAIC,CAAAA,CAA6B,CAC/B,KAAA,CAAOF,CAAAA,CAAQ,KAAA,EAAS,EAAC,CACzB,KAAA,CAAOA,CAAAA,CAAQ,KAAA,EAAS,EAAC,CACzB,KAAA,CAAOA,CAAAA,CAAQ,KAAA,EAAS,KAC1B,CAAA,CACMG,CAAAA,CAAY,IAAI,IAsCtB,OAAO,CAAE,QAAA,CApCQ,IAAMD,CAAAA,CAoCJ,QAAA,CAnCDE,CAAAA,EAA0C,CAC1DF,CAAAA,CAAQ,CAAE,GAAGA,CAAAA,CAAO,GAAGE,CAAQ,CAAA,CAC/BD,CAAAA,CAAU,OAAA,CAAQE,CAAAA,EAAKA,CAAAA,CAAEH,CAAK,CAAC,EACjC,CAAA,CAgC6B,SAAA,CA/BVI,CAAAA,GACjBH,CAAAA,CAAU,GAAA,CAAIG,CAAQ,CAAA,CACf,IAAMH,CAAAA,CAAU,MAAA,CAAOG,CAAQ,CAAA,CAAA,CA6BA,gBAAA,CA1BdC,CAAAA,EAA8B,CACtD,IAAM/B,CAAAA,CAAa0B,CAAAA,CAAM,KAAA,CAAM,IAAA,CAAKhJ,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOqJ,CAAAA,CAAK,MAAM,CAAA,CAC7D,GAAI,CAAC/B,CAAAA,EAAcA,CAAAA,CAAW,IAAA,GAAS,QAAA,CAAU,OAAO,GAAA,CACxD,IAAMgC,CAAAA,CAAwBhC,CAAAA,CAAW,IAAA,EAAM,IAAA,EAAqB,OAAA,CAC9DiC,CAAAA,CAAOd,EAAAA,CAAcY,CAAAA,CAAK,cAAgB,EAAA,CAAI/B,CAAU,CAAA,CAC9D,GAAIiC,CAAAA,CAAM,OAAOD,CAAAA,GAAeC,CAAAA,CAAO,GAAA,CAAO,GAAA,CAE9C,IAAMC,CAAAA,CAAAA,CAAgBH,CAAAA,CAAK,YAAA,EAAgB,EAAA,EAAI,QAAA,EAAS,CAClDI,CAAAA,CAAiBD,CAAAA,CAAa,WAAA,EAAY,CAC1CjC,CAAAA,CAAgBkC,CAAAA,CAAe,UAAA,CAAW,KAAK,CAAA,EAAKA,CAAAA,CAAe,UAAA,CAAW,OAAO,CAAA,CACrFC,CAAAA,CAA0BD,CAAAA,CAAe,WAAW,MAAM,CAAA,EAAKA,CAAAA,CAAe,UAAA,CAAW,OAAO,CAAA,EAAKA,CAAAA,CAAe,UAAA,CAAW,SAAS,CAAA,EAAKA,CAAAA,CAAe,QAAA,CAAS,OAAO,CAAA,EAAKA,CAAAA,CAAe,QAAA,CAAS,OAAO,CAAA,CAChN5B,CAAAA,CAAmB,kBAAA,CAAmB,IAAA,CAAK2B,CAAY,CAAA,EAAK,CAACC,CAAAA,CAAe,UAAA,CAAW,KAAK,CAAA,EAAK,CAACA,CAAAA,CAAe,UAAA,CAAW,OAAO,EACnI9B,CAAAA,CAAkB+B,CAAAA,EAA2B7B,CAAAA,CACnD,OAAIN,CAAAA,CAAsB+B,CAAAA,GAAe,MAAA,CAAS,GAAA,CAAO,GAAA,CACrD3B,CAAAA,CAAwB2B,CAAAA,GAAe,OAAA,CAAU,GAAA,CAAO,GAAA,CACrD,GACT,CAAA,CAU0D,kBAAA,CARxCvC,CAAAA,EAAAA,CACLgC,CAAAA,CAAQ,kBAAA,EAAsBjC,EAAAA,EAC/BC,CAAAA,CAAQiC,CAAK,CAAA,CAM+D,cAAA,CAHhEjK,CAAAA,EAAeiK,CAAAA,CAAM,KAAA,CAAM,IAAA,CAAKhJ,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOjB,CAAE,CAAA,CAGgC,oBAAA,CAF1E4K,CAAAA,EAAmBX,CAAAA,CAAM,KAAA,CAAM,MAAA,CAAOrI,CAAAA,EAAKA,CAAAA,CAAE,MAAA,GAAWgJ,CAAAA,EAAUhJ,CAAAA,CAAE,MAAA,GAAWgJ,CAAM,CAEU,CAC/H,CC7MO,SAASC,EAAAA,CAAkBC,CAAAA,CAA4B,CAC5D,IAAMC,CAAAA,CAAaC,CAAAA,EAAmBF,CAAAA,CAAM,SAAA,CAAUE,CAAqD,CAAA,CACrGC,CAAAA,CAAc,IAAMH,CAAAA,CAAM,QAAA,EAAS,CAEzC,OADcI,uBAAAA,CAAqBH,CAAAA,CAAWE,CAAAA,CAAaA,CAAW,CAExE,CAEO,SAASE,EAAAA,CAASL,CAAAA,CAA2C,CAClE,IAAMC,CAAAA,CAAaC,CAAAA,EAAmBF,CAAAA,CAAM,SAAA,CAAUE,CAAqD,CAAA,CACrGC,CAAAA,CAAc,IAAMH,CAAAA,CAAM,QAAA,EAAS,CAAE,KAAA,CAC3C,OAAOI,uBAAAA,CAAqBH,CAAAA,CAAWE,CAAAA,CAAaA,CAAW,CACjE,CAEO,SAASG,EAAAA,CAASN,CAAAA,CAA2C,CAClE,IAAMC,CAAAA,CAAaC,CAAAA,EAAmBF,CAAAA,CAAM,SAAA,CAAUE,CAAqD,CAAA,CACrGC,CAAAA,CAAc,IAAMH,CAAAA,CAAM,QAAA,EAAS,CAAE,KAAA,CAC3C,OAAOI,uBAAAA,CAAqBH,CAAAA,CAAWE,CAAAA,CAAaA,CAAW,CACjE,CAMO,SAASI,EAAAA,CAAoBP,CAAAA,CAA4B,CAC9D,OAAOA,CAAAA,CAAM,gBACf,CCpBO,SAASQ,EAAAA,CAAcvO,CAAAA,CAK5B,CACA,IAAMwO,CAAAA,CAAY,GAAA,CACZC,CAAAA,CAAAA,CAAczO,CAAAA,CAAK,IAAA,CAAK,OAAA,EAAW,EAAA,EAAM,EAAA,CACzC0O,CAAAA,CAAW1O,CAAAA,CAAK,QAAA,CAAS,CAAA,CACzB2O,CAAAA,CAAY3O,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAIwO,CAAAA,CAC9BI,CAAAA,CAAU5O,CAAAA,CAAK,QAAA,CAAS,CAAA,CACxB6O,CAAAA,CAAa7O,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAIyO,CAAAA,CAErC,OAAO,CACL,IAAA,CAAMC,CAAAA,CACN,KAAA,CAAOC,CAAAA,CACP,GAAA,CAAKC,CAAAA,CACL,MAAA,CAAQC,CACV,CACF,CASO,SAASC,EAAAA,CAAcC,CAAAA,CAAiC/O,CAAAA,CAA4B,CACzF,IAAMgP,CAAAA,CAAST,EAAAA,CAAcvO,CAAI,CAAA,CACjC,OACE+O,CAAAA,CAAM,CAAA,EAAKC,CAAAA,CAAO,IAAA,EAClBD,CAAAA,CAAM,CAAA,EAAKC,CAAAA,CAAO,KAAA,EAClBD,CAAAA,CAAM,CAAA,EAAKC,CAAAA,CAAO,KAClBD,CAAAA,CAAM,CAAA,EAAKC,CAAAA,CAAO,MAEtB,CAUO,SAASC,EAAAA,CACdF,CAAAA,CACAG,CAAAA,CACoB,CACpB,IAAIC,CAAAA,CAAkC,IAAA,CAClCC,CAAAA,CAAc,CAAA,CAAA,CAAA,CAElB,IAAA,IAAWpP,KAAQkP,CAAAA,CAAO,CACxB,GAAI,CAACJ,EAAAA,CAAcC,CAAAA,CAAO/O,CAAI,CAAA,CAC5B,SAGF,IAAMqP,CAAAA,CAAW,IAAA,CAAK,IAAA,CACpB,IAAA,CAAK,GAAA,CAAIN,CAAAA,CAAM,EAAI/O,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAG,CAAC,CAAA,CAAI,IAAA,CAAK,GAAA,CAAI+O,CAAAA,CAAM,CAAA,CAAI/O,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAG,CAAC,CAChF,CAAA,CAEIqP,CAAAA,CAAWD,CAAAA,GACbA,CAAAA,CAAcC,CAAAA,CACdF,CAAAA,CAAcnP,CAAAA,EAElB,CAEA,OAAOmP,CACT,CCpDO,SAASG,EAAAA,CACdrC,CAAAA,CACe,CACf,GAAM,CAAE,KAAA,CAAAsC,CAAAA,CAAO,UAAA,CAAAC,CAAAA,CAAY,QAAA,CAAAC,CAAAA,CAAU,gBAAA,CAAAC,CAAAA,CAAkB,MAAA,CAAAC,CAAO,CAAA,CAAI1C,CAAAA,CAG5DhF,CAAAA,CAAW0H,CAAAA,GAAW,QAAA,CAAWH,CAAAA,CAAW,YAAA,CAAeA,CAAAA,CAAW,YAAA,CACtE3B,CAAAA,CAAS8B,CAAAA,GAAW,QAAA,CAAWH,CAAAA,CAAW,MAAA,CAASA,CAAAA,CAAW,MAAA,CAEpE,GAAI,CAACvH,CAAAA,EAAY,CAAC4F,EAChB,OAAO,IAAA,CAIT,IAAM+B,CAAAA,CAAeL,CAAAA,CAAM,IAAA,CAAK1K,CAAAA,EAC1B8K,CAAAA,GAAW,QAAA,CACN9K,CAAAA,CAAE,MAAA,GAAWgJ,CAAAA,EAAUhJ,CAAAA,CAAE,YAAA,GAAiBoD,CAAAA,CAE1CpD,CAAAA,CAAE,MAAA,GAAWgJ,CAAAA,EAAUhJ,CAAAA,CAAE,YAAA,GAAiBoD,CAEpD,CAAA,CAED,GAAI,CAAC2H,CAAAA,CACH,OAAO,IAAA,CAIT,IAAMC,CAAAA,CAAWN,CAAAA,CAAM,MAAA,CAAO1K,CAAAA,EAAKA,EAAE,EAAA,GAAO+K,CAAAA,CAAa,EAAE,CAAA,CAGrDE,CAAAA,CAAkBC,iBAAAA,CAAQP,CAAAA,CAAYK,CAAQ,CAAA,CAG9CG,CAAAA,CAAUF,CAAAA,CAAgBA,CAAAA,CAAgB,MAAA,CAAS,CAAC,CAAA,CACpDG,CAAAA,CAAyB,CAC7B,GAAGD,CAAAA,CACH,IAAA,CAAMP,CAAAA,CACN,MAAA,CAAQC,CAAAA,CAAiB,CAAE,GAAGF,CAAAA,CAAY,EAAA,CAAIQ,CAAAA,CAAQ,EAAA,CAAI,IAAA,CAAMP,CAAS,CAAgB,EACzF,KAAA,CAAO,CAAE,GAAGO,CAAAA,CAAQ,KAAA,CAAO,MAAA,CAAQN,CAAAA,CAAiB,CAAE,GAAGF,CAAAA,CAAY,EAAA,CAAIQ,CAAAA,CAAQ,EAAA,CAAI,IAAA,CAAMP,CAAS,CAAgB,CAAE,CACxH,CAAA,CAGA,OAAO,CAAC,GAAGK,CAAAA,CAAgB,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CAAGG,CAAgB,CAC3D,CChCA,IAAMC,EAAAA,CAAkB,CACtBhN,CAAAA,CACAC,CAAAA,CACAgN,CAAAA,IACe,CACf,IAAA,CAAOC,CAAAA,EAA0CzL,cAAAA,CAAC7B,EAAAA,CAAA,CAAU,GAAGsN,CAAAA,CAAO,YAAA,CAAclN,CAAAA,CAAc,gBAAA,CAAkBC,CAAAA,CAAkB,UAAA,CAAYgN,CAAAA,GAAmBC,CAAAA,CAAM,EAAA,CAAI,CAAA,CAC/K,KAAA,CAAOtL,EAAAA,CACP,MAAA,CAAQyC,EAAAA,CACR,cAAA,CAAgBwC,EAClB,CAAA,CAAA,CAEMsG,GAAuB,CAC3B,KAAA,CAAOpL,EAAAA,CACP,KAAA,CAAOmB,EACT,CAAA,CAEMkK,EAAAA,CAAqD,CAAC,CAC1D,KAAA,CAAA1M,CAAAA,CACA,KAAA,CAAA2L,CAAAA,CACA,YAAA,CAAAgB,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,aAAA,CAAeC,CAAAA,CACf,aAAA,CAAeC,CAAAA,CACf,KAAA,CAAA3C,CAAAA,CACA,KAAA,CAAA4C,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,YAAA,CAAA3N,CAAAA,CACA,gBAAA,CAAAC,EACA,SAAA,CAAA2N,CAAAA,CACA,KAAA,CAAAtL,CAAAA,CACA,kBAAA,CAAAuL,CAAAA,CACA,SAAA,CAAAC,CAAAA,CAAY,MAAA,CACZ,MAAA,CAAAC,CAAAA,CACA,aAAA,CAAAC,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CAAqB,KAAA,CACrB,sBAAA,CAAAC,CAAAA,CAAyB,WAAA,CACzB,kBAAA,CAAAC,CAAAA,CAAqB,gBAAA,CACrB,mBAAA,CAAAC,CACF,CAAA,GAAM,CAEJ,IAAMC,CAAAA,CAAe,KAAA,CAAM,OAAA,CAAQ3N,CAAK,CAAA,EAAK,MAAM,OAAA,CAAQ2L,CAAK,CAAA,CAE1DiC,CAAAA,CAAaC,mBAAAA,CAAM,OAAA,CAAQ,IAC3B1D,CAAAA,EAEGhB,EAAAA,CAA0B,CAC/B,KAAA,CAAOwE,CAAAA,CAAgB3N,CAAAA,EAAS,EAAC,CAAM2M,CAAAA,EAAgB3M,CAAAA,EAAS,EAAC,CACjE,KAAA,CAAO2N,CAAAA,CAAgBhC,CAAAA,EAAS,EAAC,CAAMiB,CAAAA,EAAgBjB,CAAAA,EAAS,EAAC,CACjE,KAAA,CAAAoB,CACF,CAAC,CAAA,CAEA,CAAC5C,CAAAA,CAAOwD,CAAAA,CAAcZ,CAAK,CAAC,CAAA,CAGzBe,CAAAA,CAAatD,EAAAA,CAASoD,CAAU,CAAA,CAChCG,CAAAA,CAAatD,EAAAA,CAASmD,CAAU,CAAA,CAChC,CAACI,CAAAA,CAAgBlO,CAAAA,CAAUmO,CAAa,CAAA,CAAIC,uBAAAA,CAAcJ,CAAU,CAAA,CACpE,CAACK,CAAAA,CAAgBC,CAAAA,CAAUC,EAAa,CAAA,CAAIC,uBAAAA,CAAcP,CAAU,CAAA,CACpEjC,CAAAA,CAAmBpB,EAAAA,CAAoBkD,CAAU,EACjDW,CAAAA,CAAmBC,SAAAA,CAAuB,IAAI,CAAA,CAG9C,CAAE,QAAA,CAAAC,CAAAA,CAAU,WAAA,CAAAC,EAAAA,CAAa,QAAA,CAAUC,EAAAA,CAAmB,QAAA,CAAUC,EAAkB,CAAA,CAAI7O,sBAAAA,EAAa,CAczG8O,YAAAA,CAAU,IAAM,CACVvB,CAAAA,EACFA,CAAAA,CAAc,CACZ,QAAA,CAAAmB,CAAAA,CACA,WAAA,CAAAC,EAAAA,CACA,QAAA,CAAW1O,CAAAA,EAAkB,CAC3B2O,EAAAA,CAAkB3O,CAAK,CAAA,CACvB4N,EAAW,QAAA,CAAS,CAAE,KAAA,CAAO5N,CAAuB,CAAC,EACvD,CAAA,CACA,QAAA,CAAW2L,CAAAA,EAAkB,CAC3BiD,EAAAA,CAAkBjD,CAAK,CAAA,CACvBiC,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAOjC,CAAuB,CAAC,EACvD,CAAA,CACA,OAAA,CAAUtC,CAAAA,EACHkF,CAAAA,CAAiB,OAAA,CACfO,iBAAAA,CAAMP,CAAAA,CAAiB,OAAA,CAASlF,CAAO,CAAA,CADR,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,iCAAiC,CAAC,CAGrG,CAAC,EAEL,CAAA,CAAG,CAACiE,CAAAA,CAAemB,CAAAA,CAAUC,EAAAA,CAAaC,EAAAA,CAAmBC,EAAAA,CAAmBhB,CAAU,CAAC,CAAA,CAG3F,IAAMmB,EAAAA,CAAaC,cAAAA,CAAY,IAAM,CACnC,GAAI,CAACT,CAAAA,CAAiB,OAAA,CAAS,CACzBxB,CAAAA,EACF,OAAA,CAAQ,KAAA,CAAM,wCAAwC,CAAA,CAExD,MACF,CAEA+B,iBAAAA,CAAMP,CAAAA,CAAiB,OAAA,CAAS,CAC9B,MAAA,CAASzQ,CAAAA,EACP,EACEA,CAAAA,EAAM,SAAA,EAAW,QAAA,CAAS,qBAAqB,CAAA,EAC/CA,CAAAA,EAAM,SAAA,EAAW,QAAA,CAAS,sBAAsB,CAAA,EAChDA,CAAAA,EAAM,SAAA,EAAW,QAAA,CAAS,yBAAyB,CAAA,EACnDA,CAAAA,EAAM,SAAA,EAAW,QAAA,CAAS,iBAAiB,CAAA,EAC3CA,CAAAA,EAAM,OAAA,GAAY,QAAA,CAAA,CAEtB,eAAA,CAAiBsP,CAAAA,GAAc,QAAU,SAAA,CAAY,SAAA,CACrD,UAAA,CAAY,CACd,CAAC,CAAA,CAAE,IAAA,CAAM6B,CAAAA,EAAoB,CAC3B,IAAMC,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA,CACvCA,CAAAA,CAAK,QAAA,CAAW,CAAA,gBAAA,EAAmB,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,IAAA,CAAA,CACzEA,CAAAA,CAAK,IAAA,CAAOD,CAAAA,CACZC,EAAK,KAAA,GACP,CAAC,CAAA,CAAE,KAAA,CAAOC,CAAAA,EAAmB,CACvBpC,CAAAA,EACF,OAAA,CAAQ,KAAA,CAAM,0BAAA,CAA4BoC,CAAK,EAEnD,CAAC,EACH,CAAA,CAAG,CAAC/B,CAAAA,CAAWL,CAAK,CAAC,CAAA,CAGf,CAACR,EAAAA,CAAgB6C,EAAiB,CAAA,CAAIjP,WAAAA,CAAwB,IAAI,CAAA,CAIlEkP,EAAAA,CAAoBC,UAAAA,CACxB,IAAMhD,EAAAA,CAAgBhN,CAAAA,CAAcC,EAAkBgN,EAAc,CAAA,CAEpE,CAACjN,CAAAA,CAAcC,CAAAA,CAAkBgN,EAAc,CACjD,CAAA,CAGMgD,EAAAA,CAAoBD,UAAAA,CAAQ,IAAM7C,EAAAA,CAAW,EAAE,CAAA,CAI/C+C,EAAAA,CAAiBhB,SAAAA,CAAeR,CAAc,CAAA,CACpDa,YAAAA,CAAU,IAAM,CAAEW,EAAAA,CAAe,OAAA,CAAUxB,EAAgB,CAAA,CAAG,CAACA,CAAc,CAAC,CAAA,CAG9E,IAAMyB,EAAAA,CAAiBjB,UAAeL,CAAc,CAAA,CACpDU,YAAAA,CAAU,IAAM,CAAEY,EAAAA,CAAe,OAAA,CAAUtB,EAAgB,CAAA,CAAG,CAACA,CAAc,CAAC,CAAA,CAG9EU,YAAAA,CAAU,IAAM,CAAE/O,CAAAA,CAASgO,CAAU,EAAG,CAAA,CAAG,CAACA,CAAAA,CAAYhO,CAAQ,CAAC,CAAA,CACjE+O,YAAAA,CAAU,IAAM,CAAET,CAAAA,CAASL,CAAU,EAAG,CAAA,CAAG,CAACA,CAAAA,CAAYK,CAAQ,CAAC,CAAA,CAEjES,YAAAA,CAAU,IAAM,CACVlB,CAAAA,EACFC,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAO5N,CAAAA,EAAS,EAAG,CAAC,EAE9C,CAAA,CAAG,CAAC2N,CAAAA,CAAc3N,CAAAA,CAAO4N,CAAU,CAAC,CAAA,CACpCiB,YAAAA,CAAU,IAAM,CACVlB,CAAAA,EACFC,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAOjC,GAAS,EAAG,CAAC,EAE9C,CAAA,CAAG,CAACgC,CAAAA,CAAchC,CAAAA,CAAOiC,CAAU,CAAC,CAAA,CAGpCiB,YAAAA,CAAU,IAAM,CAEd,GADI,CAAC1B,CAAAA,EACD,CAACa,CAAAA,EAAkBA,CAAAA,CAAe,MAAA,GAAW,CAAA,CAAG,OAEpD,IAAM1C,CAAAA,CAAQ0C,CAAAA,CAAe,MAAA,CAAO1N,CAAAA,EAAKA,CAAAA,CAAE,IAAA,GAAS,MAAM,CAAA,CAC1D,GAAIgL,CAAAA,CAAM,MAAA,GAAW,CAAA,CAAG,OAGxB,IAAMoE,CAAAA,CAAcpE,CAAAA,CAAM,GAAA,CAAIqE,CAAAA,EAAK,CAEjC,IAAM7S,EAAAA,CADW6S,CAAAA,CAAE,IAAA,EACO,OAAA,EAAW,EAAA,CAC/BnJ,EAAAA,CAAW,EAAA,CAAqB1J,EAAAA,CAAU,EAAA,CAChD,OAAA,CAAQ6S,CAAAA,CAAE,QAAA,EAAU,CAAA,EAAK,CAAA,EAAKnJ,EAChC,CAAC,CAAA,CAGKoJ,CAAAA,CAAY,IAAA,CAAK,GAAA,CAAI,GAAGF,CAAW,CAAA,CACnCG,CAAAA,CAAY,IAAA,CAAK,GAAA,CAAI,GAAGH,CAAW,CAAA,CAKzC,GAJcG,CAAAA,CAAYD,CAAAA,CAId,EAAA,CAAI,OAGhB,IAAME,CAAAA,CAAiBD,CAAAA,CAGjBE,CAAAA,CAAY/B,CAAAA,CAAe,GAAA,CAAI1N,CAAAA,EAAK,CACxC,GAAIA,CAAAA,CAAE,IAAA,GAAS,MAAA,CAAQ,OAAOA,CAAAA,CAE9B,IAAMxD,EAAAA,CADWwD,CAAAA,CAAE,IAAA,EACO,OAAA,EAAW,EAAA,CAC/BkG,GAAW,EAAA,CAAqB1J,EAAAA,CAAU,EAAA,CAC1CkT,EAAAA,CAAAA,CAAiB1P,CAAAA,CAAE,QAAA,EAAU,CAAA,EAAK,CAAA,EAAKkG,EAAAA,CACvCyJ,EAAAA,CAAQH,CAAAA,CAAiBE,EAAAA,CAC/B,OAAI,IAAA,CAAK,GAAA,CAAIC,EAAK,CAAA,CAAI,CAAA,CAAU3P,CAAAA,CACzB,CACL,GAAGA,CAAAA,CACH,QAAA,CAAU,CACR,CAAA,CAAGA,CAAAA,CAAE,QAAA,EAAU,CAAA,EAAK,CAAA,CACpB,CAAA,CAAA,CAAIA,CAAAA,CAAE,QAAA,EAAU,GAAK,CAAA,EAAK2P,EAC5B,CACF,CACF,CAAC,CAAA,CAEeF,CAAAA,CAAU,IAAA,CAAK,CAACzP,CAAAA,CAAGM,CAAAA,GAAMN,CAAAA,CAAE,QAAA,GAAa0N,CAAAA,CAAepN,CAAC,CAAA,CAAE,QAAQ,CAAA,EACrEd,CAAAA,CAASiQ,CAAS,EACjC,CAAA,CAAG,CAAC5C,CAAAA,CAAoBa,CAAAA,CAAgBlO,CAAQ,CAAC,CAAA,CAGjD,IAAMoQ,CAAAA,CAAclB,cAAAA,CAAa3P,CAAAA,EACxBmQ,GAAe,OAAA,CAAQ,IAAA,CAAKlP,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOjB,CAAE,CAAA,CAClD,EAAE,CAAA,CAGLwP,YAAAA,CAAU,IAAM,CACdT,CAAAA,CAAU+B,CAAAA,EACRA,CAAAA,CAAI,GAAA,CAAIxG,CAAAA,EAAQ,CACd,IAAMyG,CAAAA,CAAYtE,CAAAA,CAAiBnC,CAAmB,CAAA,CACtD,OAAO,CACL,GAAGA,CAAAA,CACH,MAAA,CAAQyG,CAAAA,CACR,KAAA,CAAO,CAAE,GAAGzG,CAAAA,CAAK,KAAA,CAAO,MAAA,CAAQyG,CAAU,CAC5C,CACF,CAAC,CACH,EACF,CAAA,CAAG,CAACpC,CAAAA,CAAgBI,CAAAA,CAAUtC,CAAgB,CAAC,CAAA,CAE/C+C,YAAAA,CAAU,IAAM,CACd,IAAMwB,CAAAA,CAAerC,CAAAA,CAAe,GAAA,CAAIlQ,CAAAA,EAAQ,CAC9C,GACEA,CAAAA,CAAK,IAAA,GAAS,QAAA,EACdA,CAAAA,CAAK,QAAA,EACLA,CAAAA,CAAK,KAAK,SAAA,GACT,CAACA,CAAAA,CAAK,QAAA,EAAaA,CAAAA,CAAK,QAAA,CAAS,CAAA,GAAM,CAAA,EAAKA,CAAAA,CAAK,QAAA,CAAS,CAAA,GAAM,CAAA,CAAA,CACjE,CACA,IAAMwS,CAAAA,CAAaJ,CAAAA,CAAYpS,CAAAA,CAAK,QAAQ,CAAA,CAC5C,GAAIwS,CAAAA,CAAY,CACd,IAAMC,CAAAA,CAAqB/R,EAAAA,CAA6B8R,CAAAA,CAA2BxS,CAAAA,CAAK,IAAA,CAAK,SAAS,CAAA,CACtG,OAAO,CACL,GAAGA,CAAAA,CACH,QAAA,CAAUyS,CACZ,CACF,CACF,CACA,OAAOzS,CACT,CAAC,CAAA,CAEkBuS,CAAAA,CAAa,IAAA,CAAK,CAACvS,CAAAA,CAAM0S,CAAAA,GAC1C1S,CAAAA,CAAK,QAAA,GAAakQ,CAAAA,CAAewC,CAAK,CAAA,CAAE,QAC1C,CAAA,EAEE1Q,CAAAA,CAASuQ,CAAY,EAEzB,CAAA,CAAG,CAACrC,CAAAA,CAAgBlO,CAAAA,CAAUoQ,CAAW,CAAC,CAAA,KAEpCO,EAAAA,CAAoBzB,cAAAA,CAAa0B,CAAAA,EAA0B,CAC/D,IAAMC,CAAAA,CAAiBD,CAAAA,CAAQ,GAAA,CAAKE,CAAAA,EAAW,CAC7C,GAAIA,CAAAA,CAAO,IAAA,GAAS,UAAA,EAAcA,CAAAA,CAAO,QAAA,CAAU,CACjD,IAAM9S,CAAAA,CAAOoS,CAAAA,CAAYU,CAAAA,CAAO,EAAE,CAAA,CAElC,GAAI9S,CAAAA,EAAQA,CAAAA,CAAK,IAAA,GAAS,QAAA,EAAYA,CAAAA,CAAK,QAAA,CAAU,CACnD,IAAMwS,EAAaJ,CAAAA,CAAYpS,CAAAA,CAAK,QAAQ,CAAA,CAC5C,GAAIwS,CAAAA,CAAY,CACd,IAAMO,CAAAA,CAAgBnU,EAAAA,CACpBoB,CAAAA,CACAwS,CAAAA,CACAM,CAAAA,CAAO,QAAA,CACPpB,EAAAA,CAAe,OACjB,CAAA,CAEA,GAAIqB,CAAAA,CAAc,SAAA,GAAc,MAAA,CAAW,CACzC,IAAMC,CAAAA,CAAc,CAClB,GAAGhT,CAAAA,CACH,IAAA,CAAM,CACJ,GAAGA,CAAAA,CAAK,IAAA,CACR,UAAW+S,CAAAA,CAAc,SAC3B,CACF,CAAA,CAEA/Q,CAAAA,CAAUE,CAAAA,EACRA,CAAAA,CAAM,GAAA,CAAIM,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOxC,CAAAA,CAAK,EAAA,CAAKgT,CAAAA,CAAcxQ,CAAC,CACnD,EACF,CAEA,OAAO,CAAE,GAAGsQ,CAAAA,CAAQ,QAAA,CAAU,CAAE,CAAA,CAAGC,CAAAA,CAAc,CAAA,CAAG,CAAA,CAAGA,CAAAA,CAAc,CAAE,CAAE,CAC3E,CACF,CAGA,GAAI/S,CAAAA,EAAQA,CAAAA,CAAK,IAAA,GAAS,QAAA,EAAYA,CAAAA,CAAK,QAAA,CAAU,CACnD,IAAMwS,CAAAA,CAAaJ,CAAAA,CAAYpS,CAAAA,CAAK,QAAQ,CAAA,CAC5C,GAAIwS,EAAY,CACd,IAAMS,CAAAA,CAAWT,CAAAA,CAEjB,GAAI,CAACpF,EAAAA,CAAc0F,CAAAA,CAAO,QAAA,CAAUG,CAAQ,CAAA,CAAG,CAC7C,IAAMC,CAAAA,CAAYJ,CAAAA,CAAO,QAAA,CAAS,EAAIG,CAAAA,CAAS,QAAA,CAAS,CAAA,CAClDE,CAAAA,CAAYL,CAAAA,CAAO,QAAA,CAAS,CAAA,CAAIG,CAAAA,CAAS,QAAA,CAAS,CAAA,CAClDD,CAAAA,CAAc,CAClB,GAAGhT,CAAAA,CACH,QAAA,CAAU,MAAA,CACV,MAAA,CAAQ,MAAA,CACR,IAAA,CAAM,CACJ,GAAGA,CAAAA,CAAK,IAAA,CACR,SAAA,CAAW,MACb,CACF,CAAA,CACA,OAAAgC,CAAAA,CAAUE,CAAAA,EACRA,CAAAA,CAAM,GAAA,CAAIM,IAAKA,EAAAA,CAAE,EAAA,GAAOxC,CAAAA,CAAK,EAAA,CAAKgT,CAAAA,CAAcxQ,EAAC,CACnD,CAAA,CACO,CAAE,GAAGsQ,CAAAA,CAAQ,QAAA,CAAU,CAAE,CAAA,CAAGI,CAAAA,CAAW,CAAA,CAAGC,CAAU,CAAE,CAC/D,CACF,CACF,CACF,CACA,OAAOL,CACT,CAAC,CAAA,CAED3C,CAAAA,CAAc0C,CAAc,EAC9B,CAAA,CAAG,CAAC1C,EAAenO,CAAAA,CAAUoQ,CAAW,CAAC,CAAA,CAGnCgB,EAAAA,CAAsBlC,cAAAA,CAAY,CAACmC,CAAAA,CAA0BC,CAAAA,GAAgB,CAEjFhC,EAAAA,CAAkB,IAAI,EACxB,CAAA,CAAG,EAAE,CAAA,CAGCiC,EAAAA,CAAiBrC,cAAAA,CAAY,CAACmC,CAAAA,CAA0BrT,CAAAA,CAAYwT,CAAAA,GAAmB,CAC3F,GAAIxT,CAAAA,CAAK,IAAA,GAAS,QAAA,EAAY,CAACA,CAAAA,CAAK,QAAA,CAAU,CAE5C,IAAMwN,CAAAA,CAAQkE,EAAAA,CAAe,OAAA,CAC1B,MAAA,CAAOlP,CAAAA,EAAKA,CAAAA,CAAE,IAAA,GAAS,MAAM,CAAA,CAC7B,GAAA,CAAIA,CAAAA,EAAKA,CAAgB,CAAA,CACtBiL,CAAAA,CAAcF,EAAAA,CAAgBvN,CAAAA,CAAK,QAAA,CAAUwN,CAAK,CAAA,CAGxD8D,EAAAA,CAAkB7D,CAAAA,EAAa,EAAA,EAAM,IAAI,EAC3C,CAAA,KACE6D,EAAAA,CAAkB,IAAI,EAE1B,CAAA,CAAG,EAAE,CAAA,CAGCmC,GAAqBvC,cAAAA,CAAY,CAACmC,CAAAA,CAA0BrT,CAAAA,CAAYwT,CAAAA,GAAmB,CAC/F,GAAIxT,CAAAA,CAAK,IAAA,GAAS,QAAA,EAAY,CAACA,CAAAA,CAAK,QAAA,CAAU,CAE5C,IAAMwN,CAAAA,CAAQkE,EAAAA,CAAe,OAAA,CAC1B,MAAA,CAAOlP,CAAAA,EAAKA,CAAAA,CAAE,IAAA,GAAS,MAAM,CAAA,CAC7B,GAAA,CAAIA,CAAAA,EAAKA,CAAgB,CAAA,CACtBiL,CAAAA,CAAcF,EAAAA,CAAgBvN,CAAAA,CAAK,QAAA,CAAUwN,CAAK,CAAA,CAExD,GAAIC,CAAAA,CAAa,CAEf,IAAMiG,CAAAA,CAAY1T,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAIyN,CAAAA,CAAY,QAAA,CAAS,CAAA,CACnDvO,CAAAA,CAAYc,CAAAA,CAAK,QAAA,CAAS,CAAA,CAAIyN,CAAAA,CAAY,QAAA,CAAS,CAAA,CAGnDuF,CAAAA,CAAc,CAClB,GAAGhT,CAAAA,CACH,QAAA,CAAUyN,CAAAA,CAAY,EAAA,CACtB,MAAA,CAAQ,QAAA,CACR,QAAA,CAAU,CAAEiG,CAAAA,CAAc,CAAA,CAAGxU,CAAU,CAAA,CACvC,IAAA,CAAM,CACJ,GAAGc,CAAAA,CAAK,IAAA,CACR,SAAA,CAAW,CACb,CACF,CAAA,CAEMuS,CAAAA,CAAeb,EAAAA,CAAe,OAAA,CAAQ,GAAA,CAAIlP,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOxC,CAAAA,CAAK,EAAA,CAAKgT,CAAAA,CAAcxQ,CAAC,CAAA,CACvFR,CAAAA,CAASuQ,CAAY,CAAA,CAGhB1C,CAAAA,EACHC,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAOyC,CAA8B,CAAC,EAEhE,CACF,CAGAjB,EAAAA,CAAkB,IAAI,EACxB,CAAA,CAAG,CAACtP,CAAAA,CAAU6N,CAAAA,CAAcC,CAAU,CAAC,CAAA,CAKZoB,cAAAA,CAAapD,CAAAA,EAAgE,CACtG,GAAI,CAACA,CAAAA,CAAW,MAAA,EAAU,CAACA,CAAAA,CAAW,MAAA,EAAU,CAACA,CAAAA,CAAW,YAAA,EAAgB,CAACA,CAAAA,CAAW,YAAA,CACtF,OAAO,CAAE,KAAA,CAAO,IAAK,CAAA,CAGvB,IAAMnE,CAAAA,CAAiBmE,CAAAA,CAAW,YAAA,CAC5BlE,CAAAA,CAAiBkE,CAAAA,CAAW,YAAA,CAE5B6F,CAAAA,CAAyBhC,EAAAA,CAAe,OAAA,CAAQ,IAAA,CAAK9F,CAAAA,EACzDA,CAAAA,CAAK,MAAA,GAAWiC,CAAAA,CAAW,MAAA,EAAUjC,CAAAA,CAAK,YAAA,GAAiBlC,CAC7D,CAAA,CAEMiK,CAAAA,CAAyBjC,EAAAA,CAAe,OAAA,CAAQ,IAAA,CAAK9F,CAAAA,EACzDA,CAAAA,CAAK,MAAA,GAAWiC,CAAAA,CAAW,MAAA,EAAUjC,CAAAA,CAAK,YAAA,GAAiBjC,CAC7D,CAAA,CAEA,OAAI+J,CAAAA,CACK,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,kCAAmC,CAAA,CAGhEC,CAAAA,CACK,CAAE,KAAA,CAAO,KAAA,CAAO,MAAA,CAAQ,kCAAmC,CAAA,CAG7D,CAAE,KAAA,CAAO,IAAK,CACvB,CAAA,CAAG,EAAE,CAAA,KAECC,EAAAA,CAAY3C,cAAAA,CACf3H,CAAAA,EAAuB,CACtB,IAAMM,CAAAA,CAAauI,CAAAA,CAAY7I,CAAAA,CAAO,MAAO,CAAA,CACvCmB,CAAAA,CAAcb,CAAAA,EAAY,IAAA,GAAS,cAAA,CACnCiK,CAAAA,CAAiBjK,CAAAA,EAAY,IAAA,CAC7BkK,CAAAA,CAAiBlK,CAAAA,EAAY,IAAA,GAAS,QAAA,EAAYiK,CAAAA,EAAgB,UAAA,GAAe,QAAA,CACjFE,CAAAA,CAAuB,CAAC,CAACzK,CAAAA,CAAO,YAAA,GAAiBA,CAAAA,CAAO,YAAA,CAAa,UAAA,CAAW,KAAK,CAAA,EAAKA,CAAAA,CAAO,YAAA,CAAa,UAAA,CAAW,OAAO,CAAA,CAAA,CAChI0K,CAAAA,CAAyB,CAAC,CAAC1K,CAAAA,CAAO,YAAA,GACtCA,CAAAA,CAAO,YAAA,CAAa,UAAA,CAAW,MAAM,CAAA,EACrCA,CAAAA,CAAO,YAAA,CAAa,UAAA,CAAW,OAAO,CAAA,EACtC,kBAAA,CAAmB,IAAA,CAAKA,CAAAA,CAAO,YAAY,CAAA,CAAA,CAI7C,GAAImB,CAAAA,EAAesJ,CAAAA,EAAwBzK,CAAAA,CAAO,MAAA,EAAUA,CAAAA,CAAO,YAAA,CAAc,CAC/E,IAAM2K,CAAAA,CAAWtG,EAAAA,CAAY,CAC3B,KAAA,CAAO+D,EAAAA,CAAe,OAAA,CACtB,WAAYpI,CAAAA,CACZ,QAAA,CAAU,OAAA,CACV,gBAAA,CAAAyE,CAAAA,CACA,MAAA,CAAQ,QACV,CAAC,CAAA,CACD,GAAIkG,CAAAA,CAAU,CACZ5D,CAAAA,CAAS4D,CAAQ,CAAA,CACjB,MACF,CACF,CAGA,GAAIH,CAAAA,EAAkBE,CAAAA,EAA0B1K,CAAAA,CAAO,MAAA,EAAUA,CAAAA,CAAO,YAAA,CAAc,CACpF,IAAM2K,CAAAA,CAAWtG,EAAAA,CAAY,CAC3B,KAAA,CAAO+D,EAAAA,CAAe,QACtB,UAAA,CAAYpI,CAAAA,CACZ,QAAA,CAAU,OAAA,CACV,gBAAA,CAAAyE,CAAAA,CACA,MAAA,CAAQ,QACV,CAAC,CAAA,CACD,GAAIkG,CAAAA,CAAU,CACZ5D,CAAAA,CAAS4D,CAAQ,CAAA,CACjB,MACF,CACF,CAEA,IAAMC,CAAAA,CAAarE,CAAAA,CAAW,kBAAA,CAAmB,CAC/C,MAAA,CAAQvG,CAAAA,CAAO,MAAA,EAAU,IAAA,CACzB,MAAA,CAAQA,CAAAA,CAAO,MAAA,EAAU,IAAA,CACzB,aAAcA,CAAAA,CAAO,YAAA,EAAgB,IAAA,CACrC,YAAA,CAAcA,CAAAA,CAAO,YAAA,EAAgB,IACvC,CAAC,CAAA,CACD,GAAI,CAAC4K,CAAAA,CAAW,KAAA,CAAO,CAErB,GAAIzJ,CAAAA,EAAenB,CAAAA,CAAO,MAAA,EAAUA,CAAAA,CAAO,YAAA,CAAc,CACvD,IAAM2K,CAAAA,CAAWtG,EAAAA,CAAY,CAC3B,KAAA,CAAO+D,EAAAA,CAAe,OAAA,CACtB,UAAA,CAAYpI,CAAAA,CACZ,QAAA,CAAUyK,CAAAA,CAAuB,QAAU,OAAA,CAC3C,gBAAA,CAAAhG,CAAAA,CACA,MAAA,CAAQ,QACV,CAAC,CAAA,CACD,GAAIkG,CAAAA,CAAU,CACZ5D,CAAAA,CAAS4D,CAAQ,CAAA,CACjB,MACF,CACF,CAEA,GAAIH,CAAAA,EAAkBxK,CAAAA,CAAO,MAAA,EAAUA,CAAAA,CAAO,YAAA,CAAc,CAC1D,IAAM2K,CAAAA,CAAWtG,EAAAA,CAAY,CAC3B,KAAA,CAAO+D,EAAAA,CAAe,OAAA,CACtB,UAAA,CAAYpI,CAAAA,CACZ,QAAA,CAAU,QACV,gBAAA,CAAAyE,CAAAA,CACA,MAAA,CAAQ,QACV,CAAC,CAAA,CACD,GAAIkG,CAAAA,CAAU,CACZ5D,CAAAA,CAAS4D,CAAQ,CAAA,CACjB,MACF,CACF,CACIjF,CAAAA,EACF,OAAA,CAAQ,IAAA,CAAK,CAAA,qBAAA,EAAwBkF,CAAAA,CAAW,MAAM,CAAA,CAAE,CAAA,CAE1D,MACF,CAEA,IAAMC,CAAAA,CAAY,CAChB,GAAG7K,CAAAA,CACH,IAAA,CAAOmB,CAAAA,EAAesJ,EAAwB,OAAA,CAAU,OAAA,CACxD,MAAA,CAAQhG,CAAAA,CAAiB,CAAE,GAAGzE,CAAAA,CAAQ,EAAA,CAAI,SAAU,CAAgB,CACtE,CAAA,CAEA+G,CAAAA,CAAU+B,CAAAA,EAAQhE,iBAAAA,CAAQ+F,CAAAA,CAAW/B,CAAG,CAAC,EAC3C,CAAA,CACA,CAAC/B,CAAAA,CAAUR,CAAAA,CAAY9B,CAAAA,CAAkBoE,CAAAA,CAAanD,CAAK,CAC7D,CAAA,CAEMoF,EAAAA,CAAkBnD,cAAAA,CACtB,CAACoD,CAAAA,CAAyBtU,IAAe,CAGvC,GAAA,CAFuBsU,CAAAA,CAAM,OAAA,EAAWA,CAAAA,CAAM,OAAA,GAExBtU,CAAAA,CAAK,IAAA,GAAS,QAAA,CAAU,CAC5C,IAAMqB,CAAAA,CAAOrB,CAAAA,CAAK,IAAA,EAAQ,EAAC,CACrBuU,CAAAA,CAAgClT,CAAAA,CAAK,IAAA,GAAS,KAAA,CAAM,OAAA,CAAQA,CAAAA,CAAK,SAAS,CAAA,EAAKA,CAAAA,CAAK,SAAA,CAAU,MAAA,CAAS,CAAA,CAAI,MAAA,CAAS,OAAA,CAAA,CACpHmT,CAAAA,CAA6BD,CAAAA,GAAgB,QAAU,MAAA,CAAS,OAAA,CAElEtF,CAAAA,EACF,OAAA,CAAQ,GAAA,CAAI,CAAA,+BAAA,EAAkCjP,CAAAA,CAAK,EAAE,CAAA,MAAA,EAASuU,CAAW,CAAA,IAAA,EAAOC,CAAQ,CAAA,CAAE,CAAA,CAIxFhT,CAAAA,EACFA,CAAAA,CAAaxB,CAAAA,CAAK,EAAA,CAAIwU,CAAQ,CAAA,CAGhCtF,CAAAA,EAAeA,CAAAA,CAAYlP,CAAmB,EAChD,CAAA,KAGEkP,CAAAA,EAAeA,CAAAA,CAAYlP,CAAmB,EAElD,CAAA,CACA,CAACwB,CAAAA,CAAc0N,EAAaD,CAAK,CACnC,CAAA,CAGMwF,EAAAA,CAAwBvD,cAAAA,CAAY,IAAM,CAAC,CAAA,CAAG,EAAE,CAAA,CAEhDwD,EAAAA,CAAkBxD,cAAAA,CACtB,CAACoD,CAAAA,CAAyBzI,CAAAA,GAAe,CACnCsD,CAAAA,EACFA,CAAAA,CAAYtD,CAAmB,EAEnC,CAAA,CACA,CAACsD,CAAW,CACd,CAAA,CAGM,CAACwF,CAAAA,CAAcC,EAAe,CAAA,CAAIvS,WAAAA,CAAsB,IAAI,EAClEwS,8BAAAA,CAAqB,CACnB,QAAA,CAAU,CAAC,CAAE,KAAA,CAAA3S,CAAM,CAAA,GAAM,CACvB,GAAIA,CAAAA,EAASA,CAAAA,CAAM,MAAA,GAAW,CAAA,CAAG,CAC/B,IAAMlC,CAAAA,CAAOkC,CAAAA,CAAM,CAAC,CAAA,CACpB0S,EAAAA,CAAgB5U,CAAI,CAAA,CAGhBkP,CAAAA,EACFA,CAAAA,CAAYlP,CAAmB,EAEnC,CAAA,KACE4U,EAAAA,CAAgB,IAAI,CAAA,CAEhB1F,CAAAA,EACFA,EAAY,IAAI,EAGtB,CACF,CAAC,CAAA,CAED,IAAM4F,EAAAA,CAAqB5D,cAAAA,CAAY,IAAM,CAC3C,GAAI,CAACyD,CAAAA,CAAc,OACnB,IAAM3U,CAAAA,CAAOoS,CAAAA,CAAYuC,CAAAA,CAAa,EAAE,CAAA,CACxC,GAAK3U,CAAAA,CAEL,CAAA,GAAIA,CAAAA,CAAK,IAAA,GAAS,MAAA,CAAQ,CAGxB,IAAM0C,CAAAA,CAAAA,CAAAA,CAFY1C,CAAAA,CAAK,IAAA,EAAgC,IACP,IAAA,EAA6B,OAAA,IAC9B,OAAA,CAAU,MAAA,CAAS,OAAA,CAC9DyB,CAAAA,CACFA,CAAAA,CAAiBzB,CAAAA,CAAK,EAAA,CAAI0C,CAAI,CAAA,CAG9BV,CAAAA,CAAUE,CAAAA,EAAUA,CAAAA,CAAM,GAAA,CAAIM,CAAAA,EACxBA,CAAAA,CAAE,EAAA,GAAOxC,CAAAA,CAAK,EAAA,CACT,CAAE,GAAGwC,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,IAAA,CAAME,CAAK,CAAE,CAAA,CAE7CF,EAAE,QAAA,GAAaxC,CAAAA,CAAK,EAAA,CACf,CAAE,GAAGwC,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,IAAA,CAAME,CAAK,CAAE,CAAA,CAE1CF,CACR,CAAC,CAAA,CAEJ,MACF,CAEA,GAAIxC,CAAAA,CAAK,IAAA,GAAS,QAAA,CAAU,CAC1B,IAAM+U,CAAAA,CAAY/U,CAAAA,CAAK,IAAA,EAAgC,EAAC,CAClDgV,CAAAA,CAAU,MAAM,OAAA,CAAQD,CAAAA,CAAS,SAAS,CAAA,EAAKA,CAAAA,CAAS,SAAA,CAAU,MAAA,CAAS,CAAA,CAC3EE,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQF,CAAAA,CAAS,KAAK,CAAA,EAAKA,CAAAA,CAAS,KAAA,CAAM,MAAA,CAAS,CAAA,CAEpErS,CAAAA,CAAAA,CADiCqS,CAAAA,CAAS,IAAA,GAA8BC,CAAAA,EAAW,CAACC,CAAAA,CAAW,MAAA,CAAS,OAAA,CAAA,IAC/D,OAAA,CAAU,MAAA,CAAS,OAAA,CAC9DzT,CAAAA,CACFA,CAAAA,CAAaxB,CAAAA,CAAK,GAAI0C,CAAI,CAAA,CAE1BV,CAAAA,CAAUE,CAAAA,EAAUA,CAAAA,CAAM,GAAA,CAAIM,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOxC,CAAAA,CAAK,EAAA,CAAM,CAAE,GAAGwC,CAAAA,CAAG,IAAA,CAAM,CAAE,GAAGA,CAAAA,CAAE,IAAA,CAAM,IAAA,CAAME,CAAK,CAAE,CAAA,CAAaF,CAAC,CAAC,EAElH,CAAA,CACF,CAAA,CAAG,CAACmS,CAAAA,CAAcvC,CAAAA,CAAa3Q,CAAAA,CAAkBD,EAAcQ,CAAQ,CAAC,CAAA,CAExE,OACEkB,eAAAA,CAAC,KAAA,CAAA,CAAI,GAAA,CAAKuN,CAAAA,CAAkB,SAAA,CAAW,CAAA,EAAGrB,CAAAA,EAAa,EAAE,CAAA,CAAA,EAAIE,CAAAA,GAAc,OAAA,CAAU,kBAAA,CAAqB,iBAAiB,CAAA,CAAA,CAAI,KAAA,CAAO,CAAE,KAAA,CAAO,MAAA,CAAQ,MAAA,CAAQ,MAAA,CAAQ,GAAGxL,CAAM,CAAA,CAC9K,QAAA,CAAA,CAAAZ,eAAAA,CAACgS,mBAAAA,CAAA,CACC,KAAA,CAAOhF,EACP,KAAA,CAAOG,CAAAA,CACP,aAAA,CAAgBuC,CAAAA,EAAY,CAC1BD,EAAAA,CAAkBC,CAAO,CAAA,CACpB/C,CAAAA,CAGHd,CAAAA,EAAyBA,CAAAA,CAAsB2C,EAAAA,CAAe,OAAwB,CAAA,CAFtF5B,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAO4B,EAAAA,CAAe,OAAyB,CAAC,EAI1E,CAAA,CACA,aAAA,CAAgBkB,CAAAA,EAAY,CAC1BrC,EAAAA,CAAcqC,CAAO,CAAA,CAChB/C,CAAAA,CAGHb,CAAAA,EAAyBA,CAAAA,CAAsB2C,GAAe,OAAwB,CAAA,CAFtF7B,CAAAA,CAAW,QAAA,CAAS,CAAE,KAAA,CAAO6B,EAAAA,CAAe,OAAyB,CAAC,EAI1E,CAAA,CACA,SAAA,CAAWkC,EAAAA,CACX,WAAA,CAAaQ,EAAAA,CACb,iBAAA,CAAmBI,EAAAA,CACnB,eAAA,CAAiBrB,EAAAA,CACjB,UAAA,CAAYG,EAAAA,CACZ,cAAA,CAAgBE,EAAAA,CAChB,WAAA,CAAaiB,EAAAA,CACb,MAAA,CAAQnF,CAAAA,CACR,SAAA,CAAWgC,EAAAA,CACX,SAAA,CAAWE,EAAAA,CACX,kBAAA,CAAoB,CAClB,MAAA,CAAQ,GAAA,CACR,aAAA,CAAe,IACjB,CAAA,CACA,cAAA,CAAgB,IAAA,CAChB,gBAAA,CAAkB,IAAA,CAClB,kBAAA,CAAoB,IAAA,CACpB,iBAAA,CAAmB,KAAA,CACnB,OAAA,CAAO,IAAA,CACP,UAAA,CAAY,CAAE,eAAA,CAAiB,IAAK,CAAA,CAEpC,QAAA,CAAA,CAAAxO,cAAAA,CAACkS,oBAAAA,CAAA,EAAW,CAAA,CACZlS,cAAAA,CAACmS,kBAAAA,CAAA,EAAS,CAAA,CACVnS,cAAAA,CAACoS,iBAAAA,CAAA,EAAQ,EACTpS,cAAAA,CAACqS,eAAAA,CAAA,CAAM,QAAA,CAAS,cAAA,CAAe,SAAA,CAAU,4BAAA,CACvC,QAAA,CAAArS,cAAAA,CAAC,GAAA,CAAA,CACC,IAAA,CAAK,wCAAA,CACL,MAAA,CAAO,QAAA,CACP,GAAA,CAAI,qBAAA,CACJ,UAAU,iCAAA,CACX,QAAA,CAAA,gBAAA,CAED,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACCwM,CAAAA,EACCxM,cAAAA,CAAC,QAAA,CAAA,CACC,SAAA,CAAU,iBAAA,CACV,OAAA,CAASgO,EAAAA,CACT,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,IAAKvB,CAAAA,CAAuB,QAAA,CAAS,KAAK,CAAA,CAAI,MAAA,CAAS,MAAA,CACvD,MAAA,CAAQA,CAAAA,CAAuB,QAAA,CAAS,QAAQ,CAAA,CAAI,MAAA,CAAS,MAAA,CAC7D,KAAA,CAAOA,CAAAA,CAAuB,QAAA,CAAS,OAAO,CAAA,CAAI,MAAA,CAAS,MAAA,CAC3D,IAAA,CAAMA,CAAAA,CAAuB,QAAA,CAAS,MAAM,CAAA,CAAI,MAAA,CAAS,MAAA,CACzD,MAAA,CAAQ,GAAA,CACR,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,UACP,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,KAAA,CACd,OAAA,CAAS,gBAAA,CACT,QAAA,CAAU,UAAA,CACV,MAAA,CAAQ,SAAA,CACR,UAAA,CAAY,eAAA,CACZ,GAAGE,CACL,CAAA,CAEC,QAAA,CAAAD,CAAAA,CACH,CAAA,CAEDgF,CAAAA,GAAiBA,CAAAA,CAAa,IAAA,GAAS,MAAA,EAAUA,CAAAA,CAAa,IAAA,GAAS,QAAA,CAAA,EACtE1R,cAAAA,CAAC,KAAA,CAAA,CACC,KAAA,CAAO,CACL,QAAA,CAAU,UAAA,CACV,GAAA,CAAK,GACL,KAAA,CAAO,EAAA,CACP,OAAA,CAAS,MAAA,CACT,GAAA,CAAK,CAAA,CACL,MAAA,CAAQ,GACV,CAAA,CAEA,QAAA,CAAAA,cAAAA,CAAC,QAAA,CAAA,CACC,OAAA,CAAUE,CAAAA,EAAM,CAAEA,CAAAA,CAAE,cAAA,EAAe,CAAG2R,EAAAA,GAAsB,CAAA,CAC5D,KAAA,CAAO,CACL,UAAA,CAAY,SAAA,CACZ,KAAA,CAAO,SAAA,CACP,MAAA,CAAQ,mBAAA,CACR,YAAA,CAAc,CAAA,CACd,OAAA,CAAS,WACT,QAAA,CAAU,EAAA,CACV,UAAA,CAAY,WAAA,CACZ,MAAA,CAAQ,SACV,CAAA,CACA,KAAA,CAAA,CAAQ,IAAM,CACZ,IAAMC,CAAAA,CAAWJ,CAAAA,CAAa,IAAA,CAC9B,GAAIA,CAAAA,CAAa,IAAA,GAAS,MAAA,CAExB,OAAA,CADcI,CAAAA,EAAU,IAAA,EAA6B,OAAA,IACrC,OAAA,CAAU,gBAAA,CAAmB,iBAAA,CACxC,CACL,IAAMC,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQD,CAAAA,EAAU,SAAS,GAAKA,CAAAA,CAAS,SAAA,CAAU,MAAA,CAAS,CAAA,CAC5EE,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQF,CAAAA,EAAU,KAAK,CAAA,EAAKA,CAAAA,CAAS,KAAA,CAAM,MAAA,CAAS,CAAA,CAE3E,OAAA,CADcA,CAAAA,EAAU,IAAA,GAA8BC,CAAAA,EAAW,CAACC,CAAAA,CAAW,MAAA,CAAS,OAAA,CAAA,IACtE,OAAA,CAAU,gBAAA,CAAmB,iBAC/C,CACF,CAAA,GAAG,CAED,QAAA,CAAA,CAAA,IAAM,CACN,IAAMF,CAAAA,CAAWJ,EAAa,IAAA,CAC9B,GAAIA,CAAAA,CAAa,IAAA,GAAS,MAAA,CAExB,OAAA,CADcI,CAAAA,EAAU,IAAA,EAA6B,OAAA,IACrC,OAAA,CAAU,aAAA,CAAW,cAAA,CAChC,CACL,IAAMC,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQD,CAAAA,EAAU,SAAS,CAAA,EAAKA,CAAAA,CAAS,SAAA,CAAU,MAAA,CAAS,CAAA,CAC5EE,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQF,CAAAA,EAAU,KAAK,CAAA,EAAKA,CAAAA,CAAS,KAAA,CAAM,OAAS,CAAA,CAE3E,OAAA,CADcA,CAAAA,EAAU,IAAA,GAA8BC,CAAAA,EAAW,CAACC,CAAAA,CAAW,MAAA,CAAS,OAAA,CAAA,IACtE,OAAA,CAAU,aAAA,CAAW,cACvC,CACF,CAAA,GAAG,CACL,CAAA,CACF,CAAA,CAAA,CAEJ,CAEJ,CAAA,CAEaM,EAAAA,CAAiD7G,CAAAA,EAE1DzL,cAAAA,CAACuS,2BAAAA,CAAA,CACC,QAAA,CAAAvS,cAAAA,CAAC2L,EAAAA,CAAA,CAAqB,GAAGF,CAAAA,CAAO,CAAA,CAClC,MC7uBS+G,EAAAA,CAA8BnX,CAAAA,GAClC,CACL,EAAA,CAAI,CAAA,KAAA,EAAQA,CAAAA,CAAK,EAAE,CAAA,CAAA,CACnB,IAAA,CAAM,MAAA,CACN,QAAA,CAAU,CAAE,CAAA,CAAG,CAAA,CAAG,CAAA,CAAG,CAAE,CAAA,CACvB,IAAA,CAAM,CACJ,KAAA,CAAOA,CAAAA,CAAK,IAAA,CACZ,MAAA,CAAU,OAAOA,CAAAA,CAAK,MAAA,EAAW,QAAA,EAAYA,CAAAA,CAAK,MAAA,CAAWA,CAAAA,CAAK,MAAA,CAA8B,KAAA,CAAQA,EAAK,MAAA,CAC7G,OAAA,CAASA,CAAAA,CAAK,QAAA,EAAYA,CAAAA,CAAK,KAAA,EAAS,EAAA,CACxC,WAAA,CAAaA,CAAAA,CAAK,EAAA,CAClB,aAAA,CAAe,MAAA,CACf,UAAA,CAAYA,CAAAA,CAAK,WAAA,CACjB,MAAA,CAAQA,CAAAA,CAAK,MAAA,CACb,QAAA,CAAUA,CAAAA,CAAK,SAAA,CACf,IAAA,CAAO,OAAOA,CAAAA,CAAK,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAK,IAAA,CAASA,CAAAA,CAAK,IAAA,CAA2B,IAAA,CAAOA,CAAAA,CAAK,KAClG,IAAA,CAAO,OAAOA,CAAAA,CAAK,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAK,IAAA,CAASA,CAAAA,CAAK,IAAA,CAA2B,IAAA,CAAOA,CAAAA,CAAK,IAAA,CAClG,MAAA,CAAS,OAAOA,CAAAA,CAAK,MAAA,EAAW,QAAA,EAAYA,CAAAA,CAAK,MAAA,CAAWA,CAAAA,CAAK,MAAA,CAA6B,IAAA,CAAOA,CAAAA,CAAK,MAC5G,CACF,CAAA,CAAA,CAMWoX,EAAAA,CAAgC7W,CAAAA,GACpC,CACL,EAAA,CAAI,CAAA,OAAA,EAAUA,CAAAA,CAAO,EAAE,CAAA,CAAA,CACvB,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,CAAE,CAAA,CAAG,CAAA,CAAG,CAAA,CAAG,CAAE,CAAA,CACvB,QAAA,CAAUA,CAAAA,CAAO,IAAA,CAAO,CAAA,KAAA,EAAS,OAAOA,CAAAA,CAAO,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAO,IAAA,CAAQA,CAAAA,CAAO,IAAA,CAAkC,EAAA,CAAKA,CAAAA,CAAO,IAAK,CAAA,CAAA,CAAK,MAAA,CAClJ,MAAA,CAAQA,CAAAA,CAAO,IAAA,CAAO,QAAA,CAAW,MAAA,CACjC,KAAM,CACJ,KAAA,CAAOA,CAAAA,CAAO,IAAA,CACd,MAAA,CAAU,OAAOA,CAAAA,CAAO,MAAA,EAAW,QAAA,EAAYA,CAAAA,CAAO,MAAA,CAAWA,CAAAA,CAAO,MAAA,CAA8B,KAAA,CAAQA,CAAAA,CAAO,MAAA,CACrH,UAAA,CAAYA,CAAAA,CAAO,WAAA,EAAa,KAAA,EAASA,CAAAA,CAAO,KAAA,CAChD,YAAA,CAAeA,CAAAA,CAAO,WAAA,EAAa,YAAA,EAAc,IAAA,EAAQA,CAAAA,CAAO,YAAA,CAEhE,IAAA,CAAO,OAAOA,CAAAA,CAAO,aAAgB,QAAA,EAAYA,CAAAA,CAAO,WAAA,CAAgBA,CAAAA,CAAO,WAAA,CAAkC,IAAA,CAAQA,CAAAA,CAAe,IAAA,CACxI,OAAA,CAASA,CAAAA,CAAO,WAAA,EAAa,QAAA,EAAYA,CAAAA,CAAO,QAAA,EAAY,CAAA,CAC5D,SAAA,CAAWA,CAAAA,CAAO,QAAA,EAAY,CAAA,CAC9B,IAAA,CAAOA,CAAAA,CAAO,IAAA,EAA6B,OAAA,CAC3C,WAAA,CAAaA,CAAAA,CAAO,EAAA,CACpB,aAAA,CAAe,QAAA,CACf,UAAA,CAAa,OAAOA,CAAAA,CAAO,WAAA,EAAgB,UAAYA,CAAAA,CAAO,WAAA,CAAgBA,CAAAA,CAAO,WAAA,CAAqC,OAAA,CAAUA,CAAAA,CAAO,WAAA,CAC3I,UAAA,CAAa,OAAOA,CAAAA,CAAO,WAAA,EAAgB,QAAA,EAAYA,CAAAA,CAAO,WAAA,CAAgBA,CAAAA,CAAO,WAAA,CAAqC,OAAA,CAAUA,CAAAA,CAAO,WAAA,CAC3I,IAAA,CAAO,OAAOA,CAAAA,CAAO,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAO,IAAA,CAASA,CAAAA,CAAO,IAAA,CAA2B,IAAA,CAAOA,CAAAA,CAAO,IAAA,CAE1G,IAAA,CAAO,OAAOA,CAAAA,CAAO,IAAA,EAAS,QAAA,EAAYA,CAAAA,CAAO,IAAA,CAASA,CAAAA,CAAO,IAAA,CAA2B,IAAA,CAAQA,CAAAA,CAAO,IAC7G,CACF,CAAA,CAAA,CAMW8W,EAAAA,CAA+BC,CAAAA,EAA0C,CACpF,IAAMC,CAAAA,CAAeC,CAAAA,EAA6C,CAChE,GAAI,CAACA,CAAAA,CAAM,OACX,GAAI,OAAOA,CAAAA,EAAS,QAAA,CAAU,OAAOA,CAAAA,CAErC,IAAMC,CAAAA,CAAOD,CAAAA,CAAa,OAC1B,OAAI,OAAOC,CAAAA,EAAQ,QAAA,EAAYA,CAAAA,CAAaA,CAAAA,CAAiC,EAAA,CACtEA,CACT,CAAA,CACMC,CAAAA,CAAgBH,CAAAA,CAAYD,CAAAA,CAAM,aAAa,CAAA,CAC/CK,CAAAA,CAAgBJ,CAAAA,CAAYD,EAAM,aAAa,CAAA,CACrD,OAAO,CACL,EAAA,CAAI,CAAA,MAAA,EAASA,CAAAA,CAAM,EAAE,CAAA,CAAA,CACrB,MAAA,CAAQ,CAAA,OAAA,EAAUI,CAAa,CAAA,CAAA,CAC/B,MAAA,CAAQ,CAAA,OAAA,EAAUC,CAAa,GAC/B,IAAA,CAAM,OAAA,CACN,IAAA,CAAM,CACJ,SAAA,CAAWL,CAAAA,CAAM,IAAA,EAAM,KAAA,EAASA,CAAAA,CAAM,SAAA,CACtC,MAAA,CAAQA,CAAAA,CAAM,MAAA,EAAU,CAAA,CACxB,KAAA,CAAOA,CAAAA,CAAM,KAAA,CACb,WAAA,CAAaA,CAAAA,CAAM,EAAA,CACnB,aAAA,CAAe,OAAA,CACf,MAAA,CAAU,OAAOA,CAAAA,CAAM,MAAA,EAAW,QAAA,EAAYA,CAAAA,CAAM,MAAA,CAAWA,CAAAA,CAAM,MAAA,CAA8B,KAAA,CAAQA,EAAM,MAAA,CAEjH,YAAA,CAAe,OAAOA,CAAAA,CAAM,aAAA,EAAkB,QAAA,EAAYA,CAAAA,CAAM,aAAA,CAAkBA,CAAAA,CAAM,aAAA,CAAoC,IAAA,CAAQA,CAAAA,CAAM,aAAA,CAE1I,YAAA,CAAe,OAAOA,CAAAA,CAAM,aAAA,EAAkB,QAAA,EAAYA,CAAAA,CAAM,aAAA,CAAkBA,CAAAA,CAAM,aAAA,CAAoC,IAAA,CAAQA,CAAAA,CAAM,aAC5I,CACF,CACF,CAAA,CAKaM,EAAAA,CAA6B7U,CAAAA,EAIY,CACpD,IAAMa,EAAuB,EAAC,CACxB2L,CAAAA,CAAuB,EAAC,CAE9B,OAAAxM,CAAAA,CAAK,KAAA,CAAM,OAAA,CAAQ/C,CAAAA,EAAQ4D,CAAAA,CAAM,IAAA,CAAKuT,EAAAA,CAA2BnX,CAAI,CAAC,CAAC,CAAA,CACvE+C,CAAAA,CAAK,OAAA,CAAQ,OAAA,CAAQxC,CAAAA,EAAUqD,CAAAA,CAAM,IAAA,CAAKwT,EAAAA,CAA6B7W,CAAM,CAAC,CAAC,CAAA,CAC/EwC,CAAAA,CAAK,MAAA,CAAO,OAAA,CAAQuU,CAAAA,EAAS/H,EAAM,IAAA,CAAK8H,EAAAA,CAA4BC,CAAK,CAAC,CAAC,CAAA,CAEpE,CAAE,KAAA,CAAA1T,CAAAA,CAAO,KAAA,CAAA2L,CAAM,CACxB,CAAA,CAKasI,EAAAA,CAAkBjU,CAAAA,EAAwC,CACrE,IAAMkU,CAAAA,CAAYlU,CAAAA,CAAM,MAAA,CAAOM,CAAAA,EAAKA,CAAAA,CAAE,IAAA,GAAS,MAAM,CAAA,CAC/C6T,CAAAA,CAAcnU,CAAAA,CAAM,MAAA,CAAOM,CAAAA,EAAKA,CAAAA,CAAE,IAAA,GAAS,QAAQ,EACnD8T,CAAAA,CAAapU,CAAAA,CAAM,MAAA,CAAOM,CAAAA,EAAK,CAAC,CAAC,MAAA,CAAQ,QAAQ,CAAA,CAAE,QAAA,CAASA,CAAAA,CAAE,IAAI,CAAC,CAAA,CAEzE,OAAA4T,CAAAA,CAAU,OAAA,CAAQ,CAAC9X,CAAAA,CAAMoU,CAAAA,GAAU,CACjCpU,CAAAA,CAAK,QAAA,CAAW,CAAE,CAAA,CAAGoU,CAAAA,CAAQ,GAAA,CAAK,CAAA,CAAG,GAAI,EAC3C,CAAC,CAAA,CAED2D,EAAY,OAAA,CAAQxX,CAAAA,EAAU,CAC5B,GAAIA,CAAAA,CAAO,QAAA,CAAU,CACnB,IAAM2T,CAAAA,CAAa4D,CAAAA,CAAU,IAAA,CAAKvE,CAAAA,EAAKA,CAAAA,CAAE,EAAA,GAAOhT,CAAAA,CAAO,QAAQ,CAAA,CAC/D,GAAI2T,CAAAA,CAAY,CACd,IAAMhU,CAAAA,CAAYK,CAAAA,CAAO,IAAA,CAAK,SAAA,EAAa,CAAA,CACrCG,CAAAA,CAAUH,CAAAA,CAAO,IAAA,CAAK,OAAA,EAAW,CAAA,CACvCA,CAAAA,CAAO,SAAW,CAChB,CAAA,CAAG2T,CAAAA,CAAW,QAAA,CAAS,CAAA,CAAI,EAAA,CAC3B,CAAA,CAAGA,CAAAA,CAAW,QAAA,CAAS,CAAA,CAAKhU,CAAAA,CAAY,EAAA,CAAOQ,CAAAA,CAAU,EAC3D,EACF,CACF,CAAA,KACEH,CAAAA,CAAO,QAAA,CAAW,CAAE,CAAA,CAAG,IAAA,CAAK,MAAA,EAAO,CAAI,GAAA,CAAM,GAAA,CAAK,CAAA,CAAG,IAAA,CAAK,MAAA,EAAO,CAAI,GAAA,CAAM,EAAG,EAElF,CAAC,CAAA,CAEDyX,CAAAA,CAAW,OAAA,CAAQ,CAACtW,CAAAA,CAAM0S,CAAAA,GAAU,CAClC1S,CAAAA,CAAK,QAAA,CAAW,CAAE,CAAA,CAAG0S,CAAAA,CAAQ,GAAA,CAAM,GAAA,CAAK,CAAA,CAAG,GAAI,EACjD,CAAC,CAAA,CAEMxQ,CACT,ECtKO,IAAMqU,EAAAA,CAAN,cAAmC,KAAM,CAC9C,WAAA,CACSC,CAAAA,CACAC,CAAAA,CACAjY,CAAAA,CACAQ,CAAAA,CACA0X,EACP,CACA,KAAA,CACE,CAAA,2BAAA,EAA8BD,CAAQ,CAAA,KAAA,EAAQjY,CAAS,CAAA,CAAA,EAAIA,CAAAA,CAAYQ,CAAAA,CAAU,CAAC,CAAA,SAAA,EAAYwX,CAAM,CAAA,EAClGE,CAAAA,CAAe,CAAA,gBAAA,EAAmBA,CAAY,CAAA,CAAA,CAAK,EACrD,CAAA,CACF,CAAA,CAVO,IAAA,CAAA,MAAA,CAAAF,CAAAA,CACA,IAAA,CAAA,QAAA,CAAAC,CAAAA,CACA,IAAA,CAAA,SAAA,CAAAjY,CAAAA,CACA,IAAA,CAAA,OAAA,CAAAQ,CAAAA,CACA,IAAA,CAAA,YAAA,CAAA0X,CAAAA,CAOP,IAAA,CAAK,IAAA,CAAO,uBACd,CACF,EAwBO,SAASC,EAAAA,CACdrY,CAAAA,CACAsY,CAAAA,CAA8B,EAAC,CACJ,CAC3B,IAAMC,CAAAA,CAAoD,EAAC,CACrDC,CAAAA,CAAwD,EAAC,CAG/D,IAAA,IAAWjY,CAAAA,IAAUP,CAAAA,CAAK,OAAA,CACNO,CAAAA,CAAO,IAAA,CAAOA,CAAAA,CAAO,MAAA,CAAS,CAAA,CAChCP,CAAAA,CAAK,KAAA,EACnBwY,CAAAA,CAAY,IAAA,CAAK,CACf,QAAA,CAAUjY,CAAAA,CAAO,GACjB,SAAA,CAAWA,CAAAA,CAAO,IAAA,CAClB,OAAA,CAASA,CAAAA,CAAO,MAAA,CAChB,WAAA,CAAaP,CAAAA,CAAK,KACpB,CAAC,CAAA,CAKL,IAAA,IAASwE,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIxE,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAQwE,CAAAA,EAAAA,CAAK,CAC5C,IAAMiU,CAAAA,CAAUzY,CAAAA,CAAK,OAAA,CAAQwE,CAAC,CAAA,CACxBkU,CAAAA,CAAeD,CAAAA,CAAQ,IAAA,CACvBE,CAAAA,CAAaF,CAAAA,CAAQ,IAAA,CAAOA,EAAQ,MAAA,CAAS,CAAA,CAEnD,IAAA,IAASG,CAAAA,CAAIpU,CAAAA,CAAI,CAAA,CAAGoU,CAAAA,CAAI5Y,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAQ4Y,CAAAA,EAAAA,CAAK,CAChD,IAAMC,CAAAA,CAAU7Y,CAAAA,CAAK,OAAA,CAAQ4Y,CAAC,CAAA,CACxBE,CAAAA,CAAeD,CAAAA,CAAQ,IAAA,CACvBE,CAAAA,CAAaF,CAAAA,CAAQ,IAAA,CAAOA,CAAAA,CAAQ,MAAA,CAAS,CAAA,CAG/CH,CAAAA,EAAgBK,CAAAA,EAAcJ,CAAAA,EAAcG,CAAAA,EAC9CP,CAAAA,CAAU,KAAK,CACb,QAAA,CAAUE,CAAAA,CAAQ,EAAA,CAClB,SAAA,CAAWA,CAAAA,CAAQ,IAAA,CACnB,OAAA,CAASA,CAAAA,CAAQ,MAAA,CACjB,YAAA,CAAcI,CAAAA,CAAQ,EACxB,CAAC,EAEL,CACF,CAEA,OAAO,CACL,OAAA,CAASN,CAAAA,CAAU,MAAA,GAAW,CAAA,EAAKC,CAAAA,CAAY,MAAA,GAAW,CAAA,CAC1D,SAAA,CAAAD,CAAAA,CACA,WAAA,CAAAC,CACF,CACF,CAKA,SAASQ,EAAAA,CACPzY,CAAAA,CACAP,CAAAA,CACAiN,CAAAA,CAA6B,EAAC,CACjB,CACb,GAAM,CAAE,iBAAA,CAAAgM,CAAAA,CAAoB,EAAG,CAAA,CAAIhM,CAAAA,CAG7BiM,CAAAA,CAAWD,CAAAA,CAAkB1Y,CAAAA,CAAO,IAAI,CAAA,EAAK,QAAA,CAG7C+H,CAAAA,CAAWlG,EAAAA,CAA6BpC,CAAAA,CAAMO,CAAAA,CAAO,IAAA,CAAMA,CAAAA,CAAO,MAAM,CAAA,CAG9E,OAAO,CACL,EAAA,CAAIA,EAAO,EAAA,CACX,IAAA,CAAM2Y,CAAAA,CACN,QAAA,CAAA5Q,CAAAA,CACA,QAAA,CAAUtI,CAAAA,CAAK,EAAA,CACf,MAAA,CAAQ,QAAA,CACR,IAAA,CAAM,CACJ,KAAA,CAAOO,CAAAA,CAAO,IAAA,CACd,MAAA,CAAQ,QAAA,CACR,UAAA,CAAYA,CAAAA,CAAO,IAAA,CACnB,OAAA,CAASA,CAAAA,CAAO,MAAA,CAChB,SAAA,CAAWA,CAAAA,CAAO,IAAA,CAClB,KAAA,CAAOA,CAAAA,CAAO,KAAA,EAAS,MAAA,CAEvB,IAAA,CAAMA,CAAAA,CAAO,KACb,KAAA,CAAOA,CAAAA,CAAO,KAAA,CACd,SAAA,CAAWA,CAAAA,CAAO,SAAA,CAClB,WAAA,CAAaA,CAAAA,CAAO,WACtB,CACF,CACF,CAKA,SAAS4Y,EAAAA,CAAenZ,CAAAA,CAA+B,CACrD,OAAO,CACL,EAAA,CAAIA,CAAAA,CAAK,EAAA,CACT,IAAA,CAAM,MAAA,CACN,QAAA,CAAUA,CAAAA,CAAK,QAAA,CACf,IAAA,CAAM,CACJ,KAAA,CAAOA,CAAAA,CAAK,IAAA,CACZ,MAAA,CAAQ,QAAA,CACR,QAASA,CAAAA,CAAK,KAAA,CACd,mBAAA,CAAqBA,CAAAA,CAAK,mBAAA,EAAuB,WAAA,CACjD,gBAAA,CAAkBA,CAAAA,CAAK,gBAAA,CACvB,KAAA,CAAO,EACT,CACF,CACF,CAKO,SAASoZ,EAAAA,CACdlK,CAAAA,CACAjC,CAAAA,CAA6B,EAAC,CACf,CACf,GAAM,CAAE,cAAA,CAAAoM,CAAAA,CAAiB,QAAA,CAAU,kBAAA,CAAAC,CAAAA,CAAqB,IAAK,CAAA,CAAIrM,CAAAA,CAC3DrJ,EAAuB,EAAC,CACxBmU,CAAAA,CAA6B,EAAC,CAGpC,GAAIuB,CAAAA,CACF,IAAA,IAAWtZ,CAAAA,IAAQkP,CAAAA,CAAO,CACxB,IAAM2G,CAAAA,CAAawC,EAAAA,CAA6BrY,CAAAA,CAAMiN,CAAO,CAAA,CAE7D,GAAI,CAAC4I,CAAAA,CAAW,OAAA,EACVwD,CAAAA,GAAmB,QAAA,CAAU,CAE/B,IAAME,CAAAA,CAAmB,EAAC,CAE1B,MAAA1D,CAAAA,CAAW,SAAA,CAAU,OAAA,CAAQ2D,GAAY,CACvCD,CAAAA,CAAO,IAAA,CACL,CAAA,OAAA,EAAUC,CAAAA,CAAS,QAAQ,CAAA,KAAA,EAAQA,CAAAA,CAAS,SAAS,CAAA,CAAA,EAAIA,CAAAA,CAAS,SAAA,CAAYA,CAAAA,CAAS,OAAA,CAAU,CAAC,CAAA,gBAAA,EAAmBA,CAAAA,CAAS,YAAY,CAAA,CAC5I,EACF,CAAC,CAAA,CAED3D,CAAAA,CAAW,WAAA,CAAY,OAAA,CAAQ4D,CAAAA,EAAS,CACtCF,CAAAA,CAAO,IAAA,CACL,CAAA,OAAA,EAAUE,CAAAA,CAAM,QAAQ,QAAQA,CAAAA,CAAM,SAAS,CAAA,CAAA,EAAIA,CAAAA,CAAM,SAAA,CAAYA,CAAAA,CAAM,OAAA,CAAU,CAAC,CAAA,sBAAA,EAAyBA,CAAAA,CAAM,WAAW,CAAA,EAAA,CAClI,EACF,CAAC,CAAA,CAEK,IAAIxB,EAAAA,CACRjY,CAAAA,CAAK,EAAA,CACL6V,CAAAA,CAAW,SAAA,CAAU,CAAC,CAAA,EAAG,QAAA,EAAYA,CAAAA,CAAW,WAAA,CAAY,CAAC,CAAA,EAAG,QAAA,EAAY,SAAA,CAC5EA,CAAAA,CAAW,SAAA,CAAU,CAAC,CAAA,EAAG,SAAA,EAAaA,CAAAA,CAAW,WAAA,CAAY,CAAC,CAAA,EAAG,SAAA,EAAa,CAAA,CAC9EA,CAAAA,CAAW,SAAA,CAAU,CAAC,CAAA,EAAG,OAAA,EAAWA,CAAAA,CAAW,WAAA,CAAY,CAAC,CAAA,EAAG,OAAA,EAAW,CAC5E,CACF,CAEJ,CAIF,IAAA,IAAW7V,CAAAA,IAAQkP,CAAAA,CAAO,CACxB,IAAMyF,CAAAA,CAAWwE,EAAAA,CAAenZ,CAAI,CAAA,CACpC4D,CAAAA,CAAM,KAAK+Q,CAAQ,CAAA,CAGnB,IAAA,IAAWpU,CAAAA,IAAUP,CAAAA,CAAK,OAAA,CACxB,GAAI,CACF,IAAMsM,CAAAA,CAAa0M,EAAAA,CAAiBzY,CAAAA,CAAQoU,CAAAA,CAAU1H,CAAO,CAAA,CAC7D8K,CAAAA,CAAY,IAAA,CAAKzL,CAAU,EAC7B,CAAA,MAASyG,CAAAA,CAAO,CACd,GAAIsG,CAAAA,GAAmB,QAAA,CACrB,MAAMtG,CAAAA,CACD,GAAIsG,CAAAA,GAAmB,SAAA,CAAW,CAEvC,IAAMnY,EAAoBC,EAAAA,CACxBwT,CAAAA,CACA,CAAE,EAAA,CAAIpU,CAAAA,CAAO,EAAA,CAA8C,IAAA,CAAM,CAAE,KAAA,CAAOA,CAAAA,CAAO,IAAA,CAAM,OAAA,CAASA,CAAAA,CAAO,MAAO,CAAE,CAAA,CAChHwX,CAAAA,CACAxX,CAAAA,CAAO,IACT,CAAA,CAEA,GAAIW,CAAAA,GAAsBX,CAAAA,CAAO,KAAM,CACrC,OAAA,CAAQ,IAAA,CACN,CAAA,OAAA,EAAUA,CAAAA,CAAO,EAAE,CAAA,aAAA,EAAgBA,CAAAA,CAAO,IAAI,CAAA,KAAA,EAAQW,CAAiB,CAAA,gBAAA,CACzE,CAAA,CAEA,IAAMwY,CAAAA,CAAiB,CAAE,GAAGnZ,CAAAA,CAAQ,IAAA,CAAMW,CAAkB,CAAA,CACtDoL,CAAAA,CAAa0M,EAAAA,CAAiBU,CAAAA,CAAgB/E,CAAAA,CAAU1H,CAAO,CAAA,CACrE8K,CAAAA,CAAY,IAAA,CAAKzL,CAAU,EAC7B,CAAA,WACQ,IAAI2L,EAAAA,CAAqBjY,CAAAA,CAAK,EAAA,CAAIO,CAAAA,CAAO,EAAA,CAAIA,CAAAA,CAAO,IAAA,CAAMA,CAAAA,CAAO,MAAM,CAEjF,CACF,CAEJ,CAGA,OAAAqD,CAAAA,CAAM,IAAA,CAAK,GAAGmU,CAAW,CAAA,CAElBnU,CACT,CAKO,SAAS+V,EAAAA,CAA0B/V,CAAAA,CAAoC,CAC5E,IAAMsL,CAAAA,CAAsB,EAAC,CACvB4I,CAAAA,CAAYlU,CAAAA,CAAM,OAAOlC,CAAAA,EAAQA,CAAAA,CAAK,IAAA,GAAS,MAAM,CAAA,CAE3D,IAAA,IAAWiT,CAAAA,IAAYmD,CAAAA,CAAW,CAKhC,IAAM8B,CAAAA,CAJchW,CAAAA,CAAM,MAAA,CACxBlC,CAAAA,EAAQA,CAAAA,CAAK,IAAA,GAAS,QAAA,EAAYA,CAAAA,CAAK,QAAA,GAAaiT,CAAAA,CAAS,EAC/D,CAAA,CAE0C,GAAA,CAAIrI,CAAAA,GAAe,CAC3D,EAAA,CAAIA,CAAAA,CAAW,EAAA,CACf,IAAA,CAAMA,CAAAA,CAAW,IAAA,CAAK,KAAA,CACtB,KAAMA,CAAAA,CAAW,IAAA,CAAK,SAAA,EAAa,CAAA,CACnC,MAAA,CAAQA,CAAAA,CAAW,IAAA,CAAK,OAAA,EAAW,CAAA,CACnC,IAAA,CAAOA,CAAAA,CAAW,IAAA,CAAK,UAAA,EAAqC,QAAA,CAC5D,KAAA,CAAOA,CAAAA,CAAW,IAAA,CAAK,KAAA,CACvB,KAAA,CAAOA,CAAAA,CAAW,IAAA,CAAK,KAAA,CACvB,WAAA,CAAaA,CAAAA,CAAW,IAAA,CAAK,WAC/B,CAAA,CAAE,CAAA,CAEF4C,CAAAA,CAAM,IAAA,CAAK,CACT,EAAA,CAAIyF,EAAS,EAAA,CACb,IAAA,CAAMA,CAAAA,CAAS,IAAA,CAAK,KAAA,CACpB,QAAA,CAAUA,CAAAA,CAAS,QAAA,CACnB,KAAA,CAAOA,CAAAA,CAAS,IAAA,CAAK,OAAA,EAAW,EAAA,CAChC,mBAAA,CAAqBA,CAAAA,CAAS,IAAA,CAAK,mBAAA,EAAuB,WAAA,CAC1D,gBAAA,CAAkBA,CAAAA,CAAS,IAAA,CAAK,gBAAA,CAChC,OAAA,CAAAiF,CACF,CAAC,EACH,CAEA,OAAO1K,CACT,CAKO,SAAS3M,EAAAA,CACd2M,EACAgJ,CAAAA,CACAC,CAAAA,CACA3V,CAAAA,CACc,CACd,OAAO0M,CAAAA,CAAM,GAAA,CAAIlP,CAAAA,EACXA,CAAAA,CAAK,EAAA,GAAOkY,CAAAA,CAAelY,CAAAA,CAExB,CACL,GAAGA,CAAAA,CACH,OAAA,CAASA,CAAAA,CAAK,OAAA,CAAQ,GAAA,CAAIO,CAAAA,EACpBA,CAAAA,CAAO,EAAA,GAAO4X,CAAAA,CAAiB5X,CAAAA,CAC5B,CAAE,GAAGA,CAAAA,CAAQ,IAAA,CAAMiC,CAAa,CACxC,CACH,CACD,CACH,CAKO,SAASqX,EAAAA,CACd3K,CAAAA,CACAgJ,CAAAA,CACA3X,CAAAA,CACA0M,CAAAA,CAA6B,EAAC,CAChB,CACd,GAAM,CAAE,cAAA,CAAAoM,CAAAA,CAAiB,QAAS,CAAA,CAAIpM,CAAAA,CAEtC,OAAOiC,CAAAA,CAAM,GAAA,CAAIlP,CAAAA,EAAQ,CACvB,GAAIA,CAAAA,CAAK,EAAA,GAAOkY,CAAAA,CAAQ,OAAOlY,CAAAA,CAG/B,GAAIqZ,CAAAA,GAAmB,QAAA,EAMjB,CALehB,GACjB,CAAE,GAAGrY,CAAAA,CAAM,OAAA,CAAS,CAAC,GAAGA,CAAAA,CAAK,OAAA,CAASO,CAAM,CAAE,CAAA,CAC9C0M,CACF,CAAA,CAEgB,OAAA,CACd,MAAM,IAAIgL,EAAAA,CAAqBC,CAAAA,CAAQ3X,CAAAA,CAAO,EAAA,CAAIA,CAAAA,CAAO,IAAA,CAAMA,CAAAA,CAAO,MAAM,CAAA,CAIhF,OAAO,CACL,GAAGP,CAAAA,CACH,OAAA,CAAS,CAAC,GAAGA,EAAK,OAAA,CAASO,CAAM,CACnC,CACF,CAAC,CACH,CAKO,SAASuZ,EAAAA,CACd5K,CAAAA,CACAgJ,CAAAA,CACAC,CAAAA,CACc,CACd,OAAOjJ,CAAAA,CAAM,GAAA,CAAIlP,GACXA,CAAAA,CAAK,EAAA,GAAOkY,CAAAA,CAAelY,CAAAA,CAExB,CACL,GAAGA,CAAAA,CACH,OAAA,CAASA,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAOO,CAAAA,EAAUA,CAAAA,CAAO,EAAA,GAAO4X,CAAQ,CAC/D,CACD,CACH","file":"index.js","sourcesContent":["import { NetworkNode, UNumberingDirection } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from './constants';\n\n/**\n * Get the default U numbering direction\n */\nexport const getDefaultUNumberingDirection = (): UNumberingDirection => 'bottom-up';\n\n/**\n * Get the U numbering direction for a rack\n */\nexport const getRackUNumberingDirection = (rack: NetworkNode): UNumberingDirection => {\n return rack.data.uNumberingDirection || getDefaultUNumberingDirection();\n};\n\n/**\n * Convert U position number based on numbering direction\n * For bottom-up: U position 1 is at the bottom\n * For top-down: U position 1 is at the top\n */\nexport const convertUPositionForDirection = (\n uPosition: number,\n rackUHeight: number,\n direction: UNumberingDirection\n): number => {\n if (direction === 'bottom-up') {\n // For bottom-up, U position 1 is at the bottom, so we need to flip the numbering\n return rackUHeight - uPosition + 1;\n }\n // For top-down, U position 1 is at the top, so no conversion needed\n return uPosition;\n};\n\n/**\n * Convert U position number back to physical position\n */\nexport const convertUPositionFromDirection = (\n uPosition: number,\n rackUHeight: number,\n direction: UNumberingDirection\n): number => {\n if (direction === 'bottom-up') {\n // For bottom-up, convert back from the flipped numbering\n return rackUHeight - uPosition + 1;\n }\n // For top-down, no conversion needed\n return uPosition;\n};\n\n/**\n * Calculate U position from device Y coordinate within a rack\n */\nexport const calculateUPositionFromY = (\n deviceY: number,\n rackY: number,\n rackUHeight: number = 42,\n direction: UNumberingDirection = 'bottom-up'\n): number => {\n const startY = RACK_HEADER_HEIGHT; // Start at top of rack body\n const relativeY = deviceY - rackY - startY;\n const physicalUPosition = Math.max(1, Math.min(rackUHeight, Math.round(relativeY / U_HEIGHT_PX) + 1));\n \n // Convert to the appropriate numbering direction\n return convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\n};\n\n/**\n * Snap a device position to the nearest U position within a rack\n */\nexport const snapToUPosition = (\n device: NetworkNode,\n rack: NetworkNode,\n newPosition: { x: number; y: number },\n allNodes: NetworkNode[]\n): { x: number; y: number; uPosition?: number } => {\n if (!device.parentId || device.parentId !== rack.id) {\n return newPosition;\n }\n\n const uHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n const direction = getRackUNumberingDirection(rack);\n \n // Calculate U position based on Y coordinate\n const startY = RACK_HEADER_HEIGHT; // After header\n \n // Calculate which U position this corresponds to\n // Y coordinate represents the MIDDLE of the device for better drag behavior\n const relativeY = newPosition.y - startY; // child position is already parent-relative\n const physicalUPosition = Math.round(relativeY / U_HEIGHT_PX) + 1;\n \n // Convert to logical U position based on direction\n // For snapping, we want to find the U position that corresponds to the Y position\n // The Y position represents where the user wants to place the device\n let calculatedUPosition;\n if (direction === 'bottom-up') {\n // For bottom-up, the logical U position represents the BOTTOM of the device\n // But the Y position represents the TOP of the device\n // So we need to adjust for the device height\n const logicalPosition = convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\n calculatedUPosition = logicalPosition - uHeight + 1;\n } else {\n // For top-down, the logical U position represents the TOP of the device\n const logicalPosition = convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\n calculatedUPosition = logicalPosition;\n }\n \n // Ensure the device doesn't extend beyond the rack boundaries\n // For multi-U devices, we need to ensure the entire device fits\n const maxUPosition = rackUHeight - uHeight + 1;\n let snappedUPosition = Math.max(1, Math.min(maxUPosition, calculatedUPosition));\n \n // For top-down numbering, ensure we can place devices at the top (U1)\n if (direction === 'top-down' && calculatedUPosition <= 1) {\n snappedUPosition = 1;\n }\n \n // Debug logging (commented out for production)\n // console.log('SnapToUPosition Debug:', {\n // deviceId: device.id,\n // newPosition,\n // rackPosition: rack.position,\n // startY,\n // relativeY,\n // physicalUPosition,\n // calculatedUPosition,\n // snappedUPosition,\n // uHeight,\n // rackUHeight,\n // direction\n // });\n \n // Check if the calculated position is available, if not find the nearest available position\n if (!isUPositionAvailable(rack, device, snappedUPosition, allNodes)) {\n // Try to find the nearest available position\n const availablePosition = findNextAvailableUPosition(rack, device, allNodes, snappedUPosition);\n if (availablePosition !== snappedUPosition) {\n snappedUPosition = availablePosition;\n }\n }\n \n // Snap to exact U position - ensure devices are exactly on U boundaries\n // Account for device border (1px) to align properly with U grid\n // The Y coordinate should ALWAYS represent the TOP of the device\n // For bottom-up direction, we need to calculate the Y position of the TOP of the device\n let snappedY;\n if (direction === 'bottom-up') {\n // For bottom-up, the logical U position represents the BOTTOM of the device\n // So we need to calculate the Y position of the TOP of the device\n const topLogicalUPosition = snappedUPosition + uHeight - 1;\n const topPhysicalUPosition = convertUPositionFromDirection(topLogicalUPosition, rackUHeight, direction);\n snappedY = startY + (topPhysicalUPosition - 1) * U_HEIGHT_PX - 1;\n } else {\n // For top-down, the logical U position represents the TOP of the device\n const snappedPhysicalUPosition = convertUPositionFromDirection(snappedUPosition, rackUHeight, direction);\n snappedY = startY + (snappedPhysicalUPosition - 1) * U_HEIGHT_PX - 1;\n }\n \n return {\n x: newPosition.x,\n y: snappedY,\n uPosition: snappedUPosition,\n };\n};\n\n/**\n * Check if a U position is available in a rack\n */\nexport const isUPositionAvailable = (\n rack: NetworkNode,\n device: NetworkNode,\n uPosition: number,\n allNodes: NetworkNode[]\n): boolean => {\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n // Check bounds\n if (uPosition < 1 || uPosition + deviceUHeight - 1 > rackUHeight) {\n return false;\n }\n \n // Check for conflicts with other devices in the same rack\n const rackDevices = allNodes.filter(node => \n node.type === 'device' && \n node.parentId === rack.id && \n node.id !== device.id\n );\n \n for (const otherDevice of rackDevices) {\n const otherUPosition = otherDevice.data.uPosition || 1;\n const otherUHeight = otherDevice.data.uHeight || 1;\n \n // Check if the new device would overlap with existing device\n const newDeviceStart = uPosition;\n const newDeviceEnd = uPosition + deviceUHeight - 1;\n const otherDeviceStart = otherUPosition;\n const otherDeviceEnd = otherUPosition + otherUHeight - 1;\n \n if (newDeviceStart <= otherDeviceEnd && newDeviceEnd >= otherDeviceStart) {\n return false; // Overlap detected\n }\n }\n \n return true;\n};\n\n/**\n * Find the next available U position in a rack\n */\nexport const findNextAvailableUPosition = (\n rack: NetworkNode,\n device: NetworkNode,\n allNodes: NetworkNode[],\n startFrom: number = 1\n): number => {\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n for (let u = startFrom; u <= rackUHeight - deviceUHeight + 1; u++) {\n if (isUPositionAvailable(rack, device, u, allNodes)) {\n return u;\n }\n }\n \n return 1; // Fallback to position 1\n};\n\n/**\n * Calculate device position based on U position within a rack\n */\nexport const calculateDevicePositionFromU = (\n rack: NetworkNode,\n uPosition: number,\n deviceHeight: number = 1\n): { x: number; y: number } => {\n const startY = RACK_HEADER_HEIGHT; // After header\n const direction = getRackUNumberingDirection(rack);\n const rackUHeight = rack.data.uHeight || 42;\n \n // Convert U position to physical position\n const physicalUPosition = convertUPositionFromDirection(uPosition, rackUHeight, direction);\n \n // Position device so its TOP edge aligns with the U position\n // For initial positioning, we place the device at the exact U position specified\n let deviceY;\n if (direction === 'bottom-up') {\n // For bottom-up, the logical U position represents the BOTTOM of the device\n // So we need to calculate the Y position of the TOP of the device\n const topLogicalUPosition = uPosition + deviceHeight - 1;\n const topPhysicalUPosition = convertUPositionFromDirection(topLogicalUPosition, rackUHeight, direction);\n deviceY = startY + (topPhysicalUPosition - 1) * U_HEIGHT_PX - 1;\n } else {\n // For top-down, the logical U position represents the TOP of the device\n deviceY = startY + (physicalUPosition - 1) * U_HEIGHT_PX - 1;\n }\n \n return {\n x: 0, // Align with rack left edge (relative to parent)\n y: deviceY,\n };\n};\n\n/**\n * Update device U position and recalculate position\n */\nexport const updateDeviceUPosition = (\n device: NetworkNode,\n rack: NetworkNode,\n newUPosition: number\n): NetworkNode => {\n const deviceHeight = device.data.uHeight || 1;\n const newPosition = calculateDevicePositionFromU(rack, newUPosition, deviceHeight);\n \n return {\n ...device,\n position: newPosition,\n data: {\n ...device.data,\n uPosition: newUPosition,\n },\n };\n};\n\n/**\n * Validate and snap device to valid U position\n */\nexport const validateAndSnapDevice = (\n device: NetworkNode,\n rack: NetworkNode\n): NetworkNode => {\n const currentUPosition = device.data.uPosition || 1;\n const deviceUHeight = device.data.uHeight || 1;\n const rackUHeight = rack.data.uHeight || 42;\n \n // Ensure U position is within bounds\n const validUPosition = Math.max(1, Math.min(rackUHeight - deviceUHeight + 1, currentUPosition));\n \n if (validUPosition !== currentUPosition) {\n return updateDeviceUPosition(device, rack, validUPosition);\n }\n \n return device;\n};\n","import { DeviceStatus } from '../types';\n\n/**\n * Get the color code for a device status\n * @param status - The device status\n * @returns Hex color code for the status\n * @public\n */\nexport function getStatusColor(status: DeviceStatus | string): string {\n switch (status) {\n case 'active':\n return '#10b981';\n case 'inactive':\n return '#6b7280';\n case 'maintenance':\n return '#f59e0b';\n default:\n return '#6b7280';\n }\n}\n\n","import React, { useState } from 'react';\nimport { NodeProps, useReactFlow } from 'reactflow';\nimport { NetworkNode, UNumberingDirection } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT, RACK_WIDTH_PX } from '../utils/constants';\nimport { getRackUNumberingDirection, convertUPositionForDirection } from '../utils/u-positioning';\nimport { getStatusColor } from '../utils/status-colors';\n\ninterface RackNodeProps extends NodeProps<NetworkNode['data']> {\n onViewChange?: (nodeId: string, view: 'front' | 'rear') => void;\n onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void;\n isDragOver?: boolean;\n}\n\nexport const RackNode: React.FC<RackNodeProps> = ({ data, selected, id, onViewChange, onRackFaceChange, isDragOver = false }) => {\n const { \n label, \n ports = 0, \n status = 'active',\n uHeight = 42, // Standard rack height\n face = 'front',\n customHeaderText\n } = data;\n \n const { getNodes, setNodes } = useReactFlow();\n const nodes = getNodes();\n const [showUMarkers, setShowUMarkers] = useState(true);\n \n const toggleUNumberingDirection = () => {\n const currentDirection = getRackUNumberingDirection({ data } as NetworkNode);\n const newDirection: UNumberingDirection = currentDirection === 'bottom-up' ? 'top-down' : 'bottom-up';\n \n setNodes(nodes => nodes.map(n => \n n.id === id \n ? { ...n, data: { ...n.data, uNumberingDirection: newDirection } }\n : n\n ));\n };\n\n \n const toggleFace = () => {\n const next = face === 'front' ? 'rear' : 'front';\n \n if (onRackFaceChange) {\n onRackFaceChange(id, next);\n // Also update child devices via onViewChange if provided\n if (onViewChange) {\n const childNodes = nodes.filter(n => n.parentId === id);\n childNodes.forEach(child => {\n onViewChange(child.id, next);\n });\n }\n } else if (onViewChange) {\n // Use external onViewChange for devices\n const childNodes = nodes.filter(n => n.parentId === id);\n childNodes.forEach(child => {\n onViewChange(child.id, next);\n });\n } else {\n // Fallback to internal state management\n setNodes(nodes => nodes.map(n => \n n.id === id \n ? { ...n, data: { ...n.data, face: next } }\n : n.parentId === id \n ? { ...n, data: { ...n.data, view: next } } // Use 'view' for devices\n : n\n ));\n }\n };\n\n // Generate U position markers aligned to rack origin\n const renderUPositions = () => {\n const positions = [];\n const startY = RACK_HEADER_HEIGHT; // Start after header from rack origin\n const direction = getRackUNumberingDirection({ data } as NetworkNode);\n \n for (let i = 1; i <= uHeight; i++) {\n const yPos = startY + (i - 1) * U_HEIGHT_PX - 4; // Align with device positioning, shifted up 3px\n // Convert the physical position to the display number based on direction\n const displayNumber = convertUPositionForDirection(i, uHeight, direction);\n \n positions.push(\n <div\n key={i}\n style={{\n position: 'absolute',\n left: '-35px',\n top: `${yPos}px`,\n background: '#374151',\n color: '#9ca3af',\n padding: '2px 4px',\n borderRadius: '2px',\n fontSize: '8px',\n fontWeight: 'bold',\n width: '28px',\n textAlign: 'center',\n border: '1px solid #4b5563',\n zIndex: 10,\n height: `${U_HEIGHT_PX}px`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 1,\n }}\n >\n {displayNumber}\n </div>\n );\n }\n return positions;\n };\n\n\n return (\n <div\n className={`rack-node ${selected ? 'selected' : ''} ${isDragOver ? 'drag-over' : ''}`}\n style={{\n background: 'transparent',\n border: `2px solid ${getStatusColor(status)}`,\n borderRadius: '8px',\n padding: 0,\n width: `${RACK_WIDTH_PX}px`, // Fixed width for parent node\n height: `${RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX}px`, // Header + exact U area\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '12px',\n boxShadow: isDragOver \n ? '0 0 20px #3b82f6, 0 0 40px #3b82f6, 0 0 60px #3b82f6' \n : selected \n ? '0 0 0 2px #3b82f6' \n : '0 2px 4px rgba(0,0,0,0.1)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n transition: 'box-shadow 0.2s ease-in-out',\n }}\n >\n {/* Rack Header */}\n <div style={{ \n textAlign: 'center', \n marginBottom: 0, \n zIndex: 2, \n background: '#1f2937', \n padding: '8px',\n position: 'relative',\n height: `${RACK_HEADER_HEIGHT}px`, // Fixed header height\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n }}>\n <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{label}</div>\n <div style={{ fontSize: '10px', color: '#9ca3af' }}>\n {customHeaderText ? (\n <span style={{ color: '#fbbf24', fontWeight: 'bold' }}>{customHeaderText}</span>\n ) : (\n <span>{typeof ports === 'number' ? ports : 0} ports</span>\n )} • {uHeight}U • {face}\n </div>\n <div style={{ display: 'flex', gap: '4px', position: 'absolute', top: '4px', right: '4px' }}>\n <button\n onPointerDown={(e) => { e.stopPropagation(); }}\n onMouseDown={(e) => { e.stopPropagation(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); setShowUMarkers(!showUMarkers); }}\n style={{\n background: showUMarkers ? '#10b981' : '#374151',\n color: showUMarkers ? '#ffffff' : '#9ca3af',\n border: '1px solid #4b5563',\n borderRadius: '2px',\n padding: '2px 6px',\n fontSize: '8px',\n cursor: 'pointer',\n fontFamily: 'monospace',\n }}\n title={`${showUMarkers ? 'Hide' : 'Show'} U markers`}\n >\n U\n </button>\n <button\n onPointerDown={(e) => { e.stopPropagation(); }}\n onMouseDown={(e) => { e.stopPropagation(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); toggleUNumberingDirection(); }}\n style={{\n background: '#374151',\n color: '#9ca3af',\n border: '1px solid #4b5563',\n borderRadius: '2px',\n padding: '2px 6px',\n fontSize: '8px',\n cursor: 'pointer',\n fontFamily: 'monospace',\n }}\n title={`Switch U numbering to ${getRackUNumberingDirection({ data } as NetworkNode) === 'bottom-up' ? 'top-down' : 'bottom-up'}`}\n >\n {getRackUNumberingDirection({ data } as NetworkNode) === 'bottom-up' ? '↑↓' : '↓↑'}\n </button>\n <button\n onPointerDown={(e) => { e.stopPropagation(); }}\n onMouseDown={(e) => { e.stopPropagation(); }}\n onClick={(e) => { e.stopPropagation(); e.preventDefault(); toggleFace(); }}\n style={{\n background: '#374151',\n color: '#9ca3af',\n border: '1px solid #4b5563',\n borderRadius: '2px',\n padding: '2px 6px',\n fontSize: '8px',\n cursor: 'pointer',\n fontFamily: 'monospace',\n }}\n title={`Switch to ${face === 'front' ? 'rear' : 'front'} view`}\n >\n {face === 'front' ? '⇄ Rear' : '⇄ Front'}\n </button>\n </div>\n </div>\n \n {/* Rack Body - transparent background; devices are positioned relative to rack origin */}\n <div\n style={{\n flex: 1,\n background: 'transparent',\n // no borders to avoid pixel offsets\n position: 'relative',\n minHeight: `${uHeight * U_HEIGHT_PX}px`,\n overflow: 'hidden',\n }}\n />\n\n {/* Overlay for U markers aligned to rack origin */}\n {showUMarkers && (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: 'none',\n }}\n >\n {renderUPositions()}\n </div>\n )}\n \n </div>\n );\n};\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode } from '../types';\nimport { getStatusColor } from '../utils/status-colors';\n\nexport const FiberNode: React.FC<NodeProps<NetworkNode['data']>> = ({ data, selected }) => {\n const { label, status = 'active' } = data;\n\n return (\n <div\n className={`fiber-node ${selected ? 'selected' : ''}`}\n style={{\n background: '#1f2937',\n border: `2px solid ${getStatusColor(status)}`,\n borderRadius: '50%',\n width: '60px',\n height: '60px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '10px',\n fontWeight: 'bold',\n boxShadow: selected ? '0 0 0 2px #3b82f6' : '0 2px 4px rgba(0,0,0,0.1)',\n position: 'relative',\n }}\n >\n <Handle type=\"target\" position={Position.Top} />\n <Handle type=\"source\" position={Position.Bottom} />\n <Handle type=\"target\" position={Position.Left} />\n <Handle type=\"source\" position={Position.Right} />\n \n <div style={{ textAlign: 'center' }}>\n <div style={{ fontSize: '8px', lineHeight: '1.2' }}>{label}</div>\n </div>\n \n <div\n style={{\n position: 'absolute',\n bottom: '4px',\n left: '50%',\n transform: 'translateX(-50%)',\n width: '8px',\n height: '8px',\n background: getStatusColor(status),\n borderRadius: '50%',\n }}\n />\n </div>\n );\n};\n","import React from 'react';\nimport { EdgeProps, getBezierPath, EdgeLabelRenderer, BaseEdge } from 'reactflow';\nimport { NetworkEdge } from '../types';\n\nexport const FiberEdge: React.FC<EdgeProps<NetworkEdge['data']>> = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n selected,\n style = {},\n}) => {\n const [edgePath, labelX, labelY] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const { bandwidth, length, color = '#00FFFF' } = data || {};\n\n // Use BaseEdge so React Flow layering/zIndex works consistently like power edges\n // Spread style first, then override with our specific properties to ensure data color takes precedence\n const edgeStyle = {\n ...style, // includes zIndex from React Flow\n stroke: color, // Override any stroke from style prop with our data color\n strokeWidth: selected ? 3 : 2,\n strokeDasharray: 'none', // Solid lines for all network edges\n } as React.CSSProperties;\n\n\n return (\n <>\n <BaseEdge id={id} path={edgePath} style={edgeStyle} />\n <EdgeLabelRenderer>\n {selected && data && (bandwidth || length) && (\n <div\n style={{\n position: 'absolute',\n transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,\n background: '#1f2937',\n padding: '4px 8px',\n borderRadius: '4px',\n fontSize: '10px',\n color: 'white',\n fontFamily: 'monospace',\n border: `1px solid ${color}`,\n pointerEvents: 'none',\n zIndex: 9999,\n }}\n >\n {bandwidth && <div>{bandwidth}</div>}\n {length && <div>{length}m</div>}\n </div>\n )}\n </EdgeLabelRenderer>\n </>\n );\n};\n","import React from 'react';\nimport { EdgeProps, getBezierPath, BaseEdge } from 'reactflow';\n\nexport const PowerEdge: React.FC<EdgeProps> = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n style = {},\n data,\n markerEnd,\n}) => {\n const [edgePath] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n // Determine connector type based on data\n const connectorType = data?.connectorType || 'C13';\n\n // Different styling for different connector types\n const getEdgeStyle = () => {\n const baseStyle = {\n stroke: data?.color || '#f59e0b',\n strokeWidth: connectorType === 'C19' ? 5 : 3, // Thicker for C19 (higher power)\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n ...style, // This includes zIndex from React Flow\n };\n\n\n // C19 (16A) gets solid line, C13 (10A) gets dashed\n if (connectorType === 'C19') {\n return {\n ...baseStyle,\n strokeDasharray: 'none', // Solid line for high power\n };\n } else {\n return {\n ...baseStyle,\n strokeDasharray: '6,3', // Dashed line for standard power\n };\n }\n };\n\n return (\n <BaseEdge\n id={id}\n path={edgePath}\n markerEnd={markerEnd}\n style={getEdgeStyle()}\n />\n );\n};\n","/**\n * Rack device width configuration\n * @public\n */\nexport enum Width {\n /** Full width device (19\" rack width) */\n FULL = 'full',\n /** Half width device (9.5\" rack width) */\n HALF = 'half'\n}\n\n/**\n * Port configuration for network devices\n * @public\n */\nexport interface Port {\n /** Display label for the port */\n label: string;\n /** Whether the port is currently connected */\n connected: boolean;\n /** Type of port for styling and validation */\n type?: 'ethernet' | 'fiber' | 'console' | 'mgmt' | 'usb' | 'power_ac' | 'power_c13' | 'power_c19';\n /** Cable type for connection validation */\n cableType?: 'smf' | 'cat6' | 'om3' | 'om4' | 'om5' | 'cat5e' | 'cat6a' | 'cat7' | 'fiber' | 'ethernet';\n}\n\n/**\n * Group of related ports on a device\n * @public\n */\nexport interface PortBlock {\n /** Name of the port group */\n name: string;\n /** Array of ports in this group */\n ports: Port[];\n}\n\n/**\n * Network node types supported by the diagram\n * @public\n */\nexport type NetworkNodeType = \n | 'rack' \n | 'switch' \n | 'router' \n | 'server' \n | 'fiber' \n | 'patch-panel' \n | 'device' \n | 'vertical-pdu';\n\n/**\n * Device status states\n * @public\n */\nexport type DeviceStatus = 'active' | 'inactive' | 'maintenance';\n\n/**\n * Device view orientations\n * @public\n */\nexport type DeviceView = 'front' | 'rear';\n\n/**\n * Power port side configuration\n * @public\n */\nexport type PowerSide = 'left' | 'right';\n\n/**\n * U numbering direction for racks\n * @public\n */\nexport type UNumberingDirection = 'bottom-up' | 'top-down';\n\n/**\n * Network node data structure\n * @public\n */\nexport interface NetworkNode {\n /** Unique identifier for the node */\n id: string;\n /** Type of network node */\n type: NetworkNodeType;\n /** Position coordinates in the diagram */\n position: { x: number; y: number };\n /** Parent node ID for React Flow sub-flows */\n parentId?: string;\n /** Node extent for sub-flows */\n extent?: 'parent' | [[number, number], [number, number]];\n /** Node data and configuration */\n data: {\n /** Display label for the node */\n label: string;\n /** Port configurations for the device */\n ports?: PortBlock[];\n /** List of connected node IDs */\n connections?: string[];\n /** Current status of the device */\n status?: DeviceStatus;\n /** NetBox integration ID */\n netboxId?: number;\n /** NetBox object type */\n netboxType?: 'device' | 'rack' | 'interface' | 'cable';\n /** Rack height in U units */\n uHeight?: number;\n /** Device position within rack in U units */\n uPosition?: number;\n /** Current view orientation */\n view?: DeviceView;\n /** Device type specification */\n deviceType?: string;\n /** Device manufacturer */\n manufacturer?: string;\n /** Device role in network */\n role?: string;\n /** Device width configuration */\n width?: Width;\n /** Rear port configurations */\n rearPorts?: PortBlock[];\n /** Power port side for rear view */\n powerSide?: PowerSide;\n /** Vertical PDU height in centimeters */\n heightCm?: number;\n /** Number of AC power ports */\n powerPorts?: number;\n /** U numbering direction for rack nodes */\n uNumberingDirection?: UNumberingDirection;\n /** Custom header text for rack nodes */\n customHeaderText?: string;\n /** Additional custom properties */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n };\n}\n\n/**\n * Network edge types\n * @public\n */\nexport type NetworkEdgeType = 'fiber' | 'ethernet' | 'power';\n\n/**\n * Network edge data structure\n * @public\n */\nexport interface NetworkEdge {\n /** Unique identifier for the edge */\n id: string;\n /** Source node ID */\n source: string;\n /** Target node ID */\n target: string;\n /** Source handle/port ID */\n sourceHandle?: string;\n /** Target handle/port ID */\n targetHandle?: string;\n /** Type of network connection */\n type?: NetworkEdgeType;\n /** Edge data and configuration */\n data?: {\n /** Connection bandwidth */\n bandwidth?: string;\n /** Cable length */\n length?: number;\n /** Edge color for styling */\n color?: string;\n /** Edge kind for styling/validation */\n kind?: 'fiber' | 'power' | 'network';\n /** Additional custom properties */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n };\n}\n\n/**\n * Rack device types\n * @public\n */\nexport type RackDeviceType = 'server' | 'switch' | 'router' | 'patch-panel' | 'ups';\n\n/**\n * Rack configuration structure\n * @public\n */\nexport interface RackConfig {\n /** Unique rack identifier */\n id: string;\n /** Rack display name */\n name: string;\n /** Rack position coordinates */\n position: { x: number; y: number };\n /** Rack height in U units */\n units: number;\n /** U numbering direction (default: 'bottom-up') */\n uNumberingDirection?: UNumberingDirection;\n /** Custom header text for rack */\n customHeaderText?: string;\n /** Devices mounted in the rack */\n devices: RackDevice[];\n}\n\n/**\n * Device mounted in a rack\n * @public\n */\nexport interface RackDevice {\n /** Unique device identifier */\n id: string;\n /** Device display name */\n name: string;\n /** Starting U position in rack */\n unit: number;\n /** Device height in U units */\n height: number;\n /** Device type */\n type: RackDeviceType;\n /** Device width configuration */\n width?: Width;\n /** Device role in network */\n role?: string;\n /** Front port configurations */\n ports?: PortBlock[];\n /** Rear port configurations */\n rearPorts?: PortBlock[];\n /** Power port side for rear view */\n powerSide?: PowerSide;\n /** Connected device IDs */\n connections?: string[];\n}\n\n/**\n * Fiber cable types\n * @public\n */\nexport type FiberCableType = 'single-mode' | 'multi-mode';\n\n/**\n * Fiber cable configuration\n * @public\n */\nexport interface FiberCable {\n /** Unique cable identifier */\n id: string;\n /** Cable display name */\n name: string;\n /** Fiber cable type */\n type: FiberCableType;\n /** Cable length */\n length: number;\n /** Cable color for visualization */\n color: string;\n /** Connection endpoints */\n connections: {\n /** Source connection point */\n from: string;\n /** Target connection point */\n to: string;\n };\n}\n\n// Inventory/CMDB integrations are generic and not tied to specific vendors\n\n/**\n * Network diagram component props\n * @public\n */\nexport interface NetworkDiagramProps {\n /** Controlled nodes array */\n nodes?: NetworkNode[];\n /** Controlled edges array */\n edges?: NetworkEdge[];\n /** Callback when nodes change (controlled mode) */\n onNodesChange?: (nodes: NetworkNode[]) => void;\n /** Callback when edges change (controlled mode) */\n onEdgesChange?: (edges: NetworkEdge[]) => void;\n /** Initial nodes for uncontrolled mode */\n initialNodes?: NetworkNode[];\n /** Initial edges for uncontrolled mode */\n initialEdges?: NetworkEdge[];\n /** Headless store injection */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n store?: any;\n /** Enable debug mode */\n debug?: boolean;\n /** Callback when a node is clicked or selection changes (null when deselected) */\n onNodeClick?: (node: NetworkNode | null) => void;\n /** Callback when an edge is clicked */\n onEdgeClick?: (edge: NetworkEdge) => void;\n /** Callback when device view changes */\n onViewChange?: (nodeId: string, view: DeviceView) => void;\n /** Callback when rack face changes */\n onRackFaceChange?: (rackId: string, face: DeviceView) => void;\n /** CSS class name */\n className?: string;\n /** Inline styles */\n style?: React.CSSProperties;\n /** If true, vertically align rack bottoms to the same baseline */\n alignRacksToBottom?: boolean;\n /** Color mode for the diagram */\n colorMode?: 'light' | 'dark' | 'system';\n /** Callback when React Flow instance is initialized */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onInit?: (instance: any) => void;\n /** Callback to get React Flow methods for save/restore */\n onFlowMethods?: (methods: { \n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toObject: () => any; \n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setViewport: (viewport: any) => void; \n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setNodes: (nodes: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setEdges: (edges: any[]) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toImage: (options?: any) => Promise<string> \n }) => void;\n /** Show download button */\n showDownloadButton?: boolean;\n /** Download button position */\n downloadButtonPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n /** Custom download button text */\n downloadButtonText?: string;\n /** Download button styling options */\n downloadButtonStyle?: React.CSSProperties;\n}\n\nexport * from './netbox';\n","/**\n * Power connector utilities for consistent styling across devices and PDUs\n */\n\nexport interface PowerConnectorConfig {\n type: 'C13' | 'C14' | 'C19' | 'C20';\n color: string;\n borderColor: string;\n amperage: number;\n voltage: number;\n phases: number;\n}\n\nexport const POWER_CONNECTORS: Record<string, PowerConnectorConfig> = {\n C13: {\n type: 'C13',\n color: '#f59e0b', // Orange\n borderColor: '#d97706',\n amperage: 10,\n voltage: 230,\n phases: 1\n },\n C14: {\n type: 'C14',\n color: '#f59e0b', // Orange\n borderColor: '#d97706',\n amperage: 10,\n voltage: 230,\n phases: 1\n },\n C19: {\n type: 'C19',\n color: '#fbbf24', // Amber\n borderColor: '#d97706',\n amperage: 16,\n voltage: 230,\n phases: 1\n },\n C20: {\n type: 'C20',\n color: '#fbbf24', // Amber\n borderColor: '#d97706',\n amperage: 16,\n voltage: 230,\n phases: 1\n }\n};\n\nexport interface PowerPortStyle {\n width: number;\n height: number;\n borderRadius?: string;\n clipPath?: string;\n color: string;\n borderColor: string;\n fontSize: string;\n}\n\n/**\n * Get consistent power port styling for any connector type\n */\nexport function getPowerPortStyle(connectorType: string): PowerPortStyle {\n const connector = POWER_CONNECTORS[connectorType];\n if (!connector) {\n throw new Error(`Unknown connector type: ${connectorType}`);\n }\n\n const isHighPower = connector.amperage === 16; // C19/C20 are 16A\n\n // Size: High power connectors are bigger\n const width = isHighPower ? 12 : 8; // C19/C20 bigger; C13/C14 smaller\n const height = isHighPower ? 10 : 5; // C19/C20 bigger; C13/C14 smaller\n\n // Shape: C13/C14 have chamfered corners, C19/C20 have rounded corners\n const cornerStyle = isHighPower \n ? { borderRadius: '3px' } // C19/C20: rounded corners\n : { \n clipPath: `polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)`,\n borderRadius: '0px'\n };\n\n return {\n width,\n height,\n color: connector.color,\n borderColor: connector.borderColor,\n fontSize: isHighPower ? '3px' : '4px',\n ...cornerStyle\n };\n}\n\n/**\n * Get connector configuration by type\n */\nexport function getConnectorConfig(connectorType: string): PowerConnectorConfig {\n const connector = POWER_CONNECTORS[connectorType];\n if (!connector) {\n throw new Error(`Unknown connector type: ${connectorType}`);\n }\n return connector;\n}\n\n/**\n * Determine if a connector is high power (16A)\n */\nexport function isHighPowerConnector(connectorType: string): boolean {\n const connector = getConnectorConfig(connectorType);\n return connector.amperage === 16;\n}\n\n/**\n * Get PDU port type based on position in cycle\n * PDU cycle: [8xC13, 2xC19] = 10 ports per cycle\n */\nexport function getPDUPortType(portIndex: number): string {\n const cyclePosition = portIndex % 10; // 10 ports per cycle\n return cyclePosition < 8 ? 'C13' : 'C19';\n}\n\n/**\n * Get device connector type based on device name\n */\nexport function getDeviceConnectorType(deviceName: string): string {\n const name = deviceName.toLowerCase();\n \n // High power devices use C20\n if (name.includes('mx304') || name.includes('mx480') || name.includes('mx960')) {\n return 'C20';\n }\n \n // Standard devices use C14\n return 'C14';\n}\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode, Width, PortBlock, Port } from '../types';\nimport { U_HEIGHT_PX } from '../utils/constants';\nimport { getPowerPortStyle, getConnectorConfig, getDeviceConnectorType } from '../utils/power-connectors';\nimport { getStatusColor } from '../utils/status-colors';\n\n// Power connector styling is now handled by shared utility\n\nexport const DeviceNode: React.FC<NodeProps<NetworkNode['data']>> = ({ data, selected }) => {\n const { \n label, \n status = 'active', \n deviceType = 'server',\n manufacturer,\n role,\n uHeight = 1,\n width = Width.FULL, // Default to full width\n ports = [], // Array of port configurations\n rearPorts = [],\n view // Optional view override\n } = data;\n\n // Determine view: prefer explicit view; if both front and rear ports exist, default to 'front'\n const currentFace = view || ((rearPorts.length > 0 && ports.length === 0) ? 'rear' : 'front');\n\n // Debug logging removed in production build; keep component silent by default\n\n // Create handle-to-side mapping for zIndex calculation\n const handleSideMap: Record<string, 'front' | 'rear'> = {};\n \n // Map ALL handles to their sides (both front and rear) for proper zIndex calculation\n // This should be independent of the current view - handles have fixed positions\n \n // Front view handles (always on front regardless of current view)\n handleSideMap['net-top'] = 'front';\n handleSideMap['net-bottom'] = 'front';\n // Add any custom front handles from ports array\n if (ports.length > 0) {\n ports.forEach(portBlock => {\n portBlock.ports.forEach(port => {\n const handleId = port.type?.includes('power') ? port.label : `${portBlock.name}-${port.label}`;\n handleSideMap[handleId] = 'front';\n });\n });\n }\n \n // Rear view handles (always on rear regardless of current view)\n handleSideMap['pwr-left-1'] = 'rear';\n handleSideMap['pwr-left-2'] = 'rear';\n handleSideMap['net-right-1'] = 'rear';\n handleSideMap['net-right-2'] = 'rear';\n // Add any custom rear handles from rearPorts array\n if (rearPorts.length > 0) {\n rearPorts.forEach(portBlock => {\n portBlock.ports.forEach(port => {\n const handleId = port.type?.includes('power') ? port.label : `${portBlock.name}-${port.label}`;\n handleSideMap[handleId] = 'rear';\n });\n });\n }\n \n\n // Removed data mutation; z-index is derived in headless selectors\n\n // Calculate device height based on U height\n const deviceHeight = uHeight * U_HEIGHT_PX;\n \n // Calculate rackDevice width based on width setting\n // Rack width is 300px, so full width = 300px, half width = 150px\n const rackDeviceWidth = width === Width.HALF ? '150px' : '304px';\n const rackDeviceLeft = width === Width.HALF ? '150px' : undefined;\n\n // Render ports from port arrays\n const renderPortsFromArray = (portBlocks: PortBlock[], position: 'front' | 'rear') => {\n const handles: React.ReactElement[] = [];\n \n if (portBlocks.length === 0) return handles;\n \n // Calculate port dimensions based on device height\n const portWidth = Math.max(4, Math.floor(deviceHeight * 0.4)); // 40% of device height, minimum 4px\n const portHeight = Math.max(2, Math.floor(deviceHeight * 0.2)); // 20% of device height, minimum 2px\n \n portBlocks.forEach((portBlock, _blockIndex) => {\n portBlock.ports.forEach((port: Port, portIndex: number) => {\n const isPower = !!port.type && port.type.includes('power');\n // Remove front-facing power connections: skip power ports on front face\n if (position === 'front' && isPower) {\n return;\n }\n const handleId = isPower ? `${port.label}` : `${portBlock.name}-${port.label}`;\n const isConnected = port.connected;\n \n // Determine port color based on type and cable medium\n let portColor = '#6b7280'; // Default grey for empty/disconnected\n if (isConnected) {\n if (port.type?.includes('power')) {\n portColor = port.type === 'power_c19' ? '#fbbf24' : '#f59e0b'; // Amber for C19, orange for C13\n } else if (port.type === 'console' || port.type === 'mgmt') {\n portColor = '#8b5cf6'; // Purple for management\n } else if (port.type === 'usb') {\n portColor = '#10b981'; // Green for USB\n } else {\n // Network port colors based on cable/transceiver type\n switch (port.cableType) {\n case 'smf': // Single Mode Fiber\n portColor = '#fbbf24'; // Yellow\n break;\n case 'cat6': // Category 6 Ethernet\n portColor = '#8b5cf6'; // Purple\n break;\n case 'om3': // OM3 Multimode Fiber\n portColor = '#06b6d4'; // Aqua/Cyan\n break;\n case 'om4': // OM4 Multimode Fiber\n portColor = '#8b5cf6'; // Violet\n break;\n case 'om5': // OM5 Multimode Fiber\n portColor = '#84cc16'; // Lime Green\n break;\n case 'cat5e': // Category 5e Ethernet\n portColor = '#3b82f6'; // Blue\n break;\n case 'cat6a': // Category 6A Ethernet\n portColor = '#ef4444'; // Red\n break;\n case 'cat7': // Category 7 Ethernet\n portColor = '#f97316'; // Orange\n break;\n case 'fiber': // Generic fiber\n portColor = '#3b82f6'; // Blue\n break;\n case 'ethernet': // Generic ethernet\n portColor = '#10b981'; // Green\n break;\n default:\n portColor = '#10b981'; // Default green for connected\n }\n }\n }\n \n // Determine position based on port type and face\n let handlePosition = Position.Top;\n let handleStyle: React.CSSProperties = {\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: isConnected ? portColor : '#6b7280',\n border: `1px solid ${isConnected ? portColor : '#374151'}`,\n borderRadius: '1px',\n cursor: 'pointer',\n };\n \n if (position === 'front') {\n // Front view: network ports on top/bottom\n if (portIndex % 2 === 0) {\n handlePosition = Position.Top;\n handleStyle.transform = 'translateY(50%)';\n handleStyle.left = `${(portIndex / 2) * (portWidth + 2)}px`;\n } else {\n handlePosition = Position.Bottom;\n handleStyle.transform = 'translateY(-50%)';\n handleStyle.left = `${((portIndex - 1) / 2) * (portWidth + 2)}px`;\n }\n } else {\n // Rear view: patch panels use same top/bottom layout as front\n // Normalize deviceType to handle both 'patch_panel' (JSON) and 'patch-panel' (code)\n const normalizedDeviceType = deviceType?.toLowerCase().replace(/_/g, '-') || '';\n if (normalizedDeviceType === 'patch-panel') {\n // Patch panel rear ports: same layout as front (top/bottom)\n if (portIndex % 2 === 0) {\n handlePosition = Position.Top;\n handleStyle.transform = 'translateY(50%)';\n handleStyle.left = `${(portIndex / 2) * (portWidth + 2)}px`;\n } else {\n handlePosition = Position.Bottom;\n handleStyle.transform = 'translateY(-50%)';\n handleStyle.left = `${((portIndex - 1) / 2) * (portWidth + 2)}px`;\n }\n } else if (port.type?.includes('power')) {\n // Power ports on left (for non-patch-panel devices)\n handlePosition = Position.Left;\n handleStyle.transform = 'translateX(50%)'; // Move inside device boundary\n // Better spacing for 1U devices - start at top and space appropriately\n const baseTop = deviceHeight <= 20 ? 10 : 20;\n const spacing = deviceHeight <= 20 ? 30 : 50;\n handleStyle.top = `${baseTop + (portIndex * spacing)}%`;\n \n // Use shared utility for consistent power port styling\n const connectorType = getDeviceConnectorType(label);\n const portStyle = getPowerPortStyle(connectorType);\n \n handleStyle = {\n ...handleStyle,\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n };\n } else {\n // Network ports on right (for non-patch-panel devices)\n handlePosition = Position.Right;\n handleStyle.transform = 'translateX(-50%)';\n handleStyle.top = `${25 + (portIndex * 50)}%`;\n }\n }\n \n // Switches and routers output connections, so their network ports should be 'source'\n // But they also need 'target' handles for switch-to-switch mesh connections\n // Patch panels route traffic bidirectionally, so they need both source and target handles\n // Servers and other devices receive connections, so their network ports should be 'target'\n // Power ports are always 'target' (devices receive power)\n const normalizedDeviceType = deviceType?.toLowerCase().replace(/_/g, '-') || '';\n const isPatchPanel = normalizedDeviceType === 'patch-panel';\n let handleType: 'source' | 'target';\n if (isPower) {\n handleType = 'target';\n } else if (deviceType === 'switch' || deviceType === 'router') {\n handleType = 'source'; // Switches/routers output network connections\n // Also create a target handle for switch-to-switch mesh connections\n handles.push(\n <Handle\n key={`${handleId}-target`}\n id={`${handleId}-target`}\n type=\"target\"\n position={handlePosition}\n style={handleStyle}\n title={`${portBlock.name} - ${port.label} (input) ${isConnected ? '(connected)' : '(disconnected)'}`}\n />\n );\n } else if (isPatchPanel) {\n // Patch panels route traffic bidirectionally\n // Front ports: receive from switches (target), but also need source for routing to rear\n // Rear ports: send to other patch panels (source), but also receive from other patch panels (target)\n handleType = position === 'rear' ? 'source' : 'target';\n // Always create both source and target handles for patch panels to enable routing\n const oppositeType = position === 'rear' ? 'target' : 'source';\n handles.push(\n <Handle\n key={`${handleId}-${oppositeType}`}\n id={`${handleId}-${oppositeType}`}\n type={oppositeType}\n position={handlePosition}\n style={handleStyle}\n title={`${portBlock.name} - ${port.label} (${oppositeType}) ${isConnected ? '(connected)' : '(disconnected)'}`}\n />\n );\n } else {\n handleType = isConnected ? 'source' : 'target'; // Other devices receive connections by default\n }\n\n handles.push(\n <Handle\n key={handleId}\n id={handleId}\n type={handleType}\n position={handlePosition}\n style={handleStyle}\n title={`${portBlock.name} - ${port.label} ${isConnected ? '(connected)' : '(disconnected)'}`}\n >\n {isPower ? portIndex + 1 : undefined}\n </Handle>\n );\n });\n });\n \n return handles;\n };\n\n // Render handles based on face orientation\n const renderHandles = () => {\n const handles: React.ReactElement[] = [];\n \n // Calculate port dimensions based on device height\n const portWidth = Math.max(4, Math.floor(deviceHeight * 0.4)); // 40% of device height, minimum 4px\n const portHeight = Math.max(2, Math.floor(deviceHeight * 0.2)); // 20% of device height, minimum 2px\n \n if (currentFace === 'front') {\n // Front view\n // Front view: render from ports array if provided, else fall back to defaults\n if (ports.length > 0) {\n // Render ports from provided configuration\n return renderPortsFromArray(ports, 'front');\n }\n\n // Check if this is an AGG/core switch\n const isAGGSwitch = deviceType === 'switch' && (label.toLowerCase().includes('agg') || label.toLowerCase().includes('core') || role === 'agg' || role === 'core');\n if (isAGGSwitch) {\n return renderAGGSwitchHandles();\n }\n\n // Standard network ports on top and bottom (target - receives network from switches)\n // Standard device fallbacks\n handles.push(\n <Handle\n key=\"net-top\"\n id=\"net-top\"\n type=\"target\"\n position={Position.Top}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateY(50%)',\n }}\n title=\"Network Port (Top)\"\n />\n );\n\n handles.push(\n <Handle\n key=\"net-bottom\"\n id=\"net-bottom\"\n type=\"target\"\n position={Position.Bottom}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateY(-50%)',\n }}\n title=\"Network Port (Bottom)\"\n />\n );\n \n } else if (currentFace === 'rear') {\n // Rear view\n // Rear view: render from rearPorts array if provided, else fall back to defaults\n if (rearPorts.length > 0) {\n // Render ports from provided configuration\n return renderPortsFromArray(rearPorts, 'rear');\n }\n\n const isSwitch = deviceType === 'switch';\n // Normalize deviceType to handle both 'patch_panel' (JSON) and 'patch-panel' (code)\n const normalizedDeviceType = deviceType?.toLowerCase().replace(/_/g, '-') || '';\n const isPatchPanel = normalizedDeviceType === 'patch-panel';\n\n // Power ports on left side (all devices except patch panels)\n if (!isPatchPanel) {\n // Get connector type and styling using shared utility\n const connectorType = getDeviceConnectorType(label);\n const connector = getConnectorConfig(connectorType);\n const portStyle = getPowerPortStyle(connectorType);\n\n // Power port 1 - position based on device height\n const port1Top = deviceHeight <= 20 ? '10%' : '25%'; // Start at top for 1U devices\n \n handles.push(\n <Handle\n key=\"pwr-1\"\n id=\"pwr-left-1\"\n type=\"target\"\n position={Position.Left}\n style={{\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n transform: 'translateX(50%)', // Move inside the device boundary\n top: port1Top,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port 1 (${connector.type}) - ${connector.voltage}V, ${connector.amperage}A`}\n >\n 1\n </Handle>\n );\n\n // Power port 2 - position based on device height with proper spacing\n const port2Top = deviceHeight <= 20 ? '50%' : '75%'; // Position second port lower for 1U devices\n \n handles.push(\n <Handle\n key=\"pwr-2\"\n id=\"pwr-left-2\"\n type=\"target\"\n position={Position.Left}\n style={{\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n transform: 'translateX(50%)', // Move inside the device boundary\n top: port2Top,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port 2 (${connector.type}) - ${connector.voltage}V, ${connector.amperage}A`}\n >\n 2\n </Handle>\n );\n }\n\n // Network ports on right side (for non-switch, non-patch-panel devices)\n if (!isSwitch && !isPatchPanel) {\n handles.push(\n <Handle\n key=\"net-right-1\"\n id=\"net-right-1\"\n type=\"target\"\n position={Position.Right}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateX(-50%)',\n top: '25%',\n }}\n title=\"Network Port 1 (Right)\"\n />\n );\n\n handles.push(\n <Handle\n key=\"net-right-2\"\n id=\"net-right-2\"\n type=\"target\"\n position={Position.Right}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '0.5px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n transform: 'translateX(-50%)',\n top: '75%',\n }}\n title=\"Network Port 2 (Right)\"\n />\n );\n }\n }\n\n return handles;\n };\n\n // Render AGG switch handles: 48 ports on front, 4 uplinks on right\n const renderAGGSwitchHandles = () => {\n // AGG/core switch ports and uplinks\n const handles: React.ReactElement[] = [];\n \n // Calculate port dimensions - middle size for good visibility\n const portWidth = Math.max(10, Math.floor(deviceHeight * 0.45)); // 45% of device height, minimum 10px\n const portHeight = Math.max(5, Math.floor(deviceHeight * 0.25)); // 25% of device height, minimum 5px\n \n // 32 ports arranged in grid pattern: 16 on top, 16 on bottom\n // Create 32 front ports\n \n // Top row: 16 ports\n for (let i = 1; i <= 16; i++) {\n const handle = (\n <Handle\n key={`port-${i}`}\n id={`port-${i}`}\n type=\"source\"\n position={Position.Top}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '1px solid #059669', // Thinner border for cleaner look\n borderRadius: '2px',\n cursor: 'pointer',\n transform: 'translateY(50%)', // Pull handle into node\n zIndex: 1000,\n // Position ports across the top edge\n left: `${(i - 1) * (portWidth + 2)}px`, // Space ports across the width\n }}\n title={`Port ${i}`}\n />\n );\n \n \n \n handles.push(handle);\n }\n \n // Bottom row: 16 ports\n for (let i = 17; i <= 32; i++) {\n const bottomIndex = i - 16; // 1-16 for bottom row positioning\n const handle = (\n <Handle\n key={`port-${i}`}\n id={`port-${i}`}\n type=\"source\"\n position={Position.Bottom}\n style={{\n width: `${portWidth}px`,\n height: `${portHeight}px`,\n background: '#10b981',\n border: '1px solid #059669', // Thinner border for cleaner look\n borderRadius: '2px',\n cursor: 'pointer',\n transform: 'translateY(-50%)', // Pull handle into node\n zIndex: 1000,\n // Position ports across the bottom edge\n left: `${(bottomIndex - 1) * (portWidth + 2)}px`, // Space ports across the width\n }}\n title={`Port ${i}`}\n />\n );\n \n \n \n handles.push(handle);\n }\n \n // 4 uplink ports on the right edge (larger, different color)\n for (let i = 1; i <= 4; i++) {\n const uplinkWidth = Math.max(4, Math.floor(deviceHeight * 0.3)); // Larger uplink ports\n const uplinkHeight = Math.max(3, Math.floor(deviceHeight * 0.15)); // Taller uplink ports\n \n handles.push(\n <Handle\n key={`uplink-${i}`}\n id={`uplink-${i}`}\n type=\"source\"\n position={Position.Right}\n style={{\n width: `${uplinkWidth}px`,\n height: `${uplinkHeight}px`,\n background: '#8b5cf6', // Purple color for uplinks\n border: '0.5px solid #7c3aed',\n borderRadius: '0.5px',\n cursor: 'pointer',\n transform: 'translateX(-50%)', // Pull handle into node\n }}\n title={`Uplink ${i}`}\n />\n );\n }\n\n return handles;\n };\n\n return (\n <div\n className={`device-node ${selected ? 'selected' : ''}`}\n style={{\n background: '#1f2937',\n border: `1px solid ${getStatusColor(status)}`,\n borderRadius: '2px',\n padding: '0px', // Remove padding to fix alignment\n width: rackDeviceWidth, // Width based on width setting\n ...(rackDeviceLeft && { left: rackDeviceLeft }), // Only set left for HALF width rackDevices\n height: `${deviceHeight}px`, // Exact U height (20px per U)\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '8px',\n boxShadow: selected ? '0 0 0 1px #3b82f6' : '0 1px 2px rgba(0,0,0,0.1)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n cursor: 'grab',\n marginBottom: '0px', // No gap - devices should be exactly U height\n boxSizing: 'border-box',\n marginTop: '0px',\n marginLeft: '0px',\n marginRight: '0px',\n }}\n >\n {/* Standard handles are now always rendered */}\n \n {/* U Position will be calculated dynamically based on position */}\n \n \n <div style={{ \n textAlign: 'center', \n flex: 1, \n display: 'flex', \n flexDirection: 'column', \n justifyContent: 'center',\n overflow: 'hidden',\n padding: '2px', // Add small padding for text readability\n }}>\n <div style={{ \n fontWeight: 'bold', \n fontSize: '7px',\n lineHeight: '1.1',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {label}\n </div>\n {uHeight > 1 && (\n <div style={{ \n fontSize: '6px', \n color: '#9ca3af',\n lineHeight: '1',\n }}>\n {manufacturer}\n </div>\n )}\n </div>\n \n {/* U Height indicator */}\n {uHeight > 1 && (\n <div\n style={{\n position: 'absolute',\n bottom: '1px',\n right: '1px',\n background: '#374151',\n color: '#9ca3af',\n padding: '1px 2px',\n borderRadius: '1px',\n fontSize: '6px',\n lineHeight: '1',\n }}\n >\n {uHeight}U\n </div>\n )}\n \n {/* Status indicator */}\n <div\n style={{\n position: 'absolute',\n bottom: '1px',\n left: '1px',\n width: '4px',\n height: '4px',\n background: getStatusColor(status),\n borderRadius: '50%',\n }}\n />\n \n {/* React Flow edge handles based on face orientation */}\n {renderHandles()}\n </div>\n );\n};\n","import React from 'react';\nimport { Handle, Position, NodeProps } from 'reactflow';\nimport { NetworkNode } from '../types';\nimport { getStatusColor } from '../utils/status-colors';\nimport { getPowerPortStyle, getPDUPortType } from '../utils/power-connectors';\n\nexport enum MgmtUnitPosition {\n TOP = 'top',\n MIDDLE = 'middle',\n BOTTOM = 'bottom'\n}\n\nexport const VerticalPDU: React.FC<NodeProps<NetworkNode['data']>> = ({\n data,\n selected,\n}) => {\n const {\n label,\n status = 'active',\n heightCm = 100,\n powerPorts = 36, // Default number of AC power ports (10 C13 + 2 C19) × 3\n widthPx = 15,\n mgmt_unit, // Optional management unit position\n } = data;\n\n // Convert cm to pixels (1cm = 4.2px)\n const heightPx = heightCm * 4.2;\n\n // Completely custom vertical positioning for C13/C19/sets\n const renderPowerHandles = () => {\n // CYCLE = [8xC13, 2xC19], three times (for 30 ports)\n // Strategy:\n // - Use minimal/gapless \"start\" offset (header), so first port right beneath header.\n // - C13 ports: minimal gap (tight)\n // - C19 ports: even tighter gap than C13 (or zero)\n // - After last C19 of set: add a MUCH bigger gap before the new cycle (visual break).\n // - Ensure total height, including all ports and gaps, fits exactly into the available drawing area, and cycles are visually distinct.\n const cycleLength = 10; // 8 C13, 2 C19\n const nCycles = Math.ceil(powerPorts / cycleLength);\n const portsPerCycle = Array(cycleLength).fill(0).map((_, i) => (i < 8 ? '10A' : '16A'));\n\n // Sizing\n const C13_HEIGHT = 5;\n const C19_HEIGHT = 7;\n\n // Build metadata of port types and port heights\n const portMeta = [];\n for (let c = 0, idx = 0; c < nCycles; ++c) {\n for (let i = 0; i < cycleLength && idx < powerPorts; ++i, ++idx) {\n const portType = portsPerCycle[i];\n const is16A = portType === '16A';\n portMeta.push({\n portType,\n is16A,\n idx,\n isLastInCycle: i === cycleLength - 1,\n // For gap calculation\n isC19: is16A,\n portHeight: is16A ? C19_HEIGHT : C13_HEIGHT,\n });\n }\n }\n\n // Calculate the \"cycle\" indices (where to add the larger cycle gap)\n const handles = [];\n // Account for header height (20px) and add minimal padding\n const headerHeight = 15;\n const availableHeight = heightPx - headerHeight - 3; // 5px padding at bottom\n\n // REDUCE vertical spacing: 30% less spacing between ports\n // So multiply the calculated spacing by 0.7\n const rawPortSpacing = availableHeight / (powerPorts - 9);\n const portSpacing = rawPortSpacing * 0.5; // Even tighter spacing\n \n for (let i = 0; i < powerPorts; i++) {\n const yPos = headerHeight - 2 + (portSpacing * i); // Start slightly above header\n const handleId = `${i + 1}`;\n \n // Check if this position should be the management unit\n const isMgmtPosition = mgmt_unit && (\n (mgmt_unit === 'top' && i === 0) ||\n (mgmt_unit === 'middle' && i === Math.floor(powerPorts / 2)) ||\n (mgmt_unit === 'bottom' && i === powerPorts - 1)\n );\n \n if (isMgmtPosition) {\n handles.push(renderMgmtUnit(yPos));\n continue;\n }\n \n // Get port type and styling using shared utility\n const portType = getPDUPortType(i);\n const portStyle = getPowerPortStyle(portType);\n \n // Fix: Center the port more accurately (add -1px shift for visual center).\n const leftPx = Math.round((widthPx - portStyle.width) / 2 -1) ;\n\n handles.push(\n <Handle\n key={`handle-${handleId}`}\n type=\"source\"\n position={Position.Right}\n id={handleId}\n style={{\n position: 'absolute',\n left: `${leftPx}px`,\n top: `${yPos - (portStyle.height / 2)}px`,\n width: `${portStyle.width}px`,\n height: `${portStyle.height}px`,\n background: portStyle.color,\n border: `1px solid ${portStyle.borderColor}`,\n cursor: 'pointer',\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: portStyle.fontSize,\n color: '#1a1a1a',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n borderRadius: portStyle.borderRadius,\n clipPath: portStyle.clipPath,\n }}\n title={`Power Port ${i + 1} (${portType})`}\n >\n {i + 1}\n </Handle>\n );\n }\n return handles;\n };\n\n // Render management unit as a power port in the sequence\n const renderMgmtUnit = (yPos: number) => {\n const mgmtWidth = 16;\n const mgmtHeight = 12;\n\n return (\n <div\n key=\"mgmt-unit\"\n style={{\n position: 'absolute',\n left: `${(widthPx - mgmtWidth) / 2}px`,\n top: `${yPos - (mgmtHeight / 2)}px`,\n width: `${mgmtWidth}px`,\n height: `${mgmtHeight}px`,\n background: '#1a1a1a',\n border: '1px solid #374151',\n borderRadius: '1px',\n display: 'flex',\n flexDirection: 'column',\n padding: '1px',\n zIndex: 10,\n }}\n >\n {/* Screen positioned on the left */}\n <div\n style={{\n position: 'absolute',\n left: '-10px',\n top: '1px',\n background: '#ffffff',\n border: '0.5px solid #6b7280',\n borderRadius: '0.5px',\n width: '8px',\n height: '10px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '3px',\n color: '#10b981',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n transform: 'rotate(90deg)',\n transformOrigin: 'center',\n }}\n >\n APC\n </div>\n \n {/* Single Network Port Handle */}\n <Handle\n key=\"mgmt-net-1\"\n type=\"source\"\n position={Position.Right}\n id=\"mgmt-net-1\"\n style={{\n width: '70%',\n height: '6px',\n background: '#10b981',\n border: '1px solid #059669',\n borderRadius: '1px',\n cursor: 'pointer',\n zIndex: 11,\n margin: '0 auto',\n }}\n title=\"Management Network Port\"\n />\n </div>\n );\n };\n\n return (\n <div\n className={`vertical-pdu-node ${selected ? 'selected' : ''}`}\n style={{\n background: 'linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)',\n border: `1px solid ${getStatusColor(status)}`,\n borderRadius: '2px',\n padding: 0,\n width: `${widthPx}px`,\n height: `${heightPx}px`,\n color: 'white',\n fontFamily: 'monospace',\n fontSize: '12px',\n boxShadow: selected ? '0 0 0 2px #3b82f6' : '0 1px 3px rgba(0,0,0,0.3)',\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n \n {/* PDU Header */}\n <div style={{ \n textAlign: 'center', \n marginBottom: 0, \n zIndex: 2, \n background: 'linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)', \n padding: '2px',\n position: 'relative',\n height: '20px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n borderBottom: '1px solid #4a5568',\n }}>\n <div style={{ fontWeight: 'bold', fontSize: '6px', color: '#e2e8f0' }}>{label}</div>\n </div>\n \n {/* PDU Body with power ports */}\n <div\n style={{\n flex: 1,\n background: 'linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)',\n position: 'relative',\n minHeight: `${heightPx - 20}px`,\n overflow: 'hidden',\n }}\n >\n {renderPowerHandles()}\n </div>\n </div>\n );\n};\n","import type { NetworkEdge, NetworkNode } from '../types';\n\nexport type ViewFace = 'front' | 'rear';\n\nexport interface NetworkDiagramState {\n nodes: NetworkNode[];\n edges: NetworkEdge[];\n debug?: boolean;\n}\n\nexport interface ValidateConnectionParams {\n source: string | null;\n target: string | null;\n sourceHandle?: string | null;\n targetHandle?: string | null;\n}\n\nexport interface ValidationResult { valid: boolean; reason?: string }\n\nexport interface NetworkDiagramOptions {\n validateConnection?: (params: ValidateConnectionParams, ctx: NetworkDiagramState) => ValidationResult;\n}\n\nexport interface NetworkDiagramStore {\n getState: () => NetworkDiagramState;\n setState: (partial: Partial<NetworkDiagramState>) => void;\n subscribe: (listener: (state: NetworkDiagramState) => void) => () => void;\n // selectors\n selectEdgeZIndex: (edge: NetworkEdge) => number;\n validateConnection: (params: ValidateConnectionParams) => ValidationResult;\n selectNodeById: (id: string) => NetworkNode | undefined;\n selectConnectedEdges: (nodeId: string) => NetworkEdge[];\n}\n\nfunction defaultValidateConnection(params: ValidateConnectionParams, ctx: NetworkDiagramState): ValidationResult {\n if (!params.source || !params.target || !params.sourceHandle || !params.targetHandle) return { valid: true };\n\n const sourceAlready = ctx.edges.some(e => e.source === params.source && e.sourceHandle === params.sourceHandle);\n const targetAlready = ctx.edges.some(e => e.target === params.target && e.targetHandle === params.targetHandle);\n if (sourceAlready) return { valid: false, reason: 'Source port is already connected' };\n if (targetAlready) return { valid: false, reason: 'Target port is already connected' };\n\n // Enforce basic port-type compatibility: prevent network cables into power ports (and vice versa)\n const sourceHandleId = params.sourceHandle;\n const targetHandleId = params.targetHandle;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sourceNode = ctx.nodes.find(n => n.id === params.source) as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const targetNode = ctx.nodes.find(n => n.id === params.target) as any;\n\n // Treat any power outlet handle on a PDU as power (IDs are numeric), except the explicit mgmt network port\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isPowerHandle = (h: string, node?: any) => {\n if (!h) return false;\n const looksLikeDevicePower = h.startsWith('pwr') || h.startsWith('power');\n const isPduPower = node?.type === 'vertical-pdu' && h !== 'mgmt-net-1';\n return looksLikeDevicePower || isPduPower;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isNetworkHandle = (h: string, node?: any) => {\n if (!h) return false;\n if (node?.type === 'vertical-pdu' && h === 'mgmt-net-1') return true;\n // Check for common network handle patterns\n const looksLikeNetwork = h.startsWith('net-') || h.startsWith('port-') || h.startsWith('uplink-') || h.includes('Fiber') || h.includes('Ports');\n // Check if this is a custom port name from port blocks (e.g., \"QSFP28-1\", \"SFP+-2\", etc.)\n // Custom port names typically follow pattern: \"BlockName-Number\" where BlockName contains port type info\n const isCustomPortName = /^[A-Z0-9]+-\\d+$/.test(h) && !h.startsWith('pwr') && !h.startsWith('power');\n return looksLikeNetwork || isCustomPortName;\n };\n\n const sourceIsPower = isPowerHandle(sourceHandleId, sourceNode);\n const targetIsPower = isPowerHandle(targetHandleId, targetNode);\n const sourceIsNetwork = isNetworkHandle(sourceHandleId, sourceNode);\n const targetIsNetwork = isNetworkHandle(targetHandleId, targetNode);\n\n // If one side is power and the other is network, reject\n if ((sourceIsPower && targetIsNetwork) || (targetIsPower && sourceIsNetwork)) {\n return { valid: false, reason: 'Cannot connect network cable to power port' };\n }\n\n // If one side is explicitly power and the other side is neither power nor network, still reject\n if ((sourceIsPower && !targetIsPower) || (targetIsPower && !sourceIsPower)) {\n return { valid: false, reason: 'Power ports must connect to power-compatible ports' };\n }\n\n // Dual-feed power rule: if a device has two power ports, they must go to different PDUs\n // Identify PDU node and Device node for this connection\n const isPduSource = sourceNode?.type === 'vertical-pdu';\n const isPduTarget = targetNode?.type === 'vertical-pdu';\n\n if (sourceIsPower || targetIsPower) {\n const deviceNode = isPduSource ? targetNode : isPduTarget ? sourceNode : null;\n const pduNode = isPduSource ? sourceNode : isPduTarget ? targetNode : null;\n\n // Only enforce if we can identify both sides (PDU <-> device)\n if (deviceNode && pduNode) {\n // Find existing power edges connected to this device\n const devicePowerEdges = ctx.edges.filter(e => {\n const eSourceIsPower = isPowerHandle(e.sourceHandle || '');\n const eTargetIsPower = isPowerHandle(e.targetHandle || '');\n const involvesDevice = e.source === deviceNode.id || e.target === deviceNode.id;\n return (eSourceIsPower || eTargetIsPower) && involvesDevice;\n });\n\n // If there is already a power edge to this device from the same PDU, reject\n const samePduAlready = devicePowerEdges.some(e => e.source === pduNode.id || e.target === pduNode.id);\n if (samePduAlready) {\n // If device has more than one power handle, enforce connecting to the other PDU\n return { valid: false, reason: 'Dual-feed required: connect second power to a different PDU' };\n }\n }\n }\n\n return { valid: true };\n}\n\n// Determine which face a given handle belongs to, based on node data\nexport function getHandleSide(handleId: string, node: NetworkNode | undefined): ViewFace | undefined {\n if (!node) return undefined;\n const data = node.data ?? {};\n\n // Check handleSideMap first if available\n const handleSideMap = (data as { handleSideMap?: Record<string, ViewFace> }).handleSideMap;\n if (handleSideMap && handleSideMap[handleId]) {\n return handleSideMap[handleId];\n }\n\n // Known defaults\n if (handleId === 'net-top' || handleId === 'net-bottom') return 'front';\n if (handleId === 'pwr-left-1' || handleId === 'pwr-left-2' || handleId === 'net-right-1' || handleId === 'net-right-2') return 'rear';\n\n // Ports from arrays\n const frontBlocks = Array.isArray((data as { ports?: Array<{ name: string; ports?: Array<{ label: string; type?: string }> }> }).ports)\n ? (data as { ports?: Array<{ name: string; ports?: Array<{ label: string; type?: string }> }> }).ports!\n : [];\n const rearBlocks = Array.isArray((data as { rearPorts?: Array<{ name: string; ports?: Array<{ label: string; type?: string }> }> }).rearPorts)\n ? (data as { rearPorts?: Array<{ name: string; ports?: Array<{ label: string; type?: string }> }> }).rearPorts!\n : [];\n\n // If the handleId matches a power label, treat as rear by default\n const looksLikePower = handleId.startsWith('pwr') || handleId.includes('power');\n if (looksLikePower) return 'rear';\n\n // Try to match against front port blocks\n for (const block of frontBlocks) {\n for (const port of block.ports || []) {\n const isPowerPort = !!port.type && String(port.type).includes('power');\n const expected = isPowerPort ? port.label : `${block.name}-${port.label}`;\n if (expected === handleId) return 'front';\n }\n }\n // Try to match against rear port blocks\n for (const block of rearBlocks) {\n for (const port of block.ports || []) {\n const isPowerPort = !!port.type && String(port.type).includes('power');\n const expected = isPowerPort ? port.label : `${block.name}-${port.label}`;\n if (expected === handleId) return 'rear';\n }\n }\n\n return undefined;\n}\n\nexport function createNetworkDiagramStore(initial: Partial<NetworkDiagramState> = {}, options: NetworkDiagramOptions = {}): NetworkDiagramStore {\n let state: NetworkDiagramState = {\n nodes: initial.nodes ?? [],\n edges: initial.edges ?? [],\n debug: initial.debug ?? false,\n };\n const listeners = new Set<(s: NetworkDiagramState) => void>();\n\n const getState = () => state;\n const setState = (partial: Partial<NetworkDiagramState>) => {\n state = { ...state, ...partial };\n listeners.forEach(l => l(state));\n };\n const subscribe = (listener: (s: NetworkDiagramState) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n\n const selectEdgeZIndex = (edge: NetworkEdge): number => {\n const targetNode = state.nodes.find(n => n.id === edge.target);\n if (!targetNode || targetNode.type !== 'device') return 1000;\n const deviceView: ViewFace = (targetNode.data?.view as ViewFace) || 'front';\n const side = getHandleSide(edge.targetHandle || '', targetNode);\n if (side) return deviceView === side ? 1000 : 500;\n\n const targetHandle = (edge.targetHandle || '').toString();\n const targetHandleLc = targetHandle.toLowerCase();\n const isPowerHandle = targetHandleLc.startsWith('pwr') || targetHandleLc.startsWith('power');\n const isStandardNetworkHandle = targetHandleLc.startsWith('net-') || targetHandleLc.startsWith('port-') || targetHandleLc.startsWith('uplink-') || targetHandleLc.includes('fiber') || targetHandleLc.includes('ports');\n const isCustomPortName = /^[A-Z0-9]+-\\d+$/i.test(targetHandle) && !targetHandleLc.startsWith('pwr') && !targetHandleLc.startsWith('power');\n const isNetworkHandle = isStandardNetworkHandle || isCustomPortName;\n if (isPowerHandle) return deviceView === 'rear' ? 1000 : 500;\n if (isNetworkHandle) return deviceView === 'front' ? 1000 : 500;\n return 1000;\n };\n\n const validate = (params: ValidateConnectionParams): ValidationResult => {\n const fn = options.validateConnection || defaultValidateConnection;\n return fn(params, state);\n };\n\n const selectNodeById = (id: string) => state.nodes.find(n => n.id === id);\n const selectConnectedEdges = (nodeId: string) => state.edges.filter(e => e.source === nodeId || e.target === nodeId);\n\n return { getState, setState, subscribe, selectEdgeZIndex, validateConnection: validate, selectNodeById, selectConnectedEdges };\n}\n\n\n","import { useSyncExternalStore } from 'react';\nimport type { NetworkEdge, NetworkNode } from '../types';\nimport type { NetworkDiagramStore, NetworkDiagramState, ValidateConnectionParams, ValidationResult } from './store';\n\nexport function useNetworkDiagram(store: NetworkDiagramStore) {\n const subscribe = (cb: () => void) => store.subscribe(cb as unknown as (state: NetworkDiagramState) => void);\n const getSnapshot = () => store.getState();\n const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return state;\n}\n\nexport function useNodes(store: NetworkDiagramStore): NetworkNode[] {\n const subscribe = (cb: () => void) => store.subscribe(cb as unknown as (state: NetworkDiagramState) => void);\n const getSnapshot = () => store.getState().nodes;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport function useEdges(store: NetworkDiagramStore): NetworkEdge[] {\n const subscribe = (cb: () => void) => store.subscribe(cb as unknown as (state: NetworkDiagramState) => void);\n const getSnapshot = () => store.getState().edges;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport function useConnectionValidation(store: NetworkDiagramStore) {\n return (params: ValidateConnectionParams): ValidationResult => store.validateConnection(params);\n}\n\nexport function useSelectEdgeZIndex(store: NetworkDiagramStore) {\n return store.selectEdgeZIndex;\n}\n\n\n","import { NetworkNode } from '../types';\nimport { RACK_WIDTH_PX, U_HEIGHT_PX } from './constants';\n\n/**\n * Calculate the bounding box of a rack node\n * @param rack - The rack node\n * @returns Object with left, right, top, and bottom coordinates\n * @public\n */\nexport function getRackBounds(rack: NetworkNode): {\n left: number;\n right: number;\n top: number;\n bottom: number;\n} {\n const rackWidth = RACK_WIDTH_PX;\n const rackHeight = (rack.data.uHeight || 42) * U_HEIGHT_PX;\n const rackLeft = rack.position.x;\n const rackRight = rack.position.x + rackWidth;\n const rackTop = rack.position.y;\n const rackBottom = rack.position.y + rackHeight;\n\n return {\n left: rackLeft,\n right: rackRight,\n top: rackTop,\n bottom: rackBottom,\n };\n}\n\n/**\n * Check if a point is inside a rack's bounds\n * @param point - The point coordinates { x, y }\n * @param rack - The rack node\n * @returns True if the point is inside the rack\n * @public\n */\nexport function isPointInRack(point: { x: number; y: number }, rack: NetworkNode): boolean {\n const bounds = getRackBounds(rack);\n return (\n point.x >= bounds.left &&\n point.x <= bounds.right &&\n point.y >= bounds.top &&\n point.y <= bounds.bottom\n );\n}\n\n/**\n * Find the nearest rack to a point from a list of racks\n * Only considers racks that contain the point\n * @param point - The point coordinates { x, y }\n * @param racks - Array of rack nodes\n * @returns The nearest rack node, or null if no rack contains the point\n * @public\n */\nexport function findNearestRack(\n point: { x: number; y: number },\n racks: NetworkNode[]\n): NetworkNode | null {\n let nearestRack: NetworkNode | null = null;\n let minDistance = Infinity;\n\n for (const rack of racks) {\n if (!isPointInRack(point, rack)) {\n continue;\n }\n\n const distance = Math.sqrt(\n Math.pow(point.x - rack.position.x, 2) + Math.pow(point.y - rack.position.y, 2)\n );\n\n if (distance < minDistance) {\n minDistance = distance;\n nearestRack = rack;\n }\n }\n\n return nearestRack;\n}\n\n","import { Connection, Edge, addEdge } from 'reactflow';\nimport { NetworkEdge } from '../types';\n\n/**\n * Options for replacing an edge in the edges array\n */\nexport interface ReplaceEdgeOptions {\n /** Existing edges array */\n edges: Edge[];\n /** Connection parameters for the new edge */\n connection: Connection;\n /** Type of edge to create */\n edgeType: 'power' | 'fiber';\n /** Function to calculate zIndex for the edge */\n selectEdgeZIndex: (edge: NetworkEdge) => number;\n /** Whether to find edge by source or target */\n findBy: 'source' | 'target';\n}\n\n/**\n * Replace an existing edge with a new connection\n * This is used for PDU and switch connections that allow replacing existing edges\n * @param options - Options for edge replacement\n * @returns New edges array with the edge replaced, or null if no existing edge found\n * @public\n */\nexport function replaceEdge(\n options: ReplaceEdgeOptions\n): Edge[] | null {\n const { edges, connection, edgeType, selectEdgeZIndex, findBy } = options;\n\n // Determine which handle to search by\n const handleId = findBy === 'source' ? connection.sourceHandle : connection.targetHandle;\n const nodeId = findBy === 'source' ? connection.source : connection.target;\n\n if (!handleId || !nodeId) {\n return null;\n }\n\n // Find existing edge\n const existingEdge = edges.find(e => {\n if (findBy === 'source') {\n return e.source === nodeId && e.sourceHandle === handleId;\n } else {\n return e.target === nodeId && e.targetHandle === handleId;\n }\n });\n\n if (!existingEdge) {\n return null;\n }\n\n // Remove the existing edge\n const filtered = edges.filter(e => e.id !== existingEdge.id);\n\n // Create new edge using addEdge helper, then add type and zIndex\n const edgeFromAddEdge = addEdge(connection, filtered);\n \n // Find the newly added edge and update it with type and zIndex\n const newEdge = edgeFromAddEdge[edgeFromAddEdge.length - 1];\n const edgeWithMetadata: Edge = {\n ...newEdge,\n type: edgeType,\n zIndex: selectEdgeZIndex({ ...connection, id: newEdge.id, type: edgeType } as NetworkEdge),\n style: { ...newEdge.style, zIndex: selectEdgeZIndex({ ...connection, id: newEdge.id, type: edgeType } as NetworkEdge) },\n };\n\n // Replace the last edge with the one that has metadata\n return [...edgeFromAddEdge.slice(0, -1), edgeWithMetadata];\n}\n\n","import React, { useCallback, useMemo, useState, useEffect, useRef } from 'react';\nimport {\n ReactFlow,\n Background,\n Controls,\n MiniMap,\n useNodesState,\n useEdgesState,\n addEdge,\n Connection,\n Edge,\n Node,\n NodeTypes,\n EdgeTypes,\n useReactFlow,\n NodeChange,\n useOnSelectionChange,\n ReactFlowProvider,\n Panel,\n NodeProps,\n} from 'reactflow';\nimport { toPng } from 'html-to-image';\nimport { NetworkDiagramProps, NetworkNode, NetworkEdge } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from '../utils/constants';\nimport { RackNode } from './RackNode';\nimport { FiberNode } from './FiberNode';\nimport { FiberEdge } from './FiberEdge';\nimport { PowerEdge } from './PowerEdge';\nimport { DeviceNode } from './DeviceNode';\nimport { VerticalPDU } from './VerticalPDU';\nimport { snapToUPosition, calculateDevicePositionFromU } from '../utils/u-positioning';\nimport { createNetworkDiagramStore } from '../core/store';\nimport { useEdges, useNodes, useSelectEdgeZIndex } from '../core/hooks';\nimport { isPointInRack, findNearestRack } from '../utils/rack-geometry';\nimport { replaceEdge } from '../utils/edge-connection';\n\n// Create nodeTypes with onViewChange prop - memoized outside component\nconst createNodeTypes = (\n onViewChange?: (nodeId: string, view: 'front' | 'rear') => void,\n onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void,\n dragOverRackId?: string | null\n): NodeTypes => ({\n rack: (props: NodeProps<NetworkNode['data']>) => <RackNode {...props} onViewChange={onViewChange} onRackFaceChange={onRackFaceChange} isDragOver={dragOverRackId === props.id} />,\n fiber: FiberNode,\n device: DeviceNode,\n 'vertical-pdu': VerticalPDU,\n});\n\nconst edgeTypes: EdgeTypes = {\n fiber: FiberEdge,\n power: PowerEdge,\n};\n\nconst NetworkDiagramInner: React.FC<NetworkDiagramProps> = ({\n nodes,\n edges,\n initialNodes,\n initialEdges,\n onNodesChange: externalOnNodesChange,\n onEdgesChange: externalOnEdgesChange,\n store,\n debug,\n onNodeClick,\n onEdgeClick,\n onViewChange,\n onRackFaceChange,\n className,\n style,\n alignRacksToBottom,\n colorMode = 'dark',\n onInit,\n onFlowMethods,\n showDownloadButton = false,\n downloadButtonPosition = 'top-right',\n downloadButtonText = 'Download Image',\n downloadButtonStyle,\n}) => {\n // Decide controlled vs uncontrolled\n const isControlled = Array.isArray(nodes) && Array.isArray(edges);\n // Important: do not recreate store on nodes/edges changes to avoid perceived resets\n const localStore = React.useMemo(() => {\n if (store) return store;\n // Create store once; controlled updates will sync via effects below\n return createNetworkDiagramStore({\n nodes: isControlled ? (nodes || []) : (initialNodes || nodes || []),\n edges: isControlled ? (edges || []) : (initialEdges || edges || []),\n debug,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, isControlled, debug]);\n\n // Local React Flow states mirror store state for rendering\n const storeNodes = useNodes(localStore);\n const storeEdges = useEdges(localStore);\n const [reactFlowNodes, setNodes, onNodesChange] = useNodesState(storeNodes);\n const [reactFlowEdges, setEdges, onEdgesChange] = useEdgesState(storeEdges);\n const selectEdgeZIndex = useSelectEdgeZIndex(localStore);\n const reactFlowWrapper = useRef<HTMLDivElement>(null);\n \n // Get React Flow methods for save/restore\n const { toObject, setViewport, setNodes: setReactFlowNodes, setEdges: setReactFlowEdges } = useReactFlow();\n \n // Type for html-to-image options\n interface ToImageOptions {\n width?: number;\n height?: number;\n backgroundColor?: string;\n padding?: number;\n pixelRatio?: number;\n quality?: number;\n filter?: (domNode: HTMLElement) => boolean;\n }\n \n // Expose React Flow methods to parent component\n useEffect(() => {\n if (onFlowMethods) {\n onFlowMethods({\n toObject,\n setViewport,\n setNodes: (nodes: Node[]) => {\n setReactFlowNodes(nodes);\n localStore.setState({ nodes: nodes as NetworkNode[] });\n },\n setEdges: (edges: Edge[]) => {\n setReactFlowEdges(edges);\n localStore.setState({ edges: edges as NetworkEdge[] });\n },\n toImage: (options?: ToImageOptions) => {\n if (!reactFlowWrapper.current) return Promise.reject(new Error('ReactFlow wrapper not available'));\n return toPng(reactFlowWrapper.current, options);\n }\n });\n }\n }, [onFlowMethods, toObject, setViewport, setReactFlowNodes, setReactFlowEdges, localStore]);\n\n // Download functionality\n const onDownload = useCallback(() => {\n if (!reactFlowWrapper.current) {\n if (debug) {\n console.error('ReactFlow wrapper ref is not available');\n }\n return;\n }\n \n toPng(reactFlowWrapper.current, {\n filter: (node) =>\n !(\n node?.classList?.contains('react-flow__minimap') ||\n node?.classList?.contains('react-flow__controls') ||\n node?.classList?.contains('react-flow__attribution') ||\n node?.classList?.contains('download-button') ||\n node?.tagName === 'BUTTON'\n ),\n backgroundColor: colorMode === 'light' ? '#ffffff' : '#1a1a1a',\n pixelRatio: 2,\n }).then((dataUrl: string) => {\n const link = document.createElement('a');\n link.download = `network-diagram-${new Date().toISOString().split('T')[0]}.png`;\n link.href = dataUrl;\n link.click();\n }).catch((error: unknown) => {\n if (debug) {\n console.error('Error downloading image:', error);\n }\n });\n }, [colorMode, debug]);\n \n // Track which rack is being dragged over for visual feedback\n const [dragOverRackId, setDragOverRackId] = useState<string | null>(null);\n \n // Memoize nodeTypes to avoid recreating object every render (prevents node remounts)\n // Note: intentionally excluding nodes/edges/initialNodes/initialEdges from deps to prevent recreating nodeTypes on every render\n const memoizedNodeTypes = useMemo(\n () => createNodeTypes(onViewChange, onRackFaceChange, dragOverRackId),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onViewChange, onRackFaceChange, dragOverRackId]\n );\n \n // Memoize edgeTypes to prevent recreation warnings\n const memoizedEdgeTypes = useMemo(() => edgeTypes, []);\n\n\n // Maintain the latest nodes in a ref for always-current lookups in callbacks\n const latestNodesRef = useRef<Node[]>(reactFlowNodes);\n useEffect(() => { latestNodesRef.current = reactFlowNodes; }, [reactFlowNodes]);\n\n // Maintain the latest edges in a ref for always-current lookups in callbacks\n const latestEdgesRef = useRef<Edge[]>(reactFlowEdges);\n useEffect(() => { latestEdgesRef.current = reactFlowEdges; }, [reactFlowEdges]);\n\n // Sync store -> RF state updates\n useEffect(() => { setNodes(storeNodes); }, [storeNodes, setNodes]);\n useEffect(() => { setEdges(storeEdges); }, [storeEdges, setEdges]);\n // Sync controlled props -> store (if controlled)\n useEffect(() => {\n if (isControlled) {\n localStore.setState({ nodes: nodes || [] });\n }\n }, [isControlled, nodes, localStore]);\n useEffect(() => {\n if (isControlled) {\n localStore.setState({ edges: edges || [] });\n }\n }, [isControlled, edges, localStore]);\n\n // Optionally align rack bottoms to a common baseline\n useEffect(() => {\n if (!alignRacksToBottom) return;\n if (!reactFlowNodes || reactFlowNodes.length === 0) return;\n\n const racks = reactFlowNodes.filter(n => n.type === 'rack');\n if (racks.length === 0) return;\n\n // Compute each rack's bottom (y + header + uHeight * U_HEIGHT_PX)\n const rackBottoms = racks.map(r => {\n const rackData = r.data as NetworkNode['data'];\n const uHeight = rackData?.uHeight || 42;\n const heightPx = RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX;\n return (r.position?.y || 0) + heightPx;\n });\n \n // Find the range of bottom positions\n const minBottom = Math.min(...rackBottoms);\n const maxBottom = Math.max(...rackBottoms);\n const range = maxBottom - minBottom;\n \n // Only align if there's a significant difference (more than 20px)\n // This prevents constant micro-adjustments during dragging\n if (range < 20) return;\n \n // Use the highest bottom as the baseline (floor level)\n const baselineBottom = maxBottom;\n\n // Align all racks to the baseline - move them up or down as needed\n const nextNodes = reactFlowNodes.map(n => {\n if (n.type !== 'rack') return n;\n const nodeData = n.data as NetworkNode['data'];\n const uHeight = nodeData?.uHeight || 42;\n const heightPx = RACK_HEADER_HEIGHT + uHeight * U_HEIGHT_PX;\n const currentBottom = (n.position?.y || 0) + heightPx;\n const delta = baselineBottom - currentBottom;\n if (Math.abs(delta) < 5) return n; // Don't make tiny adjustments\n return {\n ...n,\n position: {\n x: n.position?.x || 0,\n y: (n.position?.y || 0) + delta,\n },\n } as Node;\n });\n\n const changed = nextNodes.some((n, i) => n.position !== reactFlowNodes[i].position);\n if (changed) setNodes(nextNodes);\n }, [alignRacksToBottom, reactFlowNodes, setNodes]);\n\n // Helper: always get current version of a node (beyond closure scope issue)\n const getNodeById = useCallback((id: string) => {\n return latestNodesRef.current.find(n => n.id === id);\n }, []);\n\n // Update edges zIndex when nodes change\n useEffect(() => {\n setEdges((eds) =>\n eds.map(edge => {\n const newZIndex = selectEdgeZIndex(edge as NetworkEdge);\n return {\n ...edge,\n zIndex: newZIndex,\n style: { ...edge.style, zIndex: newZIndex }\n };\n })\n );\n }, [reactFlowNodes, setEdges, selectEdgeZIndex]);\n\n useEffect(() => {\n const updatedNodes = reactFlowNodes.map(node => {\n if (\n node.type === 'device' &&\n node.parentId &&\n node.data.uPosition &&\n (!node.position || (node.position.x === 0 && node.position.y === 0))\n ) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const calculatedPosition = calculateDevicePositionFromU(parentRack as NetworkNode, node.data.uPosition);\n return {\n ...node,\n position: calculatedPosition,\n };\n }\n }\n return node;\n });\n\n const hasChanges = updatedNodes.some((node, index) =>\n node.position !== reactFlowNodes[index].position\n );\n if (hasChanges) {\n setNodes(updatedNodes);\n }\n }, [reactFlowNodes, setNodes, getNodeById]);\n\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n const updatedChanges = changes.map((change) => {\n if (change.type === 'position' && change.position) {\n const node = getNodeById(change.id);\n\n if (node && node.type === 'device' && node.parentId) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const snappedResult = snapToUPosition(\n node as NetworkNode,\n parentRack as NetworkNode,\n change.position,\n latestNodesRef.current as NetworkNode[]\n );\n\n if (snappedResult.uPosition !== undefined) {\n const updatedNode = {\n ...node,\n data: {\n ...node.data,\n uPosition: snappedResult.uPosition,\n },\n };\n\n setNodes((nodes) =>\n nodes.map(n => n.id === node.id ? updatedNode : n)\n );\n }\n\n return { ...change, position: { x: snappedResult.x, y: snappedResult.y } };\n }\n }\n\n\n if (node && node.type === 'device' && node.parentId) {\n const parentRack = getNodeById(node.parentId);\n if (parentRack) {\n const rackNode = parentRack as NetworkNode;\n\n if (!isPointInRack(change.position, rackNode)) {\n const absoluteX = change.position.x + rackNode.position.x;\n const absoluteY = change.position.y + rackNode.position.y;\n const updatedNode = {\n ...node,\n parentId: undefined,\n extent: undefined,\n data: {\n ...node.data,\n uPosition: undefined,\n },\n };\n setNodes((nodes) =>\n nodes.map(n => n.id === node.id ? updatedNode : n)\n );\n return { ...change, position: { x: absoluteX, y: absoluteY } };\n }\n }\n }\n }\n return change;\n });\n\n onNodesChange(updatedChanges);\n }, [onNodesChange, setNodes, getNodeById]);\n\n // Handle drag start to track which node is being dragged\n const handleNodeDragStart = useCallback((_event: React.MouseEvent, _node: Node) => {\n // Reset drag over state when starting a new drag\n setDragOverRackId(null);\n }, []);\n\n // Handle drag over to detect when device is over a rack\n const handleNodeDrag = useCallback((_event: React.MouseEvent, node: Node, _nodes: Node[]) => {\n if (node.type === 'device' && !node.parentId) {\n // Find the nearest rack\n const racks = latestNodesRef.current\n .filter(n => n.type === 'rack')\n .map(n => n as NetworkNode);\n const nearestRack = findNearestRack(node.position, racks);\n\n // Update drag over state\n setDragOverRackId(nearestRack?.id ?? null);\n } else {\n setDragOverRackId(null);\n }\n }, []);\n\n // Handle drag end to group ungrouped nodes into racks\n const handleNodeDragStop = useCallback((_event: React.MouseEvent, node: Node, _nodes: Node[]) => {\n if (node.type === 'device' && !node.parentId) {\n // Find the nearest rack\n const racks = latestNodesRef.current\n .filter(n => n.type === 'rack')\n .map(n => n as NetworkNode);\n const nearestRack = findNearestRack(node.position, racks);\n\n if (nearestRack) {\n // Calculate relative position\n const relativeX = node.position.x - nearestRack.position.x;\n const relativeY = node.position.y - nearestRack.position.y;\n \n // Update the node with parent relationship and new position\n const updatedNode = {\n ...node,\n parentId: nearestRack.id,\n extent: 'parent' as const,\n position: { x: relativeX, y: relativeY },\n data: {\n ...node.data,\n uPosition: 1,\n },\n };\n \n const updatedNodes = latestNodesRef.current.map(n => n.id === node.id ? updatedNode : n);\n setNodes(updatedNodes);\n \n // Update store in uncontrolled mode\n if (!isControlled) {\n localStore.setState({ nodes: updatedNodes as NetworkNode[] });\n }\n }\n }\n \n // Clear drag over state when drag ends\n setDragOverRackId(null);\n }, [setNodes, isControlled, localStore]);\n\n // Connection validation - enforce single connection per handle and allow PDU → device power\n // Note: isValidConnection is currently unused but kept for potential future use\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _isValidConnection = useCallback((connection: Connection): { valid: boolean; reason?: string } => {\n if (!connection.source || !connection.target || !connection.sourceHandle || !connection.targetHandle) {\n return { valid: true };\n }\n\n const sourceHandleId = connection.sourceHandle;\n const targetHandleId = connection.targetHandle;\n\n const sourceAlreadyConnected = latestEdgesRef.current.some(edge =>\n edge.source === connection.source && edge.sourceHandle === sourceHandleId\n );\n\n const targetAlreadyConnected = latestEdgesRef.current.some(edge =>\n edge.target === connection.target && edge.targetHandle === targetHandleId\n );\n\n if (sourceAlreadyConnected) {\n return { valid: false, reason: 'Source port is already connected' };\n }\n\n if (targetAlreadyConnected) {\n return { valid: false, reason: 'Target port is already connected' };\n }\n\n return { valid: true };\n }, []);\n\n const onConnect = useCallback(\n (params: Connection) => {\n const sourceNode = getNodeById(params.source!);\n const isPduSource = sourceNode?.type === 'vertical-pdu';\n const sourceNodeData = sourceNode?.data as NetworkNode['data'];\n const isSwitchSource = sourceNode?.type === 'device' && sourceNodeData?.deviceType === 'switch';\n const looksLikePowerTarget = !!params.targetHandle && (params.targetHandle.startsWith('pwr') || params.targetHandle.startsWith('power'));\n const looksLikeNetworkTarget = !!params.targetHandle && (\n params.targetHandle.startsWith('net-') || \n params.targetHandle.startsWith('port-') || \n /^[A-Z0-9]+-\\d+$/i.test(params.targetHandle) // Custom port names like \"QSFP28-1\"\n );\n\n // Try to replace existing edge on target for PDU power connections\n if (isPduSource && looksLikePowerTarget && params.target && params.targetHandle) {\n const newEdges = replaceEdge({\n edges: latestEdgesRef.current,\n connection: params,\n edgeType: 'power',\n selectEdgeZIndex,\n findBy: 'target',\n });\n if (newEdges) {\n setEdges(newEdges);\n return;\n }\n }\n\n // Allow replacing existing network edge on target when connecting from switch (like power PDU behavior)\n if (isSwitchSource && looksLikeNetworkTarget && params.target && params.targetHandle) {\n const newEdges = replaceEdge({\n edges: latestEdgesRef.current,\n connection: params,\n edgeType: 'fiber',\n selectEdgeZIndex,\n findBy: 'target',\n });\n if (newEdges) {\n setEdges(newEdges);\n return;\n }\n }\n\n const validation = localStore.validateConnection({\n source: params.source ?? null,\n target: params.target ?? null,\n sourceHandle: params.sourceHandle ?? null,\n targetHandle: params.targetHandle ?? null,\n });\n if (!validation.valid) {\n // Try to replace existing edge on source for PDU connections\n if (isPduSource && params.source && params.sourceHandle) {\n const newEdges = replaceEdge({\n edges: latestEdgesRef.current,\n connection: params,\n edgeType: looksLikePowerTarget ? 'power' : 'fiber',\n selectEdgeZIndex,\n findBy: 'source',\n });\n if (newEdges) {\n setEdges(newEdges);\n return;\n }\n }\n // Allow replacing existing network edge on source when connecting from switch (like power PDU behavior)\n if (isSwitchSource && params.source && params.sourceHandle) {\n const newEdges = replaceEdge({\n edges: latestEdgesRef.current,\n connection: params,\n edgeType: 'fiber',\n selectEdgeZIndex,\n findBy: 'source',\n });\n if (newEdges) {\n setEdges(newEdges);\n return;\n }\n }\n if (debug) {\n console.warn(`Connection rejected: ${validation.reason}`);\n }\n return;\n }\n\n const edgeToAdd = {\n ...params,\n type: (isPduSource && looksLikePowerTarget) ? 'power' : 'fiber',\n zIndex: selectEdgeZIndex({ ...params, id: 'temp-id' } as NetworkEdge),\n } as Connection;\n\n setEdges((eds) => addEdge(edgeToAdd, eds));\n },\n [setEdges, localStore, selectEdgeZIndex, getNodeById, debug]\n );\n\n const handleNodeClick = useCallback(\n (event: React.MouseEvent, node: Node) => {\n const isCommandClick = event.metaKey || event.ctrlKey;\n\n if (isCommandClick && node.type === 'device') {\n const data = node.data || {};\n const currentView: 'front' | 'rear' = data.view || (Array.isArray(data.rearPorts) && data.rearPorts.length > 0 ? 'rear' : 'front');\n const nextView: 'front' | 'rear' = currentView === 'front' ? 'rear' : 'front';\n\n if (debug) {\n console.log(`Command+click: Toggling device ${node.id} from ${currentView} to ${nextView}`);\n }\n\n // Use external onViewChange instead of internal state management\n if (onViewChange) {\n onViewChange(node.id, nextView);\n }\n\n onNodeClick && onNodeClick(node as NetworkNode);\n } else {\n // Allow regular clicks on all nodes (including devices) to trigger selection\n // React Flow will handle the selection, and useOnSelectionChange will call onNodeClick\n onNodeClick && onNodeClick(node as NetworkNode);\n }\n },\n [onViewChange, onNodeClick, debug]\n );\n\n // Double-click no longer removes edges to avoid accidental disconnects during interactions\n const handleNodeDoubleClick = useCallback(() => {}, []);\n\n const handleEdgeClick = useCallback(\n (event: React.MouseEvent, edge: Edge) => {\n if (onEdgeClick) {\n onEdgeClick(edge as NetworkEdge);\n }\n },\n [onEdgeClick]\n );\n\n // Track selection to show a toggle UI\n const [selectedNode, setSelectedNode] = useState<Node | null>(null);\n useOnSelectionChange({\n onChange: ({ nodes }) => {\n if (nodes && nodes.length === 1) {\n const node = nodes[0];\n setSelectedNode(node);\n // Also call onNodeClick when a node is selected via React Flow selection\n // This ensures device nodes can be selected even if regular clicks don't trigger onNodeClick\n if (onNodeClick) {\n onNodeClick(node as NetworkNode);\n }\n } else {\n setSelectedNode(null);\n // Clear selection in parent when no nodes are selected\n if (onNodeClick) {\n onNodeClick(null);\n }\n }\n },\n });\n\n const toggleSelectedFace = useCallback(() => {\n if (!selectedNode) return;\n const node = getNodeById(selectedNode.id);\n if (!node) return;\n\n if (node.type === 'rack') {\n const nodeData = (node.data as NetworkNode['data']) || {};\n const currentFace: 'front' | 'rear' = (nodeData.face as 'front' | 'rear') || 'front';\n const next: 'front' | 'rear' = currentFace === 'front' ? 'rear' : 'front';\n if (onRackFaceChange) {\n onRackFaceChange(node.id, next);\n } else {\n // Fallback: update rack face and propagate to child devices' view\n setNodes((nodes) => nodes.map(n => {\n if (n.id === node.id) {\n return { ...n, data: { ...n.data, face: next } } as Node;\n }\n if (n.parentId === node.id) {\n return { ...n, data: { ...n.data, view: next } } as Node;\n }\n return n;\n }));\n }\n return;\n }\n\n if (node.type === 'device') {\n const nodeData = (node.data as NetworkNode['data']) || {};\n const hasRear = Array.isArray(nodeData.rearPorts) && nodeData.rearPorts.length > 0;\n const hasFront = Array.isArray(nodeData.ports) && nodeData.ports.length > 0;\n const currentView: 'front' | 'rear' = (nodeData.view as 'front' | 'rear') || (hasRear && !hasFront ? 'rear' : 'front');\n const next: 'front' | 'rear' = currentView === 'front' ? 'rear' : 'front';\n if (onViewChange) {\n onViewChange(node.id, next);\n } else {\n setNodes((nodes) => nodes.map(n => n.id === node.id ? ({ ...n, data: { ...n.data, view: next } } as Node) : n));\n }\n }\n }, [selectedNode, getNodeById, onRackFaceChange, onViewChange, setNodes]);\n\n return (\n <div ref={reactFlowWrapper} className={`${className || ''} ${colorMode === 'light' ? 'react-flow-light' : 'react-flow-dark'}`} style={{ width: '100%', height: '100%', ...style }}>\n <ReactFlow\n nodes={reactFlowNodes}\n edges={reactFlowEdges}\n onNodesChange={(changes) => {\n handleNodesChange(changes);\n if (!isControlled) {\n localStore.setState({ nodes: latestNodesRef.current as NetworkNode[] });\n } else {\n externalOnNodesChange && externalOnNodesChange(latestNodesRef.current as NetworkNode[]);\n }\n }}\n onEdgesChange={(changes) => {\n onEdgesChange(changes);\n if (!isControlled) {\n localStore.setState({ edges: latestEdgesRef.current as NetworkEdge[] });\n } else {\n externalOnEdgesChange && externalOnEdgesChange(latestEdgesRef.current as NetworkEdge[]);\n }\n }}\n onConnect={onConnect}\n onNodeClick={handleNodeClick}\n onNodeDoubleClick={handleNodeDoubleClick}\n onNodeDragStart={handleNodeDragStart}\n onNodeDrag={handleNodeDrag}\n onNodeDragStop={handleNodeDragStop}\n onEdgeClick={handleEdgeClick}\n onInit={onInit}\n nodeTypes={memoizedNodeTypes}\n edgeTypes={memoizedEdgeTypes}\n defaultEdgeOptions={{\n zIndex: 1000,\n reconnectable: true\n }}\n nodesDraggable={true}\n nodesConnectable={true}\n elementsSelectable={true}\n selectNodesOnDrag={false}\n fitView\n proOptions={{ hideAttribution: true }}\n >\n <Background />\n <Controls />\n <MiniMap />\n <Panel position=\"bottom-right\" className=\"react-networks-attribution\">\n <a\n href=\"https://github.com/MP70/react-networks\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"react-networks-attribution-link\"\n >\n react-networks\n </a>\n </Panel>\n </ReactFlow>\n {showDownloadButton && (\n <button\n className=\"download-button\"\n onClick={onDownload}\n style={{\n position: 'absolute',\n top: downloadButtonPosition.includes('top') ? '10px' : 'auto',\n bottom: downloadButtonPosition.includes('bottom') ? '10px' : 'auto',\n right: downloadButtonPosition.includes('right') ? '10px' : 'auto',\n left: downloadButtonPosition.includes('left') ? '10px' : 'auto',\n zIndex: 1000,\n background: '#374151',\n color: '#e5e7eb',\n border: '1px solid #4b5563',\n borderRadius: '4px',\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n ...downloadButtonStyle,\n }}\n >\n {downloadButtonText}\n </button>\n )}\n {selectedNode && (selectedNode.type === 'rack' || selectedNode.type === 'device') && (\n <div\n style={{\n position: 'absolute',\n top: 12,\n right: 12,\n display: 'flex',\n gap: 8,\n zIndex: 2000,\n }}\n >\n <button\n onClick={(e) => { e.preventDefault(); toggleSelectedFace(); }}\n style={{\n background: '#374151',\n color: '#e5e7eb',\n border: '1px solid #4b5563',\n borderRadius: 4,\n padding: '6px 10px',\n fontSize: 11,\n fontFamily: 'monospace',\n cursor: 'pointer',\n }}\n title={(() => {\n const nodeData = selectedNode.data as NetworkNode['data'];\n if (selectedNode.type === 'rack') {\n const face = (nodeData?.face as 'front' | 'rear') || 'front';\n return face === 'front' ? 'Switch to rear' : 'Switch to front';\n } else {\n const hasRear = Array.isArray(nodeData?.rearPorts) && nodeData.rearPorts.length > 0;\n const hasFront = Array.isArray(nodeData?.ports) && nodeData.ports.length > 0;\n const view = (nodeData?.view as 'front' | 'rear') || (hasRear && !hasFront ? 'rear' : 'front');\n return view === 'front' ? 'Switch to rear' : 'Switch to front';\n }\n })()}\n >\n {(() => {\n const nodeData = selectedNode.data as NetworkNode['data'];\n if (selectedNode.type === 'rack') {\n const face = (nodeData?.face as 'front' | 'rear') || 'front';\n return face === 'front' ? '⇄ Rear' : '⇄ Front';\n } else {\n const hasRear = Array.isArray(nodeData?.rearPorts) && nodeData.rearPorts.length > 0;\n const hasFront = Array.isArray(nodeData?.ports) && nodeData.ports.length > 0;\n const view = (nodeData?.view as 'front' | 'rear') || (hasRear && !hasFront ? 'rear' : 'front');\n return view === 'front' ? '⇄ Rear' : '⇄ Front';\n }\n })()}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const NetworkDiagram: React.FC<NetworkDiagramProps> = (props) => {\n return (\n <ReactFlowProvider>\n <NetworkDiagramInner {...props} />\n </ReactFlowProvider>\n );\n};\n","import { NetworkNode, NetworkEdge } from '../types';\n\ninterface InventoryRackDTO {\n id: string | number;\n name: string;\n status?: { value?: string } | string;\n u_height?: number;\n units?: number;\n facility_id?: string | number;\n serial?: string;\n asset_tag?: string;\n site?: { name?: string } | string;\n role?: { name?: string } | string;\n tenant?: { name?: string } | string;\n}\n\ninterface InventoryDeviceDTO {\n id: string | number;\n name: string;\n status?: { value?: string } | string;\n device_type?: { u_height?: number; model?: string; manufacturer?: { name?: string } };\n model?: string;\n manufacturer?: string;\n device_role?: { name?: string } | string;\n u_height?: number;\n position?: number;\n face?: 'front' | 'rear';\n rack?: { id?: string | number; name?: string } | string | number;\n primary_ip4?: { address?: string } | string;\n primary_ip6?: { address?: string } | string;\n site?: { name?: string } | string;\n}\n\ninterface InventoryCableDTO {\n id: string | number;\n type?: { label?: string };\n bandwidth?: string;\n length?: number;\n color?: string;\n status?: { value?: string } | string;\n termination_a?: { device?: { id?: string | number } | string | number; name?: string } | string;\n termination_b?: { device?: { id?: string | number } | string | number; name?: string } | string;\n}\n\n/**\n * Convert inventory rack data to NetworkNode\n */\nexport const inventoryRackToNetworkNode = (rack: InventoryRackDTO): NetworkNode => {\n return {\n id: `rack-${rack.id}`,\n type: 'rack',\n position: { x: 0, y: 0 },\n data: {\n label: rack.name,\n status: ((typeof rack.status === 'object' && rack.status) ? (rack.status as { value?: string }).value : rack.status) as 'active' | 'inactive' | 'maintenance',\n uHeight: rack.u_height ?? rack.units ?? 42,\n inventoryId: rack.id,\n inventoryType: 'rack',\n facilityId: rack.facility_id,\n serial: rack.serial,\n assetTag: rack.asset_tag,\n site: (typeof rack.site === 'object' && rack.site) ? (rack.site as { name?: string }).name : rack.site,\n role: (typeof rack.role === 'object' && rack.role) ? (rack.role as { name?: string }).name : rack.role,\n tenant: (typeof rack.tenant === 'object' && rack.tenant) ? (rack.tenant as { name?: string }).name : rack.tenant,\n },\n };\n};\n\n/**\n * Convert inventory device data to NetworkNode\n */\nexport const inventoryDeviceToNetworkNode = (device: InventoryDeviceDTO): NetworkNode => {\n return {\n id: `device-${device.id}`,\n type: 'device',\n position: { x: 0, y: 0 },\n parentId: device.rack ? `rack-${(typeof device.rack === 'object' && device.rack ? (device.rack as { id?: string | number }).id : device.rack)}` : undefined,\n extent: device.rack ? 'parent' : undefined,\n data: {\n label: device.name,\n status: ((typeof device.status === 'object' && device.status) ? (device.status as { value?: string }).value : device.status) as 'active' | 'inactive' | 'maintenance',\n deviceType: device.device_type?.model ?? device.model,\n manufacturer: (device.device_type?.manufacturer?.name ?? device.manufacturer),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n role: (typeof device.device_role === 'object' && device.device_role) ? (device.device_role as { name?: string }).name : (device as any).role,\n uHeight: device.device_type?.u_height ?? device.u_height ?? 1,\n uPosition: device.position || 1,\n view: (device.face as 'front' | 'rear') || 'front',\n inventoryId: device.id,\n inventoryType: 'device',\n primaryIp4: (typeof device.primary_ip4 === 'object' && device.primary_ip4) ? (device.primary_ip4 as { address?: string }).address : device.primary_ip4,\n primaryIp6: (typeof device.primary_ip6 === 'object' && device.primary_ip6) ? (device.primary_ip6 as { address?: string }).address : device.primary_ip6,\n site: (typeof device.site === 'object' && device.site) ? (device.site as { name?: string }).name : device.site,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n rack: (typeof device.rack === 'object' && device.rack) ? (device.rack as { name?: string }).name : (device.rack as any),\n },\n };\n};\n\n/**\n * Convert inventory cable data to NetworkEdge\n */\nexport const inventoryCableToNetworkEdge = (cable: InventoryCableDTO): NetworkEdge => {\n const getDeviceId = (term: InventoryCableDTO['termination_a']) => {\n if (!term) return undefined;\n if (typeof term === 'string') return term;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const dev = (term as any).device;\n if (typeof dev === 'object' && dev) return (dev as { id?: string | number }).id;\n return dev as string | number | undefined;\n };\n const termADeviceId = getDeviceId(cable.termination_a);\n const termBDeviceId = getDeviceId(cable.termination_b);\n return {\n id: `cable-${cable.id}`,\n source: `device-${termADeviceId}`,\n target: `device-${termBDeviceId}`,\n type: 'fiber',\n data: {\n bandwidth: cable.type?.label ?? cable.bandwidth,\n length: cable.length || 0,\n color: cable.color,\n inventoryId: cable.id,\n inventoryType: 'cable',\n status: ((typeof cable.status === 'object' && cable.status) ? (cable.status as { value?: string }).value : cable.status),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n terminationA: (typeof cable.termination_a === 'object' && cable.termination_a) ? (cable.termination_a as { name?: string }).name : (cable.termination_a as any),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n terminationB: (typeof cable.termination_b === 'object' && cable.termination_b) ? (cable.termination_b as { name?: string }).name : (cable.termination_b as any),\n },\n };\n};\n\n/**\n * Convert inventory data to network diagram format\n */\nexport const inventoryToNetworkDiagram = (data: {\n racks: InventoryRackDTO[];\n devices: InventoryDeviceDTO[];\n cables: InventoryCableDTO[];\n}): { nodes: NetworkNode[]; edges: NetworkEdge[] } => {\n const nodes: NetworkNode[] = [];\n const edges: NetworkEdge[] = [];\n\n data.racks.forEach(rack => nodes.push(inventoryRackToNetworkNode(rack)));\n data.devices.forEach(device => nodes.push(inventoryDeviceToNetworkNode(device)));\n data.cables.forEach(cable => edges.push(inventoryCableToNetworkEdge(cable)));\n\n return { nodes, edges };\n};\n\n/**\n * Generate simple layout positions for nodes array\n */\nexport const generateLayout = (nodes: NetworkNode[]): NetworkNode[] => {\n const rackNodes = nodes.filter(n => n.type === 'rack');\n const deviceNodes = nodes.filter(n => n.type === 'device');\n const otherNodes = nodes.filter(n => !['rack', 'device'].includes(n.type));\n\n rackNodes.forEach((rack, index) => {\n rack.position = { x: index * 300, y: 100 };\n });\n\n deviceNodes.forEach(device => {\n if (device.parentId) {\n const parentRack = rackNodes.find(r => r.id === device.parentId);\n if (parentRack) {\n const uPosition = device.data.uPosition || 1;\n const uHeight = device.data.uHeight || 1;\n device.position = {\n x: parentRack.position.x + 50,\n y: parentRack.position.y + (uPosition * 20) - (uHeight * 10),\n };\n }\n } else {\n device.position = { x: Math.random() * 400 + 100, y: Math.random() * 200 + 50 };\n }\n });\n\n otherNodes.forEach((node, index) => {\n node.position = { x: index * 150 + 100, y: 300 };\n });\n\n return nodes;\n};\n\n\n","import { NetworkNode, RackConfig, RackDevice, Width } from '../types';\nimport { calculateDevicePositionFromU, findNextAvailableUPosition } from './u-positioning';\n\n/**\n * Configuration options for building nodes from rack schema\n */\nexport interface RackSchemaOptions {\n /** How to handle device placement conflicts */\n conflictPolicy?: 'strict' | 'nearest';\n /** Whether to validate all placements before creating nodes */\n validatePlacements?: boolean;\n /** Custom device type mapping from schema to NetworkNode type */\n deviceTypeMapping?: Record<string, NetworkNode['type']>;\n}\n\n/**\n * Error thrown when device placement conflicts occur in strict mode\n */\nexport class DevicePlacementError extends Error {\n constructor(\n public rackId: string,\n public deviceId: string,\n public uPosition: number,\n public uHeight: number,\n public conflictWith?: string\n ) {\n super(\n `Device placement conflict: ${deviceId} at U${uPosition}-${uPosition + uHeight - 1} in rack ${rackId}${\n conflictWith ? ` conflicts with ${conflictWith}` : ''\n }`\n );\n this.name = 'DevicePlacementError';\n }\n}\n\n/**\n * Validation result for device placement\n */\nexport interface DevicePlacementValidation {\n isValid: boolean;\n conflicts: Array<{\n deviceId: string;\n uPosition: number;\n uHeight: number;\n conflictWith: string;\n }>;\n outOfBounds: Array<{\n deviceId: string;\n uPosition: number;\n uHeight: number;\n rackUHeight: number;\n }>;\n}\n\n/**\n * Validate device placements within a rack schema\n */\nexport function validateRackDevicePlacements(\n rack: RackConfig,\n _options: RackSchemaOptions = {}\n): DevicePlacementValidation {\n const conflicts: DevicePlacementValidation['conflicts'] = [];\n const outOfBounds: DevicePlacementValidation['outOfBounds'] = [];\n \n // Check for out-of-bounds placements\n for (const device of rack.devices) {\n const deviceEnd = device.unit + device.height - 1;\n if (deviceEnd > rack.units) {\n outOfBounds.push({\n deviceId: device.id,\n uPosition: device.unit,\n uHeight: device.height,\n rackUHeight: rack.units,\n });\n }\n }\n \n // Check for device-to-device conflicts\n for (let i = 0; i < rack.devices.length; i++) {\n const deviceA = rack.devices[i];\n const deviceAStart = deviceA.unit;\n const deviceAEnd = deviceA.unit + deviceA.height - 1;\n \n for (let j = i + 1; j < rack.devices.length; j++) {\n const deviceB = rack.devices[j];\n const deviceBStart = deviceB.unit;\n const deviceBEnd = deviceB.unit + deviceB.height - 1;\n \n // Check for overlap using 1a rule (start to start+height-1)\n if (deviceAStart <= deviceBEnd && deviceAEnd >= deviceBStart) {\n conflicts.push({\n deviceId: deviceA.id,\n uPosition: deviceA.unit,\n uHeight: deviceA.height,\n conflictWith: deviceB.id,\n });\n }\n }\n }\n \n return {\n isValid: conflicts.length === 0 && outOfBounds.length === 0,\n conflicts,\n outOfBounds,\n };\n}\n\n/**\n * Convert a RackDevice to NetworkNode with proper U positioning\n */\nfunction createDeviceNode(\n device: RackDevice,\n rack: NetworkNode,\n options: RackSchemaOptions = {}\n): NetworkNode {\n const { deviceTypeMapping = {} } = options;\n \n // Map device type to NetworkNode type\n const nodeType = deviceTypeMapping[device.type] || 'device';\n \n // Calculate pixel position from U position\n const position = calculateDevicePositionFromU(rack, device.unit, device.height);\n \n \n return {\n id: device.id,\n type: nodeType,\n position,\n parentId: rack.id,\n extent: 'parent',\n data: {\n label: device.name,\n status: 'active', // Default status\n deviceType: device.type,\n uHeight: device.height,\n uPosition: device.unit,\n width: device.width || Width.FULL,\n // view is controlled at node-level; default computed in DeviceNode when absent\n role: device.role, // Pass through the role property\n ports: device.ports,\n rearPorts: device.rearPorts,\n connections: device.connections,\n },\n };\n}\n\n/**\n * Convert a RackConfig to NetworkNode\n */\nfunction createRackNode(rack: RackConfig): NetworkNode {\n return {\n id: rack.id,\n type: 'rack',\n position: rack.position,\n data: {\n label: rack.name,\n status: 'active',\n uHeight: rack.units,\n uNumberingDirection: rack.uNumberingDirection || 'bottom-up',\n customHeaderText: rack.customHeaderText,\n ports: [], // Default empty array, can be overridden\n },\n };\n}\n\n/**\n * Build NetworkNode array from RackConfig array with comprehensive validation\n */\nexport function buildNodesFromRackConfig(\n racks: RackConfig[],\n options: RackSchemaOptions = {}\n): NetworkNode[] {\n const { conflictPolicy = 'strict', validatePlacements = true } = options;\n const nodes: NetworkNode[] = [];\n const deviceNodes: NetworkNode[] = [];\n \n // Validate all racks first if requested\n if (validatePlacements) {\n for (const rack of racks) {\n const validation = validateRackDevicePlacements(rack, options);\n \n if (!validation.isValid) {\n if (conflictPolicy === 'strict') {\n // Report all conflicts and out-of-bounds\n const errors: string[] = [];\n \n validation.conflicts.forEach(conflict => {\n errors.push(\n `Device ${conflict.deviceId} at U${conflict.uPosition}-${conflict.uPosition + conflict.uHeight - 1} conflicts with ${conflict.conflictWith}`\n );\n });\n \n validation.outOfBounds.forEach(bound => {\n errors.push(\n `Device ${bound.deviceId} at U${bound.uPosition}-${bound.uPosition + bound.uHeight - 1} exceeds rack height (${bound.rackUHeight}U)`\n );\n });\n \n throw new DevicePlacementError(\n rack.id,\n validation.conflicts[0]?.deviceId || validation.outOfBounds[0]?.deviceId || 'unknown',\n validation.conflicts[0]?.uPosition || validation.outOfBounds[0]?.uPosition || 1,\n validation.conflicts[0]?.uHeight || validation.outOfBounds[0]?.uHeight || 1\n );\n }\n }\n }\n }\n \n // Create rack nodes first (required for device parent references)\n for (const rack of racks) {\n const rackNode = createRackNode(rack);\n nodes.push(rackNode);\n \n // Create device nodes for this rack\n for (const device of rack.devices) {\n try {\n const deviceNode = createDeviceNode(device, rackNode, options);\n deviceNodes.push(deviceNode);\n } catch (error) {\n if (conflictPolicy === 'strict') {\n throw error;\n } else if (conflictPolicy === 'nearest') {\n // Try to find nearest available position\n const availablePosition = findNextAvailableUPosition(\n rackNode,\n { id: device.id, type: 'device', position: { x: 0, y: 0 }, data: { label: device.name, uHeight: device.height } } as NetworkNode,\n deviceNodes,\n device.unit\n );\n \n if (availablePosition !== device.unit) {\n console.warn(\n `Device ${device.id} moved from U${device.unit} to U${availablePosition} due to conflict`\n );\n \n const adjustedDevice = { ...device, unit: availablePosition };\n const deviceNode = createDeviceNode(adjustedDevice, rackNode, options);\n deviceNodes.push(deviceNode);\n } else {\n throw new DevicePlacementError(rack.id, device.id, device.unit, device.height);\n }\n }\n }\n }\n }\n \n // Add device nodes after all rack nodes\n nodes.push(...deviceNodes);\n \n return nodes;\n}\n\n/**\n * Create a RackConfig from existing NetworkNode data (reverse operation)\n */\nexport function createRackConfigFromNodes(nodes: NetworkNode[]): RackConfig[] {\n const racks: RackConfig[] = [];\n const rackNodes = nodes.filter(node => node.type === 'rack');\n \n for (const rackNode of rackNodes) {\n const deviceNodes = nodes.filter(\n node => node.type === 'device' && node.parentId === rackNode.id\n );\n \n const devices: RackDevice[] = deviceNodes.map(deviceNode => ({\n id: deviceNode.id,\n name: deviceNode.data.label,\n unit: deviceNode.data.uPosition || 1,\n height: deviceNode.data.uHeight || 1,\n type: (deviceNode.data.deviceType as RackDevice['type']) || 'server',\n width: deviceNode.data.width,\n ports: deviceNode.data.ports,\n connections: deviceNode.data.connections,\n }));\n \n racks.push({\n id: rackNode.id,\n name: rackNode.data.label,\n position: rackNode.position,\n units: rackNode.data.uHeight || 42,\n uNumberingDirection: rackNode.data.uNumberingDirection || 'bottom-up',\n customHeaderText: rackNode.data.customHeaderText,\n devices,\n });\n }\n \n return racks;\n}\n\n/**\n * Update device U position in a rack schema\n */\nexport function updateDeviceUPosition(\n racks: RackConfig[],\n rackId: string,\n deviceId: string,\n newUPosition: number\n): RackConfig[] {\n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n return {\n ...rack,\n devices: rack.devices.map(device => {\n if (device.id !== deviceId) return device;\n return { ...device, unit: newUPosition };\n }),\n };\n });\n}\n\n/**\n * Add a device to a rack schema\n */\nexport function addDeviceToRack(\n racks: RackConfig[],\n rackId: string,\n device: RackDevice,\n options: RackSchemaOptions = {}\n): RackConfig[] {\n const { conflictPolicy = 'strict' } = options;\n \n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n // Check for conflicts if in strict mode\n if (conflictPolicy === 'strict') {\n const validation = validateRackDevicePlacements(\n { ...rack, devices: [...rack.devices, device] },\n options\n );\n \n if (!validation.isValid) {\n throw new DevicePlacementError(rackId, device.id, device.unit, device.height);\n }\n }\n \n return {\n ...rack,\n devices: [...rack.devices, device],\n };\n });\n}\n\n/**\n * Remove a device from a rack schema\n */\nexport function removeDeviceFromRack(\n racks: RackConfig[],\n rackId: string,\n deviceId: string\n): RackConfig[] {\n return racks.map(rack => {\n if (rack.id !== rackId) return rack;\n \n return {\n ...rack,\n devices: rack.devices.filter(device => device.id !== deviceId),\n };\n });\n}\n"]}