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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,151 +1,6 @@
1
1
  import React$1 from 'react';
2
2
  import { NodeProps, EdgeProps } from 'reactflow';
3
3
 
4
- interface NetBoxDevice {
5
- id: number;
6
- name: string;
7
- device_type: {
8
- id: number;
9
- model: string;
10
- manufacturer: {
11
- name: string;
12
- };
13
- };
14
- device_role: {
15
- name: string;
16
- color: string;
17
- };
18
- site: {
19
- name: string;
20
- };
21
- rack: {
22
- id: number;
23
- name: string;
24
- } | null;
25
- position: number | null;
26
- face: 'front' | 'rear' | null;
27
- status: {
28
- label: string;
29
- value: string;
30
- color: string;
31
- };
32
- primary_ip4?: {
33
- address: string;
34
- };
35
- primary_ip6?: {
36
- address: string;
37
- };
38
- interfaces: NetBoxInterface[];
39
- }
40
- interface NetBoxInterface {
41
- id: number;
42
- name: string;
43
- type: {
44
- label: string;
45
- value: string;
46
- };
47
- enabled: boolean;
48
- mac_address: string | null;
49
- mtu: number | null;
50
- connected_endpoint_type: string | null;
51
- connected_endpoint: {
52
- device: {
53
- name: string;
54
- };
55
- name: string;
56
- } | null;
57
- cable: {
58
- id: number;
59
- label: string;
60
- type: string;
61
- color: string;
62
- } | null;
63
- }
64
- interface NetBoxRack {
65
- id: number;
66
- name: string;
67
- site: {
68
- name: string;
69
- };
70
- group: {
71
- name: string;
72
- } | null;
73
- tenant: {
74
- name: string;
75
- } | null;
76
- role: {
77
- name: string;
78
- color: string;
79
- } | null;
80
- status: {
81
- label: string;
82
- value: string;
83
- color: string;
84
- };
85
- facility_id: string | null;
86
- serial: string | null;
87
- asset_tag: string | null;
88
- type: {
89
- label: string;
90
- value: string;
91
- };
92
- width: {
93
- label: string;
94
- value: number;
95
- };
96
- u_height: number;
97
- desc_units: boolean;
98
- outer_width: number | null;
99
- outer_depth: number | null;
100
- weight: number | null;
101
- max_weight: number | null;
102
- weight_unit: string;
103
- mounting_depth: number | null;
104
- devices: NetBoxDevice[];
105
- }
106
- interface NetBoxCable {
107
- id: number;
108
- label: string;
109
- type: {
110
- label: string;
111
- value: string;
112
- };
113
- status: {
114
- label: string;
115
- value: string;
116
- color: string;
117
- };
118
- color: string;
119
- length: number | null;
120
- length_unit: string;
121
- termination_a_type: string;
122
- termination_a: {
123
- device: {
124
- name: string;
125
- };
126
- name: string;
127
- };
128
- termination_b_type: string;
129
- termination_b: {
130
- device: {
131
- name: string;
132
- };
133
- name: string;
134
- };
135
- }
136
- interface NetBoxConnection {
137
- id: string;
138
- source: {
139
- device: string;
140
- interface: string;
141
- };
142
- target: {
143
- device: string;
144
- interface: string;
145
- };
146
- cable: NetBoxCable;
147
- }
148
-
149
4
  /**
150
5
  * Rack device width configuration
151
6
  * @public
@@ -200,6 +55,11 @@ type DeviceView = 'front' | 'rear';
200
55
  * @public
201
56
  */
202
57
  type PowerSide = 'left' | 'right';
58
+ /**
59
+ * U numbering direction for racks
60
+ * @public
61
+ */
62
+ type UNumberingDirection = 'bottom-up' | 'top-down';
203
63
  /**
204
64
  * Network node data structure
205
65
  * @public
@@ -254,6 +114,10 @@ interface NetworkNode {
254
114
  heightCm?: number;
255
115
  /** Number of AC power ports */
256
116
  powerPorts?: number;
117
+ /** U numbering direction for rack nodes */
118
+ uNumberingDirection?: UNumberingDirection;
119
+ /** Custom header text for rack nodes */
120
+ customHeaderText?: string;
257
121
  /** Additional custom properties */
258
122
  [key: string]: any;
259
123
  };
@@ -315,6 +179,10 @@ interface RackConfig {
315
179
  };
316
180
  /** Rack height in U units */
317
181
  units: number;
182
+ /** U numbering direction (default: 'bottom-up') */
183
+ uNumberingDirection?: UNumberingDirection;
184
+ /** Custom header text for rack */
185
+ customHeaderText?: string;
318
186
  /** Devices mounted in the rack */
319
187
  devices: RackDevice[];
320
188
  }
@@ -374,7 +242,6 @@ interface FiberCable {
374
242
  to: string;
375
243
  };
376
244
  }
377
-
378
245
  /**
379
246
  * Network diagram component props
380
247
  * @public
@@ -396,8 +263,8 @@ interface NetworkDiagramProps {
396
263
  store?: any;
397
264
  /** Enable debug mode */
398
265
  debug?: boolean;
399
- /** Callback when a node is clicked */
400
- onNodeClick?: (node: NetworkNode) => void;
266
+ /** Callback when a node is clicked or selection changes (null when deselected) */
267
+ onNodeClick?: (node: NetworkNode | null) => void;
401
268
  /** Callback when an edge is clicked */
402
269
  onEdgeClick?: (edge: NetworkEdge) => void;
403
270
  /** Callback when device view changes */
@@ -410,23 +277,24 @@ interface NetworkDiagramProps {
410
277
  style?: React.CSSProperties;
411
278
  /** If true, vertically align rack bottoms to the same baseline */
412
279
  alignRacksToBottom?: boolean;
413
- }
414
- /**
415
- * NetBox integration props
416
- * @public
417
- */
418
- interface NetBoxNetworkDiagramProps extends NetworkDiagramProps {
419
- /** NetBox data for integration */
420
- netboxData?: {
421
- /** NetBox racks */
422
- racks: NetBoxRack[];
423
- /** NetBox devices */
424
- devices: NetBoxDevice[];
425
- /** NetBox cables */
426
- cables: NetBoxCable[];
427
- };
428
- /** Callback when NetBox data is updated */
429
- onNetBoxUpdate?: (data: any) => void;
280
+ /** Color mode for the diagram */
281
+ colorMode?: 'light' | 'dark' | 'system';
282
+ /** Callback when React Flow instance is initialized */
283
+ onInit?: (instance: any) => void;
284
+ /** Callback to get React Flow methods for save/restore */
285
+ onFlowMethods?: (methods: {
286
+ toObject: () => any;
287
+ setViewport: (viewport: any) => void;
288
+ toImage: (options?: any) => Promise<string>;
289
+ }) => void;
290
+ /** Show download button */
291
+ showDownloadButton?: boolean;
292
+ /** Download button position */
293
+ downloadButtonPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
294
+ /** Custom download button text */
295
+ downloadButtonText?: string;
296
+ /** Download button styling options */
297
+ downloadButtonStyle?: React.CSSProperties;
430
298
  }
431
299
 
432
300
  declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
@@ -434,6 +302,7 @@ declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
434
302
  interface RackNodeProps extends NodeProps<NetworkNode['data']> {
435
303
  onViewChange?: (nodeId: string, view: 'front' | 'rear') => void;
436
304
  onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void;
305
+ isDragOver?: boolean;
437
306
  }
438
307
  declare const RackNode: React$1.FC<RackNodeProps>;
439
308
 
@@ -447,35 +316,111 @@ declare const DeviceNode: React$1.FC<NodeProps<NetworkNode['data']>>;
447
316
 
448
317
  declare const VerticalPDU: React$1.FC<NodeProps<NetworkNode['data']>>;
449
318
 
319
+ interface InventoryRackDTO {
320
+ id: string | number;
321
+ name: string;
322
+ status?: {
323
+ value?: string;
324
+ } | string;
325
+ u_height?: number;
326
+ units?: number;
327
+ facility_id?: string | number;
328
+ serial?: string;
329
+ asset_tag?: string;
330
+ site?: {
331
+ name?: string;
332
+ } | string;
333
+ role?: {
334
+ name?: string;
335
+ } | string;
336
+ tenant?: {
337
+ name?: string;
338
+ } | string;
339
+ }
340
+ interface InventoryDeviceDTO {
341
+ id: string | number;
342
+ name: string;
343
+ status?: {
344
+ value?: string;
345
+ } | string;
346
+ device_type?: {
347
+ u_height?: number;
348
+ model?: string;
349
+ manufacturer?: {
350
+ name?: string;
351
+ };
352
+ };
353
+ model?: string;
354
+ manufacturer?: string;
355
+ device_role?: {
356
+ name?: string;
357
+ } | string;
358
+ u_height?: number;
359
+ position?: number;
360
+ face?: 'front' | 'rear';
361
+ rack?: {
362
+ id?: string | number;
363
+ name?: string;
364
+ } | string | number;
365
+ primary_ip4?: {
366
+ address?: string;
367
+ } | string;
368
+ primary_ip6?: {
369
+ address?: string;
370
+ } | string;
371
+ site?: {
372
+ name?: string;
373
+ } | string;
374
+ }
375
+ interface InventoryCableDTO {
376
+ id: string | number;
377
+ type?: {
378
+ label?: string;
379
+ };
380
+ bandwidth?: string;
381
+ length?: number;
382
+ color?: string;
383
+ status?: {
384
+ value?: string;
385
+ } | string;
386
+ termination_a?: {
387
+ device?: {
388
+ id?: string | number;
389
+ } | string | number;
390
+ name?: string;
391
+ } | string;
392
+ termination_b?: {
393
+ device?: {
394
+ id?: string | number;
395
+ } | string | number;
396
+ name?: string;
397
+ } | string;
398
+ }
450
399
  /**
451
- * Convert NetBox rack data to NetworkNode
400
+ * Convert inventory rack data to NetworkNode
452
401
  */
453
- declare const netboxRackToNetworkNode: (rack: NetBoxRack) => NetworkNode;
402
+ declare const inventoryRackToNetworkNode: (rack: InventoryRackDTO) => NetworkNode;
454
403
  /**
455
- * Convert NetBox device data to NetworkNode
404
+ * Convert inventory device data to NetworkNode
456
405
  */
457
- declare const netboxDeviceToNetworkNode: (device: NetBoxDevice) => NetworkNode;
406
+ declare const inventoryDeviceToNetworkNode: (device: InventoryDeviceDTO) => NetworkNode;
458
407
  /**
459
- * Convert NetBox cable data to NetworkEdge
408
+ * Convert inventory cable data to NetworkEdge
460
409
  */
461
- declare const netboxCableToNetworkEdge: (cable: NetBoxCable) => NetworkEdge;
410
+ declare const inventoryCableToNetworkEdge: (cable: InventoryCableDTO) => NetworkEdge;
462
411
  /**
463
- * Convert NetBox data to network diagram format
412
+ * Convert inventory data to network diagram format
464
413
  */
