@mp70/react-networks 0.11.1-alpha → 0.11.2-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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/u-positioning.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/components/NetworkDiagram.tsx","../src/utils/netbox.ts","../src/utils/rack-schema.ts"],"names":["getDefaultUNumberingDirection","getRackUNumberingDirection","rack","convertUPositionForDirection","uPosition","rackUHeight","direction","convertUPositionFromDirection","snapToUPosition","device","newPosition","allNodes","startY","relativeY","physicalUPosition","calculatedUPosition","snappedUPosition","isUPositionAvailable","availablePosition","findNextAvailableUPosition","snappedPhysicalUPosition","snappedY","deviceUHeight","rackDevices","node","otherDevice","otherUPosition","otherUHeight","newDeviceStart","newDeviceEnd","otherDeviceStart","otherDeviceEnd","startFrom","u","calculateDevicePositionFromU","updateDeviceUPosition","newUPosition","validateAndSnapDevice","currentUPosition","validUPosition","RackNode","data","selected","id","onViewChange","onRackFaceChange","label","ports","status","uHeight","face","customHeaderText","getNodes","setNodes","useReactFlow","nodes","showUMarkers","setShowUMarkers","useState","toggleUNumberingDirection","newDirection","n","toggleFace","next","child","getStatusColor","renderUPositions","positions","i","yPos","displayNumber","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","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.mjs","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 const relativeY = newPosition.y - startY; // child position is already parent-relative\n const physicalUPosition = Math.round(relativeY / U_HEIGHT_PX) + 1;\n const calculatedUPosition = convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\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 // Convert logical U position back to physical position for Y calculation\n const snappedPhysicalUPosition = convertUPositionFromDirection(snappedUPosition, rackUHeight, direction);\n const snappedY = startY + (snappedPhysicalUPosition - 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 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 // 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 + (physicalUPosition - 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 React, { useState } from 'react';\nimport { Handle, Position, NodeProps, useReactFlow } from 'reactflow';\nimport { NetworkNode, UNumberingDirection } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from '../utils/constants';\nimport { getRackUNumberingDirection, convertUPositionForDirection } from '../utils/u-positioning';\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 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 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 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' : ''}`}\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 {customHeaderText && (\n <div style={{ fontSize: '9px', color: '#fbbf24', fontWeight: 'bold', marginTop: '2px' }}>\n {customHeaderText}\n </div>\n )}\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';\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 * 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 [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 /** 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// 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 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 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"]}
1
+ {"version":3,"sources":["../src/utils/u-positioning.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/components/NetworkDiagram.tsx","../src/utils/netbox.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","updateDeviceUPosition","newUPosition","validateAndSnapDevice","currentUPosition","validUPosition","RackNode","data","selected","id","onViewChange","onRackFaceChange","label","ports","status","face","customHeaderText","getNodes","setNodes","useReactFlow","nodes","showUMarkers","setShowUMarkers","useState","toggleUNumberingDirection","newDirection","n","toggleFace","next","child","getStatusColor","renderUPositions","positions","i","yPos","displayNumber","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","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.mjs","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 ALWAYS represents the TOP of the device\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 bottom-up direction, we need to account for device height since Y represents the TOP\n let calculatedUPosition;\n if (direction === 'bottom-up') {\n // For bottom-up, Y represents the top of the device\n // So we need to adjust the logical U position to account for device height\n const logicalTopUPosition = convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\n calculatedUPosition = logicalTopUPosition - uHeight + 1;\n } else {\n // For top-down, Y represents the top of the device, so no adjustment needed\n calculatedUPosition = convertUPositionForDirection(physicalUPosition, rackUHeight, direction);\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 // 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 // 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): { 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 // 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 + (physicalUPosition - 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 React, { useState } from 'react';\nimport { Handle, Position, NodeProps, useReactFlow } from 'reactflow';\nimport { NetworkNode, UNumberingDirection } from '../types';\nimport { U_HEIGHT_PX, RACK_HEADER_HEIGHT } from '../utils/constants';\nimport { getRackUNumberingDirection, convertUPositionForDirection } from '../utils/u-positioning';\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 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 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 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' : ''}`}\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 {customHeaderText ? (\n <div style={{ fontSize: '9px', color: '#fbbf24', fontWeight: 'bold' }}>\n {customHeaderText}\n </div>\n ) : (\n <div style={{ fontSize: '10px', color: '#9ca3af' }}>\n {typeof ports === 'number' ? ports : 0} ports • {uHeight}U • {face}\n </div>\n )}\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';\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 * 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 [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 /** 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// 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 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 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"]}