465
- declare const netboxToNetworkDiagram: (data: {
466
- racks: NetBoxRack[];
467
- devices: NetBoxDevice[];
468
- cables: NetBoxCable[];
414
+ declare const inventoryToNetworkDiagram: (data: {
415
+ racks: InventoryRackDTO[];
416
+ devices: InventoryDeviceDTO[];
417
+ cables: InventoryCableDTO[];
469
418
  }) => {
470
419
  nodes: NetworkNode[];
471
420
  edges: NetworkEdge[];
472
421
  };
473
422
  /**
474
- * Calculate U position for devices in a rack
475
- */
476
- declare const calculateUPositions: (devices: NetBoxDevice[], rackHeight: number) => Map<number, number>;
477
- /**
478
- * Generate layout positions for nodes
423
+ * Generate simple layout positions for nodes array
479
424
  */
480
425
  declare const generateLayout: (nodes: NetworkNode[]) => NetworkNode[];
481
426
 
@@ -501,7 +446,7 @@ declare const findNextAvailableUPosition: (rack: NetworkNode, device: NetworkNod
501
446
  /**
502
447
  * Calculate device position based on U position within a rack
503
448
  */
504
- declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number) => {
449
+ declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number, deviceHeight?: number) => {
505
450
  x: number;
506
451
  y: number;
507
452
  };
@@ -646,6 +591,8 @@ interface NetworkDiagramStore {
646
591
  subscribe: (listener: (state: NetworkDiagramState) => void) => () => void;
647
592
  selectEdgeZIndex: (edge: NetworkEdge) => number;
648
593
  validateConnection: (params: ValidateConnectionParams) => ValidationResult;
594
+ selectNodeById: (id: string) => NetworkNode | undefined;
595
+ selectConnectedEdges: (nodeId: string) => NetworkEdge[];
649
596
  }
650
597
  declare function createNetworkDiagramStore(initial?: Partial<NetworkDiagramState>, options?: NetworkDiagramOptions): NetworkDiagramStore;
651
598
 
@@ -653,4 +600,4 @@ declare function useNetworkDiagram(store: NetworkDiagramStore): NetworkDiagramSt
653
600
  declare function useNodes(store: NetworkDiagramStore): NetworkNode[];
654
601
  declare function useEdges(store: NetworkDiagramStore): NetworkEdge[];
655
602
 
656
- export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, type NetBoxCable, type NetBoxConnection, type NetBoxDevice, type NetBoxInterface, type NetBoxNetworkDiagramProps, type NetBoxRack, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, calculateUPositions, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, isHighPowerConnector, isUPositionAvailable, netboxCableToNetworkEdge, netboxDeviceToNetworkNode, netboxRackToNetworkNode, netboxToNetworkDiagram, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
603
+ export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isUPositionAvailable, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var wt=require('react'),reactflow=require('reactflow'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var wt__default=/*#__PURE__*/_interopDefault(wt);var ve=({data:e,selected:o,id:t,onViewChange:r,onRackFaceChange:n})=>{let{label:i,ports:a=0,status:d="active",uHeight:u=42,uPosition:p=1,face:g="front"}=e,{getNodes:w,setNodes:M}=reactflow.useReactFlow(),E=w(),[T,C]=wt.useState(true),b=()=>{let h=g==="front"?"rear":"front";n?(n(t,h),r&&E.filter(R=>R.parentId===t).forEach(R=>{r(R.id,h);})):r?E.filter(R=>R.parentId===t).forEach(R=>{r(R.id,h);}):M(A=>A.map(R=>R.id===t?{...R,data:{...R.data,face:h}}:R.parentId===t?{...R,data:{...R.data,view:h}}:R));},Y=h=>{switch(h){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},Z=()=>{let h=[],A=60;for(let R=1;R<=u;R++){let K=A+(R-1)*20-4;h.push(jsxRuntime.jsx("div",{style:{position:"absolute",left:"-35px",top:`${K}px`,background:"#374151",color:"#9ca3af",padding:"2px 4px",borderRadius:"2px",fontSize:"8px",fontWeight:"bold",width:"28px",textAlign:"center",border:"1px solid #4b5563",zIndex:10,height:`${20}px`,display:"flex",alignItems:"center",justifyContent:"center",lineHeight:1},children:R},R));}return h};return jsxRuntime.jsxs("div",{className:`rack-node ${o?"selected":""}`,style:{background:"transparent",border:`2px solid ${Y(d)}`,borderRadius:"8px",padding:0,width:"300px",height:`${60+u*20}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:o?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsxs("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"#1f2937",padding:"8px",position:"relative",height:`${60}px`,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:i}),jsxRuntime.jsxs("div",{style:{fontSize:"10px",color:"#9ca3af"},children:[typeof a=="number"?a:0," ports \u2022 ",u,"U \u2022 ",g]}),jsxRuntime.jsxs("div",{style:{display:"flex",gap:"4px",position:"absolute",top:"4px",right:"4px"},children:[jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),C(!T);},style:{background:T?"#10b981":"#374151",color:T?"#ffffff":"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`${T?"Hide":"Show"} U markers`,children:"U"}),jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),b();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch to ${g==="front"?"rear":"front"} view`,children:g==="front"?"\u21C4 Rear":"\u21C4 Front"})]})]}),jsxRuntime.jsx("div",{style:{flex:1,background:"transparent",position:"relative",minHeight:`${u*20}px`,overflow:"hidden"}}),T&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,pointerEvents:"none"},children:Z()})]})};var Pe=({data:e,selected:o})=>{let{label:t,status:r="active"}=e,n=i=>{switch(i){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}};return jsxRuntime.jsxs("div",{className:`fiber-node ${o?"selected":""}`,style:{background:"#1f2937",border:`2px solid ${n(r)}`,borderRadius:"50%",width:"60px",height:"60px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontFamily:"monospace",fontSize:"10px",fontWeight:"bold",boxShadow:o?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Bottom}),jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Left}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right}),jsxRuntime.jsx("div",{style:{textAlign:"center"},children:jsxRuntime.jsx("div",{style:{fontSize:"8px",lineHeight:"1.2"},children:t})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"4px",left:"50%",transform:"translateX(-50%)",width:"8px",height:"8px",background:n(r),borderRadius:"50%"}})]})};var Se=({id:e,sourceX:o,sourceY:t,targetX:r,targetY:n,sourcePosition:i,targetPosition:a,data:d,selected:u,style:p})=>{let[g,w,M]=reactflow.getBezierPath({sourceX:o,sourceY:t,sourcePosition:i,targetX:r,targetY:n,targetPosition:a}),{bandwidth:E,length:T,color:C="#10b981"}=d||{},b={stroke:C,strokeWidth:u?3:2,strokeDasharray:d?.type==="fiber"?"5,5":"none",fill:"none",...p};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("path",{id:e,className:"react-flow__edge-path",d:g,stroke:C,strokeWidth:u?3:2,strokeDasharray:d?.type==="fiber"?"5,5":"none",fill:"none",style:b}),jsxRuntime.jsx(reactflow.EdgeLabelRenderer,{children:d&&(E||T)&&jsxRuntime.jsxs("div",{style:{position:"absolute",transform:`translate(-50%, -50%) translate(${w}px,${M}px)`,background:"#1f2937",padding:"4px 8px",borderRadius:"4px",fontSize:"10px",color:"white",fontFamily:"monospace",border:`1px solid ${C}`,pointerEvents:"none"},children:[E&&jsxRuntime.jsx("div",{children:E}),T&&jsxRuntime.jsxs("div",{children:[T,"m"]})]})})]})};var De=({id:e,sourceX:o,sourceY:t,targetX:r,targetY:n,sourcePosition:i,targetPosition:a,style:d={},data:u,markerEnd:p})=>{let [g,w,M]=reactflow.getBezierPath({sourceX:o,sourceY:t,sourcePosition:i,targetX:r,targetY:n,targetPosition:a}),E=u?.connectorType||"C13";u?.voltage||"AC";u?.amperage||(E==="C19"?"16A":"10A");return jsxRuntime.jsx(reactflow.BaseEdge,{id:e,path:g,markerEnd:p,style:(()=>{let Y={stroke:u?.color||"#f59e0b",strokeWidth:E==="C19"?5:3,strokeLinecap:"round",strokeLinejoin:"round",...d};return E==="C19"?{...Y,strokeDasharray:"none"}:{...Y,strokeDasharray:"6,3"}})()})};var Ve=(t=>(t.FULL="full",t.HALF="half",t))(Ve||{});var He={C13:{type:"C13",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C14:{type:"C14",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C19:{type:"C19",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1},C20:{type:"C20",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1}};function ce(e){let o=He[e];if(!o)throw new Error(`Unknown connector type: ${e}`);let t=o.amperage===16;o.amperage===10;let n=t?12:8,i=t?10:5,a=t?{borderRadius:"3px"}:{clipPath:"polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)",borderRadius:"0px"};return {width:n,height:i,color:o.color,borderColor:o.borderColor,fontSize:t?"3px":"4px",...a}}function me(e){let o=He[e];if(!o)throw new Error(`Unknown connector type: ${e}`);return o}function ft(e){return me(e).amperage===16}function Ee(e){return e%10<8?"C13":"C19"}function xe(e){let o=e.toLowerCase();return o.includes("mx304")||o.includes("mx480")||o.includes("mx960")?"C20":"C14"}var Te=({data:e,selected:o})=>{let{label:t,status:r="active",deviceType:n="server",manufacturer:i,role:a,uHeight:d=1,uPosition:u=1,width:p="full",ports:g=[],rearPorts:w=[],view:M,powerSide:E="left"}=e,T=M||(w.length>0&&g.length===0?"rear":"front"),C={};C["net-top"]="front",C["net-bottom"]="front",g.length>0&&g.forEach(v=>{v.ports.forEach(I=>{let F=I.type?.includes("power")?I.label:`${v.name}-${I.label}`;C[F]="front";});}),C["pwr-left-1"]="rear",C["pwr-left-2"]="rear",C["net-right-1"]="rear",C["net-right-2"]="rear",w.length>0&&w.forEach(v=>{v.ports.forEach(I=>{let F=I.type?.includes("power")?I.label:`${v.name}-${I.label}`;C[F]="rear";});});let b=d*20,Y=p==="half"?"150px":"304px",Z=p==="half"?"150px":void 0,h=v=>{switch(v){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},R=(v,I)=>{let F=[];if(v.length===0)return F;let z=Math.max(4,Math.floor(b*.4)),W=Math.max(2,Math.floor(b*.2));return v.forEach((f,P)=>{f.ports.forEach((k,D)=>{let L=!!k.type&&k.type.includes("power");if(I==="front"&&L)return;let B=L?`${k.label}`:`${f.name}-${k.label}`,q=k.connected,U="#6b7280";if(q)if(k.type?.includes("power"))U=k.type==="power_c19"?"#fbbf24":"#f59e0b";else if(k.type==="console"||k.type==="mgmt")U="#8b5cf6";else if(k.type==="usb")U="#10b981";else switch(k.cableType){case "smf":U="#fbbf24";break;case "cat6":U="#8b5cf6";break;case "om3":U="#06b6d4";break;case "om4":U="#8b5cf6";break;case "om5":U="#84cc16";break;case "cat5e":U="#3b82f6";break;case "cat6a":U="#ef4444";break;case "cat7":U="#f97316";break;case "fiber":U="#3b82f6";break;case "ethernet":U="#10b981";break;default:U="#10b981";}let re=reactflow.Position.Top,N={width:`${z}px`,height:`${W}px`,background:q?U:"#6b7280",border:`1px solid ${q?U:"#374151"}`,borderRadius:"1px",cursor:"pointer"};if(I==="front")D%2===0?(re=reactflow.Position.Top,N.transform="translateY(50%)",N.left=`${D/2*(z+2)}px`):(re=reactflow.Position.Bottom,N.transform="translateY(-50%)",N.left=`${(D-1)/2*(z+2)}px`);else if(k.type?.includes("power")){re=reactflow.Position.Left,N.transform="translateX(50%)";let ye=b<=20?10:20,s=b<=20?30:50;N.top=`${ye+D*s}%`;let m=xe(t),c=ce(m);N={...N,width:`${c.width}px`,height:`${c.height}px`,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:c.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:c.borderRadius,clipPath:c.clipPath};}else re=reactflow.Position.Right,N.transform="translateX(50%)",N.top=`${25+D*50}%`;let ue=L?"target":q?"source":"target";F.push(jsxRuntime.jsx(reactflow.Handle,{id:B,type:ue,position:re,style:N,title:`${f.name} - ${k.label} ${q?"(connected)":"(disconnected)"}`,children:L?D+1:void 0},B));});}),F},K=()=>{let v=[],F=Math.max(4,Math.floor(b*.4)),z=Math.max(2,Math.floor(b*.2));if(T==="front"){if(g.length>0)return R(g,"front");if(n==="switch"&&(t.toLowerCase().includes("agg")||t.toLowerCase().includes("core")||a==="agg"||a==="core"))return X();v.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-top",type:"target",position:reactflow.Position.Top,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(50%)"},title:"Network Port (Top)"},"net-top")),v.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-bottom",type:"target",position:reactflow.Position.Bottom,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(-50%)"},title:"Network Port (Bottom)"},"net-bottom"));}else if(T==="rear"){if(w.length>0)return R(w,"rear");let W=n==="switch",f=n==="patch-panel";if(!f){let P=xe(t),k=me(P),D=ce(P),L=b<=20?"10%":"25%";v.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-1",type:"target",position:reactflow.Position.Left,style:{width:`${D.width}px`,height:`${D.height}px`,background:D.color,border:`1px solid ${D.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:L,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:D.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:D.borderRadius,clipPath:D.clipPath},title:`Power Port 1 (${k.type}) - ${k.voltage}V, ${k.amperage}A`,children:"1"},"pwr-1"));let B=b<=20?"50%":"75%";v.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-2",type:"target",position:reactflow.Position.Left,style:{width:`${D.width}px`,height:`${D.height}px`,background:D.color,border:`1px solid ${D.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:B,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:D.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:D.borderRadius,clipPath:D.clipPath},title:`Power Port 2 (${k.type}) - ${k.voltage}V, ${k.amperage}A`,children:"2"},"pwr-2"));}!W&&!f&&(v.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-1",type:"target",position:reactflow.Position.Right,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(50%)",top:"25%"},title:"Network Port 1 (Right)"},"net-right-1")),v.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-2",type:"target",position:reactflow.Position.Right,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(50%)",top:"75%"},title:"Network Port 2 (Right)"},"net-right-2")));}return v},X=()=>{let v=[],F=Math.max(10,Math.floor(b*.45)),z=Math.max(5,Math.floor(b*.25));for(let f=1;f<=16;f++){let P=jsxRuntime.jsx(reactflow.Handle,{id:`port-${f}`,type:"source",position:reactflow.Position.Top,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(50%)",zIndex:1e3,left:`${(f-1)*(F+2)}px`},title:`Port ${f}`},`port-${f}`);v.push(P);}for(let f=17;f<=32;f++){let P=f-16,k=jsxRuntime.jsx(reactflow.Handle,{id:`port-${f}`,type:"source",position:reactflow.Position.Bottom,style:{width:`${F}px`,height:`${z}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(-50%)",zIndex:1e3,left:`${(P-1)*(F+2)}px`},title:`Port ${f}`},`port-${f}`);v.push(k);}for(let f=1;f<=4;f++){let P=Math.max(4,Math.floor(b*.3)),k=Math.max(3,Math.floor(b*.15));v.push(jsxRuntime.jsx(reactflow.Handle,{id:`uplink-${f}`,type:"source",position:reactflow.Position.Right,style:{width:`${P}px`,height:`${k}px`,background:"#8b5cf6",border:"0.5px solid #7c3aed",borderRadius:"0.5px",cursor:"pointer",transform:"translateX(-50%)"},title:`Uplink ${f}`},`uplink-${f}`));}return v};return jsxRuntime.jsxs("div",{className:`device-node ${o?"selected":""}`,style:{background:"#1f2937",border:`1px solid ${h(r)}`,borderRadius:"2px",padding:"0px",width:Y,...Z&&{left:Z},height:`${b}px`,color:"white",fontFamily:"monospace",fontSize:"8px",boxShadow:o?"0 0 0 1px #3b82f6":"0 1px 2px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",justifyContent:"center",cursor:"grab",marginBottom:"0px",boxSizing:"border-box",marginTop:"0px",marginLeft:"0px",marginRight:"0px"},children:[jsxRuntime.jsxs("div",{style:{textAlign:"center",flex:1,display:"flex",flexDirection:"column",justifyContent:"center",overflow:"hidden",padding:"2px"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"7px",lineHeight:"1.1",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:t}),d>1&&jsxRuntime.jsx("div",{style:{fontSize:"6px",color:"#9ca3af",lineHeight:"1"},children:i})]}),d>1&&jsxRuntime.jsxs("div",{style:{position:"absolute",bottom:"1px",right:"1px",background:"#374151",color:"#9ca3af",padding:"1px 2px",borderRadius:"1px",fontSize:"6px",lineHeight:"1"},children:[d,"U"]}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"1px",left:"1px",width:"4px",height:"4px",background:h(r),borderRadius:"50%"}}),K()]})};var Ie=({data:e,selected:o,id:t})=>{let{label:r,status:n="active",heightCm:i=100,powerPorts:a=36,portTypes:d=[],widthPx:u=15,mgmt_unit:p}=e,g=T=>{switch(T){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},w=i*4.2,M=()=>{let C=Math.ceil(a/10),b=Array(10).fill(0).map((f,P)=>P<8?"10A":"16A");for(let f=0,P=0;f<C;++f)for(let k=0;k<10&&P<a;++k,++P){b[k];}let v=[],I=15,W=(w-I-3)/(a-9)*.5;for(let f=0;f<a;f++){let P=I-2+W*f,k=`${f+1}`;if(p&&(p==="top"&&f===0||p==="middle"&&f===Math.floor(a/2)||p==="bottom"&&f===a-1)){v.push(E(P));continue}let L=Ee(f),B=ce(L),q=Math.round((u-B.width)/2-1);v.push(jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:k,style:{position:"absolute",left:`${q}px`,top:`${P-B.height/2}px`,width:`${B.width}px`,height:`${B.height}px`,background:B.color,border:`1px solid ${B.borderColor}`,cursor:"pointer",zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:B.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:B.borderRadius,clipPath:B.clipPath},title:`Power Port ${f+1} (${L})`,children:f+1},`handle-${k}`));}return v},E=T=>jsxRuntime.jsxs("div",{style:{position:"absolute",left:`${(u-16)/2}px`,top:`${T-12/2}px`,width:"16px",height:"12px",background:"#1a1a1a",border:"1px solid #374151",borderRadius:"1px",display:"flex",flexDirection:"column",padding:"1px",zIndex:10},children:[jsxRuntime.jsx("div",{style:{position:"absolute",left:"-10px",top:"1px",background:"#ffffff",border:"0.5px solid #6b7280",borderRadius:"0.5px",width:"8px",height:"10px",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"3px",color:"#10b981",fontFamily:"monospace",fontWeight:"bold",transform:"rotate(90deg)",transformOrigin:"center"},children:"APC"}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:"mgmt-net-1",style:{width:"70%",height:"6px",background:"#10b981",border:"1px solid #059669",borderRadius:"1px",cursor:"pointer",zIndex:11,margin:"0 auto"},title:"Management Network Port"},"mgmt-net-1")]},"mgmt-unit");return jsxRuntime.jsxs("div",{className:`vertical-pdu-node ${o?"selected":""}`,style:{background:"linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",border:`1px solid ${g(n)}`,borderRadius:"2px",padding:0,width:`${u}px`,height:`${w}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:o?"0 0 0 2px #3b82f6":"0 1px 3px rgba(0,0,0,0.3)",position:"relative",display:"flex",flexDirection:"column"},children:[jsxRuntime.jsx("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)",padding:"2px",position:"relative",height:"20px",display:"flex",flexDirection:"column",justifyContent:"center",borderBottom:"1px solid #4a5568"},children:jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"6px",color:"#e2e8f0"},children:r})}),jsxRuntime.jsx("div",{style:{flex:1,background:"linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",position:"relative",minHeight:`${w-20}px`,overflow:"hidden"},children:M()})]})};var Ae=(e,o,t,r)=>{if(!e.parentId||e.parentId!==o.id)return t;e.data.uHeight||1;o.data.uHeight||42;let a=60,d=t.y-a,u=Math.round(d/20)+1,p=Math.max(1,u);if(!Fe(o,e,p,r)){let w=be(o,e,r,p);w!==p&&(p=w);}let g=a+(p-1)*20-1;return {x:t.x,y:g,uPosition:p}},Fe=(e,o,t,r)=>{let n=o.data.uHeight||1,i=e.data.uHeight||42;if(t<1||t+n-1>i)return false;let a=r.filter(d=>d.type==="device"&&d.parentId===e.id&&d.id!==o.id);for(let d of a){let u=d.data.uPosition||1,p=d.data.uHeight||1,g=t,w=t+n-1,M=u,E=u+p-1;if(g<=E&&w>=M)return false}return true},be=(e,o,t,r=1)=>{let n=o.data.uHeight||1,i=e.data.uHeight||42;for(let a=r;a<=i-n+1;a++)if(Fe(e,o,a,t))return a;return 1},pe=(e,o)=>({x:0,y:60+(o-1)*20-1}),Xe=(e,o,t)=>{let r=pe(o,t);return {...e,position:r,data:{...e.data,uPosition:t}}},mt=(e,o)=>{let t=e.data.uPosition||1,r=e.data.uHeight||1,n=o.data.uHeight||42,i=Math.max(1,Math.min(n-r+1,t));return i!==t?Xe(e,o,i):e};function xt(e,o){if(!e.source||!e.target||!e.sourceHandle||!e.targetHandle)return {valid:true};let t=o.edges.some(n=>n.source===e.source&&n.sourceHandle===e.sourceHandle),r=o.edges.some(n=>n.target===e.target&&n.targetHandle===e.targetHandle);return t?{valid:false,reason:"Source port is already connected"}:r?{valid:false,reason:"Target port is already connected"}:{valid:true}}function bt(e,o){if(!o)return;let t=o.data||{};if(t.handleSideMap&&t.handleSideMap[e])return t.handleSideMap[e];if(e==="net-top"||e==="net-bottom")return "front";if(e==="pwr-left-1"||e==="pwr-left-2"||e==="net-right-1"||e==="net-right-2")return "rear";let r=Array.isArray(t.ports)?t.ports:[],n=Array.isArray(t.rearPorts)?t.rearPorts:[];if(e.startsWith("pwr")||e.includes("power"))return "rear";if(r.length>0){for(let a of r)for(let d of a.ports||[])if((d.type&&String(d.type).includes("power")?d.label:`${a.name}-${d.label}`)===e)return "front"}if(n.length>0){for(let a of n)for(let d of a.ports||[])if((d.type&&String(d.type).includes("power")?d.label:`${a.name}-${d.label}`)===e)return "rear"}}function Me(e={},o={}){let t={nodes:e.nodes??[],edges:e.edges??[],debug:e.debug??false},r=new Set;return {getState:()=>t,setState:p=>{t={...t,...p},r.forEach(g=>g(t));},subscribe:p=>(r.add(p),()=>r.delete(p)),selectEdgeZIndex:p=>{let g=t.nodes.find(b=>b.id===p.target);if(!g||g.type!=="device")return 1e3;let w=g.data?.view||"front",M=bt(p.targetHandle||"",g);if(M)return w===M?1e3:500;let E=p.targetHandle||"",T=E.startsWith("pwr")||E.startsWith("power"),C=E.startsWith("net-")||E.startsWith("port-")||E.startsWith("uplink-")||E.includes("Fiber")||E.includes("Ports");return T?w==="rear"?1e3:500:C?w==="front"?1e3:500:1e3},validateConnection:p=>(o.validateConnection||xt)(p,t)}}function yt(e){let o=n=>e.subscribe(n),t=()=>e.getState();return wt.useSyncExternalStore(o,t,t)}function Be(e){let o=r=>e.subscribe(r),t=()=>e.getState().nodes;return wt.useSyncExternalStore(o,t,t)}function _e(e){let o=r=>e.subscribe(r),t=()=>e.getState().edges;return wt.useSyncExternalStore(o,t,t)}function Ze(e){return e.selectEdgeZIndex}var Et=(e,o)=>({rack:t=>jsxRuntime.jsx(ve,{...t,onViewChange:e,onRackFaceChange:o}),fiber:Pe,device:Te,"vertical-pdu":Ie}),$t={fiber:Se,power:De},Tt=({nodes:e,edges:o,initialNodes:t,initialEdges:r,onNodesChange:n,onEdgesChange:i,store:a,debug:d,onNodeClick:u,onEdgeClick:p,onViewChange:g,onRackFaceChange:w,className:M,style:E,alignRacksToBottom:T})=>{let C=Array.isArray(e)&&Array.isArray(o),b=wt__default.default.useMemo(()=>a||Me({nodes:C?e:t||e||[],edges:C?o:r||o||[],debug:d}),[a,C,e,o,t,r,d]),Y=Be(b),Z=_e(b),[h,A,R]=reactflow.useNodesState(Y),[K,X,v]=reactflow.useEdgesState(Z),I=Ze(b),F=wt.useMemo(()=>Et(g,w),[g,w]),z=wt.useMemo(()=>$t,[]),W=wt.useRef(h);wt.useEffect(()=>{W.current=h;},[h]);let f=wt.useRef(K);wt.useEffect(()=>{f.current=K;},[K]),wt.useEffect(()=>{A(Y);},[Y,A]),wt.useEffect(()=>{X(Z);},[Z,X]),wt.useEffect(()=>{C&&b.setState({nodes:e||[]});},[C,e,b]),wt.useEffect(()=>{C&&b.setState({edges:o||[]});},[C,o,b]),wt.useEffect(()=>{if(!T||!h||h.length===0)return;let s=h.filter(x=>x.type==="rack");if(s.length===0)return;let m=s.map(x=>{let _=x.data&&x.data.uHeight||42,O=60+_*20;return (x.position?.y||0)+O}),c=Math.min(...m),l=Math.max(...m);if(l-c<20)return;let y=l,$=h.map(x=>{if(x.type!=="rack")return x;let _=x.data&&x.data.uHeight||42,O=60+_*20,te=(x.position?.y||0)+O,ae=y-te;return Math.abs(ae)<5?x:{...x,position:{x:x.position?.x||0,y:(x.position?.y||0)+ae}}});$.some((x,_)=>x.position!==h[_].position)&&A($);},[T,h,A]);let P=wt.useCallback(s=>W.current.find(m=>m.id===s),[]);wt.useCallback((s,m)=>{let c=P(s);if(!c||c.type!=="device")return 1e3;let l=c.data?.view||"front",y=(c.data?.handleSideMap||{})[m],$;if(y)$=l===y?1e3:500;else {let H=m.startsWith("pwr-left")||m.startsWith("power"),x=m.startsWith("net-")||m.startsWith("port-")||m.startsWith("uplink-")||m.includes("Fiber")||m.includes("Ports");H?$=l==="rear"?1e3:500:x?$=l==="front"?1e3:500:$=1e3;}return $},[P]);wt.useEffect(()=>{X(s=>s.map(m=>{let c=I(m);return {...m,zIndex:c,style:{...m.style,zIndex:c}}}));},[h,X,I]),wt.useEffect(()=>{let s=h.map(c=>{if(c.type==="device"&&c.parentId&&c.data.uPosition&&(!c.position||c.position.x===0&&c.position.y===0)){let l=P(c.parentId);if(l){let S=pe(l,c.data.uPosition);return {...c,position:S}}}return c});s.some((c,l)=>c.position!==h[l].position)&&A(s);},[h,A,P]);let D=wt.useCallback(s=>{let m=s.map(c=>{if(c.type==="position"&&c.position){let l=P(c.id);if(l&&l.type==="device"&&l.parentId){let S=P(l.parentId);if(S){let y=Ae(l,S,c.position,W.current);if(y.uPosition!==void 0){let $={...l,data:{...l.data,uPosition:y.uPosition}};A(H=>H.map(x=>x.id===l.id?$:x));}return {...c,position:{x:y.x,y:y.y}}}}if(l&&l.type==="device"&&!l.parentId){let S=W.current.filter(H=>H.type==="rack"),y=null,$=1/0;for(let H of S){let x=H,_=Math.sqrt(Math.pow(c.position.x-x.position.x,2)+Math.pow(c.position.y-x.position.y,2)),O=300,te=(x.data.uHeight||42)*20,ae=x.position.x,we=x.position.x+O,ke=x.position.y,Ne=x.position.y+te;c.position.x>=ae&&c.position.x<=we&&c.position.y>=ke&&c.position.y<=Ne&&_<$&&($=_,y=x);}if(y){let H={...l,parentId:y.id,extent:"parent",data:{...l.data,uPosition:1}};A(O=>O.map(te=>te.id===l.id?H:te));let x=c.position.x-y.position.x,_=c.position.y-y.position.y;return {...c,position:{x,y:_}}}}if(l&&l.type==="device"&&l.parentId){let S=P(l.parentId);if(S){let y=S,$=300,H=(y.data.uHeight||42)*20,x=y.position.x,_=y.position.x+$,O=y.position.y,te=y.position.y+H;if(c.position.x<x||c.position.x>_||c.position.y<O||c.position.y>te){let ae=c.position.x+y.position.x,we=c.position.y+y.position.y,ke={...l,parentId:void 0,extent:void 0,data:{...l.data,uPosition:void 0}};return A(Ne=>Ne.map(Le=>Le.id===l.id?ke:Le)),{...c,position:{x:ae,y:we}}}}}}return c});R(m);},[R,A,P]);wt.useCallback(s=>{if(!s.source||!s.target||!s.sourceHandle||!s.targetHandle)return {valid:true};let m=s.sourceHandle,c=s.targetHandle,l=f.current.some(y=>y.source===s.source&&y.sourceHandle===m),S=f.current.some(y=>y.target===s.target&&y.targetHandle===c);return l?{valid:false,reason:"Source port is already connected"}:S?{valid:false,reason:"Target port is already connected"}:{valid:true}},[]);let B=wt.useCallback(s=>{let c=P(s.source)?.type==="vertical-pdu",l=!!s.targetHandle&&(s.targetHandle.startsWith("pwr")||s.targetHandle.startsWith("power"));if(c&&l&&s.target&&s.targetHandle){let $=f.current.find(H=>H.target===s.target&&H.targetHandle===s.targetHandle);if($){let H={...s,type:"power",zIndex:I({...s,id:"temp-id"})};X(x=>{let _=x.filter(O=>O.id!==$.id);return reactflow.addEdge(H,_)});return}}let S=b.validateConnection({source:s.source??null,target:s.target??null,sourceHandle:s.sourceHandle??null,targetHandle:s.targetHandle??null});if(!S.valid){if(c&&s.source&&s.sourceHandle){let $=f.current.find(H=>H.source===s.source&&H.sourceHandle===s.sourceHandle);if($){let H={...s,type:l?"power":"fiber",zIndex:I({...s,id:"temp-id"})};X(x=>{let _=x.filter(O=>O.id!==$.id);return reactflow.addEdge(H,_)});return}}console.warn(`Connection rejected: ${S.reason}`);return}let y={...s,type:c&&l?"power":"fiber",zIndex:I({...s,id:"temp-id"})};X($=>reactflow.addEdge(y,$));},[X,b,I,P]),q=wt.useCallback((s,m)=>{if((s.metaKey||s.ctrlKey)&&m.type==="device"){let l=m.data||{},S=l.view||(Array.isArray(l.rearPorts)&&l.rearPorts.length>0?"rear":"front"),y=S==="front"?"rear":"front";console.log(`Command+click: Toggling device ${m.id} from ${S} to ${y}`),g&&g(m.id,y),u&&u(m);}else m.type!=="device"&&u&&u(m);},[g,u]),U=wt.useCallback(()=>{},[]),re=wt.useCallback((s,m)=>{p&&p(m);},[p]),[N,ue]=wt.useState(null);reactflow.useOnSelectionChange({onChange:({nodes:s})=>{s&&s.length===1?ue(s[0]):ue(null);}});let ye=wt.useCallback(()=>{if(!N)return;let s=P(N.id);if(s){if(s.type==="rack"){let c=(s.data&&s.data.face||"front")==="front"?"rear":"front";w?w(s.id,c):A(l=>l.map(S=>S.id===s.id?{...S,data:{...S.data,face:c}}:S.parentId===s.id?{...S,data:{...S.data,view:c}}:S));return}if(s.type==="device"){let m=s.data||{},c=Array.isArray(m.rearPorts)&&m.rearPorts.length>0,l=Array.isArray(m.ports)&&m.ports.length>0,y=(m.view||(c&&!l?"rear":"front"))==="front"?"rear":"front";g?g(s.id,y):A($=>$.map(H=>H.id===s.id?{...H,data:{...H.data,view:y}}:H));}}},[N,P,w,g,A]);return jsxRuntime.jsxs("div",{className:M,style:{width:"100%",height:"100%",...E},children:[jsxRuntime.jsxs(reactflow.ReactFlow,{nodes:h,edges:K,onNodesChange:s=>{D(s);s.reduce((c,l)=>(l.type==="add"||l.type==="remove",c),null);C?n&&n(W.current):b.setState({nodes:W.current});},onEdgesChange:s=>{v(s),C?i&&i(f.current):b.setState({edges:f.current});},onConnect:B,onNodeClick:q,onNodeDoubleClick:U,onEdgeClick:re,nodeTypes:F,edgeTypes:z,defaultEdgeOptions:{zIndex:1e3,reconnectable:true},fitView:true,attributionPosition:"bottom-left",children:[jsxRuntime.jsx(reactflow.Background,{}),jsxRuntime.jsx(reactflow.Controls,{}),jsxRuntime.jsx(reactflow.MiniMap,{})]}),N&&(N.type==="rack"||N.type==="device")&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,right:12,display:"flex",gap:8,zIndex:2e3},children:jsxRuntime.jsx("button",{onClick:s=>{s.preventDefault(),ye();},style:{background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:4,padding:"6px 10px",fontSize:11,fontFamily:"monospace",cursor:"pointer"},title:N.type==="rack"?(N.data?.face||"front")==="front"?"Switch to rear":"Switch to front":(N.data?.view||(Array.isArray(N.data?.rearPorts)&&N.data.rearPorts.length>0&&!(Array.isArray(N.data?.ports)&&N.data.ports.length>0)?"rear":"front"))==="front"?"Switch to rear":"Switch to front",children:N.type==="rack"?(N.data?.face||"front")==="front"?"\u21C4 Rear":"\u21C4 Front":(N.data?.view||(Array.isArray(N.data?.rearPorts)&&N.data.rearPorts.length>0&&!(Array.isArray(N.data?.ports)&&N.data.ports.length>0)?"rear":"front"))==="front"?"\u21C4 Rear":"\u21C4 Front"})})]})},It=e=>jsxRuntime.jsx(reactflow.ReactFlowProvider,{children:jsxRuntime.jsx(Tt,{...e})});var Je=e=>({id:`rack-${e.id}`,type:"rack",position:{x:0,y:0},data:{label:e.name,status:e.status.value,uHeight:e.u_height,netboxId:e.id,netboxType:"rack",facilityId:e.facility_id,serial:e.serial,assetTag:e.asset_tag,site:e.site.name,role:e.role?.name,tenant:e.tenant?.name}}),Qe=e=>({id:`device-${e.id}`,type:"device",position:{x:0,y:0},parentId:e.rack?`rack-${e.rack.id}`:void 0,extent:e.rack?"parent":void 0,data:{label:e.name,status:e.status.value,deviceType:e.device_type.model,manufacturer:e.device_type.manufacturer.name,role:e.device_role.name,uHeight:1,uPosition:e.position||1,face:e.face||"front",netboxId:e.id,netboxType:"device",primaryIp4:e.primary_ip4?.address,primaryIp6:e.primary_ip6?.address,site:e.site.name,rack:e.rack?.name}}),et=e=>({id:`cable-${e.id}`,source:`device-${e.termination_a.device.name}`,target:`device-${e.termination_b.device.name}`,type:"fiber",data:{bandwidth:e.type.label,length:e.length||0,color:e.color,netboxId:e.id,netboxType:"cable",status:e.status.value,terminationA:e.termination_a.name,terminationB:e.termination_b.name}}),At=e=>{let o=[],t=[];return e.racks.forEach(r=>{o.push(Je(r));}),e.devices.forEach(r=>{o.push(Qe(r));}),e.cables.forEach(r=>{t.push(et(r));}),{nodes:o,edges:t}},Ft=(e,o)=>{let t=new Map,r=new Set;return e.filter(i=>i.position!==null).sort((i,a)=>(i.position||0)-(a.position||0)).forEach(i=>{i.position&&(t.set(i.id,i.position),r.add(i.position));}),t},Mt=e=>{let o=e.filter(n=>n.type==="rack"),t=e.filter(n=>n.type==="device"),r=e.filter(n=>!["rack","device"].includes(n.type));return o.forEach((n,i)=>{n.position={x:i*300,y:100};}),t.forEach(n=>{if(n.parentId){let i=o.find(a=>a.id===n.parentId);if(i){let a=n.data.uPosition||1,d=n.data.uHeight||1;n.position={x:i.position.x+50,y:i.position.y+a*20-d*10};}}else n.position={x:Math.random()*400+100,y:Math.random()*200+50};}),r.forEach((n,i)=>{n.position={x:i*150+100,y:300};}),e};var le=class extends Error{constructor(t,r,n,i,a){super(`Device placement conflict: ${r} at U${n}-${n+i-1} in rack ${t}${a?` conflicts with ${a}`:""}`);this.rackId=t;this.deviceId=r;this.uPosition=n;this.uHeight=i;this.conflictWith=a;this.name="DevicePlacementError";}};function We(e,o={}){let{conflictPolicy:t="strict"}=o,r=[],n=[];for(let i of e.devices)i.unit+i.height-1>e.units&&n.push({deviceId:i.id,uPosition:i.unit,uHeight:i.height,rackUHeight:e.units});for(let i=0;i<e.devices.length;i++){let a=e.devices[i],d=a.unit,u=a.unit+a.height-1;for(let p=i+1;p<e.devices.length;p++){let g=e.devices[p],w=g.unit,M=g.unit+g.height-1;d<=M&&u>=w&&r.push({deviceId:a.id,uPosition:a.unit,uHeight:a.height,conflictWith:g.id});}}return {isValid:r.length===0&&n.length===0,conflicts:r,outOfBounds:n}}function tt(e,o,t={}){let{deviceTypeMapping:r={}}=t,n=r[e.type]||"device",i=pe(o,e.unit);return {id:e.id,type:n,position:i,parentId:o.id,extent:"parent",data:{label:e.name,status:"active",deviceType:e.type,uHeight:e.height,uPosition:e.unit,width:e.width||"full",role:e.role,ports:e.ports,rearPorts:e.rearPorts,connections:e.connections}}}function Ut(e){return {id:e.id,type:"rack",position:e.position,data:{label:e.name,status:"active",uHeight:e.units,ports:[]}}}function Bt(e,o={}){let{conflictPolicy:t="strict",validatePlacements:r=true}=o,n=[],i=[];if(r)for(let a of e){let d=We(a,o);if(!d.isValid&&t==="strict"){let u=[];throw d.conflicts.forEach(p=>{u.push(`Device ${p.deviceId} at U${p.uPosition}-${p.uPosition+p.uHeight-1} conflicts with ${p.conflictWith}`);}),d.outOfBounds.forEach(p=>{u.push(`Device ${p.deviceId} at U${p.uPosition}-${p.uPosition+p.uHeight-1} exceeds rack height (${p.rackUHeight}U)`);}),new le(a.id,d.conflicts[0]?.deviceId||d.outOfBounds[0]?.deviceId||"unknown",d.conflicts[0]?.uPosition||d.outOfBounds[0]?.uPosition||1,d.conflicts[0]?.uHeight||d.outOfBounds[0]?.uHeight||1)}}for(let a of e){let d=Ut(a);n.push(d);for(let u of a.devices)try{let p=tt(u,d,o);i.push(p);}catch(p){if(t==="strict")throw p;if(t==="nearest"){let g=be(d,{id:u.id,data:{label:u.name,uHeight:u.height}},i,u.unit);if(g!==u.unit){console.warn(`Device ${u.id} moved from U${u.unit} to U${g} due to conflict`);let w={...u,unit:g},M=tt(w,d,o);i.push(M);}else throw new le(a.id,u.id,u.unit,u.height)}}}return n.push(...i),n}function _t(e){let o=[],t=e.filter(r=>r.type==="rack");for(let r of t){let i=e.filter(a=>a.type==="device"&&a.parentId===r.id).map(a=>({id:a.id,name:a.data.label,unit:a.data.uPosition||1,height:a.data.uHeight||1,type:a.data.deviceType||"server",width:a.data.width,ports:a.data.ports,connections:a.data.connections}));o.push({id:r.id,name:r.data.label,position:r.position,units:r.data.uHeight||42,devices:i});}return o}function zt(e,o,t,r){return e.map(n=>n.id!==o?n:{...n,devices:n.devices.map(i=>i.id!==t?i:{...i,unit:r})})}function Wt(e,o,t,r={}){let{conflictPolicy:n="strict"}=r;return e.map(i=>{if(i.id!==o)return i;if(n==="strict"&&!We({...i,devices:[...i.devices,t]},r).isValid)throw new le(o,t.id,t.unit,t.height);return {...i,devices:[...i.devices,t]}})}function Lt(e,o,t){return e.map(r=>r.id!==o?r:{...r,devices:r.devices.filter(n=>n.id!==t)})}exports.DeviceNode=Te;exports.DevicePlacementError=le;exports.FiberEdge=Se;exports.FiberNode=Pe;exports.NetworkDiagram=It;exports.POWER_CONNECTORS=He;exports.PowerEdge=De;exports.RackNode=ve;exports.VerticalPDU=Ie;exports.Width=Ve;exports.addDeviceToRack=Wt;exports.buildNodesFromRackConfig=Bt;exports.calculateDevicePositionFromU=pe;exports.calculateUPositions=Ft;exports.createNetworkDiagramStore=Me;exports.createRackConfigFromNodes=_t;exports.findNextAvailableUPosition=be;exports.generateLayout=Mt;exports.getConnectorConfig=me;exports.getDeviceConnectorType=xe;exports.getPDUPortType=Ee;exports.getPowerPortStyle=ce;exports.isHighPowerConnector=ft;exports.isUPositionAvailable=Fe;exports.netboxCableToNetworkEdge=et;exports.netboxDeviceToNetworkNode=Qe;exports.netboxRackToNetworkNode=Je;exports.netboxToNetworkDiagram=At;exports.removeDeviceFromRack=Lt;exports.snapToUPosition=Ae;exports.updateDeviceUPosition=Xe;exports.updateDeviceUPositionInSchema=zt;exports.useDiagramEdges=_e;exports.useDiagramNodes=Be;exports.useNetworkDiagram=yt;exports.validateAndSnapDevice=mt;exports.validateRackDevicePlacements=We;//# sourceMappingURL=index.js.map
1
+ 'use strict';var Be=require('react'),reactflow=require('reactflow'),htmlToImage=require('html-to-image'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Be__default=/*#__PURE__*/_interopDefault(Be);var ke=()=>"bottom-up",pt=t=>t.data.uNumberingDirection||ke(),vt=(t,e,o)=>o==="bottom-up"?e-t+1:t,Pt=(t,e,o)=>o==="bottom-up"?e-t+1:t;var Et=(t,e,o,i)=>{if(!t.parentId||t.parentId!==e.id)return o;let n=t.data.uHeight||1,a=e.data.uHeight||42,s=pt(e),d=60,l=o.y-d,u=Math.round(l/20)+1,y;s==="bottom-up"?y=vt(u,a,s)-n+1:y=vt(u,a,s);let f=a-n+1,N=Math.max(1,Math.min(f,y));if(s==="top-down"&&y<=1&&(N=1),!Tt(e,t,N,i)){let D=Dt(e,t,i,N);D!==N&&(N=D);}let U;if(s==="bottom-up"){let D=N+n-1,E=Pt(D,a,s);U=d+(E-1)*20-1;}else {let D=Pt(N,a,s);U=d+(D-1)*20-1;}return {x:o.x,y:U,uPosition:N}},Tt=(t,e,o,i)=>{let n=e.data.uHeight||1,a=t.data.uHeight||42;if(o<1||o+n-1>a)return false;let s=i.filter(d=>d.type==="device"&&d.parentId===t.id&&d.id!==e.id);for(let d of s){let l=d.data.uPosition||1,u=d.data.uHeight||1,y=o,f=o+n-1,N=l,U=l+u-1;if(y<=U&&f>=N)return false}return true},Dt=(t,e,o,i=1)=>{let n=e.data.uHeight||1,a=t.data.uHeight||42;for(let s=i;s<=a-n+1;s++)if(Tt(t,e,s,o))return s;return 1},mt=(t,e,o=1)=>{let i=60,n=pt(t),a=t.data.uHeight||42,s=Pt(e,a,n),d;if(n==="bottom-up"){let l=e+o-1,u=Pt(l,a,n);d=i+(u-1)*20-1;}else d=i+(s-1)*20-1;return {x:0,y:d}},Qt=(t,e,o)=>{let i=t.data.uHeight||1,n=mt(e,o,i);return {...t,position:n,data:{...t.data,uPosition:o}}},ve=(t,e)=>{let o=t.data.uPosition||1,i=t.data.uHeight||1,n=e.data.uHeight||42,a=Math.max(1,Math.min(n-i+1,o));return a!==o?Qt(t,e,a):t};var It=({data:t,selected:e,id:o,onViewChange:i,onRackFaceChange:n,isDragOver:a=false})=>{let{label:s,ports:d=0,status:l="active",uHeight:u=42,uPosition:y=1,face:f="front",customHeaderText:N}=t,{getNodes:U,setNodes:D}=reactflow.useReactFlow(),E=U(),[c,F]=Be.useState(true),X=()=>{let _=pt({data:t})==="bottom-up"?"top-down":"bottom-up";D(g=>g.map(T=>T.id===o?{...T,data:{...T.data,uNumberingDirection:_}}:T));},O=()=>{let h=f==="front"?"rear":"front";n?(n(o,h),i&&E.filter(g=>g.parentId===o).forEach(g=>{i(g.id,h);})):i?E.filter(g=>g.parentId===o).forEach(g=>{i(g.id,h);}):D(_=>_.map(g=>g.id===o?{...g,data:{...g.data,face:h}}:g.parentId===o?{...g,data:{...g.data,view:h}}:g));},V=h=>{switch(h){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},et=()=>{let h=[],_=60,g=pt({data:t});for(let T=1;T<=u;T++){let v=_+(T-1)*20-4,R=vt(T,u,g);h.push(jsxRuntime.jsx("div",{style:{position:"absolute",left:"-35px",top:`${v}px`,background:"#374151",color:"#9ca3af",padding:"2px 4px",borderRadius:"2px",fontSize:"8px",fontWeight:"bold",width:"28px",textAlign:"center",border:"1px solid #4b5563",zIndex:10,height:`${20}px`,display:"flex",alignItems:"center",justifyContent:"center",lineHeight:1},children:R},T));}return h};return jsxRuntime.jsxs("div",{className:`rack-node ${e?"selected":""} ${a?"drag-over":""}`,style:{background:"transparent",border:`2px solid ${V(l)}`,borderRadius:"8px",padding:0,width:`${300}px`,height:`${60+u*20}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:a?"0 0 20px #3b82f6, 0 0 40px #3b82f6, 0 0 60px #3b82f6":e?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",transition:"box-shadow 0.2s ease-in-out"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsxs("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"#1f2937",padding:"8px",position:"relative",height:`${60}px`,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:s}),jsxRuntime.jsxs("div",{style:{fontSize:"10px",color:"#9ca3af"},children:[N?jsxRuntime.jsx("span",{style:{color:"#fbbf24",fontWeight:"bold"},children:N}):jsxRuntime.jsxs("span",{children:[typeof d=="number"?d:0," ports"]})," \u2022 ",u,"U \u2022 ",f]}),jsxRuntime.jsxs("div",{style:{display:"flex",gap:"4px",position:"absolute",top:"4px",right:"4px"},children:[jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),F(!c);},style:{background:c?"#10b981":"#374151",color:c?"#ffffff":"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`${c?"Hide":"Show"} U markers`,children:"U"}),jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),X();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch U numbering to ${pt({data:t})==="bottom-up"?"top-down":"bottom-up"}`,children:pt({data:t})==="bottom-up"?"\u2191\u2193":"\u2193\u2191"}),jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),O();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch to ${f==="front"?"rear":"front"} view`,children:f==="front"?"\u21C4 Rear":"\u21C4 Front"})]})]}),jsxRuntime.jsx("div",{style:{flex:1,background:"transparent",position:"relative",minHeight:`${u*20}px`,overflow:"hidden"}}),c&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,pointerEvents:"none"},children:et()})]})};var At=({data:t,selected:e})=>{let{label:o,status:i="active"}=t,n=a=>{switch(a){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}};return jsxRuntime.jsxs("div",{className:`fiber-node ${e?"selected":""}`,style:{background:"#1f2937",border:`2px solid ${n(i)}`,borderRadius:"50%",width:"60px",height:"60px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontFamily:"monospace",fontSize:"10px",fontWeight:"bold",boxShadow:e?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Bottom}),jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Left}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right}),jsxRuntime.jsx("div",{style:{textAlign:"center"},children:jsxRuntime.jsx("div",{style:{fontSize:"8px",lineHeight:"1.2"},children:o})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"4px",left:"50%",transform:"translateX(-50%)",width:"8px",height:"8px",background:n(i),borderRadius:"50%"}})]})};var Ft=({id:t,sourceX:e,sourceY:o,targetX:i,targetY:n,sourcePosition:a,targetPosition:s,data:d,selected:l,style:u={}})=>{let[y,f,N]=reactflow.getBezierPath({sourceX:e,sourceY:o,sourcePosition:a,targetX:i,targetY:n,targetPosition:s}),{bandwidth:U,length:D,color:E="#00FFFF"}=d||{},c={...u,stroke:E,strokeWidth:l?3:2,strokeDasharray:"none"};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(reactflow.BaseEdge,{id:t,path:y,style:c}),jsxRuntime.jsx(reactflow.EdgeLabelRenderer,{children:l&&d&&(U||D)&&jsxRuntime.jsxs("div",{style:{position:"absolute",transform:`translate(-50%, -50%) translate(${f}px,${N}px)`,background:"#1f2937",padding:"4px 8px",borderRadius:"4px",fontSize:"10px",color:"white",fontFamily:"monospace",border:`1px solid ${E}`,pointerEvents:"none",zIndex:9999},children:[U&&jsxRuntime.jsx("div",{children:U}),D&&jsxRuntime.jsxs("div",{children:[D,"m"]})]})})]})};var Mt=({id:t,sourceX:e,sourceY:o,targetX:i,targetY:n,sourcePosition:a,targetPosition:s,style:d={},data:l,markerEnd:u})=>{let [y,f,N]=reactflow.getBezierPath({sourceX:e,sourceY:o,sourcePosition:a,targetX:i,targetY:n,targetPosition:s}),U=l?.connectorType||"C13";l?.voltage||"AC";l?.amperage||(U==="C19"?"16A":"10A");return jsxRuntime.jsx(reactflow.BaseEdge,{id:t,path:y,markerEnd:u,style:(()=>{let F={stroke:l?.color||"#f59e0b",strokeWidth:U==="C19"?5:3,strokeLinecap:"round",strokeLinejoin:"round",...d};return U==="C19"?{...F,strokeDasharray:"none"}:{...F,strokeDasharray:"6,3"}})()})};var te=(o=>(o.FULL="full",o.HALF="half",o))(te||{});var zt={C13:{type:"C13",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C14:{type:"C14",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C19:{type:"C19",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1},C20:{type:"C20",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1}};function ht(t){let e=zt[t];if(!e)throw new Error(`Unknown connector type: ${t}`);let o=e.amperage===16;e.amperage===10;let n=o?12:8,a=o?10:5,s=o?{borderRadius:"3px"}:{clipPath:"polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)",borderRadius:"0px"};return {width:n,height:a,color:e.color,borderColor:e.borderColor,fontSize:o?"3px":"4px",...s}}function Rt(t){let e=zt[t];if(!e)throw new Error(`Unknown connector type: ${t}`);return e}function _e(t){return Rt(t).amperage===16}function Lt(t){return t%10<8?"C13":"C19"}function St(t){let e=t.toLowerCase();return e.includes("mx304")||e.includes("mx480")||e.includes("mx960")?"C20":"C14"}var Bt=({data:t,selected:e})=>{let{label:o,status:i="active",deviceType:n="server",manufacturer:a,role:s,uHeight:d=1,uPosition:l=1,width:u="full",ports:y=[],rearPorts:f=[],view:N,powerSide:U="left"}=t,D=N||(f.length>0&&y.length===0?"rear":"front"),E={};E["net-top"]="front",E["net-bottom"]="front",y.length>0&&y.forEach(g=>{g.ports.forEach(T=>{let v=T.type?.includes("power")?T.label:`${g.name}-${T.label}`;E[v]="front";});}),E["pwr-left-1"]="rear",E["pwr-left-2"]="rear",E["net-right-1"]="rear",E["net-right-2"]="rear",f.length>0&&f.forEach(g=>{g.ports.forEach(T=>{let v=T.type?.includes("power")?T.label:`${g.name}-${T.label}`;E[v]="rear";});});let c=d*20,F=u==="half"?"150px":"304px",X=u==="half"?"150px":void 0,O=g=>{switch(g){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},et=(g,T)=>{let v=[];if(g.length===0)return v;let R=Math.max(4,Math.floor(c*.4)),rt=Math.max(2,Math.floor(c*.2));return g.forEach((b,I)=>{b.ports.forEach(($,A)=>{let H=!!$.type&&$.type.includes("power");if(T==="front"&&H)return;let j=H?`${$.label}`:`${b.name}-${$.label}`,J=$.connected,B="#6b7280";if(J)if($.type?.includes("power"))B=$.type==="power_c19"?"#fbbf24":"#f59e0b";else if($.type==="console"||$.type==="mgmt")B="#8b5cf6";else if($.type==="usb")B="#10b981";else switch($.cableType){case "smf":B="#fbbf24";break;case "cat6":B="#8b5cf6";break;case "om3":B="#06b6d4";break;case "om4":B="#8b5cf6";break;case "om5":B="#84cc16";break;case "cat5e":B="#3b82f6";break;case "cat6a":B="#ef4444";break;case "cat7":B="#f97316";break;case "fiber":B="#3b82f6";break;case "ethernet":B="#10b981";break;default:B="#10b981";}let nt=reactflow.Position.Top,M={width:`${R}px`,height:`${rt}px`,background:J?B:"#6b7280",border:`1px solid ${J?B:"#374151"}`,borderRadius:"1px",cursor:"pointer"};if(T==="front")A%2===0?(nt=reactflow.Position.Top,M.transform="translateY(50%)",M.left=`${A/2*(R+2)}px`):(nt=reactflow.Position.Bottom,M.transform="translateY(-50%)",M.left=`${(A-1)/2*(R+2)}px`);else if((n?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel")A%2===0?(nt=reactflow.Position.Top,M.transform="translateY(50%)",M.left=`${A/2*(R+2)}px`):(nt=reactflow.Position.Bottom,M.transform="translateY(-50%)",M.left=`${(A-1)/2*(R+2)}px`);else if($.type?.includes("power")){nt=reactflow.Position.Left,M.transform="translateX(50%)";let st=c<=20?10:20,ot=c<=20?30:50;M.top=`${st+A*ot}%`;let Q=St(o),lt=ht(Q);M={...M,width:`${lt.width}px`,height:`${lt.height}px`,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:lt.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:lt.borderRadius,clipPath:lt.clipPath};}else nt=reactflow.Position.Right,M.transform="translateX(-50%)",M.top=`${25+A*50}%`;let gt;H?gt="target":n==="switch"||n==="router"?gt="source":gt=J?"source":"target",v.push(jsxRuntime.jsx(reactflow.Handle,{id:j,type:gt,position:nt,style:M,title:`${b.name} - ${$.label} ${J?"(connected)":"(disconnected)"}`,children:H?A+1:void 0},j));});}),v},h=()=>{let g=[],v=Math.max(4,Math.floor(c*.4)),R=Math.max(2,Math.floor(c*.2));if(D==="front"){if(y.length>0)return et(y,"front");if(n==="switch"&&(o.toLowerCase().includes("agg")||o.toLowerCase().includes("core")||s==="agg"||s==="core"))return _();g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-top",type:"target",position:reactflow.Position.Top,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(50%)"},title:"Network Port (Top)"},"net-top")),g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-bottom",type:"target",position:reactflow.Position.Bottom,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(-50%)"},title:"Network Port (Bottom)"},"net-bottom"));}else if(D==="rear"){if(f.length>0)return et(f,"rear");let rt=n==="switch",I=(n?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel";if(!I){let $=St(o),A=Rt($),H=ht($),j=c<=20?"10%":"25%";g.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-1",type:"target",position:reactflow.Position.Left,style:{width:`${H.width}px`,height:`${H.height}px`,background:H.color,border:`1px solid ${H.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:j,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:H.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:H.borderRadius,clipPath:H.clipPath},title:`Power Port 1 (${A.type}) - ${A.voltage}V, ${A.amperage}A`,children:"1"},"pwr-1"));let J=c<=20?"50%":"75%";g.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-2",type:"target",position:reactflow.Position.Left,style:{width:`${H.width}px`,height:`${H.height}px`,background:H.color,border:`1px solid ${H.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:J,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:H.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:H.borderRadius,clipPath:H.clipPath},title:`Power Port 2 (${A.type}) - ${A.voltage}V, ${A.amperage}A`,children:"2"},"pwr-2"));}!rt&&!I&&(g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-1",type:"target",position:reactflow.Position.Right,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"25%"},title:"Network Port 1 (Right)"},"net-right-1")),g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-2",type:"target",position:reactflow.Position.Right,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"75%"},title:"Network Port 2 (Right)"},"net-right-2")));}return g},_=()=>{let g=[],v=Math.max(10,Math.floor(c*.45)),R=Math.max(5,Math.floor(c*.25));for(let b=1;b<=16;b++){let I=jsxRuntime.jsx(reactflow.Handle,{id:`port-${b}`,type:"source",position:reactflow.Position.Top,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(50%)",zIndex:1e3,left:`${(b-1)*(v+2)}px`},title:`Port ${b}`},`port-${b}`);g.push(I);}for(let b=17;b<=32;b++){let I=b-16,$=jsxRuntime.jsx(reactflow.Handle,{id:`port-${b}`,type:"source",position:reactflow.Position.Bottom,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(-50%)",zIndex:1e3,left:`${(I-1)*(v+2)}px`},title:`Port ${b}`},`port-${b}`);g.push($);}for(let b=1;b<=4;b++){let I=Math.max(4,Math.floor(c*.3)),$=Math.max(3,Math.floor(c*.15));g.push(jsxRuntime.jsx(reactflow.Handle,{id:`uplink-${b}`,type:"source",position:reactflow.Position.Right,style:{width:`${I}px`,height:`${$}px`,background:"#8b5cf6",border:"0.5px solid #7c3aed",borderRadius:"0.5px",cursor:"pointer",transform:"translateX(-50%)"},title:`Uplink ${b}`},`uplink-${b}`));}return g};return jsxRuntime.jsxs("div",{className:`device-node ${e?"selected":""}`,style:{background:"#1f2937",border:`1px solid ${O(i)}`,borderRadius:"2px",padding:"0px",width:F,...X&&{left:X},height:`${c}px`,color:"white",fontFamily:"monospace",fontSize:"8px",boxShadow:e?"0 0 0 1px #3b82f6":"0 1px 2px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",justifyContent:"center",cursor:"grab",marginBottom:"0px",boxSizing:"border-box",marginTop:"0px",marginLeft:"0px",marginRight:"0px"},children:[jsxRuntime.jsxs("div",{style:{textAlign:"center",flex:1,display:"flex",flexDirection:"column",justifyContent:"center",overflow:"hidden",padding:"2px"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"7px",lineHeight:"1.1",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:o}),d>1&&jsxRuntime.jsx("div",{style:{fontSize:"6px",color:"#9ca3af",lineHeight:"1"},children:a})]}),d>1&&jsxRuntime.jsxs("div",{style:{position:"absolute",bottom:"1px",right:"1px",background:"#374151",color:"#9ca3af",padding:"1px 2px",borderRadius:"1px",fontSize:"6px",lineHeight:"1"},children:[d,"U"]}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"1px",left:"1px",width:"4px",height:"4px",background:O(i),borderRadius:"50%"}}),h()]})};var Ot=({data:t,selected:e,id:o})=>{let{label:i,status:n="active",heightCm:a=100,powerPorts:s=36,portTypes:d=[],widthPx:l=15,mgmt_unit:u}=t,y=D=>{switch(D){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},f=a*4.2,N=()=>{let E=Math.ceil(s/10),c=Array(10).fill(0).map((b,I)=>I<8?"10A":"16A");for(let b=0,I=0;b<E;++b)for(let $=0;$<10&&I<s;++$,++I){c[$];}let g=[],T=15,rt=(f-T-3)/(s-9)*.5;for(let b=0;b<s;b++){let I=T-2+rt*b,$=`${b+1}`;if(u&&(u==="top"&&b===0||u==="middle"&&b===Math.floor(s/2)||u==="bottom"&&b===s-1)){g.push(U(I));continue}let H=Lt(b),j=ht(H),J=Math.round((l-j.width)/2-1);g.push(jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:$,style:{position:"absolute",left:`${J}px`,top:`${I-j.height/2}px`,width:`${j.width}px`,height:`${j.height}px`,background:j.color,border:`1px solid ${j.borderColor}`,cursor:"pointer",zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:j.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:j.borderRadius,clipPath:j.clipPath},title:`Power Port ${b+1} (${H})`,children:b+1},`handle-${$}`));}return g},U=D=>jsxRuntime.jsxs("div",{style:{position:"absolute",left:`${(l-16)/2}px`,top:`${D-12/2}px`,width:"16px",height:"12px",background:"#1a1a1a",border:"1px solid #374151",borderRadius:"1px",display:"flex",flexDirection:"column",padding:"1px",zIndex:10},children:[jsxRuntime.jsx("div",{style:{position:"absolute",left:"-10px",top:"1px",background:"#ffffff",border:"0.5px solid #6b7280",borderRadius:"0.5px",width:"8px",height:"10px",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"3px",color:"#10b981",fontFamily:"monospace",fontWeight:"bold",transform:"rotate(90deg)",transformOrigin:"center"},children:"APC"}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:"mgmt-net-1",style:{width:"70%",height:"6px",background:"#10b981",border:"1px solid #059669",borderRadius:"1px",cursor:"pointer",zIndex:11,margin:"0 auto"},title:"Management Network Port"},"mgmt-net-1")]},"mgmt-unit");return jsxRuntime.jsxs("div",{className:`vertical-pdu-node ${e?"selected":""}`,style:{background:"linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",border:`1px solid ${y(n)}`,borderRadius:"2px",padding:0,width:`${l}px`,height:`${f}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:e?"0 0 0 2px #3b82f6":"0 1px 3px rgba(0,0,0,0.3)",position:"relative",display:"flex",flexDirection:"column"},children:[jsxRuntime.jsx("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)",padding:"2px",position:"relative",height:"20px",display:"flex",flexDirection:"column",justifyContent:"center",borderBottom:"1px solid #4a5568"},children:jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"6px",color:"#e2e8f0"},children:i})}),jsxRuntime.jsx("div",{style:{flex:1,background:"linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",position:"relative",minHeight:`${f-20}px`,overflow:"hidden"},children:N()})]})};function ze(t,e){if(!t.source||!t.target||!t.sourceHandle||!t.targetHandle)return {valid:true};let o=e.edges.some(c=>c.source===t.source&&c.sourceHandle===t.sourceHandle),i=e.edges.some(c=>c.target===t.target&&c.targetHandle===t.targetHandle);if(o)return {valid:false,reason:"Source port is already connected"};if(i)return {valid:false,reason:"Target port is already connected"};let n=t.sourceHandle,a=t.targetHandle,s=e.nodes.find(c=>c.id===t.source),d=e.nodes.find(c=>c.id===t.target),l=(c,F)=>{if(!c)return false;let X=c.startsWith("pwr")||c.startsWith("power"),O=F?.type==="vertical-pdu"&&c!=="mgmt-net-1";return X||O},u=(c,F)=>{if(!c)return false;if(F?.type==="vertical-pdu"&&c==="mgmt-net-1")return true;let X=c.startsWith("net-")||c.startsWith("port-")||c.startsWith("uplink-")||c.includes("Fiber")||c.includes("Ports"),O=/^[A-Z0-9]+-\d+$/.test(c)&&!c.startsWith("pwr")&&!c.startsWith("power");return X||O},y=l(n,s),f=l(a,d),N=u(n,s),U=u(a,d);if(y&&U||f&&N)return {valid:false,reason:"Cannot connect network cable to power port"};if(y&&!f||f&&!y)return {valid:false,reason:"Power ports must connect to power-compatible ports"};let D=s?.type==="vertical-pdu",E=d?.type==="vertical-pdu";if(y||f){let c=D?d:E?s:null,F=D?s:E?d:null;if(c&&F&&e.edges.filter(V=>{let et=l(V.sourceHandle||""),h=l(V.targetHandle||""),_=V.source===c.id||V.target===c.id;V.source===F.id||V.target===F.id;return (et||h)&&_}).some(V=>V.source===F.id||V.target===F.id))return {valid:false,reason:"Dual-feed required: connect second power to a different PDU"}}return {valid:true}}function Le(t,e){if(!e)return;let o=e.data??{},i=o.handleSideMap;if(i&&i[t])return i[t];if(t==="net-top"||t==="net-bottom")return "front";if(t==="pwr-left-1"||t==="pwr-left-2"||t==="net-right-1"||t==="net-right-2")return "rear";let n=Array.isArray(o.ports)?o.ports:[],a=Array.isArray(o.rearPorts)?o.rearPorts:[];if(t.startsWith("pwr")||t.includes("power"))return "rear";for(let d of n)for(let l of d.ports||[])if((!!l.type&&String(l.type).includes("power")?l.label:`${d.name}-${l.label}`)===t)return "front";for(let d of a)for(let l of d.ports||[])if((!!l.type&&String(l.type).includes("power")?l.label:`${d.name}-${l.label}`)===t)return "rear"}function Vt(t={},e={}){let o={nodes:t.nodes??[],edges:t.edges??[],debug:t.debug??false},i=new Set;return {getState:()=>o,setState:f=>{o={...o,...f},i.forEach(N=>N(o));},subscribe:f=>(i.add(f),()=>i.delete(f)),selectEdgeZIndex:f=>{let N=o.nodes.find(et=>et.id===f.target);if(!N||N.type!=="device")return 1e3;let U=N.data?.view||"front",D=Le(f.targetHandle||"",N);if(D)return U===D?1e3:500;let E=(f.targetHandle||"").toString(),c=E.toLowerCase(),F=c.startsWith("pwr")||c.startsWith("power"),X=c.startsWith("net-")||c.startsWith("port-")||c.startsWith("uplink-")||c.includes("fiber")||c.includes("ports"),O=/^[A-Z0-9]+-\d+$/i.test(E)&&!c.startsWith("pwr")&&!c.startsWith("power"),V=X||O;return F?U==="rear"?1e3:500:V?U==="front"?1e3:500:1e3},validateConnection:f=>(e.validateConnection||ze)(f,o),selectNodeById:f=>o.nodes.find(N=>N.id===f),selectConnectedEdges:f=>o.edges.filter(N=>N.source===f||N.target===f)}}function We(t){let e=n=>t.subscribe(n),o=()=>t.getState();return Be.useSyncExternalStore(e,o,o)}function Gt(t){let e=i=>t.subscribe(i),o=()=>t.getState().nodes;return Be.useSyncExternalStore(e,o,o)}function Yt(t){let e=i=>t.subscribe(i),o=()=>t.getState().edges;return Be.useSyncExternalStore(e,o,o)}function ne(t){return t.selectEdgeZIndex}var Je=(t,e,o)=>({rack:i=>jsxRuntime.jsx(It,{...i,onViewChange:t,onRackFaceChange:e,isDragOver:o===i.id}),fiber:At,device:Bt,"vertical-pdu":Ot}),Qe={fiber:Ft,power:Mt},to=({nodes:t,edges:e,initialNodes:o,initialEdges:i,onNodesChange:n,onEdgesChange:a,store:s,debug:d,onNodeClick:l,onEdgeClick:u,onViewChange:y,onRackFaceChange:f,className:N,style:U,alignRacksToBottom:D,colorMode:E="dark",onInit:c,onFlowMethods:F,showDownloadButton:X=false,downloadButtonPosition:O="top-right",downloadButtonText:V="Download Image",downloadButtonStyle:et})=>{let h=Array.isArray(t)&&Array.isArray(e),_=Be__default.default.useMemo(()=>s||Vt({nodes:h?t||[]:o||t||[],edges:h?e||[]:i||e||[],debug:d}),[s,h,d]),g=Gt(_),T=Yt(_),[v,R,rt]=reactflow.useNodesState(g),[b,I,$]=reactflow.useEdgesState(T),A=ne(_),H=Be.useRef(null),{toObject:j,setViewport:J}=reactflow.useReactFlow();Be.useEffect(()=>{F&&F({toObject:j,setViewport:J,toImage:r=>H.current?htmlToImage.toPng(H.current,r):Promise.reject(new Error("ReactFlow wrapper not available"))});},[F,j,J]);let B=Be.useCallback(()=>{if(!H.current){d&&console.error("ReactFlow wrapper ref is not available");return}htmlToImage.toPng(H.current,{filter:r=>!(r?.classList?.contains("react-flow__minimap")||r?.classList?.contains("react-flow__controls")||r?.classList?.contains("react-flow__attribution")||r?.classList?.contains("download-button")||r?.tagName==="BUTTON"),backgroundColor:E==="light"?"#ffffff":"#1a1a1a",pixelRatio:2}).then(r=>{let p=document.createElement("a");p.download=`network-diagram-${new Date().toISOString().split("T")[0]}.png`,p.href=r,p.click();}).catch(r=>{d&&console.error("Error downloading image:",r);});},[E]),[nt,M]=Be.useState(null),gt=Be.useMemo(()=>Je(y,f,nt),[y,f,nt]),Kt=Be.useMemo(()=>Qe,[]),st=Be.useRef(v);Be.useEffect(()=>{st.current=v;},[v]);let ot=Be.useRef(b);Be.useEffect(()=>{ot.current=b;},[b]),Be.useEffect(()=>{R(g);},[g,R]),Be.useEffect(()=>{I(T);},[T,I]),Be.useEffect(()=>{h&&_.setState({nodes:t||[]});},[h,t,_]),Be.useEffect(()=>{h&&_.setState({edges:e||[]});},[h,e,_]),Be.useEffect(()=>{if(!D||!v||v.length===0)return;let r=v.filter(w=>w.type==="rack");if(r.length===0)return;let p=r.map(w=>{let C=w.data&&w.data.uHeight||42,W=60+C*20;return (w.position?.y||0)+W}),m=Math.min(...p),x=Math.max(...p);if(x-m<20)return;let P=x,z=v.map(w=>{if(w.type!=="rack")return w;let C=w.data&&w.data.uHeight||42,W=60+C*20,Z=(w.position?.y||0)+W,G=P-Z;return Math.abs(G)<5?w:{...w,position:{x:w.position?.x||0,y:(w.position?.y||0)+G}}});z.some((w,C)=>w.position!==v[C].position)&&R(z);},[D,v,R]);let Q=Be.useCallback(r=>st.current.find(p=>p.id===r),[]);Be.useEffect(()=>{I(r=>r.map(p=>{let m=A(p);return {...p,zIndex:m,style:{...p.style,zIndex:m}}}));},[v,I,A]),Be.useEffect(()=>{let r=v.map(m=>{if(m.type==="device"&&m.parentId&&m.data.uPosition&&(!m.position||m.position.x===0&&m.position.y===0)){let x=Q(m.parentId);if(x){let k=mt(x,m.data.uPosition);return {...m,position:k}}}return m});r.some((m,x)=>m.position!==v[x].position)&&R(r);},[v,R,Q]);let lt=Be.useCallback(r=>{let p=r.map(m=>{if(m.type==="position"&&m.position){let x=Q(m.id);if(x&&x.type==="device"&&x.parentId){let k=Q(x.parentId);if(k){let P=Et(x,k,m.position,st.current);if(P.uPosition!==void 0){let z={...x,data:{...x.data,uPosition:P.uPosition}};R(S=>S.map(w=>w.id===x.id?z:w));}return {...m,position:{x:P.x,y:P.y}}}}if(x&&x.type==="device"&&x.parentId){let k=Q(x.parentId);if(k){let P=k,z=300,S=(P.data.uHeight||42)*20,w=P.position.x,C=P.position.x+z,W=P.position.y,Z=P.position.y+S;if(m.position.x<w||m.position.x>C||m.position.y<W||m.position.y>Z){let G=m.position.x+P.position.x,wt=m.position.y+P.position.y,xt={...x,parentId:void 0,extent:void 0,data:{...x.data,uPosition:void 0}};return R(Ne=>Ne.map(Jt=>Jt.id===x.id?xt:Jt)),{...m,position:{x:G,y:wt}}}}}}return m});rt(p);},[rt,R,Q]),ge=Be.useCallback((r,p)=>{M(null);},[]),fe=Be.useCallback((r,p,m)=>{if(p.type==="device"&&!p.parentId){let x=st.current.filter(z=>z.type==="rack"),k=null,P=1/0;for(let z of x){let S=z,w=Math.sqrt(Math.pow(p.position.x-S.position.x,2)+Math.pow(p.position.y-S.position.y,2)),C=300,W=(S.data.uHeight||42)*20,Z=S.position.x,G=S.position.x+C,wt=S.position.y,xt=S.position.y+W;p.position.x>=Z&&p.position.x<=G&&p.position.y>=wt&&p.position.y<=xt&&w<P&&(P=w,k=S);}M(k?k.id:null);}else M(null);},[]),me=Be.useCallback((r,p,m)=>{if(p.type==="device"&&!p.parentId){let x=st.current.filter(z=>z.type==="rack"),k=null,P=1/0;for(let z of x){let S=z,w=Math.sqrt(Math.pow(p.position.x-S.position.x,2)+Math.pow(p.position.y-S.position.y,2)),C=300,W=(S.data.uHeight||42)*20,Z=S.position.x,G=S.position.x+C,wt=S.position.y,xt=S.position.y+W;p.position.x>=Z&&p.position.x<=G&&p.position.y>=wt&&p.position.y<=xt&&w<P&&(P=w,k=S);}if(k){let z=p.position.x-k.position.x,S=p.position.y-k.position.y,w={...p,parentId:k.id,extent:"parent",position:{x:z,y:S},data:{...p.data,uPosition:1}};R(C=>C.map(W=>W.id===p.id?w:W));}}M(null);},[R]);Be.useCallback(r=>{if(!r.source||!r.target||!r.sourceHandle||!r.targetHandle)return {valid:true};let p=r.sourceHandle,m=r.targetHandle,x=ot.current.some(P=>P.source===r.source&&P.sourceHandle===p),k=ot.current.some(P=>P.target===r.target&&P.targetHandle===m);return x?{valid:false,reason:"Source port is already connected"}:k?{valid:false,reason:"Target port is already connected"}:{valid:true}},[]);let he=Be.useCallback(r=>{let p=Q(r.source),m=p?.type==="vertical-pdu",x=p?.type==="device"&&p.data?.deviceType==="switch",k=!!r.targetHandle&&(r.targetHandle.startsWith("pwr")||r.targetHandle.startsWith("power")),P=!!r.targetHandle&&(r.targetHandle.startsWith("net-")||r.targetHandle.startsWith("port-")||/^[A-Z0-9]+-\d+$/i.test(r.targetHandle));if(m&&k&&r.target&&r.targetHandle){let w=ot.current.find(C=>C.target===r.target&&C.targetHandle===r.targetHandle);if(w){let C={...r,type:"power",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}if(x&&P&&r.target&&r.targetHandle){let w=ot.current.find(C=>C.target===r.target&&C.targetHandle===r.targetHandle);if(w){let C={...r,type:"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}let z=_.validateConnection({source:r.source??null,target:r.target??null,sourceHandle:r.sourceHandle??null,targetHandle:r.targetHandle??null});if(!z.valid){if(m&&r.source&&r.sourceHandle){let w=ot.current.find(C=>C.source===r.source&&C.sourceHandle===r.sourceHandle);if(w){let C={...r,type:k?"power":"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}if(x&&r.source&&r.sourceHandle){let w=ot.current.find(C=>C.source===r.source&&C.sourceHandle===r.sourceHandle);if(w){let C={...r,type:"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}d&&console.warn(`Connection rejected: ${z.reason}`);return}let S={...r,type:m&&k?"power":"fiber",zIndex:A({...r,id:"temp-id"})};I(w=>reactflow.addEdge(S,w));},[I,_,A,Q]),ye=Be.useCallback((r,p)=>{if((r.metaKey||r.ctrlKey)&&p.type==="device"){let x=p.data||{},k=x.view||(Array.isArray(x.rearPorts)&&x.rearPorts.length>0?"rear":"front"),P=k==="front"?"rear":"front";d&&console.log(`Command+click: Toggling device ${p.id} from ${k} to ${P}`),y&&y(p.id,P),l&&l(p);}else l&&l(p);},[y,l,d]),be=Be.useCallback(()=>{},[]),we=Be.useCallback((r,p)=>{u&&u(p);},[u]),[L,qt]=Be.useState(null);reactflow.useOnSelectionChange({onChange:({nodes:r})=>{if(r&&r.length===1){let p=r[0];qt(p),l&&l(p);}else qt(null),l&&l(null);}});let xe=Be.useCallback(()=>{if(!L)return;let r=Q(L.id);if(r){if(r.type==="rack"){let m=(r.data&&r.data.face||"front")==="front"?"rear":"front";f?f(r.id,m):R(x=>x.map(k=>k.id===r.id?{...k,data:{...k.data,face:m}}:k.parentId===r.id?{...k,data:{...k.data,view:m}}:k));return}if(r.type==="device"){let p=r.data||{},m=Array.isArray(p.rearPorts)&&p.rearPorts.length>0,x=Array.isArray(p.ports)&&p.ports.length>0,P=(p.view||(m&&!x?"rear":"front"))==="front"?"rear":"front";y?y(r.id,P):R(z=>z.map(S=>S.id===r.id?{...S,data:{...S.data,view:P}}:S));}}},[L,Q,f,y,R]);return jsxRuntime.jsxs("div",{ref:H,className:`${N||""} ${E==="light"?"react-flow-light":"react-flow-dark"}`,style:{width:"100%",height:"100%",...U},children:[jsxRuntime.jsxs(reactflow.ReactFlow,{nodes:v,edges:b,onNodesChange:r=>{lt(r);r.reduce((m,x)=>(x.type==="add"||x.type==="remove",m),null);h?n&&n(st.current):_.setState({nodes:st.current});},onEdgesChange:r=>{$(r),h?a&&a(ot.current):_.setState({edges:ot.current});},onConnect:he,onNodeClick:ye,onNodeDoubleClick:be,onNodeDragStart:ge,onNodeDrag:fe,onNodeDragStop:me,onEdgeClick:we,onInit:c,nodeTypes:gt,edgeTypes:Kt,defaultEdgeOptions:{zIndex:1e3,reconnectable:true},nodesDraggable:true,nodesConnectable:true,elementsSelectable:true,selectNodesOnDrag:false,fitView:true,attributionPosition:"bottom-left",children:[jsxRuntime.jsx(reactflow.Background,{}),jsxRuntime.jsx(reactflow.Controls,{}),jsxRuntime.jsx(reactflow.MiniMap,{})]}),X&&jsxRuntime.jsx("button",{className:"download-button",onClick:B,style:{position:"absolute",top:O.includes("top")?"10px":"auto",bottom:O.includes("bottom")?"10px":"auto",right:O.includes("right")?"10px":"auto",left:O.includes("left")?"10px":"auto",zIndex:1e3,background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:"4px",padding:"0.5rem 0.75rem",fontSize:"0.875rem",cursor:"pointer",transition:"all 0.2s ease",...et},children:V}),L&&(L.type==="rack"||L.type==="device")&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,right:12,display:"flex",gap:8,zIndex:2e3},children:jsxRuntime.jsx("button",{onClick:r=>{r.preventDefault(),xe();},style:{background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:4,padding:"6px 10px",fontSize:11,fontFamily:"monospace",cursor:"pointer"},title:L.type==="rack"?(L.data?.face||"front")==="front"?"Switch to rear":"Switch to front":(L.data?.view||(Array.isArray(L.data?.rearPorts)&&L.data.rearPorts.length>0&&!(Array.isArray(L.data?.ports)&&L.data.ports.length>0)?"rear":"front"))==="front"?"Switch to rear":"Switch to front",children:L.type==="rack"?(L.data?.face||"front")==="front"?"\u21C4 Rear":"\u21C4 Front":(L.data?.view||(Array.isArray(L.data?.rearPorts)&&L.data.rearPorts.length>0&&!(Array.isArray(L.data?.ports)&&L.data.ports.length>0)?"rear":"front"))==="front"?"\u21C4 Rear":"\u21C4 Front"})})]})},eo=t=>jsxRuntime.jsx(reactflow.ReactFlowProvider,{children:jsxRuntime.jsx(to,{...t})});var de=t=>({id:`rack-${t.id}`,type:"rack",position:{x:0,y:0},data:{label:t.name,status:typeof t.status=="object"&&t.status?t.status.value:t.status,uHeight:t.u_height??t.units??42,inventoryId:t.id,inventoryType:"rack",facilityId:t.facility_id,serial:t.serial,assetTag:t.asset_tag,site:typeof t.site=="object"&&t.site?t.site.name:t.site,role:typeof t.role=="object"&&t.role?t.role.name:t.role,tenant:typeof t.tenant=="object"&&t.tenant?t.tenant.name:t.tenant}}),le=t=>({id:`device-${t.id}`,type:"device",position:{x:0,y:0},parentId:t.rack?`rack-${typeof t.rack=="object"&&t.rack?t.rack.id:t.rack}`:void 0,extent:t.rack?"parent":void 0,data:{label:t.name,status:typeof t.status=="object"&&t.status?t.status.value:t.status,deviceType:t.device_type?.model??t.model,manufacturer:t.device_type?.manufacturer?.name??t.manufacturer,role:typeof t.device_role=="object"&&t.device_role?t.device_role.name:t.role,uHeight:t.device_type?.u_height??t.u_height??1,uPosition:t.position||1,view:t.face||"front",inventoryId:t.id,inventoryType:"device",primaryIp4:typeof t.primary_ip4=="object"&&t.primary_ip4?t.primary_ip4.address:t.primary_ip4,primaryIp6:typeof t.primary_ip6=="object"&&t.primary_ip6?t.primary_ip6.address:t.primary_ip6,site:typeof t.site=="object"&&t.site?t.site.name:t.site,rack:typeof t.rack=="object"&&t.rack?t.rack.name:t.rack}}),pe=t=>{let e=n=>{if(!n)return;if(typeof n=="string")return n;let a=n.device;return typeof a=="object"&&a?a.id:a},o=e(t.termination_a),i=e(t.termination_b);return {id:`cable-${t.id}`,source:`device-${o}`,target:`device-${i}`,type:"fiber",data:{bandwidth:t.type?.label??t.bandwidth,length:t.length||0,color:t.color,inventoryId:t.id,inventoryType:"cable",status:typeof t.status=="object"&&t.status?t.status.value:t.status,terminationA:typeof t.termination_a=="object"&&t.termination_a?t.termination_a.name:t.termination_a,terminationB:typeof t.termination_b=="object"&&t.termination_b?t.termination_b.name:t.termination_b}}},oo=t=>{let e=[],o=[];return t.racks.forEach(i=>e.push(de(i))),t.devices.forEach(i=>e.push(le(i))),t.cables.forEach(i=>o.push(pe(i))),{nodes:e,edges:o}},ro=t=>{let e=t.filter(n=>n.type==="rack"),o=t.filter(n=>n.type==="device"),i=t.filter(n=>!["rack","device"].includes(n.type));return e.forEach((n,a)=>{n.position={x:a*300,y:100};}),o.forEach(n=>{if(n.parentId){let a=e.find(s=>s.id===n.parentId);if(a){let s=n.data.uPosition||1,d=n.data.uHeight||1;n.position={x:a.position.x+50,y:a.position.y+s*20-d*10};}}else n.position={x:Math.random()*400+100,y:Math.random()*200+50};}),i.forEach((n,a)=>{n.position={x:a*150+100,y:300};}),t};var bt=class extends Error{constructor(o,i,n,a,s){super(`Device placement conflict: ${i} at U${n}-${n+a-1} in rack ${o}${s?` conflicts with ${s}`:""}`);this.rackId=o;this.deviceId=i;this.uPosition=n;this.uHeight=a;this.conflictWith=s;this.name="DevicePlacementError";}};function Zt(t,e={}){let{conflictPolicy:o="strict"}=e,i=[],n=[];for(let a of t.devices)a.unit+a.height-1>t.units&&n.push({deviceId:a.id,uPosition:a.unit,uHeight:a.height,rackUHeight:t.units});for(let a=0;a<t.devices.length;a++){let s=t.devices[a],d=s.unit,l=s.unit+s.height-1;for(let u=a+1;u<t.devices.length;u++){let y=t.devices[u],f=y.unit,N=y.unit+y.height-1;d<=N&&l>=f&&i.push({deviceId:s.id,uPosition:s.unit,uHeight:s.height,conflictWith:y.id});}}return {isValid:i.length===0&&n.length===0,conflicts:i,outOfBounds:n}}function ue(t,e,o={}){let{deviceTypeMapping:i={}}=o,n=i[t.type]||"device",a=mt(e,t.unit,t.height);return {id:t.id,type:n,position:a,parentId:e.id,extent:"parent",data:{label:t.name,status:"active",deviceType:t.type,uHeight:t.height,uPosition:t.unit,width:t.width||"full",role:t.role,ports:t.ports,rearPorts:t.rearPorts,connections:t.connections}}}function no(t){return {id:t.id,type:"rack",position:t.position,data:{label:t.name,status:"active",uHeight:t.units,uNumberingDirection:t.uNumberingDirection||"bottom-up",customHeaderText:t.customHeaderText,ports:[]}}}function io(t,e={}){let{conflictPolicy:o="strict",validatePlacements:i=true}=e,n=[],a=[];if(i)for(let s of t){let d=Zt(s,e);if(!d.isValid&&o==="strict"){let l=[];throw d.conflicts.forEach(u=>{l.push(`Device ${u.deviceId} at U${u.uPosition}-${u.uPosition+u.uHeight-1} conflicts with ${u.conflictWith}`);}),d.outOfBounds.forEach(u=>{l.push(`Device ${u.deviceId} at U${u.uPosition}-${u.uPosition+u.uHeight-1} exceeds rack height (${u.rackUHeight}U)`);}),new bt(s.id,d.conflicts[0]?.deviceId||d.outOfBounds[0]?.deviceId||"unknown",d.conflicts[0]?.uPosition||d.outOfBounds[0]?.uPosition||1,d.conflicts[0]?.uHeight||d.outOfBounds[0]?.uHeight||1)}}for(let s of t){let d=no(s);n.push(d);for(let l of s.devices)try{let u=ue(l,d,e);a.push(u);}catch(u){if(o==="strict")throw u;if(o==="nearest"){let y=Dt(d,{id:l.id,data:{label:l.name,uHeight:l.height}},a,l.unit);if(y!==l.unit){console.warn(`Device ${l.id} moved from U${l.unit} to U${y} due to conflict`);let f={...l,unit:y},N=ue(f,d,e);a.push(N);}else throw new bt(s.id,l.id,l.unit,l.height)}}}return n.push(...a),n}function ao(t){let e=[],o=t.filter(i=>i.type==="rack");for(let i of o){let a=t.filter(s=>s.type==="device"&&s.parentId===i.id).map(s=>({id:s.id,name:s.data.label,unit:s.data.uPosition||1,height:s.data.uHeight||1,type:s.data.deviceType||"server",width:s.data.width,ports:s.data.ports,connections:s.data.connections}));e.push({id:i.id,name:i.data.label,position:i.position,units:i.data.uHeight||42,uNumberingDirection:i.data.uNumberingDirection||"bottom-up",customHeaderText:i.data.customHeaderText,devices:a});}return e}function so(t,e,o,i){return t.map(n=>n.id!==e?n:{...n,devices:n.devices.map(a=>a.id!==o?a:{...a,unit:i})})}function co(t,e,o,i={}){let{conflictPolicy:n="strict"}=i;return t.map(a=>{if(a.id!==e)return a;if(n==="strict"&&!Zt({...a,devices:[...a.devices,o]},i).isValid)throw new bt(e,o.id,o.unit,o.height);return {...a,devices:[...a.devices,o]}})}function lo(t,e,o){return t.map(i=>i.id!==e?i:{...i,devices:i.devices.filter(n=>n.id!==o)})}exports.DeviceNode=Bt;exports.DevicePlacementError=bt;exports.FiberEdge=Ft;exports.FiberNode=At;exports.NetworkDiagram=eo;exports.POWER_CONNECTORS=zt;exports.PowerEdge=Mt;exports.RackNode=It;exports.VerticalPDU=Ot;exports.Width=te;exports.addDeviceToRack=co;exports.buildNodesFromRackConfig=io;exports.calculateDevicePositionFromU=mt;exports.createNetworkDiagramStore=Vt;exports.createRackConfigFromNodes=ao;exports.findNextAvailableUPosition=Dt;exports.generateLayout=ro;exports.getConnectorConfig=Rt;exports.getDeviceConnectorType=St;exports.getPDUPortType=Lt;exports.getPowerPortStyle=ht;exports.inventoryCableToNetworkEdge=pe;exports.inventoryDeviceToNetworkNode=le;exports.inventoryRackToNetworkNode=de;exports.inventoryToNetworkDiagram=oo;exports.isHighPowerConnector=_e;exports.isUPositionAvailable=Tt;exports.removeDeviceFromRack=lo;exports.snapToUPosition=Et;exports.updateDeviceUPosition=Qt;exports.updateDeviceUPositionInSchema=so;exports.useDiagramEdges=Yt;exports.useDiagramNodes=Gt;exports.useNetworkDiagram=We;exports.validateAndSnapDevice=ve;exports.validateRackDevicePlacements=Zt;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map