{"version":3,"file":"index.umd.cjs","sources":["../src/utils/animation.ts","../src/utils/arrow.ts","../src/utils/layout.ts","../src/utils/cluster.ts","../src/utils/dom.ts","../src/utils/geometry.ts","../src/sizing/attribute.ts","../src/sizing/centrality.ts","../src/sizing/pageRank.ts","../src/sizing/nodeSizeProvider.ts","../src/utils/visibility.ts","../src/utils/graph.ts","../src/utils/paths.ts","../src/utils/position.ts","../src/utils/textMeasurement.ts","../src/store.ts","../src/CameraControls/useCameraControls.ts","../src/CameraControls/CameraControls.tsx","../src/CameraControls/utils.ts","../src/collapse/utils.ts","../src/collapse/useCollapse.ts","../src/CameraControls/useCenterGraph.ts","../src/symbols/Arrow.tsx","../src/utils/useDrag.ts","../src/utils/useHoverIntent.ts","../src/symbols/clusters/Ring.tsx","../src/symbols/Label.tsx","../src/symbols/Cluster.tsx","../src/symbols/edges/SelfLoop.tsx","../src/symbols/Line.tsx","../src/symbols/Edge.tsx","../src/symbols/edges/Edge.tsx","../src/symbols/edges/useEdgeAnimations.ts","../src/symbols/edges/useEdgeEvents.ts","../src/symbols/edges/useEdgeGeometry.ts","../src/symbols/edges/Edges.tsx","../src/symbols/nodes/Badge.tsx","../src/symbols/nodes/Icon.tsx","../src/symbols/Ring.tsx","../src/symbols/nodes/Sphere.tsx","../src/symbols/nodes/SphereWithIcon.tsx","../src/symbols/nodes/Svg.tsx","../src/symbols/nodes/SphereWithSvg.tsx","../src/symbols/Node.tsx","../src/layout/layoutUtils.ts","../src/layout/circular2d.ts","../src/layout/concentric2d.ts","../src/layout/custom.ts","../src/layout/depthUtils.ts","../src/layout/forceatlas2.ts","../src/layout/forceInABox.ts","../src/layout/forceUtils.ts","../src/layout/forceDirected.ts","../src/layout/hierarchical.ts","../src/layout/concentric3d.ts","../src/layout/nooverlap.ts","../src/layout/layoutProvider.ts","../src/layout/recommender.ts","../src/useGraph.ts","../src/utils/aggregateEdges.ts","../src/GraphScene.tsx","../src/selection/utils.ts","../src/selection/Lasso.tsx","../src/themes/darkTheme.ts","../src/themes/lightTheme.ts","../src/GraphCanvas/GraphCanvas.tsx","../src/RadialMenu/RadialSlice.tsx","../src/RadialMenu/utils.ts","../src/RadialMenu/RadialMenu.tsx","../src/selection/useSelection.ts"],"sourcesContent":["export const animationConfig = {\n  mass: 10,\n  tension: 1000,\n  friction: 300,\n  // Decreasing precision to improve performance from 0.00001\n  precision: 0.1\n};\n","import type { Curve, Vector3 } from 'three';\n\nimport type { EdgeArrowPosition } from '../symbols/Arrow';\n\n// Calculate the correct position for an arrow along a curve,\n// as well as the tangent to the curve at that point.\nexport function getArrowVectors(\n  placement: EdgeArrowPosition,\n  curve: Curve<Vector3>,\n  arrowLength: number\n): [Vector3, Vector3] {\n  const curveLength = curve.getLength();\n  const absSize = placement === 'end' ? curveLength : curveLength / 2;\n  const offset = placement === 'end' ? arrowLength / 2 : 0;\n  const u = (absSize - offset) / curveLength;\n\n  const position = curve.getPointAt(u);\n  const rotation = curve.getTangentAt(u);\n\n  return [position, rotation];\n}\n\nexport function getArrowSize(size: number): [number, number] {\n  return [size + 6, 2 + size / 1.5];\n}\n","import type { InternalGraphNode } from '../types';\n\nexport interface CenterPositionVector {\n  x: number;\n  y: number;\n  z: number;\n  minX: number;\n  maxX: number;\n  minY: number;\n  maxY: number;\n  minZ: number;\n  maxZ: number;\n  height: number;\n  width: number;\n}\n\n/**\n * Given a collection of nodes, get the center point.\n */\nexport function getLayoutCenter(\n  nodes: InternalGraphNode[]\n): CenterPositionVector {\n  let minX = Number.POSITIVE_INFINITY;\n  let maxX = Number.NEGATIVE_INFINITY;\n  let minY = Number.POSITIVE_INFINITY;\n  let maxY = Number.NEGATIVE_INFINITY;\n  let minZ = Number.POSITIVE_INFINITY;\n  let maxZ = Number.NEGATIVE_INFINITY;\n\n  for (const node of nodes) {\n    minX = Math.min(minX, node.position.x);\n    maxX = Math.max(maxX, node.position.x);\n    minY = Math.min(minY, node.position.y);\n    maxY = Math.max(maxY, node.position.y);\n    minZ = Math.min(minZ, node.position.z);\n    maxZ = Math.max(maxZ, node.position.z);\n  }\n\n  return {\n    height: maxY - minY,\n    width: maxX - minX,\n    minX,\n    maxX,\n    minY,\n    maxY,\n    minZ,\n    maxZ,\n    x: (maxX + minX) / 2,\n    y: (maxY + minY) / 2,\n    z: (maxZ + minZ) / 2\n  };\n}\n","import type { InternalGraphNode } from '../types';\nimport type { CenterPositionVector } from './layout';\nimport { getLayoutCenter } from './layout';\n\n/**\n * Given nodes and a attribute, find all the cluster groups.\n */\nexport function buildClusterGroups(\n  nodes: InternalGraphNode[],\n  clusterAttribute?: string\n) {\n  if (!clusterAttribute) {\n    return new Map();\n  }\n\n  return nodes.reduce((entryMap, e) => {\n    const val = e.data[clusterAttribute];\n    if (val) {\n      entryMap.set(val, [...(entryMap.get(val) || []), e]);\n    }\n    return entryMap;\n  }, new Map());\n}\n\nexport interface CalculateClustersInput {\n  /**\n   * The nodes to calculate clusters for.\n   */\n  nodes: InternalGraphNode[];\n  /**\n   * The attribute to use for clustering.\n   */\n  clusterAttribute?: string;\n}\n\nexport interface ClusterGroup {\n  /**\n   * Nodes in the cluster.\n   */\n  nodes: InternalGraphNode[];\n\n  /**\n   * Center position of the cluster.\n   */\n  position: CenterPositionVector;\n\n  /**\n   * Label of the cluster.\n   */\n  label: string;\n}\n\n/**\n * Builds the cluster map.\n *\n * This function:\n *  - Builds the cluster groups\n *  - Calculates the center position of each cluster group\n *  - Creates a cluster object for each group\n */\nexport function calculateClusters({\n  nodes,\n  clusterAttribute\n}: CalculateClustersInput) {\n  const result = new Map<string, ClusterGroup>();\n\n  if (clusterAttribute) {\n    const groups = buildClusterGroups(nodes, clusterAttribute);\n    for (const [key, nodes] of groups) {\n      const position = getLayoutCenter(nodes);\n      result.set(key, {\n        label: key,\n        nodes,\n        position\n      });\n    }\n  }\n\n  return result;\n}\n","/**\n * Check if an element is not editable (input, select, textarea, contentEditable).\n * @param element - The element to check\n * @returns True if the element is not editable, false otherwise\n */\nexport const isNotEditableElement = (element: HTMLElement) => {\n  return (\n    element.tagName !== 'INPUT' &&\n    element.tagName !== 'SELECT' &&\n    element.tagName !== 'TEXTAREA' &&\n    !element.isContentEditable\n  );\n};\n","import type { Color, Curve, Vector3 } from 'three';\nimport {\n  BoxGeometry,\n  BufferGeometry,\n  CatmullRomCurve3,\n  Float32BufferAttribute,\n  TubeGeometry\n} from 'three';\nimport { mergeBufferGeometries } from 'three-stdlib';\n\n/**\n * Create a null geometry with consistent attributes\n * @returns A BufferGeometry with a null appearance\n */\nexport const createNullGeometry = (): BufferGeometry => {\n  const nullGeom = new BoxGeometry(0, 0, 0);\n  // Add color attribute to match other geometries\n  const vertexCount = nullGeom.attributes.position.count;\n  const colorArray = new Float32Array(vertexCount * 3);\n  for (let i = 0; i < vertexCount; i++) {\n    colorArray[i * 3] = 1; // white\n    colorArray[i * 3 + 1] = 1;\n    colorArray[i * 3 + 2] = 1;\n  }\n  nullGeom.setAttribute('color', new Float32BufferAttribute(colorArray, 3));\n\n  return nullGeom;\n};\n\n/**\n * Add a color attribute to a geometry\n * @param geometry - The geometry to add the color attribute to\n * @param color - The color to add to the geometry\n */\nexport const addColorAttribute = (\n  geometry: BufferGeometry,\n  color: Color\n): void => {\n  const vertexCount = geometry.attributes.position.count;\n  const colorArray = new Float32Array(vertexCount * 3);\n  for (let i = 0; i < vertexCount; i++) {\n    colorArray[i * 3] = color.r;\n    colorArray[i * 3 + 1] = color.g;\n    colorArray[i * 3 + 2] = color.b;\n  }\n  geometry.setAttribute('color', new Float32BufferAttribute(colorArray, 3));\n};\n\n/**\n * Create actual dashed geometry with gaps by making multiple small tube segments\n * @param curve - The curve to create a dashed geometry from\n * @param radius - The radius of the tube\n * @param color - The color of the tube\n * @param dashArray - The dash array [dashSize, gapSize]\n * @returns A BufferGeometry with a dashed appearance\n */\nexport const createDashedGeometry = (\n  curve: Curve<Vector3>,\n  radius: number,\n  color: Color,\n  dashArray: [number, number] = [3, 1]\n): BufferGeometry => {\n  const [dashSize, gapSize] = dashArray;\n  const totalSize = dashSize + gapSize;\n  const curveLength = curve.getLength();\n\n  // Calculate number of dashes based on curve length\n  const numDashes = Math.max(3, Math.floor(curveLength / totalSize));\n  const segments: BufferGeometry[] = [];\n\n  for (let i = 0; i < numDashes; i++) {\n    const startT = i / numDashes;\n    const endT = startT + dashSize / totalSize / numDashes;\n\n    if (endT > startT && startT < 1) {\n      // Create points for this dash segment\n      const points = [];\n      const segmentSteps = Math.max(3, Math.floor(8 * (endT - startT))); // More points for longer segments\n\n      for (let j = 0; j <= segmentSteps; j++) {\n        const t = startT + (endT - startT) * (j / segmentSteps);\n        if (t <= 1) {\n          points.push(curve.getPointAt(t));\n        }\n      }\n\n      if (points.length >= 2) {\n        // Create a curve from these points\n        const segmentCurve = new CatmullRomCurve3(points);\n        const segmentGeometry = new TubeGeometry(\n          segmentCurve,\n          Math.max(2, points.length - 1),\n          radius,\n          5,\n          false\n        );\n\n        // Add color to this segment\n        addColorAttribute(segmentGeometry, color);\n        segments.push(segmentGeometry);\n      }\n    }\n  }\n\n  return segments.length > 0\n    ? mergeBufferGeometries(segments)\n    : new BufferGeometry();\n};\n","import type { SizingStrategy, SizingStrategyInputs } from './types';\n\nexport function attributeSizing({\n  graph,\n  attribute,\n  defaultSize\n}: SizingStrategyInputs): SizingStrategy {\n  const map = new Map();\n\n  if (attribute) {\n    graph.forEachNode((id, node) => {\n      const size = node.data?.[attribute];\n      if (isNaN(size)) {\n        console.warn(`Attribute ${size} is not a number for node ${node.id}`);\n      }\n\n      map.set(id, size || 0);\n    });\n  } else {\n    console.warn('Attribute sizing configured but no attribute provided');\n  }\n\n  return {\n    getSizeForNode: (nodeId: string) => {\n      if (!attribute || !map) {\n        return defaultSize;\n      }\n\n      return map.get(nodeId);\n    }\n  };\n}\n","import { degreeCentrality } from 'graphology-metrics/centrality/degree.js';\n\nimport type { SizingStrategy, SizingStrategyInputs } from './types';\n\nexport function centralitySizing({\n  graph\n}: SizingStrategyInputs): SizingStrategy {\n  const ranks = degreeCentrality(graph);\n\n  return {\n    ranks,\n    getSizeForNode: (nodeID: string) => ranks[nodeID] * 20\n  };\n}\n","import pagerank from 'graphology-metrics/centrality/pagerank.js';\n\nimport type { SizingStrategy, SizingStrategyInputs } from './types';\n\nexport function pageRankSizing({\n  graph\n}: SizingStrategyInputs): SizingStrategy {\n  const ranks = pagerank(graph);\n\n  return {\n    ranks,\n    getSizeForNode: (nodeID: string) => ranks[nodeID] * 80\n  };\n}\n","import { scaleLinear } from 'd3-scale';\n\nimport { attributeSizing } from './attribute';\nimport { centralitySizing } from './centrality';\nimport { pageRankSizing } from './pageRank';\nimport type { SizingStrategyInputs } from './types';\n\nexport type SizingType =\n  | 'none'\n  | 'pagerank'\n  | 'centrality'\n  | 'attribute'\n  | 'default';\n\nexport interface NodeSizeProviderInputs extends SizingStrategyInputs {\n  /**\n   * The sizing strategy to use.\n   */\n  type: SizingType;\n}\n\nconst providers = {\n  pagerank: pageRankSizing,\n  centrality: centralitySizing,\n  attribute: attributeSizing,\n  none: ({ defaultSize }: SizingStrategyInputs) => ({\n    getSizeForNode: (_id: string) => defaultSize\n  })\n};\n\nexport function nodeSizeProvider({ type, ...rest }: NodeSizeProviderInputs) {\n  const provider = providers[type]?.(rest);\n  if (!provider && type !== 'default') {\n    throw new Error(`Unknown sizing strategy: ${type}`);\n  }\n\n  const { graph, minSize, maxSize } = rest;\n  const sizes = new Map();\n  let min;\n  let max;\n\n  graph.forEachNode((id, node) => {\n    let size;\n    if (type === 'default') {\n      size = node.size || rest.defaultSize;\n    } else {\n      size = provider.getSizeForNode(id);\n    }\n\n    if (min === undefined || size < min) {\n      min = size;\n    }\n\n    if (max === undefined || size > max) {\n      max = size;\n    }\n\n    sizes.set(id, size);\n  });\n\n  // Relatively scale the sizes\n  if (type !== 'none') {\n    const scale = scaleLinear()\n      .domain([min, max])\n      .rangeRound([minSize, maxSize]);\n\n    for (const [nodeId, size] of sizes) {\n      sizes.set(nodeId, scale(size));\n    }\n  }\n\n  return sizes;\n}\n","import type { PerspectiveCamera } from 'three';\n\nimport type { EdgeLabelPosition } from '../symbols';\n\nexport type LabelVisibilityType = 'all' | 'auto' | 'none' | 'nodes' | 'edges';\n\ninterface CalcLabelVisibilityArgs {\n  nodeCount: number;\n  nodePosition?: { x: number; y: number; z: number };\n  labelType: LabelVisibilityType;\n  camera?: PerspectiveCamera;\n}\n\nexport function calcLabelVisibility({\n  nodePosition,\n  labelType,\n  camera\n}: CalcLabelVisibilityArgs) {\n  return (shape: 'node' | 'edge', size: number) => {\n    const isAlwaysVisible =\n      labelType === 'all' ||\n      (labelType === 'nodes' && shape === 'node') ||\n      (labelType === 'edges' && shape === 'edge');\n\n    if (\n      !isAlwaysVisible &&\n      camera &&\n      nodePosition &&\n      camera?.position?.z / camera?.zoom - nodePosition?.z > 6000\n    ) {\n      return false;\n    }\n\n    if (isAlwaysVisible) {\n      return true;\n    } else if (labelType === 'auto' && shape === 'node') {\n      if (size > 7) {\n        return true;\n      } else if (\n        camera &&\n        nodePosition &&\n        camera.position.z / camera.zoom - nodePosition.z < 3000\n      ) {\n        return true;\n      }\n    }\n\n    return false;\n  };\n}\n\nexport function getLabelOffsetByType(\n  offset: number,\n  position: EdgeLabelPosition\n): number {\n  switch (position) {\n    case 'above':\n      return offset;\n    case 'below':\n      return -offset;\n    case 'inline':\n    case 'natural':\n    default:\n      return 0;\n  }\n}\n\nexport const isServerRender = typeof window === 'undefined';\n","import type Graph from 'graphology';\n\nimport type { LayoutStrategy } from '../layout';\nimport type { SizingType } from '../sizing';\nimport { nodeSizeProvider } from '../sizing';\nimport type {\n  GraphEdge,\n  GraphNode,\n  InternalGraphEdge,\n  InternalGraphNode\n} from '../types';\nimport type { LabelVisibilityType } from './visibility';\nimport { calcLabelVisibility } from './visibility';\n\n/**\n * Initialize the graph with the nodes/edges.\n */\nexport function buildGraph(\n  graph: Graph,\n  nodes: GraphNode[],\n  edges: GraphEdge[]\n) {\n  // TODO: We probably want to make this\n  // smarter and only add/remove nodes\n  graph.clear();\n\n  const addedNodes = new Set<string>();\n\n  for (const node of nodes) {\n    try {\n      if (!addedNodes.has(node.id)) {\n        graph.addNode(node.id, node);\n        addedNodes.add(node.id);\n      }\n    } catch (e) {\n      console.error(`[Graph] Error adding node '${node.id}`, e);\n    }\n  }\n\n  for (const edge of edges) {\n    if (!addedNodes.has(edge.source) || !addedNodes.has(edge.target)) {\n      continue;\n    }\n\n    try {\n      graph.addEdge(edge.source, edge.target, edge);\n    } catch (e) {\n      console.error(\n        `[Graph] Error adding edge '${edge.source} -> ${edge.target}`,\n        e\n      );\n    }\n  }\n\n  return graph;\n}\n\ninterface TransformGraphInput {\n  graph: Graph;\n  layout: LayoutStrategy;\n  sizingType?: SizingType;\n  labelType?: LabelVisibilityType;\n  sizingAttribute?: string;\n  minNodeSize?: number;\n  maxNodeSize?: number;\n  defaultNodeSize?: number;\n  clusterAttribute?: string;\n}\n\n/**\n * Transform the graph into a format that is easier to work with.\n */\nexport function transformGraph({\n  graph,\n  layout,\n  sizingType,\n  labelType,\n  sizingAttribute,\n  defaultNodeSize,\n  minNodeSize,\n  maxNodeSize,\n  clusterAttribute\n}: TransformGraphInput) {\n  const nodes: InternalGraphNode[] = [];\n  const edges: InternalGraphEdge[] = [];\n  const map = new Map<string, InternalGraphNode>();\n\n  const sizes = nodeSizeProvider({\n    graph,\n    type: sizingType,\n    attribute: sizingAttribute,\n    minSize: minNodeSize,\n    maxSize: maxNodeSize,\n    defaultSize: defaultNodeSize\n  });\n\n  const nodeCount = graph.nodes().length;\n  const checkVisibility = calcLabelVisibility({ nodeCount, labelType });\n\n  graph.forEachNode((id, node) => {\n    const position = layout.getNodePosition(id);\n    const { data, fill, icon, label, size, ...rest } = node;\n    const nodeSize = sizes.get(node.id);\n    const labelVisible = checkVisibility('node', nodeSize);\n\n    const nodeLinks = graph.inboundNeighbors(node.id) || [];\n    const parents = nodeLinks.map(n => graph.getNodeAttributes(n));\n\n    const n: InternalGraphNode = {\n      ...(node as any),\n      size: nodeSize,\n      labelVisible,\n      label,\n      icon,\n      fill,\n      cluster: clusterAttribute ? data[clusterAttribute] : undefined,\n      parents,\n      data: {\n        ...rest,\n        ...(data ?? {})\n      },\n      position: {\n        ...position,\n        x: position.x || 0,\n        y: position.y || 0,\n        z: position.z || 1\n      }\n    };\n\n    map.set(node.id, n);\n    nodes.push(n);\n  });\n\n  graph.forEachEdge((_id, link) => {\n    const from = map.get(link.source);\n    const to = map.get(link.target);\n\n    if (from && to) {\n      const { data, id, label, size, ...rest } = link;\n      const labelVisible = checkVisibility('edge', size);\n\n      // TODO: Fix type\n      edges.push({\n        ...link,\n        id,\n        label,\n        labelVisible,\n        size,\n        data: {\n          ...rest,\n          id,\n          ...(data || {})\n        }\n      } as any);\n    }\n  });\n\n  return {\n    nodes,\n    edges\n  };\n}\n","import type Graph from 'graphology';\nimport { bidirectional } from 'graphology-shortest-path';\n\nexport function findPath(graph: Graph, source: string, target: string) {\n  return bidirectional(graph, source, target);\n}\n","import type { EdgeSubLabelPosition } from 'symbols/Edge';\nimport type { Curve } from 'three';\nimport {\n  CatmullRomCurve3,\n  LineCurve3,\n  QuadraticBezierCurve3,\n  Vector3\n} from 'three';\n\nimport type { InternalGraphNode, InternalVector3 } from '../types';\n\nconst MULTI_EDGE_OFFSET_FACTOR = 0.7;\n\n/**\n * Get the midpoint given two points.\n */\nexport function getMidPoint(\n  from: InternalVector3,\n  to: InternalVector3,\n  offset = 0\n) {\n  const fromVector = new Vector3(from.x, from.y || 0, from.z || 0);\n  const toVector = new Vector3(to.x, to.y || 0, to.z || 0);\n  const midVector = new Vector3()\n    .addVectors(fromVector, toVector)\n    .divideScalar(2);\n\n  return midVector.setLength(midVector.length() + offset);\n}\n\n/**\n * Calculate the center for a quadratic bezier curve.\n *\n * 1) Find the point halfway between the start and end points of the desired curve\n * 2) Find the vector pependicular to that point\n * 3) Find the point 1/4 the distance between start and end along that vector.\n */\nexport function getCurvePoints(\n  from: Vector3,\n  to: Vector3,\n  offset = -1\n): [Vector3, Vector3, Vector3] {\n  const fromVector = from.clone();\n  const toVector = to.clone();\n  const v = new Vector3().subVectors(toVector, fromVector);\n  const vlen = v.length();\n  const vn = v.clone().normalize();\n  const vv = new Vector3().subVectors(toVector, fromVector).divideScalar(2);\n  const k = Math.abs(vn.x) % 1;\n  const b = new Vector3(-vn.y, vn.x - k * vn.z, k * vn.y).normalize();\n  const vm = new Vector3()\n    .add(fromVector)\n    .add(vv)\n    .add(b.multiplyScalar(vlen / 4).multiplyScalar(offset));\n\n  return [from, vm, to];\n}\n\n/**\n * Get the curve given two points.\n */\nexport function getCurve(\n  from: Vector3,\n  fromOffset: number,\n  to: Vector3,\n  toOffset: number,\n  curved: boolean,\n  curveOffset?: number\n): Curve<Vector3> {\n  const offsetFrom = getPointBetween(from, to, fromOffset);\n  const offsetTo = getPointBetween(to, from, toOffset);\n  return curved\n    ? new QuadraticBezierCurve3(\n        ...getCurvePoints(offsetFrom, offsetTo, curveOffset)\n      )\n    : new LineCurve3(offsetFrom, offsetTo);\n}\n\n/**\n * Get the curve for a self-loop.\n */\nexport function getSelfLoopCurve(from: InternalGraphNode) {\n  const nodePosition = getVector(from);\n  const loopRadius = from.size;\n  const angle = Math.PI / 2; // 90 degrees on top of the node\n\n  const loopCenter = nodePosition\n    .clone()\n    .add(\n      new Vector3(\n        loopRadius * Math.cos(angle),\n        loopRadius * 1.3 * Math.sin(angle),\n        0\n      )\n    );\n\n  // Create selfLoopCurve\n  const numPoints = 10; // Use more points for smoother curve\n  const points: Vector3[] = [];\n\n  for (let i = 0; i < numPoints; i++) {\n    const theta = (i / numPoints) * 2 * Math.PI;\n    points.push(\n      loopCenter\n        .clone()\n        .add(\n          new Vector3(\n            loopRadius * Math.cos(theta),\n            loopRadius * Math.sin(theta),\n            0\n          )\n        )\n    );\n  }\n  const selfLoopCurve = new CatmullRomCurve3(points, true);\n\n  return selfLoopCurve;\n}\n\n/**\n * Create a threejs vector for a node.\n */\nexport function getVector(node: InternalGraphNode): Vector3 {\n  return new Vector3(node.position.x, node.position.y, node.position.z || 0);\n}\n\n/**\n * Get the point between two vectors.\n */\nfunction getPointBetween(from: Vector3, to: Vector3, offset: number): Vector3 {\n  const distance = from.distanceTo(to);\n  return from.clone().add(\n    to\n      .clone()\n      .sub(from)\n      .multiplyScalar(offset / distance)\n  );\n}\n\n/**\n * Given a node and a new vector set, update the node model.\n */\nexport function updateNodePosition(node: InternalGraphNode, offset: Vector3) {\n  return {\n    ...node,\n    position: {\n      ...node.position,\n      x: node.position.x + offset.x,\n      y: node.position.y + offset.y,\n      z: node.position.z + offset.z\n    }\n  };\n}\n\n/**\n * Calculate the curve offset for an edge.\n * This is used to offset edges that are parallel to each other (same source and same target).\n * This will return a curveOffset of null if the edge is not parallel to any other edges.\n */\nexport function calculateEdgeCurveOffset({ edge, edges, curved }) {\n  let updatedCurved = curved;\n  let curveOffset: number;\n\n  const parallelEdges = edges\n    .filter(e => e.target === edge.target && e.source === edge.source)\n    .map(e => e.id);\n\n  if (parallelEdges.length > 1) {\n    updatedCurved = true;\n    const edgeIndex = parallelEdges.indexOf(edge.id);\n\n    // Progressive distribution with unique magnitude for each edge\n    // This prevents overlapping by ensuring each edge has sufficient separation\n    const offsetMultiplier = edgeIndex === 0 ? 1 : 1 + edgeIndex * 0.8;\n    const side = edgeIndex % 2 === 0 ? 1 : -1;\n    const magnitude = MULTI_EDGE_OFFSET_FACTOR * offsetMultiplier;\n    curveOffset = side * magnitude;\n  }\n\n  if (edge.data?.isAggregated && edges.length > 1) {\n    const edgeIndex = parallelEdges.indexOf(edge.id);\n    return {\n      curved: true,\n      curveOffset:\n        edgeIndex === 0 ? MULTI_EDGE_OFFSET_FACTOR : -MULTI_EDGE_OFFSET_FACTOR\n    };\n  }\n\n  return { curved: updatedCurved, curveOffset };\n}\n\n/**\n * Calculate the offset position for a subLabel based on edge orientation and placement preference\n *\n * @param fromPosition - Position of the source node\n * @param toPosition - Position of the target node\n * @param subLabelPlacement - Whether to place the subLabel 'above' or 'below' the edge\n * @returns Object with x, y offset values for positioning the subLabel perpendicular to the edge\n *\n * The function calculates a perpendicular offset from the edge line, with the direction\n * determined by both the subLabelPlacement ('above' or 'below') and the edge direction.\n * The perpendicular angle is calculated differently based on whether the edge is going\n * left-to-right or right-to-left to maintain consistent 'above'/'below' positioning.\n */\nexport function calculateSubLabelOffset(\n  fromPosition: { x: number; y: number },\n  toPosition: { x: number; y: number },\n  subLabelPlacement?: EdgeSubLabelPosition\n): { x: number; y: number; z: number } {\n  // Calculate direction vector between nodes\n  const dx = toPosition.x - fromPosition.x;\n  const dy = toPosition.y - fromPosition.y;\n\n  // Get angle of the edge\n  const angle = Math.atan2(dy, dx);\n\n  // Calculate perpendicular angle based on edge direction and subLabelPlacement\n  const perpAngle =\n    subLabelPlacement === 'above'\n      ? dx >= 0\n        ? angle + Math.PI / 2\n        : angle - Math.PI / 2\n      : dx >= 0\n        ? angle - Math.PI / 2\n        : angle + Math.PI / 2;\n\n  // Offset distance for subLabel\n  const offsetDistance = 7;\n\n  // Calculate offset using perpendicular angle\n  const offsetX = Math.cos(perpAngle) * offsetDistance;\n  const offsetY = Math.sin(perpAngle) * offsetDistance;\n\n  return { x: offsetX, y: offsetY, z: 0 };\n}\n","export interface TextDimensions {\n  width: number;\n  height: number;\n}\n\nexport interface TextMeasurementOptions {\n  text: string;\n  fontSize: number;\n  fontWeight?: number;\n  fontFamily?: string;\n}\n\n// Cache to avoid repeated measurements\nconst measurementCache = new Map<string, TextDimensions>();\n\n// Reusable canvas context for measurements\nlet canvasContext: CanvasRenderingContext2D | null = null;\n\n/**\n * Get or create a canvas context for text measurements.\n */\nfunction getCanvasContext(): CanvasRenderingContext2D {\n  if (!canvasContext) {\n    const canvas = document.createElement('canvas');\n    canvasContext = canvas.getContext('2d');\n\n    if (!canvasContext) {\n      throw new Error('Failed to create canvas context for text measurement');\n    }\n  }\n\n  return canvasContext;\n}\n\n/**\n * Generate a cache key from measurement options.\n */\nfunction getCacheKey(options: TextMeasurementOptions): string {\n  const {\n    text,\n    fontSize,\n    fontWeight = 400,\n    fontFamily = 'sans-serif'\n  } = options;\n  return `${text}|${fontSize}|${fontWeight}|${fontFamily}`;\n}\n\n/**\n * Measure text dimensions using Canvas API.\n * Results are cached for performance.\n *\n * @param options - Text measurement options\n * @returns Text dimensions (width and height)\n */\nexport function measureText(options: TextMeasurementOptions): TextDimensions {\n  const cacheKey = getCacheKey(options);\n\n  // Return cached result if available\n  const cached = measurementCache.get(cacheKey);\n  if (cached) {\n    return cached;\n  }\n\n  const {\n    text,\n    fontSize,\n    fontWeight = 400,\n    fontFamily = 'sans-serif'\n  } = options;\n\n  try {\n    const context = getCanvasContext();\n\n    // Set font properties\n    context.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n\n    // Measure text\n    const metrics = context.measureText(text);\n\n    // Calculate dimensions\n    const dimensions: TextDimensions = {\n      width: metrics.width,\n      // Use actual bounding box height if available, otherwise estimate from font size\n      height:\n        metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent ||\n        fontSize * 1.2\n    };\n\n    // Cache the result\n    measurementCache.set(cacheKey, dimensions);\n\n    return dimensions;\n  } catch (error) {\n    console.warn('Failed to measure text, falling back to estimation:', error);\n\n    // Fallback to estimation if measurement fails\n    const fallback: TextDimensions = {\n      width: text.length * fontSize * 0.6,\n      height: fontSize * 1.2\n    };\n\n    return fallback;\n  }\n}\n\n/**\n * Clear the measurement cache.\n * Useful for testing or memory management.\n */\nexport function clearMeasurementCache(): void {\n  measurementCache.clear();\n}\n\n/**\n * Get the current cache size.\n */\nexport function getMeasurementCacheSize(): number {\n  return measurementCache.size;\n}\n","import Graph from 'graphology';\nimport type { FC, ReactNode } from 'react';\nimport { createContext, useContext } from 'react';\nimport React from 'react';\nimport type { BufferGeometry, Mesh } from 'three';\nimport { Vector3 } from 'three';\nimport type { StoreApi } from 'zustand';\nimport { create, useStore as useZustandStore } from 'zustand';\nimport { useShallow } from 'zustand/shallow';\n\nimport type { Theme } from './themes';\nimport type {\n  InternalGraphEdge,\n  InternalGraphNode,\n  InternalGraphPosition\n} from './types';\nimport type { CenterPositionVector, ClusterGroup } from './utils';\nimport { getLayoutCenter, getVector, updateNodePosition } from './utils';\nimport { isServerRender } from './utils/visibility';\n\nexport type DragReferences = {\n  [key: string]: InternalGraphNode;\n};\n\nexport interface GraphState {\n  nodes: InternalGraphNode[];\n  edges: InternalGraphEdge[];\n  graph: Graph;\n  clusters: Map<string, ClusterGroup>;\n  collapsedNodeIds?: string[];\n  centerPosition?: CenterPositionVector;\n  actives?: string[];\n  selections?: string[];\n  // The node that is currently hovered, used to disable cluster dragging\n  hoveredNodeId?: string;\n  // The edges that are currently hovered over, required for cases when animation is disabled\n  hoveredEdgeIds?: string[];\n  edgeContextMenus?: Set<string>;\n  setEdgeContextMenus: (edges: Set<string>) => void;\n  edgeMeshes: Array<Mesh<BufferGeometry>>;\n  setEdgeMeshes: (edgeMeshes: Array<Mesh<BufferGeometry>>) => void;\n  draggingIds?: string[];\n  drags?: DragReferences;\n  panning?: boolean;\n  theme: Theme;\n  setTheme: (theme: Theme) => void;\n  setClusters: (clusters: Map<string, ClusterGroup>) => void;\n  setPanning: (panning: boolean) => void;\n  setDrags: (drags: DragReferences) => void;\n  addDraggingId: (id: string) => void;\n  removeDraggingId: (id: string) => void;\n  setActives: (actives: string[]) => void;\n  setSelections: (selections: string[]) => void;\n  setHoveredNodeId: (hoveredNodeId: string | null) => void;\n  setHoveredEdgeIds: (hoveredEdgeIds: string[] | null) => void;\n  setNodes: (nodes: InternalGraphNode[]) => void;\n  setEdges: (edges: InternalGraphEdge[]) => void;\n  setNodePosition: (id: string, position: InternalGraphPosition) => void;\n  setCollapsedNodeIds: (nodeIds: string[]) => void;\n  setClusterPosition: (id: string, position: CenterPositionVector) => void;\n}\n\n// Create a store factory function\nexport const createStore = ({\n  actives = [],\n  selections = [],\n  collapsedNodeIds = [],\n  theme\n}: Partial<GraphState>) =>\n  create<GraphState>(set => ({\n    theme: {\n      ...theme,\n      edge: {\n        ...theme?.edge,\n        label: {\n          ...theme?.edge?.label,\n          fontSize: theme?.edge?.label?.fontSize ?? 6\n        }\n      }\n    },\n    edges: [],\n    nodes: [],\n    collapsedNodeIds,\n    clusters: new Map(),\n    panning: false,\n    draggingIds: [],\n    actives,\n    hoveredEdgeIds: [],\n    edgeContextMenus: new Set(),\n    edgeMeshes: [],\n    selections,\n    hoveredNodeId: null,\n    drags: {},\n    graph: new Graph({ multi: true }),\n    setTheme: theme => set(state => ({ ...state, theme })),\n    setClusters: clusters => set(state => ({ ...state, clusters })),\n    setEdgeContextMenus: edgeContextMenus =>\n      set(state => ({\n        ...state,\n        edgeContextMenus\n      })),\n    setEdgeMeshes: edgeMeshes => set(state => ({ ...state, edgeMeshes })),\n    setPanning: panning => set(state => ({ ...state, panning })),\n    setDrags: drags => set(state => ({ ...state, drags })),\n    addDraggingId: id =>\n      set(state => ({ ...state, draggingIds: [...state.draggingIds, id] })),\n    removeDraggingId: id =>\n      set(state => ({\n        ...state,\n        draggingIds: state.draggingIds.filter(drag => drag !== id)\n      })),\n    setActives: actives => set(state => ({ ...state, actives })),\n    setSelections: selections => set(state => ({ ...state, selections })),\n    setHoveredNodeId: hoveredNodeId =>\n      set(state => ({ ...state, hoveredNodeId })),\n    setHoveredEdgeIds: hoveredEdgeIds =>\n      set(state => ({ ...state, hoveredEdgeIds })),\n    setNodes: nodes =>\n      set(state => ({\n        ...state,\n        nodes,\n        centerPosition: getLayoutCenter(nodes)\n      })),\n    setEdges: edges => set(state => ({ ...state, edges })),\n    setNodePosition: (id, position) =>\n      set(state => {\n        const node = state.nodes.find(n => n.id === id);\n        const originalVector = getVector(node);\n        const newVector = new Vector3(position.x, position.y, position.z);\n        const offset = newVector.sub(originalVector);\n        const nodes = [...state.nodes];\n\n        if (state.selections?.includes(id)) {\n          state.selections?.forEach(id => {\n            const node = state.nodes.find(n => n.id === id);\n            // Selections can contain edges:\n            if (node) {\n              const nodeIndex = state.nodes.indexOf(node);\n              nodes[nodeIndex] = updateNodePosition(node, offset);\n            }\n          });\n        } else {\n          const nodeIndex = state.nodes.indexOf(node);\n          nodes[nodeIndex] = updateNodePosition(node, offset);\n        }\n\n        return {\n          ...state,\n          drags: {\n            ...state.drags,\n            [id]: node\n          },\n          nodes\n        };\n      }),\n    setCollapsedNodeIds: (nodeIds = []) =>\n      set(state => ({ ...state, collapsedNodeIds: nodeIds })),\n    // Update the position of a cluster with nodes inside it\n    setClusterPosition: (id, position) =>\n      set(state => {\n        const clusters = new Map<string, any>(state.clusters);\n        const cluster = clusters.get(id);\n\n        if (cluster) {\n          // Calculate the offset between old and new position\n          const oldPos = cluster.position;\n          const offset = new Vector3(\n            position.x - oldPos.x,\n            position.y - oldPos.y,\n            position.z - (oldPos.z ?? 0)\n          );\n\n          // Update all nodes in the cluster\n          const nodes: InternalGraphNode[] = [...state.nodes];\n          const drags: DragReferences = { ...state.drags };\n          nodes.forEach((node, index) => {\n            if (node.cluster === id) {\n              nodes[index] = {\n                ...node,\n                position: {\n                  ...node.position,\n                  x: node.position.x + offset.x,\n                  y: node.position.y + offset.y,\n                  z: node.position.z + (offset.z ?? 0)\n                } as InternalGraphPosition\n              };\n              // Update node in drag reference\n              drags[node.id] = node;\n            }\n          });\n\n          const clusterNodes: InternalGraphNode[] = nodes.filter(\n            node => node.cluster === id\n          );\n          const newClusterPosition = getLayoutCenter(clusterNodes);\n          // Update cluster position\n          clusters.set(id, {\n            ...cluster,\n            position: newClusterPosition\n          });\n\n          return {\n            ...state,\n            drags: {\n              ...drags,\n              [id]: cluster\n            },\n            clusters,\n            nodes\n          };\n        }\n\n        return state;\n      })\n  }));\n\nconst defaultStore = createStore({});\nconst StoreContext = isServerRender\n  ? null\n  : createContext<StoreApi<GraphState>>(defaultStore);\n\nexport const Provider: FC<{\n  children: ReactNode;\n  store?: StoreApi<GraphState>;\n}> = ({ children, store = defaultStore }) => {\n  if (isServerRender) {\n    return children;\n  }\n\n  return React.createElement(StoreContext.Provider, { value: store }, children);\n};\n\nexport const useStore = <T>(selector: (state: GraphState) => T): T => {\n  const store = useContext(StoreContext);\n  // use the useShallow hook, which will return a stable reference (https://zustand.docs.pmnd.rs/migrations/migrating-to-v5)\n  return useZustandStore(store, useShallow(selector));\n};\n","import type CameraControls from 'camera-controls';\nimport { createContext, useContext } from 'react';\n\nexport interface CameraControlsContextProps {\n  /**\n   * The camera controls object.\n   */\n  controls: CameraControls | null;\n\n  /**\n   * A function that resets the camera controls.\n   * If the optional `animated` argument is true, the reset is animated.\n   */\n  resetControls: (animated?: boolean) => void;\n\n  /**\n   * A function that zooms in the camera.\n   */\n  zoomIn: () => void;\n\n  /**\n   * A function that zooms out the camera.\n   */\n  zoomOut: () => void;\n\n  /**\n   * A function that dollies in the camera.\n   */\n  dollyIn: (distance?: number) => void;\n\n  /**\n   * A function that dollies out the camera.\n   */\n  dollyOut: (distance?: number) => void;\n\n  /**\n   * A function that pans the camera to the left.\n   */\n  panLeft: () => void;\n\n  /**\n   * A function that pans the camera to the right.\n   */\n  panRight: () => void;\n\n  /**\n   * A function that pans the camera upwards.\n   */\n  panUp: () => void;\n\n  /**\n   * A function that pans the camera downwards.\n   */\n  panDown: () => void;\n\n  /**\n   * A function that freezes the camera.\n   */\n  freeze: () => void;\n\n  /**\n   * A function that unfreezes the camera.\n   */\n  unFreeze: () => void;\n}\n\nexport const CameraControlsContext = createContext<CameraControlsContextProps>({\n  controls: null,\n  resetControls: () => undefined,\n  zoomIn: () => undefined,\n  zoomOut: () => undefined,\n  dollyIn: () => undefined,\n  dollyOut: () => undefined,\n  panLeft: () => undefined,\n  panRight: () => undefined,\n  panUp: () => undefined,\n  panDown: () => undefined,\n  freeze: () => undefined,\n  unFreeze: () => undefined\n});\n\nexport const useCameraControls = () => {\n  const context = useContext(CameraControlsContext);\n\n  if (context === undefined) {\n    throw new Error(\n      '`useCameraControls` hook must be used within a `ControlsProvider` component'\n    );\n  }\n\n  return context;\n};\n","import { extend, useFrame, useThree } from '@react-three/fiber';\nimport ThreeCameraControls from 'camera-controls';\nimport * as holdEvent from 'hold-event';\nimport type { ReactNode, Ref } from 'react';\nimport React, {\n  forwardRef,\n  useCallback,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef,\n  useState\n} from 'react';\nimport {\n  Box3,\n  MathUtils,\n  Matrix4,\n  MOUSE,\n  Quaternion,\n  Raycaster,\n  Sphere,\n  Spherical,\n  Vector2,\n  Vector3,\n  Vector4\n} from 'three';\n\nimport { useStore } from '../store';\nimport { isServerRender } from '../utils/visibility';\nimport type { CameraControlsContextProps } from './useCameraControls';\nimport { CameraControlsContext } from './useCameraControls';\n\n// Install the camera controls\n// Use a subset for better three shaking\nThreeCameraControls.install({\n  THREE: {\n    MOUSE: MOUSE,\n    Vector2: Vector2,\n    Vector3: Vector3,\n    Vector4: Vector4,\n    Quaternion: Quaternion,\n    Matrix4: Matrix4,\n    Spherical: Spherical,\n    Box3: Box3,\n    Sphere: Sphere,\n    Raycaster: Raycaster,\n    MathUtils: {\n      DEG2RAD: MathUtils?.DEG2RAD,\n      clamp: MathUtils?.clamp\n    }\n  }\n});\n\n// Extend r3f with the new controls\nextend({ ThreeCameraControls });\n\nexport type CameraMode = 'pan' | 'rotate' | 'orbit' | 'orthographic';\n\nexport interface CameraControlsProps {\n  /**\n   * Mode of the camera.\n   */\n  mode?: CameraMode;\n\n  /**\n   * Children symbols.\n   */\n  children?: ReactNode;\n\n  /**\n   * Animate transitions to centering.\n   */\n  animated?: boolean;\n\n  /**\n   * Whether the controls are enabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * The maximum distance for the camera (perspective mode).\n   */\n  maxDistance?: number;\n\n  /**\n   * The minimum distance for the camera (perspective mode).\n   */\n  minDistance?: number;\n\n  /**\n   * The maximum zoom level for orthographic cameras.\n   */\n  maxZoom?: number;\n\n  /**\n   * The minimum zoom level for orthographic cameras.\n   */\n  minZoom?: number;\n}\n\nexport type CameraControlsRef = CameraControlsContextProps;\n\nexport const CameraControls = forwardRef<\n  CameraControlsRef,\n  CameraControlsProps\n>(\n  (\n    {\n      mode = 'rotate',\n      children,\n      animated,\n      disabled,\n      minDistance = 1000,\n      maxDistance = 50000,\n      minZoom = 1,\n      maxZoom = 100\n    },\n    ref: Ref<CameraControlsRef>\n  ) => {\n    const cameraRef = useRef<ThreeCameraControls | null>(null);\n    const camera = useThree(state => state.camera);\n    const gl = useThree(state => state.gl);\n    const isOrbiting = mode === 'orbit';\n    const setPanning = useStore(state => state.setPanning);\n    const isDragging = useStore(state => state.draggingIds.length > 0);\n    const cameraSpeedRef = useRef(0);\n    const [controlMounted, setControlMounted] = useState<boolean>(false);\n\n    useFrame((_state, delta) => {\n      if (cameraRef.current?.enabled) {\n        cameraRef.current?.update(delta);\n      }\n\n      if (isOrbiting) {\n        cameraRef.current.azimuthAngle += 20 * delta * MathUtils.DEG2RAD;\n      }\n    }, -1);\n\n    useEffect(() => () => cameraRef.current?.dispose(), []);\n\n    const zoomIn = useCallback(() => {\n      cameraRef.current?.zoom(camera.zoom / 2, animated);\n    }, [animated, camera.zoom]);\n\n    const zoomOut = useCallback(() => {\n      cameraRef.current?.zoom(-camera.zoom / 2, animated);\n    }, [animated, camera.zoom]);\n\n    const dollyIn = useCallback(\n      distance => {\n        cameraRef.current?.dolly(distance, animated);\n      },\n      [animated]\n    );\n\n    const dollyOut = useCallback(\n      distance => {\n        cameraRef.current?.dolly(distance, animated);\n      },\n      [animated]\n    );\n\n    const panRight = useCallback(\n      event => {\n        if (!isOrbiting) {\n          cameraRef.current?.truck(-0.03 * event.deltaTime, 0, animated);\n        }\n      },\n      [animated, isOrbiting]\n    );\n\n    const panLeft = useCallback(\n      event => {\n        if (!isOrbiting) {\n          cameraRef.current?.truck(0.03 * event.deltaTime, 0, animated);\n        }\n      },\n      [animated, isOrbiting]\n    );\n\n    const panUp = useCallback(\n      event => {\n        if (!isOrbiting) {\n          cameraRef.current?.truck(0, 0.03 * event.deltaTime, animated);\n        }\n      },\n      [animated, isOrbiting]\n    );\n\n    const panDown = useCallback(\n      event => {\n        if (!isOrbiting) {\n          cameraRef.current?.truck(0, -0.03 * event.deltaTime, animated);\n        }\n      },\n      [animated, isOrbiting]\n    );\n\n    const onKeyDown = useCallback(\n      event => {\n        if (event.code === 'Space') {\n          if (mode === 'rotate') {\n            cameraRef.current.mouseButtons.left =\n              ThreeCameraControls.ACTION.TRUCK;\n          } else {\n            cameraRef.current.mouseButtons.left =\n              ThreeCameraControls.ACTION.ROTATE;\n          }\n        }\n      },\n      [mode]\n    );\n\n    const onKeyUp = useCallback(\n      event => {\n        if (event.code === 'Space') {\n          if (mode === 'rotate') {\n            cameraRef.current.mouseButtons.left =\n              ThreeCameraControls.ACTION.ROTATE;\n          } else {\n            cameraRef.current.mouseButtons.left =\n              ThreeCameraControls.ACTION.TRUCK;\n          }\n        }\n      },\n      [mode]\n    );\n\n    const [keyControls, setKeyControls] = useState<{\n      leftKey: holdEvent.KeyboardKeyHold;\n      rightKey: holdEvent.KeyboardKeyHold;\n      upKey: holdEvent.KeyboardKeyHold;\n      downKey: holdEvent.KeyboardKeyHold;\n    } | null>(null);\n\n    useEffect(() => {\n      // Only initialize on client side\n      if (!isServerRender) {\n        setKeyControls({\n          leftKey: new holdEvent.KeyboardKeyHold('ArrowLeft', 100),\n          rightKey: new holdEvent.KeyboardKeyHold('ArrowRight', 100),\n          upKey: new holdEvent.KeyboardKeyHold('ArrowUp', 100),\n          downKey: new holdEvent.KeyboardKeyHold('ArrowDown', 100)\n        });\n      }\n    }, []);\n\n    useEffect(() => {\n      if (!disabled && keyControls) {\n        keyControls.leftKey.addEventListener('holding', panLeft);\n        keyControls.rightKey.addEventListener('holding', panRight);\n        keyControls.upKey.addEventListener('holding', panUp);\n        keyControls.downKey.addEventListener('holding', panDown);\n\n        window.addEventListener('keydown', onKeyDown);\n        window.addEventListener('keyup', onKeyUp);\n      }\n\n      return () => {\n        if (keyControls) {\n          keyControls.leftKey.removeEventListener('holding', panLeft);\n          keyControls.rightKey.removeEventListener('holding', panRight);\n          keyControls.upKey.removeEventListener('holding', panUp);\n          keyControls.downKey.removeEventListener('holding', panDown);\n\n          window.removeEventListener('keydown', onKeyDown);\n          window.removeEventListener('keyup', onKeyUp);\n        }\n      };\n    }, [\n      disabled,\n      onKeyDown,\n      onKeyUp,\n      panDown,\n      panLeft,\n      panRight,\n      panUp,\n      keyControls\n    ]);\n\n    useEffect(() => {\n      const isOrthographic = mode === 'orthographic';\n\n      if (disabled) {\n        cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\n        cameraRef.current.mouseButtons.middle = ThreeCameraControls.ACTION.NONE;\n        cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.NONE;\n      } else {\n        cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.TRUCK;\n        cameraRef.current.mouseButtons.middle =\n          ThreeCameraControls.ACTION.TRUCK;\n        cameraRef.current.mouseButtons.wheel = isOrthographic\n          ? ThreeCameraControls.ACTION.ZOOM\n          : ThreeCameraControls.ACTION.DOLLY;\n      }\n\n      // For orthographic cameras, use dedicated zoom props\n      if (isOrthographic && cameraRef.current) {\n        cameraRef.current.maxZoom = maxZoom;\n        cameraRef.current.minZoom = minZoom;\n      }\n    }, [disabled, mode, minZoom, maxZoom]);\n\n    useEffect(() => {\n      const onControl = () => setPanning(true);\n      const onControlEnd = () => setPanning(false);\n\n      const ref = cameraRef.current;\n      if (ref) {\n        ref.addEventListener('control', onControl);\n        ref.addEventListener('controlend', onControlEnd);\n      }\n\n      return () => {\n        if (ref) {\n          ref.removeEventListener('control', onControl);\n          ref.removeEventListener('controlend', onControlEnd);\n        }\n      };\n    }, [cameraRef, setPanning]);\n\n    useEffect(() => {\n      // If a node is being dragged, disable the camera controls\n      if (isDragging) {\n        cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\n        cameraRef.current.touches.one = ThreeCameraControls.ACTION.NONE;\n      } else {\n        if (mode === 'rotate') {\n          cameraRef.current.mouseButtons.left =\n            ThreeCameraControls.ACTION.ROTATE;\n          cameraRef.current.touches.one =\n            ThreeCameraControls.ACTION.TOUCH_ROTATE;\n        } else {\n          cameraRef.current.touches.one =\n            ThreeCameraControls.ACTION.TOUCH_TRUCK;\n          cameraRef.current.mouseButtons.left =\n            ThreeCameraControls.ACTION.TRUCK;\n        }\n      }\n    }, [isDragging, mode]);\n\n    const values = useMemo(\n      () => ({\n        controls: cameraRef.current,\n        zoomIn: () => zoomIn(),\n        zoomOut: () => zoomOut(),\n        dollyIn: (distance = 1000) => dollyIn(distance),\n        dollyOut: (distance = -1000) => dollyOut(distance),\n        panLeft: (deltaTime = 100) => panLeft({ deltaTime }),\n        panRight: (deltaTime = 100) => panRight({ deltaTime }),\n        panDown: (deltaTime = 100) => panDown({ deltaTime }),\n        panUp: (deltaTime = 100) => panUp({ deltaTime }),\n        resetControls: (animated?: boolean) =>\n          cameraRef.current?.normalizeRotations().reset(animated),\n        freeze: () => {\n          // Save the current speed\n          if (cameraRef.current.truckSpeed) {\n            cameraSpeedRef.current = cameraRef.current.truckSpeed;\n          }\n          cameraRef.current.truckSpeed = 0;\n        },\n        unFreeze: () => (cameraRef.current.truckSpeed = cameraSpeedRef.current)\n      }),\n      // eslint-disable-next-line\n      [zoomIn, zoomOut, panLeft, panRight, panDown, panUp, cameraRef.current]\n    );\n\n    useImperativeHandle(ref, () => values);\n\n    return (\n      <CameraControlsContext.Provider value={values}>\n        <threeCameraControls\n          ref={controls => {\n            cameraRef.current = controls;\n            if (!controlMounted) {\n              // Update the state when the controls are mounted to notify about it component that using that controls\n              setControlMounted(true);\n            }\n          }}\n          args={[camera, gl.domElement]}\n          smoothTime={0.1}\n          minDistance={minDistance}\n          dollyToCursor\n          maxDistance={maxDistance}\n        />\n        {children}\n      </CameraControlsContext.Provider>\n    );\n  }\n);\n","import type { PerspectiveCamera } from 'three';\n\nimport type { InternalGraphPosition } from '../types';\n\n/**\n * Get the visible height at the z depth.\n * Ref: https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269\n */\nfunction visibleHeightAtZDepth(depth: number, camera: PerspectiveCamera) {\n  // compensate for cameras not positioned at z=0\n  const cameraOffset = camera.position.z;\n  if (depth < cameraOffset) depth -= cameraOffset;\n  else depth += cameraOffset;\n\n  // vertical fov in radians\n  const vFOV = ((camera.fov / camera.zoom) * Math.PI) / 180;\n\n  // Math.abs to ensure the result is always positive\n  return 2 * Math.tan(vFOV / 2) * Math.abs(depth);\n}\n\n/**\n * Get the visible width at the z depth.\n */\nfunction visibleWidthAtZDepth(depth: number, camera: PerspectiveCamera) {\n  const height = visibleHeightAtZDepth(depth, camera);\n  return height * camera.aspect;\n}\n\n/**\n * Returns whether the node is in view of the camera.\n */\nexport function isNodeInView(\n  camera: PerspectiveCamera,\n  nodePosition: InternalGraphPosition\n): boolean {\n  const visibleWidth = visibleWidthAtZDepth(1, camera);\n  const visibleHeight = visibleHeightAtZDepth(1, camera);\n\n  // The boundary coordinates of the area visible to the camera relative to the scene\n  const visibleArea = {\n    x0: camera?.position?.x - visibleWidth / 2,\n    x1: camera?.position?.x + visibleWidth / 2,\n    y0: camera?.position?.y - visibleHeight / 2,\n    y1: camera?.position?.y + visibleHeight / 2\n  };\n\n  return (\n    nodePosition?.x > visibleArea.x0 &&\n    nodePosition?.x < visibleArea.x1 &&\n    nodePosition?.y > visibleArea.y0 &&\n    nodePosition?.y < visibleArea.y1\n  );\n}\n\n/**\n * Get the closest axis to a given angle.\n */\nexport function getClosestAxis(angle: number, axes: number[]) {\n  return axes.reduce((prev, curr) =>\n    Math.abs(curr - (angle % Math.PI)) < Math.abs(prev - (angle % Math.PI))\n      ? curr\n      : prev\n  );\n}\n\n/**\n * Get how far an angle is from the closest 2D axis in radians.\n */\nexport function getDegreesToClosest2dAxis(\n  horizontalAngle: number,\n  verticalAngle: number\n) {\n  const closestHorizontalAxis = getClosestAxis(horizontalAngle, [0, Math.PI]);\n  const closestVerticalAxis = getClosestAxis(verticalAngle, [\n    Math.PI / 2,\n    (3 * Math.PI) / 2\n  ]);\n\n  return {\n    horizontalRotation: closestHorizontalAxis - (horizontalAngle % Math.PI),\n    verticalRotation: closestVerticalAxis - (verticalAngle % Math.PI)\n  };\n}\n","import type { GraphEdge, GraphNode } from '../types';\n\ninterface GetHiddenChildrenInput {\n  nodeId: string;\n  nodes: GraphNode[];\n  edges: GraphEdge[];\n  currentHiddenNodes: GraphNode[];\n  currentHiddenEdges: GraphEdge[];\n}\n\ninterface GetVisibleIdsInput {\n  collapsedIds: string[];\n  nodes: GraphNode[];\n  edges: GraphEdge[];\n}\n\ninterface GetExpandPathInput {\n  nodeId: string;\n  edges: GraphEdge[];\n  visibleEdgeIds: string[];\n}\n\n/**\n * Get the children of a node id that is hidden.\n */\nfunction getHiddenChildren({\n  nodeId,\n  nodes,\n  edges,\n  currentHiddenNodes,\n  currentHiddenEdges\n}: GetHiddenChildrenInput) {\n  const hiddenNodes: GraphNode[] = [];\n  const hiddenEdges: GraphEdge[] = [];\n  const curHiddenNodeIds = currentHiddenNodes.map(n => n.id);\n  const curHiddenEdgeIds = currentHiddenEdges.map(e => e.id);\n\n  const outboundEdges = edges.filter(l => l.source === nodeId);\n  const outboundEdgeNodeIds = outboundEdges.map(l => l.target);\n\n  hiddenEdges.push(...outboundEdges);\n  for (const outboundEdgeNodeId of outboundEdgeNodeIds) {\n    const incomingEdges = edges.filter(\n      l => l.target === outboundEdgeNodeId && l.source !== nodeId\n    );\n    let hideNode = false;\n\n    // Check to see if any other edge is coming into this node\n    if (incomingEdges.length === 0) {\n      hideNode = true;\n    } else if (\n      incomingEdges.length > 0 &&\n      !curHiddenNodeIds.includes(outboundEdgeNodeId)\n    ) {\n      // If all inbound links are hidden, hide this node as well\n      const inboundNodeLinkIds = incomingEdges.map(l => l.id);\n      if (inboundNodeLinkIds.every(i => curHiddenEdgeIds.includes(i))) {\n        hideNode = true;\n      }\n    }\n    if (hideNode) {\n      // Need to hide this node and any children of this node\n      const node = nodes.find(n => n.id === outboundEdgeNodeId);\n      if (node) {\n        hiddenNodes.push(node);\n      }\n      const nested = getHiddenChildren({\n        nodeId: outboundEdgeNodeId,\n        nodes,\n        edges,\n        currentHiddenEdges: hiddenEdges,\n        currentHiddenNodes: hiddenNodes\n      });\n      hiddenEdges.push(...nested.hiddenEdges);\n      hiddenNodes.push(...nested.hiddenNodes);\n    }\n  }\n\n  const uniqueEdges: GraphEdge[] = Object.values(\n    hiddenEdges.reduce(\n      (acc, next) => ({\n        ...acc,\n        [next.id]: next\n      }),\n      {}\n    )\n  );\n\n  const uniqueNodes: GraphNode[] = Object.values(\n    hiddenNodes.reduce(\n      (acc, next) => ({\n        ...acc,\n        [next.id]: next\n      }),\n      {}\n    )\n  );\n\n  return {\n    hiddenEdges: uniqueEdges,\n    hiddenNodes: uniqueNodes\n  };\n}\n\n/**\n * Get the visible nodes and edges given a collapsed set of ids.\n */\nexport const getVisibleEntities = ({\n  collapsedIds,\n  nodes,\n  edges\n}: GetVisibleIdsInput) => {\n  const curHiddenNodes = [];\n  const curHiddenEdges = [];\n\n  for (const collapsedId of collapsedIds) {\n    const { hiddenEdges, hiddenNodes } = getHiddenChildren({\n      nodeId: collapsedId,\n      nodes,\n      edges,\n      currentHiddenEdges: curHiddenEdges,\n      currentHiddenNodes: curHiddenNodes\n    });\n\n    curHiddenNodes.push(...hiddenNodes);\n    curHiddenEdges.push(...hiddenEdges);\n  }\n\n  const hiddenNodeIds = curHiddenNodes.map(n => n.id);\n  const hiddenEdgeIds = curHiddenEdges.map(e => e.id);\n  const visibleNodes = nodes.filter(n => !hiddenNodeIds.includes(n.id));\n  const visibleEdges = edges.filter(e => !hiddenEdgeIds.includes(e.id));\n\n  return {\n    visibleNodes,\n    visibleEdges\n  };\n};\n\n/**\n * Get the path to expand a node.\n */\nexport const getExpandPath = ({\n  nodeId,\n  edges,\n  visibleEdgeIds\n}: GetExpandPathInput) => {\n  const parentIds = [];\n  const inboundEdges = edges.filter(l => l.target === nodeId);\n  const inboundEdgeIds = inboundEdges.map(e => e.id);\n  const hasVisibleInboundEdge = inboundEdgeIds.some(id =>\n    visibleEdgeIds.includes(id)\n  );\n\n  if (hasVisibleInboundEdge) {\n    // If there is a visible edge to this node, that means the node is\n    // visible so no parents need to be expanded\n    return parentIds;\n  }\n\n  const inboundEdgeNodeIds = inboundEdges.map(l => l.source);\n  let addedParent = false;\n\n  for (const inboundNodeId of inboundEdgeNodeIds) {\n    if (!addedParent) {\n      // Only want to expand a single path to the node, so if there\n      // are multiple hidden incoming edges, only expand the first\n      // to reduce how many nodes are expanded to get to the node\n      parentIds.push(\n        ...[\n          inboundNodeId,\n          ...getExpandPath({ nodeId: inboundNodeId, edges, visibleEdgeIds })\n        ]\n      );\n      addedParent = true;\n    }\n  }\n\n  return parentIds;\n};\n","import { useCallback } from 'react';\n\nimport type { GraphEdge, GraphNode } from '../types';\nimport { getExpandPath, getVisibleEntities } from './utils';\n\nexport interface UseCollapseProps {\n  /**\n   * Current collapsed node ids.\n   */\n  collapsedNodeIds?: string[];\n\n  /**\n   * Node data.\n   */\n  nodes?: GraphNode[];\n\n  /**\n   * Edge data.\n   */\n  edges?: GraphEdge[];\n}\n\nexport interface CollpaseResult {\n  /**\n   * Determine if a node is currently collapsed\n   */\n  getIsCollapsed: (nodeId: string) => boolean;\n\n  /**\n   * Return a list of ids required to expand in order to view the provided node\n   */\n  getExpandPathIds: (nodeId: string) => string[];\n}\n\nexport const useCollapse = ({\n  collapsedNodeIds = [],\n  nodes = [],\n  edges = []\n}: UseCollapseProps): CollpaseResult => {\n  const getIsCollapsed = useCallback(\n    (nodeId: string) => {\n      const { visibleNodes } = getVisibleEntities({\n        nodes,\n        edges,\n        collapsedIds: collapsedNodeIds\n      });\n      const visibleNodeIds = visibleNodes.map(n => n.id);\n\n      return !visibleNodeIds.includes(nodeId);\n    },\n    [collapsedNodeIds, edges, nodes]\n  );\n\n  const getExpandPathIds = useCallback(\n    (nodeId: string) => {\n      const { visibleEdges } = getVisibleEntities({\n        nodes,\n        edges,\n        collapsedIds: collapsedNodeIds\n      });\n      const visibleEdgeIds = visibleEdges.map(e => e.id);\n\n      return getExpandPath({ nodeId, edges, visibleEdgeIds });\n    },\n    [collapsedNodeIds, edges, nodes]\n  );\n\n  return {\n    getIsCollapsed,\n    getExpandPathIds\n  };\n};\n","import { useThree } from '@react-three/fiber';\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport type { PerspectiveCamera } from 'three';\nimport { Box3, Vector3 } from 'three';\n\nimport { useCameraControls } from '../CameraControls/useCameraControls';\nimport {\n  getDegreesToClosest2dAxis,\n  isNodeInView\n} from '../CameraControls/utils';\nimport type { LayoutTypes } from '../layout/types';\nimport { useStore } from '../store';\nimport type { InternalGraphNode } from '../types';\nimport { getLayoutCenter } from '../utils/layout';\n\nconst PADDING = 50;\n\nexport interface CenterNodesParams {\n  animated?: boolean;\n  centerOnlyIfNodesNotInView?: boolean;\n}\n\nexport interface FitNodesParams {\n  animated?: boolean;\n  fitOnlyIfNodesNotInView?: boolean;\n}\n\nexport interface CenterGraphInput {\n  /**\n   * Whether the animate the transition or not.\n   */\n  animated?: boolean;\n\n  /**\n   * Whether the center graph function is disabled or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * The layout type of the graph used to determine rotation logic.\n   */\n  layoutType: LayoutTypes;\n}\n\nexport interface CenterGraphOutput {\n  /**\n   * Centers the graph on a specific node or list of nodes.\n   *\n   * @param nodes - An array of `InternalGraphNode` objects to center the graph on. If this parameter is omitted,\n   * the graph will be centered on all nodes.\n   *\n   * @param animated - A boolean flag that determines whether the centering action should be animated.\n   *\n   * @param centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\n   * only be centered if the nodes specified by `nodes` are not currently in view. If this\n   * parameter is `true`, the graph will only be re-centered if one or more of the nodes\n   * specified by `nodes` are not currently visible in the viewport. If this parameter is\n   * `false` or omitted, the graph will be re-centered regardless of whether the nodes\n   * are currently in view.\n   */\n  centerNodes: (nodes: InternalGraphNode[], opts: CenterNodesParams) => void;\n\n  /**\n   * Centers the graph on a specific node or list of nodes.\n   *\n   * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\n   * the graph will be centered on all nodes.\n   *\n   * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\n   * only be centered if the nodes specified by `ids` are not currently in view. If this\n   * parameter is `true`, the graph will only be re-centered if one or more of the nodes\n   * specified by `ids` are not currently in view. If this parameter is\n   * `false` or omitted, the graph will be re-centered regardless of whether the nodes\n   * are currently in view.\n   */\n  centerNodesById: (nodeIds: string[], opts?: CenterNodesParams) => void;\n\n  /**\n   * Fit all the given nodes into view of the camera.\n   *\n   * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\n   * the view will fit to all nodes.\n   *\n   * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\n   * only be fit if the nodes specified by `ids` are not currently in view. If this\n   * parameter is `true`, the view will only be fit if one or more of the nodes\n   * specified by `ids` are not currently visible in the viewport. If this parameter is\n   * `false` or omitted, the view will be fit regardless of whether the nodes\n   * are currently in view.\n   */\n  fitNodesInViewById: (nodeIds: string[], opts?: FitNodesParams) => void;\n\n  /**\n   * Whether the graph is centered or not.\n   */\n  isCentered?: boolean;\n}\n\nexport const useCenterGraph = ({\n  animated,\n  disabled,\n  layoutType\n}: CenterGraphInput): CenterGraphOutput => {\n  const nodes = useStore(state => state.nodes);\n  const [isCentered, setIsCentered] = useState<boolean>(false);\n  const invalidate = useThree(state => state.invalidate);\n  const { controls } = useCameraControls();\n  const camera = useThree(state => state.camera) as PerspectiveCamera;\n  const mounted = useRef<boolean>(false);\n\n  const centerNodes = useCallback(\n    async (nodes, opts?: CenterNodesParams) => {\n      const animated = opts?.animated !== undefined ? opts?.animated : true;\n      const centerOnlyIfNodesNotInView =\n        opts?.centerOnlyIfNodesNotInView !== undefined\n          ? opts?.centerOnlyIfNodesNotInView\n          : false;\n\n      if (\n        !mounted.current ||\n        !centerOnlyIfNodesNotInView ||\n        (centerOnlyIfNodesNotInView &&\n          nodes?.some(node => !isNodeInView(camera, node.position)))\n      ) {\n        // Centers the graph based on the central most node\n        const { x, y, z } = getLayoutCenter(nodes);\n\n        await controls.normalizeRotations().setTarget(x, y, z, animated);\n\n        if (!isCentered) {\n          setIsCentered(true);\n        }\n\n        invalidate();\n      }\n    },\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [invalidate, controls, nodes]\n  );\n\n  const fitNodesInView = useCallback(\n    async (\n      nodes,\n      opts: FitNodesParams = { animated: true, fitOnlyIfNodesNotInView: false }\n    ) => {\n      const { fitOnlyIfNodesNotInView } = opts;\n\n      if (\n        !fitOnlyIfNodesNotInView ||\n        (fitOnlyIfNodesNotInView &&\n          nodes?.some(node => !isNodeInView(camera, node.position)))\n      ) {\n        const { minX, maxX, minY, maxY, minZ, maxZ } = getLayoutCenter(nodes);\n\n        if (!layoutType.includes('3d')) {\n          // fitToBox will auto rotate to the closest axis including the z axis,\n          // which is not desired for 2D graphs\n          // So get the rotation to the closest flat axis for 2D graphs\n          const { horizontalRotation, verticalRotation } =\n            getDegreesToClosest2dAxis(\n              controls?.azimuthAngle,\n              controls?.polarAngle\n            );\n\n          void controls?.rotate(horizontalRotation, verticalRotation, true);\n        }\n\n        await controls?.zoomTo(1, opts?.animated);\n\n        await controls?.fitToBox(\n          new Box3(\n            new Vector3(minX, minY, minZ),\n            new Vector3(maxX, maxY, maxZ)\n          ),\n          opts?.animated,\n          {\n            cover: false,\n            paddingLeft: PADDING,\n            paddingRight: PADDING,\n            paddingBottom: PADDING,\n            paddingTop: PADDING\n          }\n        );\n      }\n    },\n    [camera, controls, layoutType]\n  );\n\n  const getNodesById = useCallback(\n    (nodeIds: string[]) => {\n      let mappedNodes: InternalGraphNode[] | null = null;\n\n      if (nodeIds?.length) {\n        // Map the node ids to the actual nodes\n        mappedNodes = nodeIds.reduce((acc, id) => {\n          const node = nodes.find(n => n.id === id);\n          if (node) {\n            acc.push(node);\n          } else {\n            throw new Error(\n              `Attempted to center ${id} but it was not found in the nodes`\n            );\n          }\n\n          return acc;\n        }, []);\n      }\n\n      return mappedNodes;\n    },\n    [nodes]\n  );\n\n  const centerNodesById = useCallback(\n    (nodeIds: string[], opts: CenterNodesParams) => {\n      const mappedNodes = getNodesById(nodeIds);\n\n      centerNodes(mappedNodes || nodes, {\n        animated,\n        centerOnlyIfNodesNotInView: opts?.centerOnlyIfNodesNotInView\n      });\n    },\n    [animated, centerNodes, getNodesById, nodes]\n  );\n\n  const fitNodesInViewById = useCallback(\n    async (nodeIds: string[], opts: FitNodesParams) => {\n      const mappedNodes = getNodesById(nodeIds);\n\n      await fitNodesInView(mappedNodes || nodes, { animated, ...opts });\n    },\n    [animated, fitNodesInView, getNodesById, nodes]\n  );\n\n  useLayoutEffect(() => {\n    async function load() {\n      // Once we've loaded controls and we have nodes, let's recenter\n      if (controls && nodes?.length) {\n        if (!mounted.current) {\n          // Center the graph once nodes are loaded on mount\n          await centerNodes(nodes, { animated: false });\n          await fitNodesInView(nodes, { animated: false });\n          mounted.current = true;\n        }\n      }\n    }\n\n    load();\n  }, [controls, centerNodes, nodes, animated, camera, fitNodesInView]);\n\n  return { centerNodes, centerNodesById, fitNodesInViewById, isCentered };\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { FC } from 'react';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { ColorRepresentation, Mesh } from 'three';\nimport { Color, DoubleSide, Vector3 } from 'three';\n\nimport { useStore } from '../store';\nimport { animationConfig } from '../utils';\n\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\n\nexport interface ArrowProps {\n  /**\n   * Whether the arrow should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * The color of the arrow.\n   */\n  color?: ColorRepresentation;\n\n  /**\n   * The length of the arrow.\n   */\n  length: number;\n\n  /**\n   * The opacity of the arrow.\n   */\n  opacity?: number;\n\n  /**\n   * The position of the arrow in 3D space.\n   */\n  position: Vector3;\n\n  /**\n   * The rotation of the arrow in 3D space.\n   */\n  rotation: Vector3;\n\n  /**\n   * The size of the arrow.\n   */\n  size: number;\n\n  /**\n   * A function that is called when the arrow is right-clicked.\n   */\n  onContextMenu?: () => void;\n\n  /**\n   * A function that is called when the arrow is selected or deselected.\n   */\n  onActive?: (state: boolean) => void;\n}\n\nexport const Arrow: FC<ArrowProps> = ({\n  animated,\n  color = '#D8E6EA',\n  length,\n  opacity = 0.5,\n  position,\n  rotation,\n  size = 1,\n  onActive,\n  onContextMenu\n}) => {\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n  const meshRef = useRef<Mesh | null>(null);\n  const isDragging = useStore(state => state.draggingIds.length > 0);\n  const center = useStore(state => state.centerPosition);\n\n  const [{ pos, arrowOpacity }] = useSpring(\n    () => ({\n      from: {\n        pos: center ? [center.x, center.y, center.z] : [0, 0, 0],\n        arrowOpacity: 0\n      },\n      to: {\n        pos: [position.x, position.y, position.z],\n        arrowOpacity: opacity\n      },\n      config: {\n        ...animationConfig,\n        duration: animated && !isDragging ? undefined : 0\n      }\n    }),\n    [animated, isDragging, opacity, position]\n  );\n\n  const setQuaternion = useCallback(() => {\n    const axis = new Vector3(0, 1, 0);\n    meshRef.current?.quaternion.setFromUnitVectors(axis, rotation);\n  }, [rotation, meshRef]);\n\n  useEffect(() => setQuaternion(), [setQuaternion]);\n\n  return (\n    <a.mesh\n      position={pos as any}\n      ref={meshRef}\n      scale={[1, 1, 1]}\n      onPointerOver={() => onActive(true)}\n      onPointerOut={() => onActive(false)}\n      // context menu controls\n      onPointerDown={event => {\n        if (event.nativeEvent.buttons === 2) {\n          event.stopPropagation();\n        }\n      }}\n      onContextMenu={event => {\n        event.nativeEvent.preventDefault();\n        event.stopPropagation();\n        onContextMenu();\n      }}\n    >\n      <cylinderGeometry\n        args={[0, size, length, 20, 1, true]}\n        attach=\"geometry\"\n      />\n      <a.meshBasicMaterial\n        attach=\"material\"\n        color={normalizedColor}\n        depthTest={false}\n        opacity={arrowOpacity}\n        transparent={true}\n        side={DoubleSide}\n        fog={true}\n      />\n    </a.mesh>\n  );\n};\n","import { useThree } from '@react-three/fiber';\nimport { useGesture } from '@use-gesture/react';\nimport { useMemo } from 'react';\nimport { Plane, Vector2, Vector3 } from 'three';\n\nimport type { InternalGraphPosition } from '../types';\nimport type { CenterPositionVector } from '../utils/layout';\n\ninterface DragParams {\n  draggable: boolean;\n  position: InternalGraphPosition;\n  bounds?: CenterPositionVector;\n  set: (position: Vector3) => void;\n  onDragStart: () => void;\n  onDragEnd: () => void;\n}\n\nexport const useDrag = ({\n  draggable,\n  set,\n  position,\n  bounds,\n  onDragStart,\n  onDragEnd\n}: DragParams) => {\n  const camera = useThree(state => state.camera);\n  const raycaster = useThree(state => state.raycaster);\n  const size = useThree(state => state.size);\n  const gl = useThree(state => state.gl);\n\n  // Reference: https://codesandbox.io/s/react-three-draggable-cxu37\n  const { mouse2D, mouse3D, offset, normal, plane } = useMemo(\n    () => ({\n      // Normalized 2D screen space mouse coords\n      mouse2D: new Vector2(),\n      // 3D world space mouse coords\n      mouse3D: new Vector3(),\n      // Drag point offset from object origin\n      offset: new Vector3(),\n      // Normal of the drag plane\n      normal: new Vector3(),\n      // Drag plane\n      plane: new Plane()\n    }),\n    []\n  );\n\n  const clientRect = useMemo(\n    () => gl.domElement.getBoundingClientRect(),\n    // Size dependency ensures the clientRect updates when container dimensions change.\n    // Without it, drag calculations would use stale positioning data from the previous container size.\n    [gl.domElement, size]\n  );\n\n  return useGesture(\n    {\n      onDragStart: ({ event }) => {\n        // @ts-ignore\n        const { eventObject, point } = event;\n\n        // Save the offset of click point from object origin\n        offset.setFromMatrixPosition(eventObject.matrixWorld).sub(point);\n\n        // Set initial 3D cursor position (needed for onDrag plane calculation)\n        mouse3D.copy(point);\n\n        // Run user callback\n        onDragStart();\n      },\n      onDrag: ({ xy, buttons, cancel }) => {\n        // If the left mouse button is not pressed, cancel the drag\n        if (buttons !== 1) {\n          cancel();\n          return;\n        }\n        // Compute normalized mouse coordinates (screen space)\n        const nx = ((xy[0] - (clientRect?.left ?? 0)) / size.width) * 2 - 1;\n        const ny = -((xy[1] - (clientRect?.top ?? 0)) / size.height) * 2 + 1;\n\n        // Unlike the mouse from useThree, this works offscreen\n        mouse2D.set(nx, ny);\n\n        // Update raycaster (otherwise it doesn't track offscreen)\n        raycaster.setFromCamera(mouse2D, camera);\n\n        // The drag plane is normal to the camera view\n        camera.getWorldDirection(normal).negate();\n\n        // Find the plane that's normal to the camera and contains our drag point\n        plane.setFromNormalAndCoplanarPoint(normal, mouse3D);\n\n        // Find the point of intersection\n        raycaster.ray.intersectPlane(plane, mouse3D);\n\n        // Update the object position with the original offset\n        const updated = new Vector3(position.x, position.y, position.z)\n          .copy(mouse3D)\n          .add(offset);\n\n        // If there's a cluster, clamp the position within its circular bounds\n        if (bounds) {\n          const center = new Vector3(\n            (bounds.minX + bounds.maxX) / 2,\n            (bounds.minY + bounds.maxY) / 2,\n            (bounds.minZ + bounds.maxZ) / 2\n          );\n          const radius = (bounds.maxX - bounds.minX) / 2;\n\n          // Calculate direction from center to updated position\n          const direction = updated.clone().sub(center);\n          const distance = direction.length();\n\n          // If outside the circle, clamp to the circle's edge\n          if (distance > radius) {\n            direction.normalize().multiplyScalar(radius);\n            updated.copy(center).add(direction);\n          }\n        }\n\n        return set(updated);\n      },\n      onDragEnd\n    },\n    { drag: { enabled: draggable, threshold: 10 } }\n  );\n};\n","import type { ThreeEvent } from '@react-three/fiber';\nimport { useCallback, useRef } from 'react';\n\nexport interface HoverIntentOptions {\n  interval?: number;\n  sensitivity?: number;\n  timeout?: number;\n  disabled?: boolean;\n  onPointerOver: (event: ThreeEvent<PointerEvent>) => void;\n  onPointerOut: (event: ThreeEvent<PointerEvent>) => void;\n}\n\nexport interface HoverIntentResult {\n  pointerOut: (event: ThreeEvent<PointerEvent>) => void;\n  pointerOver: (event: ThreeEvent<PointerEvent>) => void;\n}\n\n/**\n * Hover intent identifies if the user actually is\n * intending to over by measuring the position of the mouse\n * once a pointer enters and determining if in a duration if\n * the mouse moved inside a certain threshold and fires the events.\n */\nexport const useHoverIntent = ({\n  sensitivity = 7,\n  interval = 50,\n  timeout = 0,\n  disabled,\n  onPointerOver,\n  onPointerOut\n}: HoverIntentOptions | undefined): HoverIntentResult => {\n  const mouseOver = useRef<boolean>(false);\n  const timer = useRef<any | null>(null);\n  const state = useRef<number>(0);\n  const coords = useRef({\n    x: null,\n    y: null,\n    px: null,\n    py: null\n  });\n\n  const onMouseMove = useCallback((event: MouseEvent) => {\n    coords.current.x = event.clientX;\n    coords.current.y = event.clientY;\n  }, []);\n\n  const comparePosition = useCallback(\n    (event: ThreeEvent<PointerEvent>) => {\n      timer.current = clearTimeout(timer.current);\n      const { px, x, py, y } = coords.current;\n\n      if (Math.abs(px - x) + Math.abs(py - y) < sensitivity) {\n        state.current = 1;\n        onPointerOver(event);\n      } else {\n        coords.current.px = x;\n        coords.current.py = y;\n        timer.current = setTimeout(() => comparePosition(event), interval);\n      }\n    },\n    [interval, onPointerOver, sensitivity]\n  );\n\n  const cleanup = useCallback(() => {\n    clearTimeout(timer.current);\n    if (typeof window !== 'undefined') {\n      document.removeEventListener('mousemove', onMouseMove, false);\n    }\n  }, [onMouseMove]);\n\n  const pointerOver = useCallback(\n    (event: ThreeEvent<PointerEvent>) => {\n      if (!disabled) {\n        mouseOver.current = true;\n        cleanup();\n\n        if (state.current !== 1) {\n          coords.current.px = event.pointer.x;\n          coords.current.py = event.pointer.y;\n\n          if (typeof window !== 'undefined') {\n            document.addEventListener('mousemove', onMouseMove, false);\n          }\n\n          timer.current = setTimeout(() => comparePosition(event), timeout);\n        }\n      }\n    },\n    [cleanup, comparePosition, disabled, onMouseMove, timeout]\n  );\n\n  const delay = useCallback(\n    (event: ThreeEvent<PointerEvent>) => {\n      timer.current = clearTimeout(timer.current);\n      state.current = 0;\n      onPointerOut(event);\n    },\n    [onPointerOut]\n  );\n\n  const pointerOut = useCallback(\n    (event: ThreeEvent<PointerEvent>) => {\n      mouseOver.current = false;\n      cleanup();\n\n      if (state.current === 1) {\n        timer.current = setTimeout(() => delay(event), timeout);\n      }\n    },\n    [cleanup, delay, timeout]\n  );\n\n  return {\n    pointerOver,\n    pointerOut\n  };\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { FC } from 'react';\nimport React from 'react';\nimport type { Color } from 'three';\nimport { DoubleSide } from 'three';\n\nimport type { Theme } from '../../themes';\nimport { animationConfig } from '../../utils';\n\nexport interface RingProps {\n  outerRadius: number;\n  innerRadius: number;\n  padding: number;\n  normalizedFill: Color;\n  normalizedStroke: Color;\n  opacity: number;\n  animated: boolean;\n  theme: Theme;\n}\n\nexport const Ring: FC<RingProps> = ({\n  outerRadius,\n  innerRadius,\n  padding,\n  normalizedFill,\n  normalizedStroke,\n  opacity,\n  animated,\n  theme\n}) => {\n  const { opacity: springOpacity } = useSpring({\n    from: { opacity: 0 },\n    to: { opacity },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  return (\n    <>\n      <mesh>\n        <ringGeometry attach=\"geometry\" args={[outerRadius, 0, 128]} />\n        <a.meshBasicMaterial\n          attach=\"material\"\n          color={normalizedFill}\n          transparent={true}\n          depthTest={false}\n          opacity={theme.cluster?.fill ? springOpacity : 0}\n          side={DoubleSide}\n          fog={true}\n        />\n      </mesh>\n      <mesh>\n        <ringGeometry\n          attach=\"geometry\"\n          args={[outerRadius, innerRadius + padding, 128]}\n        />\n        <a.meshBasicMaterial\n          attach=\"material\"\n          color={normalizedStroke}\n          transparent={true}\n          depthTest={false}\n          opacity={springOpacity}\n          side={DoubleSide}\n          fog={true}\n        />\n      </mesh>\n    </>\n  );\n};\n","import { Billboard, RoundedBox, Text } from '@react-three/drei';\nimport ellipsize from 'ellipsize';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport type { ColorRepresentation, Euler } from 'three';\nimport { Color } from 'three';\n\nexport interface LabelProps {\n  /**\n   * Text to render.\n   */\n  text: string;\n\n  /**\n   * Font URL.\n   * Reference: https://github.com/reaviz/reagraph/issues/23\n   */\n  fontUrl?: string;\n\n  /**\n   * Size of the font.\n   */\n  fontSize?: number;\n\n  /**\n   * Color of the text.\n   */\n  color?: ColorRepresentation;\n\n  /**\n   * Stroke of the text.\n   */\n  stroke?: ColorRepresentation;\n\n  /**\n   * Background color of the label.\n   */\n  backgroundColor?: ColorRepresentation;\n\n  /**\n   * Opacity of the background.\n   */\n  backgroundOpacity?: number;\n\n  /**\n   * Padding around the text for background sizing.\n   */\n  padding?: number;\n\n  /**\n   * Color of the background stroke/border.\n   */\n  strokeColor?: ColorRepresentation;\n\n  /**\n   * Size of the background stroke/border.\n   */\n  strokeWidth?: number;\n\n  /**\n   * Corner radius of the background.\n   */\n  radius?: number;\n\n  /**\n   * Opacity for the label.\n   */\n  opacity?: number;\n\n  /**\n   * The lenth of which to start the ellipsis.\n   */\n  ellipsis?: number;\n\n  /**\n   * Whether the label is active ( dragging, hover, focus ).\n   */\n  active?: boolean;\n\n  /**\n   * Rotation of the label.\n   */\n  rotation?: Euler | [number, number, number];\n}\n\nexport const Label: FC<LabelProps> = ({\n  text,\n  fontSize = 7,\n  fontUrl,\n  color = '#2A6475',\n  opacity = 1,\n  stroke,\n  backgroundColor,\n  backgroundOpacity = 1,\n  padding = 1,\n  strokeColor,\n  strokeWidth = 0,\n  radius = 0.1,\n  active,\n  ellipsis = 75,\n  rotation\n}) => {\n  const shortText = ellipsis && !active ? ellipsize(text, ellipsis) : text;\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n  const normalizedStroke = useMemo(\n    () => (stroke ? new Color(stroke) : undefined),\n    [stroke]\n  );\n  const normalizedBackgroundColor = useMemo(\n    () => (backgroundColor ? new Color(backgroundColor) : null),\n    [backgroundColor]\n  );\n  const normalizedStrokeColor = useMemo(\n    () => (strokeColor ? new Color(strokeColor) : null),\n    [strokeColor]\n  );\n  // Normalize the radius to be between 0 and 3\n  const normalizedRadius = Math.min(radius * fontSize, 3);\n\n  // Calculate background dimensions based on text and fontSize\n  const charCount = shortText.length;\n  const estimatedWidth = charCount * fontSize * 0.6 + padding * 2;\n  const estimatedHeight = fontSize * 1.2 + padding * 2;\n\n  const backgroundDimensions = {\n    width: estimatedWidth,\n    height: estimatedHeight\n  };\n\n  // Dynamic z-position based on active state\n  const zPosition = active ? 2 : 1;\n\n  return (\n    <Billboard position={[0, 0, zPosition]} renderOrder={1}>\n      {/* Stroke layer - rendered behind the background */}\n      {strokeWidth > 0 &&\n        normalizedStrokeColor &&\n        normalizedBackgroundColor && (\n          <mesh position={[0, 0, 10]}>\n            <RoundedBox\n              args={[\n                backgroundDimensions.width + strokeWidth,\n                backgroundDimensions.height + strokeWidth,\n                0.1\n              ]}\n              radius={normalizedRadius}\n              smoothness={8}\n              material-color={normalizedStrokeColor}\n              material-transparent={true}\n              material-opacity={backgroundOpacity}\n            />\n          </mesh>\n        )}\n      {/* Background layer */}\n      {normalizedBackgroundColor && (\n        <mesh position={[0, 0, 10]}>\n          <RoundedBox\n            args={[\n              backgroundDimensions.width,\n              backgroundDimensions.height,\n              0.1\n            ]}\n            radius={normalizedRadius}\n            smoothness={8}\n            material-color={normalizedBackgroundColor}\n            material-transparent={true}\n            material-opacity={backgroundOpacity}\n          />\n        </mesh>\n      )}\n      <Text\n        position={[0, 0, 11]}\n        font={fontUrl}\n        fontSize={fontSize}\n        color={normalizedColor}\n        fillOpacity={opacity}\n        textAlign=\"center\"\n        outlineWidth={stroke ? 1 : 0}\n        outlineColor={normalizedStroke}\n        depthOffset={0}\n        maxWidth={100}\n        overflowWrap=\"break-word\"\n        rotation={rotation}\n      >\n        {shortText}\n      </Text>\n    </Billboard>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport { useCursor } from '@react-three/drei';\nimport type { ThreeEvent } from '@react-three/fiber';\nimport type { FC } from 'react';\nimport React, { useMemo, useState } from 'react';\nimport type { Vector3 } from 'three';\nimport { Color } from 'three';\n\nimport { useCameraControls } from '../CameraControls/useCameraControls';\nimport { useStore } from '../store';\nimport type { ClusterRenderer } from '../types';\nimport type { ClusterGroup } from '../utils';\nimport { animationConfig } from '../utils';\nimport { useDrag } from '../utils/useDrag';\nimport { useHoverIntent } from '../utils/useHoverIntent';\nimport { Ring } from './clusters/Ring';\nimport { Label } from './Label';\n\nexport type ClusterEventArgs = Omit<ClusterGroup, 'position'>;\n\nexport interface ClusterProps extends ClusterGroup {\n  /**\n   * Whether the circle should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * The radius of the circle. Default 1.\n   */\n  radius?: number;\n\n  /**\n   * The padding of the circle. Default 20.\n   */\n  padding?: number;\n\n  /**\n   * The url for the label font.\n   */\n  labelFontUrl?: string;\n\n  /**\n   * Whether the node is disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * When the cluster was clicked.\n   */\n  onClick?: (cluster: ClusterEventArgs, event: ThreeEvent<MouseEvent>) => void;\n\n  /**\n   * When a cluster receives a pointer over event.\n   */\n  onPointerOver?: (\n    cluster: ClusterEventArgs,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * When cluster receives a pointer leave event.\n   */\n  onPointerOut?: (\n    cluster: ClusterEventArgs,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * Whether the cluster is draggable\n   */\n  draggable?: boolean;\n\n  /**\n   * Triggered after a cluster was dragged\n   */\n  onDragged?: (cluster: ClusterEventArgs) => void;\n\n  /**\n   * Render a custom cluster label\n   */\n  onRender?: ClusterRenderer;\n}\n\nexport const Cluster: FC<ClusterProps> = ({\n  animated,\n  position,\n  padding = 40,\n  labelFontUrl,\n  disabled,\n  radius = 2,\n  nodes,\n  label,\n  onClick,\n  onPointerOver,\n  onPointerOut,\n  draggable = false,\n  onDragged,\n  onRender\n}) => {\n  const theme = useStore(state => state.theme);\n  const rad = Math.max(position.width, position.height) / 2;\n  const offset = rad - radius + padding;\n  const [active, setActive] = useState<boolean>(false);\n  const center = useStore(state => state.centerPosition);\n  const nodesState = useStore(state => state.nodes);\n  const cameraControls = useCameraControls();\n  const draggingIds = useStore(state => state.draggingIds);\n  const isDraggingCurrent = draggingIds.includes(label);\n  const isDragging = draggingIds.length > 0;\n\n  const isActive = useStore(state =>\n    state.actives?.some(id => nodes.some(n => n.id === id))\n  );\n  const hoveredNodeId = useStore(state => state.hoveredNodeId);\n\n  const isSelected = useStore(state =>\n    state.selections?.some(id => nodes.some(n => n.id === id))\n  );\n\n  const hasSelections = useStore(state => state.selections?.length > 0);\n\n  const opacity = hasSelections\n    ? isSelected || active || isActive\n      ? theme.cluster?.selectedOpacity\n      : theme.cluster?.inactiveOpacity\n    : theme.cluster?.opacity;\n\n  const labelPosition: [number, number, number] = useMemo(() => {\n    const defaultPosition: [number, number, number] = [0, -offset, 2];\n    const themeOffset = theme.cluster?.label?.offset;\n    if (themeOffset) {\n      return [\n        defaultPosition[0] - themeOffset[0],\n        defaultPosition[1] - themeOffset[1],\n        defaultPosition[2] - themeOffset[2]\n      ];\n    }\n\n    return defaultPosition;\n  }, [offset, theme.cluster?.label?.offset]);\n\n  const { circlePosition } = useSpring({\n    from: {\n      circlePosition: [center.x, center.y, -1] as [number, number, number]\n    },\n    to: {\n      circlePosition: position\n        ? ([position.x, position.y, -1] as [number, number, number])\n        : ([0, 0, -1] as [number, number, number])\n    },\n    config: {\n      ...animationConfig,\n      duration: animated && !isDragging ? undefined : 0\n    }\n  });\n\n  const normalizedStroke = useMemo(\n    () => new Color(theme.cluster?.stroke),\n    [theme.cluster?.stroke]\n  );\n\n  const normalizedFill = useMemo(\n    () => new Color(theme.cluster?.fill),\n    [theme.cluster?.fill]\n  );\n\n  const addDraggingId = useStore(state => state.addDraggingId);\n  const removeDraggingId = useStore(state => state.removeDraggingId);\n  const setClusterPosition = useStore(state => state.setClusterPosition);\n\n  // Define the drag event handlers for the cluster\n  const bind = useDrag({\n    draggable: draggable && !hoveredNodeId,\n    position: {\n      x: position.x,\n      y: position.y,\n      z: -1\n    } as any,\n    set: (pos: Vector3) => setClusterPosition(label, pos as any),\n    onDragStart: () => {\n      addDraggingId(label);\n      setActive(true);\n    },\n    onDragEnd: () => {\n      removeDraggingId(label);\n      setActive(false);\n      // Get nodes from store with updated position after dragging\n      const updatedClusterNodes = nodesState.filter(n => n.cluster === label);\n      onDragged?.({ nodes: updatedClusterNodes, label });\n    }\n  });\n\n  // Set the cursor to pointer when the cluster is active and not dragging\n  useCursor(active && !isDragging && onClick !== undefined, 'pointer');\n  // Set the cursor to grab when the cluster is active and draggable\n  useCursor(\n    active && draggable && !isDraggingCurrent && onClick === undefined,\n    'grab'\n  );\n  // Set the cursor to grabbing when the cluster is dragging\n  useCursor(isDraggingCurrent, 'grabbing');\n\n  const { pointerOver, pointerOut } = useHoverIntent({\n    disabled,\n    onPointerOver: (event: ThreeEvent<PointerEvent>) => {\n      setActive(true);\n      cameraControls.freeze();\n      onPointerOver?.(\n        {\n          nodes,\n          label\n        },\n        event\n      );\n    },\n    onPointerOut: (event: ThreeEvent<PointerEvent>) => {\n      setActive(false);\n      cameraControls.unFreeze();\n      onPointerOut?.(\n        {\n          nodes,\n          label\n        },\n        event\n      );\n    }\n  });\n\n  const cluster = useMemo(\n    () =>\n      theme.cluster && (\n        <a.group\n          userData={{ id: label, type: 'cluster' }}\n          position={circlePosition as any}\n          onPointerOver={pointerOver}\n          onPointerOut={pointerOut}\n          onClick={(event: ThreeEvent<MouseEvent>) => {\n            if (!disabled && !isDraggingCurrent) {\n              onClick?.({ nodes, label }, event);\n            }\n          }}\n          {...(bind() as any)}\n        >\n          {onRender ? (\n            onRender({\n              label: {\n                position: labelPosition,\n                text: label,\n                opacity: opacity,\n                fontUrl: labelFontUrl\n              },\n              opacity,\n              outerRadius: offset,\n              innerRadius: rad,\n              padding,\n              theme\n            })\n          ) : (\n            <>\n              <Ring\n                outerRadius={offset}\n                innerRadius={rad}\n                padding={padding}\n                normalizedFill={normalizedFill}\n                normalizedStroke={normalizedStroke}\n                opacity={opacity}\n                animated={animated}\n                theme={theme}\n              />\n              {theme.cluster?.label && (\n                <a.group position={labelPosition}>\n                  <Label\n                    text={label}\n                    opacity={opacity}\n                    fontUrl={labelFontUrl}\n                    stroke={theme.cluster.label.stroke}\n                    active={false}\n                    color={theme.cluster?.label.color}\n                    fontSize={theme.cluster?.label.fontSize ?? 12}\n                  />\n                </a.group>\n              )}\n            </>\n          )}\n        </a.group>\n      ),\n    [\n      theme,\n      circlePosition,\n      pointerOver,\n      pointerOut,\n      offset,\n      normalizedFill,\n      rad,\n      padding,\n      normalizedStroke,\n      labelPosition,\n      label,\n      opacity,\n      labelFontUrl,\n      disabled,\n      onClick,\n      nodes,\n      bind,\n      isDraggingCurrent,\n      onRender,\n      animated\n    ]\n  );\n\n  return cluster;\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { ThreeEvent } from '@react-three/fiber';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport type { ColorRepresentation } from 'three';\nimport { Color } from 'three';\nimport { animationConfig } from 'utils/animation';\n\nexport interface SelfLoopProps {\n  /**\n   * The unique identifier of the edge.\n   */\n  id: string;\n\n  /**\n   * The color of the edge.\n   */\n  curve: any;\n\n  /**\n   * The size of the edge.\n   */\n  size: number;\n\n  /**\n   * The color of the edge.\n   */\n  color?: ColorRepresentation;\n\n  /**\n   * The opacity of the edge.\n   */\n  opacity: number;\n\n  /**\n   * Whether the edge is animated.\n   */\n  animated?: boolean;\n\n  /**\n   * A function that is called when the mouse pointer is moved over the line.\n   */\n  onPointerOver?: (event: ThreeEvent<PointerEvent>) => void;\n\n  /**\n   * A function that is called when the mouse pointer is moved out of the line.\n   */\n  onPointerOut?: (event: ThreeEvent<PointerEvent>) => void;\n\n  /**\n   * A function that is called when the line is clicked.\n   */\n  onClick?: (event: ThreeEvent<MouseEvent>) => void;\n\n  /**\n   * A function that is called when the line is right-clicked.\n   */\n  onContextMenu?: () => void;\n}\n\nexport const SelfLoop: FC<SelfLoopProps> = ({\n  id,\n  curve,\n  opacity = 1,\n  size = 1,\n  color = '#000',\n  animated,\n  onPointerOver,\n  onPointerOut,\n  onClick,\n  onContextMenu\n}) => {\n  const { scale, loopOpacity } = useSpring({\n    from: {\n      // Note: This prevents incorrect scaling w/ 0\n      scale: [0.00001, 0.00001, 0.00001],\n      loopOpacity: 0\n    },\n    to: {\n      scale: [size, size, size],\n      loopOpacity: opacity\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n\n  return (\n    <a.mesh\n      userData={{ id, type: 'edge' }}\n      renderOrder={-1}\n      onPointerOver={onPointerOver}\n      onPointerOut={onPointerOut}\n      onClick={onClick}\n      onPointerDown={event => {\n        if (event.nativeEvent.buttons === 2) {\n          event.nativeEvent.preventDefault();\n          event.stopPropagation();\n          onContextMenu();\n        }\n      }}\n      scale={scale as any}\n    >\n      <tubeGeometry attach=\"geometry\" args={[curve, 128, size / 2, 8, true]} />\n      <a.meshBasicMaterial\n        attach=\"material\"\n        opacity={loopOpacity}\n        fog={true}\n        transparent={true}\n        depthTest={false}\n        color={normalizedColor}\n      />\n    </a.mesh>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { ThreeEvent } from '@react-three/fiber';\nimport type { FC } from 'react';\nimport React, { useEffect, useMemo, useRef } from 'react';\nimport type { ColorRepresentation, Curve } from 'three';\nimport { Color, ShaderMaterial, TubeGeometry, Vector3 } from 'three';\n\nimport { useStore } from '../store';\nimport { animationConfig, getCurve } from '../utils';\n\nexport interface LineProps {\n  /**\n   * Whether the line should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * The color of the line.\n   */\n  color?: ColorRepresentation;\n\n  /**\n   * Whether the line should be curved.\n   */\n  curved: boolean;\n\n  /**\n   * The curve of the line in 3D space.\n   */\n  curve: Curve<Vector3>;\n\n  /**\n   * Whether the line should be dashed.\n   */\n  dashed?: boolean;\n\n  /**\n   * Dash pattern for the line: [dashSize, gapSize]\n   */\n  dashArray?: [number, number];\n\n  /**\n   * The unique identifier of the line.\n   */\n  id: string;\n\n  /**\n   * The opacity of the line.\n   */\n  opacity?: number;\n\n  /**\n   * The size of the line.\n   */\n  size?: number;\n\n  /**\n   * The render order of the line. Useful when edges are rendered on top of each other.\n   */\n  renderOrder?: number;\n\n  /**\n   * A function that is called when the line is clicked.\n   */\n  onClick?: (event: ThreeEvent<MouseEvent>) => void;\n\n  /**\n   * A function that is called when the line is right-clicked.\n   */\n  onContextMenu?: () => void;\n\n  /**\n   * A function that is called when the mouse pointer is moved over the line.\n   */\n  onPointerOver?: (event: ThreeEvent<PointerEvent>) => void;\n\n  /**\n   * A function that is called when the mouse pointer is moved out of the line.\n   */\n  onPointerOut?: (event: ThreeEvent<PointerEvent>) => void;\n\n  /**\n   * The offset of the curve.\n   */\n  curveOffset?: number;\n}\n\n// Dashed line shader for tube geometry\nconst dashedVertexShader = `\n  varying vec2 vUv;\n  void main() {\n    vUv = uv;\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n  }\n`;\n\nconst dashedFragmentShader = `\n  uniform vec3 color;\n  uniform float opacity;\n  uniform float dashSize;\n  uniform float gapSize;\n  uniform float lineLength;\n  varying vec2 vUv;\n\n  void main() {\n    float totalSize = dashSize + gapSize;\n    float position = mod(vUv.x * lineLength, totalSize);\n\n    if (position > dashSize) {\n      discard;\n    }\n\n    gl_FragColor = vec4(color, opacity);\n  }\n`;\n\nexport const Line: FC<LineProps> = ({\n  curveOffset,\n  animated,\n  color = '#000',\n  curve,\n  curved = false,\n  dashed = false,\n  dashArray = [3, 1],\n  id,\n  opacity = 1,\n  size = 1,\n  renderOrder = -1,\n  onContextMenu,\n  onClick,\n  onPointerOver,\n  onPointerOut\n}) => {\n  const tubeRef = useRef<TubeGeometry | null>(null);\n  const isDragging = useStore(state => state.draggingIds.length > 0);\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n  const center = useStore(state => state.centerPosition);\n  const mounted = useRef<boolean>(false);\n\n  // Create dashed material\n  const dashedMaterial = useMemo(() => {\n    if (!dashed) return null;\n    const [dashSize, dashGap] = dashArray;\n\n    return new ShaderMaterial({\n      uniforms: {\n        color: { value: normalizedColor },\n        opacity: { value: opacity },\n        dashSize: { value: dashSize },\n        gapSize: { value: dashGap },\n        lineLength: { value: curve.getLength() }\n      },\n      vertexShader: dashedVertexShader,\n      fragmentShader: dashedFragmentShader,\n      transparent: true,\n      depthTest: false\n    });\n  }, [dashed, normalizedColor, opacity, curve, dashArray]);\n\n  // Do opacity seperate from vertices for perf\n  const { lineOpacity } = useSpring({\n    from: {\n      lineOpacity: 0\n    },\n    to: {\n      lineOpacity: opacity\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  useSpring(() => {\n    const from = curve.getPoint(0);\n    const to = curve.getPoint(1);\n    return {\n      from: {\n        // Animate from center first time, then from the actual from point\n        fromVertices: !mounted.current\n          ? [center?.x, center?.y, center?.z || 0]\n          : [to?.x, to?.y, to?.z || 0],\n        toVertices: [from?.x, from?.y, from?.z || 0]\n      },\n      to: {\n        fromVertices: [from?.x, from?.y, from?.z || 0],\n        toVertices: [to?.x, to?.y, to?.z || 0]\n      },\n      onChange: event => {\n        const { fromVertices, toVertices } = event.value;\n        const fromVector = new Vector3(...fromVertices);\n        const toVector = new Vector3(...toVertices);\n\n        const curve = getCurve(fromVector, 0, toVector, 0, curved, curveOffset);\n\n        if (tubeRef.current) {\n          // Use slightly smaller radius for dashed lines for visual distinction\n          const radius = dashed ? size * 0.4 : size / 2;\n          tubeRef.current.copy(new TubeGeometry(curve, 20, radius, 5, false));\n        }\n      },\n      config: {\n        ...animationConfig,\n        duration: animated && !isDragging ? undefined : 0\n      }\n    };\n  }, [animated, isDragging, curve, size, dashed, curved, curveOffset]);\n\n  useEffect(() => {\n    // Handle mount operation for initial render\n    mounted.current = true;\n  }, []);\n\n  return (\n    <mesh\n      userData={{ id, type: 'edge' }}\n      renderOrder={renderOrder}\n      onPointerOver={onPointerOver}\n      onPointerOut={onPointerOut}\n      onClick={onClick}\n      // context menu controls\n      onPointerDown={event => {\n        if (event.nativeEvent.buttons === 2) {\n          event.stopPropagation();\n        }\n      }}\n      onContextMenu={event => {\n        event.nativeEvent.preventDefault();\n        event.stopPropagation();\n        onContextMenu();\n      }}\n    >\n      <tubeGeometry attach=\"geometry\" ref={tubeRef} />\n      {dashed ? (\n        <primitive attach=\"material\" object={dashedMaterial} />\n      ) : (\n        <a.meshBasicMaterial\n          attach=\"material\"\n          opacity={lineOpacity}\n          fog={true}\n          transparent={true}\n          color={normalizedColor}\n        />\n      )}\n    </mesh>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport { Html, useCursor } from '@react-three/drei';\nimport type { ThreeEvent } from '@react-three/fiber';\nimport type { FC } from 'react';\nimport React, { useMemo, useState } from 'react';\nimport { Euler, Vector3 } from 'three';\n\nimport { useStore } from '../store';\nimport type { ContextMenuEvent, InternalGraphEdge } from '../types';\nimport {\n  animationConfig,\n  calculateEdgeCurveOffset,\n  getArrowSize,\n  getArrowVectors,\n  getCurve,\n  getLabelOffsetByType,\n  getMidPoint,\n  getVector\n} from '../utils';\nimport { calculateSubLabelOffset, getSelfLoopCurve } from '../utils/position';\nimport { useHoverIntent } from '../utils/useHoverIntent';\nimport type { EdgeArrowPosition } from './Arrow';\nimport { Arrow } from './Arrow';\nimport { SelfLoop } from './edges/SelfLoop';\nimport { Label } from './Label';\nimport { Line } from './Line';\n\n/**\n * Label positions relatively edge.\n *\n * - below: show label under the edge line\n * - above: show label above the edge line\n * - inline: show label along the edge line\n * - natural: normal text positions\n */\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\n\n/**\n * SubLabel positions relatively to the main label.\n *\n * - below: show subLabel below the main label\n * - above: show subLabel above the main label\n */\nexport type EdgeSubLabelPosition = 'below' | 'above';\n\n/**\n * Type of edge interpolation.\n *\n * - Linear is straight\n * - Curved is curved\n */\nexport type EdgeInterpolation = 'linear' | 'curved';\n\nexport interface EdgeProps {\n  /**\n   * The url for the label font.\n   */\n  labelFontUrl?: string;\n\n  /**\n   * The unique identifier of the edge.\n   */\n  id: string;\n\n  /**\n   * Whether the edge should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * Whether the edge should be disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * The placement of the edge label.\n   */\n  labelPlacement?: EdgeLabelPosition;\n\n  /**\n   * The placement of the edge subLabel relative to the main label.\n   */\n  subLabelPlacement?: EdgeSubLabelPosition;\n\n  /**\n   * The placement of the edge arrow.\n   */\n  arrowPlacement?: EdgeArrowPosition;\n\n  /**\n   * The type of interpolation used to draw the edge.\n   */\n  interpolation: EdgeInterpolation;\n\n  /**\n   * A function that returns the context menu for the edge.\n   */\n  contextMenu?: (event: Partial<ContextMenuEvent>) => React.ReactNode;\n\n  /**\n   * A function that is called when the edge is clicked.\n   */\n  onClick?: (edge: InternalGraphEdge, event: ThreeEvent<MouseEvent>) => void;\n\n  /**\n   * A function that is called when the edge is right-clicked.\n   */\n  onContextMenu?: (edge?: InternalGraphEdge) => void;\n\n  /**\n   * A function that is called when the mouse pointer is moved over the edge.\n   */\n  onPointerOver?: (\n    edge: InternalGraphEdge,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * A function that is called when the mouse pointer is moved out of the edge.\n   */\n  onPointerOut?: (\n    edge: InternalGraphEdge,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n}\n\nconst LABEL_PLACEMENT_OFFSET = 3;\n\nexport const Edge: FC<EdgeProps> = ({\n  animated,\n  arrowPlacement = 'end',\n  contextMenu,\n  disabled,\n  labelPlacement = 'inline',\n  id,\n  interpolation,\n  labelFontUrl,\n  onContextMenu,\n  onClick,\n  onPointerOver,\n  onPointerOut,\n  subLabelPlacement = 'below'\n}) => {\n  const theme = useStore(state => state.theme);\n  const isDragging = useStore(state => state.draggingIds.length > 0);\n\n  // UI states\n  const [active, setActive] = useState<boolean>(false);\n  const [menuVisible, setMenuVisible] = useState<boolean>(false);\n\n  // Edge data\n  const edges = useStore(state => state.edges);\n  const edge = edges.find(e => e.id === id);\n  const {\n    target,\n    source,\n    label,\n    subLabel,\n    labelVisible = false,\n    size = 1,\n    fill,\n    dashed = false,\n    dashArray = [3, 1]\n  } = edge;\n\n  // Use subLabelPlacement from edge data if available, otherwise use the prop value\n  const effectiveSubLabelPlacement =\n    edge.subLabelPlacement || subLabelPlacement;\n\n  const from = useStore(store => store.nodes.find(node => node.id === source));\n  const to = useStore(store => store.nodes.find(node => node.id === target));\n\n  // Detect self-loop\n  const isSelfLoop = from.id === to.id;\n\n  // Edge properties\n  const labelOffset = (size + theme.edge.label.fontSize) / 2;\n  const [arrowLength, arrowSize] = useMemo(() => getArrowSize(size), [size]);\n\n  // Use edge-specific interpolation if available, otherwise use global interpolation\n  const effectiveInterpolation = edge.interpolation || interpolation;\n\n  // Use edge-specific arrow placement if available, otherwise use global arrow placement\n  const effectiveArrowPlacement = edge.arrowPlacement || arrowPlacement;\n\n  const { curveOffset, curved } = useMemo(\n    () =>\n      calculateEdgeCurveOffset({\n        edge,\n        edges,\n        curved: effectiveInterpolation === 'curved'\n      }),\n    [edge, edges, effectiveInterpolation]\n  );\n\n  const [curve, arrowPosition, arrowRotation] = useMemo(() => {\n    const fromVector = getVector(from);\n    const fromOffset = from.size;\n    const toVector = getVector(to);\n    const toOffset = to.size;\n\n    let curve = getCurve(\n      fromVector,\n      fromOffset,\n      toVector,\n      toOffset,\n      curved,\n      curveOffset\n    );\n\n    const [arrowPosition, arrowRotation] = getArrowVectors(\n      effectiveArrowPlacement,\n      curve,\n      arrowLength\n    );\n\n    if (effectiveArrowPlacement === 'end') {\n      curve = getCurve(\n        fromVector,\n        fromOffset,\n        arrowPosition,\n        0,\n        curved,\n        curveOffset\n      );\n    }\n\n    return [curve, arrowPosition, arrowRotation];\n  }, [from, to, curved, curveOffset, effectiveArrowPlacement, arrowLength]);\n\n  const midPoint = useMemo(() => {\n    let newMidPoint = getMidPoint(\n      from.position,\n      to.position,\n      getLabelOffsetByType(labelOffset, labelPlacement)\n    );\n\n    if (curved) {\n      // Offset the label to the mid point of the curve\n      const offset = new Vector3().subVectors(newMidPoint, curve.getPoint(0.5));\n      switch (labelPlacement) {\n        case 'above':\n          offset.y = offset.y - LABEL_PLACEMENT_OFFSET;\n          break;\n        case 'below':\n          offset.y = offset.y + LABEL_PLACEMENT_OFFSET;\n          break;\n      }\n      newMidPoint = newMidPoint.sub(offset);\n    }\n\n    return newMidPoint;\n  }, [from.position, to.position, labelOffset, labelPlacement, curved, curve]);\n\n  const center = useStore(state => state.centerPosition);\n\n  const isSelected = useStore(state => state.selections?.includes(id));\n  const hasSelections = useStore(state => state.selections?.length);\n  const isActive = useStore(state => state.actives?.includes(id));\n  const isActiveState = active || isActive || isSelected;\n\n  const selectionOpacity = hasSelections\n    ? isSelected || isActive\n      ? theme.edge.selectedOpacity\n      : theme.edge.inactiveOpacity\n    : theme.edge.opacity;\n\n  // Calculate subLabel position based on edge orientation and subLabelPlacement\n  const subLabelOffset = useMemo(() => {\n    return calculateSubLabelOffset(\n      from.position,\n      to.position,\n      effectiveSubLabelPlacement\n    );\n  }, [from.position, to.position, effectiveSubLabelPlacement]);\n\n  const [{ labelPosition }] = useSpring(\n    () => ({\n      from: {\n        labelPosition: center ? [center.x, center.y, center.z] : [0, 0, 0]\n      },\n      to: {\n        labelPosition: [midPoint.x, midPoint.y, midPoint.z]\n      },\n      config: {\n        ...animationConfig,\n        duration: animated && !isDragging ? undefined : 0\n      }\n    }),\n    [midPoint, animated, isDragging]\n  );\n\n  const labelRotation = useMemo(\n    () =>\n      new Euler(\n        0,\n        0,\n        labelPlacement === 'natural'\n          ? 0\n          : Math.atan(\n              (to.position.y - from.position.y) /\n                (to.position.x - from.position.x)\n            )\n      ),\n    [\n      to.position.x,\n      to.position.y,\n      from.position.x,\n      from.position.y,\n      labelPlacement\n    ]\n  );\n\n  useCursor(active && !isDragging && onClick !== undefined, 'pointer');\n\n  const { pointerOver, pointerOut } = useHoverIntent({\n    disabled,\n    onPointerOver: (event: ThreeEvent<PointerEvent>) => {\n      setActive(true);\n      onPointerOver?.(edge, event);\n    },\n    onPointerOut: (event: ThreeEvent<PointerEvent>) => {\n      setActive(false);\n      onPointerOut?.(edge, event);\n    }\n  });\n\n  const selfLoopCurve = useMemo(() => getSelfLoopCurve(from), [from]);\n\n  const arrowComponent = useMemo(() => {\n    if (effectiveArrowPlacement === 'none') return null;\n\n    let position: Vector3;\n    let rotation: Vector3;\n\n    if (isSelfLoop && selfLoopCurve) {\n      // Arrow for self-loop\n      const uEnd = 0.58;\n      const uMid = 0.25;\n      if (effectiveArrowPlacement === 'mid') {\n        position = selfLoopCurve.getPointAt(uMid);\n        rotation = selfLoopCurve.getTangentAt(uMid);\n      } else {\n        // end is default\n        position = selfLoopCurve.getPointAt(uEnd);\n        rotation = selfLoopCurve.getTangentAt(uEnd);\n      }\n    } else {\n      // Arrow for normal edge\n      position = arrowPosition;\n      rotation = arrowRotation;\n    }\n\n    return (\n      <Arrow\n        animated={animated}\n        color={\n          isActiveState ? theme.arrow.activeFill : fill || theme.arrow.fill\n        }\n        length={arrowLength}\n        opacity={selectionOpacity}\n        position={position}\n        rotation={rotation}\n        size={arrowSize}\n        onActive={setActive}\n        onContextMenu={() => {\n          if (!disabled) {\n            setMenuVisible(true);\n            onContextMenu?.(edge);\n          }\n        }}\n      />\n    );\n  }, [\n    fill,\n    animated,\n    arrowLength,\n    effectiveArrowPlacement,\n    arrowPosition,\n    arrowRotation,\n    arrowSize,\n    disabled,\n    edge,\n    isActiveState,\n    onContextMenu,\n    selectionOpacity,\n    theme.arrow.activeFill,\n    theme.arrow.fill,\n    isSelfLoop,\n    selfLoopCurve\n  ]);\n\n  const labelComponent = useMemo(\n    () =>\n      labelVisible &&\n      label && (\n        <a.group\n          position={labelPosition as any}\n          onContextMenu={() => {\n            if (!disabled) {\n              setMenuVisible(true);\n              onContextMenu?.(edge);\n            }\n          }}\n          onPointerOver={pointerOver}\n          onPointerOut={pointerOut}\n        >\n          <Label\n            text={label}\n            ellipsis={15}\n            fontUrl={labelFontUrl}\n            stroke={theme.edge.label.stroke}\n            color={\n              isActiveState\n                ? theme.edge.label.activeColor\n                : theme.edge.label.color\n            }\n            opacity={selectionOpacity}\n            fontSize={theme.edge.label.fontSize}\n            rotation={labelRotation}\n            active={isActiveState}\n          />\n\n          {subLabel && (\n            <group position={[subLabelOffset.x, subLabelOffset.y, 0]}>\n              <Label\n                text={subLabel}\n                ellipsis={15}\n                fontUrl={labelFontUrl}\n                stroke={theme.edge.subLabel?.stroke || theme.edge.label.stroke}\n                active={isActiveState}\n                color={\n                  isActiveState\n                    ? theme.edge.subLabel?.activeColor ||\n                      theme.edge.label.activeColor\n                    : theme.edge.subLabel?.color || theme.edge.label.color\n                }\n                opacity={selectionOpacity}\n                fontSize={\n                  theme.edge.subLabel?.fontSize ||\n                  theme.edge.label.fontSize * 0.8\n                }\n                rotation={labelRotation}\n              />\n            </group>\n          )}\n        </a.group>\n      ),\n    [\n      disabled,\n      edge,\n      isActiveState,\n      label,\n      subLabel,\n      labelFontUrl,\n      labelPosition,\n      subLabelOffset,\n      labelRotation,\n      labelVisible,\n      onContextMenu,\n      pointerOut,\n      pointerOver,\n      selectionOpacity,\n      theme.edge.label.activeColor,\n      theme.edge.label.color,\n      theme.edge.label.fontSize,\n      theme.edge.label.stroke,\n      theme.edge.subLabel?.stroke,\n      theme.edge.subLabel?.activeColor,\n      theme.edge.subLabel?.color,\n      theme.edge.subLabel?.fontSize\n    ]\n  );\n\n  const menuComponent = useMemo(\n    () =>\n      menuVisible &&\n      contextMenu && (\n        <Html prepend={true} center={true} position={midPoint}>\n          {contextMenu({ data: edge, onClose: () => setMenuVisible(false) })}\n        </Html>\n      ),\n    [menuVisible, contextMenu, midPoint, edge]\n  );\n\n  return (\n    <group position={[0, 0, isActiveState ? 1 : 0]}>\n      {isSelfLoop && selfLoopCurve ? (\n        <SelfLoop\n          id={id}\n          curve={selfLoopCurve}\n          size={size}\n          animated={animated}\n          color={\n            isActiveState ? theme.edge.activeFill : fill || theme.edge.fill\n          }\n          opacity={selectionOpacity}\n          onClick={event => {\n            if (!disabled) {\n              onClick?.(edge, event);\n            }\n          }}\n          onContextMenu={() => {\n            if (!disabled) {\n              setMenuVisible(true);\n              onContextMenu?.(edge);\n            }\n          }}\n          onPointerOver={pointerOver}\n          onPointerOut={pointerOut}\n        />\n      ) : (\n        <Line\n          curveOffset={curveOffset}\n          animated={animated}\n          color={\n            isActiveState ? theme.edge.activeFill : fill || theme.edge.fill\n          }\n          curve={curve}\n          curved={curved}\n          dashed={dashed}\n          dashArray={dashArray}\n          id={id}\n          opacity={selectionOpacity}\n          size={size}\n          renderOrder={isActiveState ? 0 : -1}\n          onClick={event => {\n            if (!disabled) {\n              onClick?.(edge, event);\n            }\n          }}\n          onPointerOver={pointerOver}\n          onPointerOut={pointerOut}\n          onContextMenu={() => {\n            if (!disabled) {\n              setMenuVisible(true);\n              onContextMenu?.(edge);\n            }\n          }}\n        />\n      )}\n      {arrowComponent}\n      {labelComponent}\n      {menuComponent}\n    </group>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport { Html } from '@react-three/drei';\nimport type { FC } from 'react';\nimport React, { useCallback, useMemo } from 'react';\nimport type { ColorRepresentation } from 'three';\nimport { Euler } from 'three';\n\nimport { useStore } from '../../store';\nimport type { ContextMenuEvent, InternalGraphEdge } from '../../types';\nimport {\n  animationConfig,\n  getLabelOffsetByType,\n  getMidPoint\n} from '../../utils';\nimport { Label } from '../Label';\n\n/**\n * Label positions relatively edge\n *\n * below: show label under the edge line\n * above: show label above the edge line\n * inline: show label along the edge line\n * natural: normal text positions\n */\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\n\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\n\nexport interface EdgeProps {\n  /**\n   * Whether the edge should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * Whether the edge should be disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * The color of the edge.\n   */\n  color: ColorRepresentation;\n\n  /**\n   * A function that returns the context menu for the edge.\n   */\n  contextMenu?: (event: Partial<ContextMenuEvent>) => React.ReactNode;\n\n  /**\n   * The edge object.\n   */\n  edge: InternalGraphEdge;\n\n  /**\n   * The URL of the font for the edge label.\n   */\n  labelFontUrl?: string;\n\n  /**\n   * The placement of the edge label.\n   */\n  labelPlacement?: EdgeLabelPosition;\n\n  /**\n   * The opacity of the edge.\n   */\n  opacity?: number;\n\n  /**\n   * Whether the edge is active.\n   */\n  active?: boolean;\n}\n\nexport const Edge: FC<EdgeProps> = ({\n  animated,\n  color,\n  contextMenu,\n  edge,\n  labelFontUrl,\n  labelPlacement = 'inline',\n  opacity,\n  active\n}) => {\n  const theme = useStore(state => state.theme);\n  const { target, source, label, labelVisible = false, size = 1 } = edge;\n\n  const nodes = useStore(store => store.nodes);\n  const [from, to] = useMemo(\n    () => [\n      nodes.find(node => node.id === source),\n      nodes.find(node => node.id === target)\n    ],\n    [nodes, source, target]\n  );\n  const isDragging = useStore(state => state.draggingIds.length > 0);\n\n  const labelOffset = useMemo(\n    () => (size + theme.edge.label.fontSize) / 2,\n    [size, theme.edge.label.fontSize]\n  );\n\n  const midPoint = useMemo(\n    () =>\n      getMidPoint(\n        from.position,\n        to.position,\n        getLabelOffsetByType(labelOffset, labelPlacement)\n      ),\n    [from.position, to.position, labelOffset, labelPlacement]\n  );\n\n  const edgeContextMenus = useStore(state => state.edgeContextMenus);\n  const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\n\n  const [{ labelPosition }] = useSpring(\n    () => ({\n      from: {\n        labelPosition: [0, 0, 0]\n      },\n      to: {\n        labelPosition: [midPoint.x, midPoint.y, midPoint.z]\n      },\n      config: {\n        ...animationConfig,\n        duration: animated && !isDragging ? undefined : 0\n      }\n    }),\n    [midPoint, animated, isDragging]\n  );\n\n  const removeContextMenu = useCallback(\n    (edgeId: string) => {\n      const newEdgeContextMenus = new Set(edgeContextMenus);\n      newEdgeContextMenus.delete(edgeId);\n      setEdgeContextMenus(newEdgeContextMenus);\n    },\n    [edgeContextMenus, setEdgeContextMenus]\n  );\n\n  const labelRotation = useMemo(\n    () =>\n      new Euler(\n        0,\n        0,\n        labelPlacement === 'natural'\n          ? 0\n          : Math.atan(\n              (to.position.y - from.position.y) /\n                (to.position.x - from.position.x)\n            )\n      ),\n    [\n      to.position.x,\n      to.position.y,\n      from.position.x,\n      from.position.y,\n      labelPlacement\n    ]\n  );\n\n  const htmlProps = useMemo(\n    () => ({\n      prepend: true,\n      center: true,\n      position: midPoint\n    }),\n    [midPoint]\n  );\n\n  const labelProps = useMemo(\n    () => ({\n      text: label,\n      ellipsis: 15,\n      fontUrl: labelFontUrl,\n      stroke: theme.edge.label.stroke,\n      color,\n      opacity,\n      fontSize: theme.edge.label.fontSize,\n      rotation: labelRotation,\n      active\n    }),\n    [\n      label,\n      labelFontUrl,\n      theme.edge.label.stroke,\n      color,\n      opacity,\n      theme.edge.label.fontSize,\n      labelRotation,\n      active\n    ]\n  );\n\n  return (\n    <group>\n      {labelVisible && label && (\n        <a.group position={labelPosition as any}>\n          <Label {...labelProps} />\n        </a.group>\n      )}\n      {contextMenu && edgeContextMenus.has(edge.id) && (\n        <Html {...htmlProps}>\n          {contextMenu({\n            data: edge,\n            onClose: () => removeContextMenu(edge.id)\n          })}\n        </Html>\n      )}\n    </group>\n  );\n};\n","import type { SpringValue } from '@react-spring/three';\nimport { useSpring } from '@react-spring/three';\nimport { useCallback, useEffect, useRef } from 'react';\nimport type { BufferGeometry } from 'three';\nimport { BufferAttribute } from 'three';\n\nimport type { Theme } from '../../themes';\nimport { animationConfig } from '../../utils';\n\nexport function useEdgePositionAnimation(\n  geometry: BufferGeometry,\n  animated: boolean\n): void {\n  const geometryRef = useRef<BufferGeometry>(geometry);\n  const bufferPool = useRef<Float32Array | null>(null);\n\n  useEffect(() => {\n    geometryRef.current = geometry;\n    const positions = geometry.getAttribute('position');\n    bufferPool.current = new Float32Array(positions.array.length);\n  }, [geometry]);\n\n  const getAnimationPositions = useCallback(() => {\n    const positions = geometryRef.current.getAttribute('position');\n    const from = new Float32Array(positions.array.length);\n    return {\n      from,\n      to: positions.array\n    };\n  }, []);\n\n  const updateGeometryPosition = useCallback((positions: Array<number>) => {\n    const buffer = bufferPool.current!;\n    buffer.set(positions);\n    const newPosition = new BufferAttribute(buffer, 3, false);\n    geometryRef.current.setAttribute('position', newPosition);\n    newPosition.needsUpdate = true;\n  }, []);\n\n  useSpring(() => {\n    if (!animated) {\n      return null;\n    }\n\n    const animationPositions = getAnimationPositions();\n\n    return {\n      from: {\n        positions: animationPositions.from\n      },\n      to: {\n        positions: animationPositions.to\n      },\n      onChange: event => {\n        updateGeometryPosition(event.value.positions);\n      },\n      config: {\n        ...animationConfig,\n        duration: animated ? undefined : 0\n      }\n    };\n  }, [animated, getAnimationPositions, updateGeometryPosition]);\n}\n\nexport type UseEdgeOpacityAnimations = {\n  activeOpacity: SpringValue<number>;\n  inactiveOpacity: SpringValue<number>;\n};\n\nexport function useEdgeOpacityAnimation(\n  animated: boolean,\n  hasSelections: boolean,\n  theme: Theme\n): UseEdgeOpacityAnimations {\n  const [{ activeOpacity, inactiveOpacity }] = useSpring(() => {\n    return {\n      from: {\n        activeOpacity: 0,\n        inactiveOpacity: 0\n      },\n      to: {\n        activeOpacity: hasSelections\n          ? theme.edge.selectedOpacity\n          : theme.edge.opacity,\n        inactiveOpacity: hasSelections\n          ? theme.edge.inactiveOpacity\n          : theme.edge.opacity\n      },\n      config: {\n        ...animationConfig,\n        duration: animated ? undefined : 0\n      }\n    };\n  }, [animated, hasSelections, theme]);\n\n  return { activeOpacity, inactiveOpacity };\n}\n","import { useCallback, useEffect, useRef } from 'react';\n\nimport { useStore } from '../../store';\nimport type { InternalGraphEdge } from '../../types';\n\nexport type EdgeEvents = {\n  onClick?: (edge: InternalGraphEdge) => void;\n  onContextMenu?: (edge?: InternalGraphEdge) => void;\n  onPointerOver?: (edge: InternalGraphEdge) => void;\n  onPointerOut?: (edge: InternalGraphEdge) => void;\n};\n\nexport function useEdgeEvents(\n  events: EdgeEvents,\n  contextMenu,\n  disabled: boolean\n) {\n  const memoizedEvents = useRef(events);\n  useEffect(() => {\n    memoizedEvents.current = events;\n  }, [events]);\n\n  const edgeContextMenus = useStore(state => state.edgeContextMenus);\n  const setEdgeContextMenus = useStore(\n    useCallback(state => state.setEdgeContextMenus, [])\n  );\n  const setHoveredEdgeIds = useStore(\n    useCallback(state => state.setHoveredEdgeIds, [])\n  );\n\n  const clickRef = useRef(false);\n  const handleClick = useCallback(() => {\n    clickRef.current = true;\n  }, []);\n\n  const contextMenuEventRef = useRef(false);\n  const handleContextMenu = useCallback(() => {\n    contextMenuEventRef.current = true;\n  }, []);\n\n  const handleIntersections = useCallback(\n    (\n      previous: Array<InternalGraphEdge>,\n      intersected: Array<InternalGraphEdge>\n    ) => {\n      const { onClick, onContextMenu, onPointerOver, onPointerOut } =\n        memoizedEvents.current;\n\n      if (onClick && clickRef.current && !disabled) {\n        clickRef.current = false;\n        for (const edge of intersected) {\n          onClick(edge);\n        }\n      }\n\n      if (\n        (contextMenu || onContextMenu) &&\n        contextMenuEventRef.current &&\n        !disabled\n      ) {\n        contextMenuEventRef.current = false;\n        const newEdges = new Set(edgeContextMenus);\n        let hasChanges = false;\n\n        for (const edge of intersected) {\n          if (!edgeContextMenus.has(edge.id)) {\n            newEdges.add(edge.id);\n            hasChanges = true;\n            onContextMenu?.(edge);\n          }\n        }\n\n        if (hasChanges) {\n          setEdgeContextMenus(newEdges);\n        }\n      }\n\n      const hoveredIds =\n        intersected.length > 0 ? intersected.map(edge => edge.id) : [];\n      setHoveredEdgeIds(hoveredIds);\n\n      if (onPointerOver) {\n        const over = intersected.filter(index => !previous.includes(index));\n        over.forEach(edge => {\n          onPointerOver(edge);\n        });\n      }\n\n      if (onPointerOut) {\n        const out = previous.filter(index => !intersected.includes(index));\n        out.forEach(edge => {\n          onPointerOut(edge);\n        });\n      }\n    },\n    [\n      contextMenu,\n      disabled,\n      edgeContextMenus,\n      setEdgeContextMenus,\n      setHoveredEdgeIds\n    ]\n  );\n\n  return {\n    handleClick,\n    handleContextMenu,\n    handleIntersections\n  };\n}\n","import { useCallback, useRef } from 'react';\nimport type { BufferGeometry, Curve } from 'three';\nimport {\n  Color,\n  CylinderGeometry,\n  Quaternion,\n  TubeGeometry,\n  Vector3\n} from 'three';\nimport { mergeBufferGeometries } from 'three-stdlib';\n\nimport type { GraphState } from '../../store';\nimport { useStore } from '../../store';\nimport type { InternalGraphEdge } from '../../types';\nimport {\n  addColorAttribute,\n  createDashedGeometry,\n  createNullGeometry,\n  getArrowSize,\n  getArrowVectors,\n  getCurve,\n  getSelfLoopCurve,\n  getVector\n} from '../../utils';\nimport type { EdgeArrowPosition } from '../Arrow';\nimport type { EdgeInterpolation } from '../Edge';\n\nexport type UseEdgeGeometry = {\n  getGeometries(edges: Array<InternalGraphEdge>): Array<BufferGeometry>;\n  getGeometry(\n    active: Array<InternalGraphEdge>,\n    inactive: Array<InternalGraphEdge>\n  ): BufferGeometry;\n};\n\nconst NULL_GEOMETRY = createNullGeometry();\n\nexport function useEdgeGeometry(\n  arrowPlacement: EdgeArrowPosition,\n  interpolation: EdgeInterpolation\n): UseEdgeGeometry {\n  // We don't want to rerun everything when the state changes,\n  // but we do want to use the most recent nodes whenever `getGeometries`\n  // or `getGeometry` is run, so we store it in a ref:\n  const stateRef = useRef<GraphState | null>(null);\n  const theme = useStore(state => state.theme);\n  useStore(state => {\n    stateRef.current = state;\n  });\n\n  const geometryCacheRef = useRef(new Map<string, BufferGeometry>());\n\n  // Add memoized geometry for arrows\n  const baseArrowGeometryRef = useRef<CylinderGeometry | null>(null);\n\n  const getGeometries = useCallback(\n    (edges: Array<InternalGraphEdge>): Array<BufferGeometry> => {\n      const geometries: Array<BufferGeometry> = [];\n      const cache = geometryCacheRef.current;\n\n      // Pre-compute values outside the loop\n      const { nodes } = stateRef.current;\n      const nodesMap = new Map(nodes.map(node => [node.id, node]));\n\n      // Initialize base arrow geometry if needed\n      if (arrowPlacement !== 'none' && !baseArrowGeometryRef.current) {\n        baseArrowGeometryRef.current = new CylinderGeometry(\n          0,\n          1,\n          1,\n          20,\n          1,\n          true\n        );\n      }\n\n      edges.forEach(edge => {\n        const { target, source, size = 1 } = edge;\n        const from = nodesMap.get(source);\n        const to = nodesMap.get(target);\n\n        if (!from || !to) {\n          return;\n        }\n        // Improved hash function to include size\n        const hash = `${from.position.x},${from.position.y},${to.position.x},${to.position.y},${size}`;\n\n        // Detect self-loop\n        const isSelfLoop = from.id === to.id;\n        // Determine interpolation for this specific edge\n        const edgeInterpolation = edge.interpolation || interpolation;\n        const curved = edgeInterpolation === 'curved';\n\n        // Determine arrow placement for this specific edge\n        const edgeArrowPlacement = edge.arrowPlacement || arrowPlacement;\n\n        if (cache.has(hash)) {\n          geometries.push(cache.get(hash));\n          return;\n        }\n        const fromVector = getVector(from);\n        const fromOffset = from.size;\n        const toVector = getVector(to);\n        const toOffset = to.size;\n\n        let curve: Curve<Vector3>;\n        if (isSelfLoop) {\n          // Self-loop curve\n          curve = getSelfLoopCurve(from);\n        } else {\n          // Regular edge curve\n          curve = getCurve(fromVector, fromOffset, toVector, toOffset, curved);\n        }\n\n        // Use smaller radius for dashed edges to match Line.tsx behavior\n        const isDashedEdge = edge.dashed;\n        const radius = isDashedEdge ? size * 0.4 : size / 2;\n\n        let edgeGeometry: BufferGeometry;\n        if (isDashedEdge) {\n          edgeGeometry = createDashedGeometry(\n            curve,\n            radius,\n            new Color(edge.fill ?? theme.edge.fill),\n            edge.dashArray\n          );\n        } else {\n          edgeGeometry = new TubeGeometry(curve, 20, radius, 5, false);\n        }\n\n        if (edgeArrowPlacement === 'none') {\n          // Add color to edge geometry for edges without arrows (only if not dashed, dashed already have colors)\n          if (!isDashedEdge) {\n            const edgeOnlyColor = new Color(edge.fill ?? theme.edge.fill);\n            addColorAttribute(edgeGeometry, edgeOnlyColor);\n          }\n\n          geometries.push(edgeGeometry);\n          cache.set(hash, edgeGeometry);\n          return;\n        }\n\n        // Reuse base arrow geometry and scale/rotate as needed\n        const [arrowLength, arrowSize] = getArrowSize(size);\n        const arrowGeometry = baseArrowGeometryRef.current.clone();\n        arrowGeometry.scale(arrowSize, arrowLength, arrowSize);\n\n        let arrowPosition: Vector3;\n        let arrowRotation: Vector3;\n\n        if (isSelfLoop) {\n          // Arrow positioning for self-loop\n          const uEnd = 0.58;\n          const uMid = 0.25;\n          if (edgeArrowPlacement === 'mid') {\n            arrowPosition = curve.getPointAt(uMid);\n            arrowRotation = curve.getTangentAt(uMid);\n          } else {\n            // end is default\n            arrowPosition = curve.getPointAt(uEnd);\n            arrowRotation = curve.getTangentAt(uEnd);\n          }\n        } else {\n          // Regular arrow positioning\n          [arrowPosition, arrowRotation] = getArrowVectors(\n            edgeArrowPlacement,\n            curve,\n            arrowLength\n          );\n        }\n\n        const quaternion = new Quaternion();\n        quaternion.setFromUnitVectors(new Vector3(0, 1, 0), arrowRotation);\n        arrowGeometry.applyQuaternion(quaternion);\n        arrowGeometry.translate(\n          arrowPosition.x,\n          arrowPosition.y,\n          arrowPosition.z\n        );\n\n        // Move edge so it doesn't stick through the arrow:\n        if (edgeArrowPlacement && edgeArrowPlacement === 'end' && !isSelfLoop) {\n          const adjustedCurve = getCurve(\n            fromVector,\n            fromOffset,\n            arrowPosition,\n            0,\n            curved\n          );\n\n          if (isDashedEdge) {\n            edgeGeometry = createDashedGeometry(\n              adjustedCurve,\n              radius,\n              new Color(edge.fill ?? theme.edge.fill),\n              edge.dashArray\n            );\n          } else {\n            edgeGeometry = new TubeGeometry(\n              adjustedCurve,\n              20,\n              radius,\n              5,\n              false\n            );\n          }\n        }\n\n        // Add color attributes to both geometries (only for non-dashed, dashed already have colors)\n        const finalColor = new Color(edge.fill ?? theme.edge.fill);\n\n        if (!isDashedEdge) {\n          addColorAttribute(edgeGeometry, finalColor);\n        }\n        addColorAttribute(arrowGeometry, finalColor);\n\n        const merged = mergeBufferGeometries([edgeGeometry, arrowGeometry]);\n        merged.userData = { ...merged.userData, type: 'edge' };\n        geometries.push(merged);\n        cache.set(hash, merged);\n      });\n      return geometries;\n    },\n    [arrowPlacement, interpolation, theme.edge.fill]\n  );\n\n  const getGeometry = useCallback(\n    (\n      active: Array<InternalGraphEdge>,\n      inactive: Array<InternalGraphEdge>\n    ): BufferGeometry => {\n      const activeGeometries = getGeometries(active);\n      const inactiveGeometries = getGeometries(inactive);\n\n      return mergeBufferGeometries(\n        [\n          inactiveGeometries.length\n            ? mergeBufferGeometries(inactiveGeometries)\n            : NULL_GEOMETRY,\n          activeGeometries.length\n            ? mergeBufferGeometries(activeGeometries)\n            : NULL_GEOMETRY\n        ],\n        true\n      );\n    },\n    [getGeometries]\n  );\n\n  return {\n    getGeometries,\n    getGeometry\n  };\n}\n","import { a } from '@react-spring/three';\nimport { useFrame } from '@react-three/fiber';\nimport type { FC } from 'react';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { Raycaster, TubeGeometry } from 'three';\nimport { DoubleSide, Mesh } from 'three';\n\nimport { useStore } from '../../store';\nimport type { ContextMenuEvent, InternalGraphEdge } from '../../types';\nimport type { EdgeArrowPosition } from '../Arrow';\nimport type { EdgeInterpolation, EdgeLabelPosition } from '../Edge';\nimport { Edge } from './Edge';\nimport {\n  useEdgeOpacityAnimation,\n  useEdgePositionAnimation\n} from './useEdgeAnimations';\nimport type { EdgeEvents } from './useEdgeEvents';\nimport { useEdgeEvents } from './useEdgeEvents';\nimport { useEdgeGeometry } from './useEdgeGeometry';\n\nexport type EdgesProps = {\n  /**\n   * Whether the edge should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * The placement of the edge arrow.\n   */\n  arrowPlacement?: EdgeArrowPosition;\n\n  /**\n   * A function that returns the context menu for the edge.\n   */\n  contextMenu?: (event: Partial<ContextMenuEvent>) => React.ReactNode;\n\n  /**\n   * Whether the edge should be disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * The array of edge objects.\n   */\n  edges: Array<InternalGraphEdge>;\n\n  /**\n   * The URL of the font for the edge label.\n   */\n  labelFontUrl?: string;\n\n  /**\n   * The placement of the edge label.\n   */\n  labelPlacement?: EdgeLabelPosition;\n\n  /**\n   * The type of interpolation used to draw the edge.\n   */\n  interpolation?: EdgeInterpolation;\n} & EdgeEvents;\n\n/**\n * Three.js rendering starts to get slower if you have an individual mesh for each edge\n * and a high number of edges.\n *\n * Instead, we take the edges and split them into their different render states:\n *\n *  * - Active (any edges that are marked as \"selected\" or \"active\" in the state)\n *  * - Dragging (any edges that are connected to a node that is being dragged)\n *  * - Intersecting (any edges that are currently intersected by the ray from the mouse position)\n *  * - Inactive (any edges that aren't active, dragging, or intersected)\n *\n * We generate the geometry for each edge in each of these groups, and then merge them\n * into a single geometry for each group. This merged mesh is rendered as one object\n * which gives much better performance. This means that we only need to update geometry\n * and positions when edges move between the different states, rather than updating all\n * edges whenever any other edge changes.\n *\n * To get this all working, we have to do a few things outside the @react-three/fiber world,\n * specifically:\n *\n *  * manually create edge/arrow geometries (see `useEdgeGeometry`)\n *  * manually track mouse/edge interactions and fire events (see `useEdgeEvents`)\n *  * manually update edge/arrow positions during aniamations (see `useEdgeAnimations`)\n */\nexport const Edges: FC<EdgesProps> = ({\n  interpolation = 'linear',\n  arrowPlacement = 'end',\n  labelPlacement = 'inline',\n  animated,\n  contextMenu,\n  disabled,\n  edges,\n  labelFontUrl,\n  onClick,\n  onContextMenu,\n  onPointerOut,\n  onPointerOver\n}) => {\n  const theme = useStore(state => state.theme);\n  const { getGeometries, getGeometry } = useEdgeGeometry(\n    arrowPlacement,\n    interpolation\n  );\n\n  const draggingIds = useStore(state => state.draggingIds);\n  const edgeMeshes = useStore(state => state.edgeMeshes);\n  const setEdgeMeshes = useStore(state => state.setEdgeMeshes);\n  const actives = useStore(state => state.actives || []);\n  const selections = useStore(state => state.selections || []);\n  const hoveredEdgeIds = useStore(state => state.hoveredEdgeIds || []);\n\n  const [active, inactive, draggingActive, draggingInactive] = useMemo(() => {\n    const active: Array<InternalGraphEdge> = [];\n    const inactive: Array<InternalGraphEdge> = [];\n    const draggingActive: Array<InternalGraphEdge> = [];\n    const draggingInactive: Array<InternalGraphEdge> = [];\n    edges.forEach(edge => {\n      if (\n        draggingIds.includes(edge.source) ||\n        draggingIds.includes(edge.target)\n      ) {\n        if (\n          selections.includes(edge.id) ||\n          actives.includes(edge.id) ||\n          hoveredEdgeIds.includes(edge.id)\n        ) {\n          draggingActive.push(edge);\n        } else {\n          draggingInactive.push(edge);\n        }\n        return;\n      }\n\n      if (\n        selections.includes(edge.id) ||\n        actives.includes(edge.id) ||\n        hoveredEdgeIds.includes(edge.id)\n      ) {\n        active.push(edge);\n      } else {\n        inactive.push(edge);\n      }\n    });\n    return [active, inactive, draggingActive, draggingInactive];\n  }, [edges, actives, selections, draggingIds, hoveredEdgeIds]);\n\n  const hasSelections = !!selections.length;\n\n  const staticEdgesGeometry = useMemo(\n    () => getGeometry(active, inactive),\n    [getGeometry, active, inactive]\n  );\n\n  const { activeOpacity, inactiveOpacity } = useEdgeOpacityAnimation(\n    animated,\n    hasSelections,\n    theme\n  );\n\n  useEdgePositionAnimation(staticEdgesGeometry, animated);\n\n  useEffect(() => {\n    if (draggingIds.length === 0) {\n      const edgeGeometries = getGeometries(edges);\n      const edgeMeshes = edgeGeometries.map(edge => new Mesh(edge));\n      setEdgeMeshes(edgeMeshes);\n    }\n  }, [getGeometries, setEdgeMeshes, edges, draggingIds.length]);\n\n  const staticEdgesRef = useRef(new Mesh());\n  const dynamicEdgesRef = useRef(new Mesh());\n\n  const intersect = useCallback(\n    (raycaster: Raycaster): Array<InternalGraphEdge> => {\n      // Handle initial raycaster state:\n      if (!raycaster.camera) {\n        return [];\n      }\n      const intersections =\n        raycaster.intersectObjects<Mesh<TubeGeometry>>(edgeMeshes);\n      if (!intersections.length) {\n        return [];\n      }\n      return intersections.map(\n        intersection => edges[edgeMeshes.indexOf(intersection.object)]\n      );\n    },\n    [edgeMeshes, edges]\n  );\n\n  const { handleClick, handleContextMenu, handleIntersections } = useEdgeEvents(\n    {\n      onClick,\n      onContextMenu,\n      onPointerOut,\n      onPointerOver\n    },\n    contextMenu,\n    disabled\n  );\n\n  const draggingIdRef = useRef<string[]>([]);\n  const intersectingRef = useRef<Array<InternalGraphEdge>>([]);\n\n  useFrame(state => {\n    staticEdgesRef.current.geometry = staticEdgesGeometry;\n\n    if (disabled) {\n      return;\n    }\n\n    const previousDraggingId = draggingIdRef.current;\n    if (\n      draggingIds.length ||\n      (draggingIds.length === 0 && previousDraggingId !== null)\n    ) {\n      dynamicEdgesRef.current.geometry = getGeometry(\n        draggingActive,\n        draggingInactive\n      );\n    }\n\n    draggingIdRef.current = draggingIds;\n    if (draggingIds.length) {\n      return;\n    }\n\n    const previousIntersecting = intersectingRef.current;\n    const intersecting = intersect(state.raycaster);\n    handleIntersections(previousIntersecting, intersecting);\n\n    if (intersecting.join() !== previousIntersecting.join()) {\n      dynamicEdgesRef.current.geometry = getGeometry(intersecting, []);\n    }\n\n    intersectingRef.current = intersecting;\n  });\n\n  return (\n    <group onClick={handleClick} onContextMenu={handleContextMenu}>\n      {/* Static edges */}\n      <mesh ref={staticEdgesRef}>\n        <a.meshBasicMaterial\n          attach=\"material-0\"\n          depthTest={false}\n          fog={true}\n          opacity={inactiveOpacity}\n          side={DoubleSide}\n          transparent={true}\n          vertexColors={true}\n        />\n        <a.meshBasicMaterial\n          attach=\"material-1\"\n          color={theme.edge.activeFill}\n          depthTest={false}\n          fog={true}\n          opacity={activeOpacity}\n          side={DoubleSide}\n          transparent={true}\n        />\n      </mesh>\n      {/* Dynamic edges */}\n      <mesh ref={dynamicEdgesRef}>\n        <a.meshBasicMaterial\n          attach=\"material-0\"\n          color={theme.edge.fill}\n          depthTest={false}\n          fog={true}\n          opacity={inactiveOpacity}\n          side={DoubleSide}\n          transparent={true}\n        />\n        <a.meshBasicMaterial\n          attach=\"material-1\"\n          color={theme.edge.activeFill}\n          depthTest={false}\n          fog={true}\n          opacity={activeOpacity}\n          side={DoubleSide}\n          transparent={true}\n        />\n      </mesh>\n      {edges.map(edge => {\n        const isSelected = selections.includes(edge.id);\n        const isActive = actives.includes(edge.id);\n        const isHovered = hoveredEdgeIds.includes(edge.id);\n\n        return (\n          <Edge\n            animated={animated}\n            contextMenu={contextMenu}\n            color={\n              isSelected || isActive || isHovered\n                ? theme.edge.label.activeColor\n                : theme.edge.label.color\n            }\n            disabled={disabled}\n            edge={edge}\n            key={edge.id}\n            labelFontUrl={labelFontUrl}\n            labelPlacement={labelPlacement}\n            active={isSelected || isActive || isHovered}\n          />\n        );\n      })}\n    </group>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport { Billboard, Image, RoundedBox, Text } from '@react-three/drei';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport { Color } from 'three';\n\nimport type { NodeRendererProps } from '../../types';\nimport { animationConfig } from '../../utils';\nimport { measureText } from '../../utils/textMeasurement';\n\nexport type BadgePosition =\n  | 'top-right'\n  | 'top-left'\n  | 'bottom-right'\n  | 'bottom-left'\n  | 'center';\n\nexport type IconPosition = 'start' | 'end';\n\nexport interface BadgeProps extends Omit<NodeRendererProps, 'opacity'> {\n  /**\n   * The text to display in the badge.\n   */\n  label: string;\n\n  /**\n   * Background color of the badge.\n   */\n  backgroundColor?: string;\n\n  /**\n   * Opacity of the badge background and stroke (0-1).\n   * Default: 1\n   */\n  opacity?: number;\n\n  /**\n   * Text color of the badge.\n   */\n  textColor?: string;\n\n  /**\n   * Stroke color of the badge border.\n   */\n  strokeColor?: string;\n\n  /**\n   * Size of the badge border stroke.\n   */\n  strokeWidth?: number;\n\n  /**\n   * Corner radius of the badge.\n   */\n  radius?: number;\n\n  /**\n   * Size multiplier for the badge relative to the node size.\n   */\n  badgeSize?: number;\n\n  /**\n   * Position offset from the node center or preset position.\n   */\n  position?: [number, number, number] | BadgePosition;\n\n  /**\n   * Padding around the badge text.\n   * Default: 0.15\n   */\n  padding?: number;\n\n  /**\n   * SVG icon path or URL to display in the badge.\n   */\n  icon?: string;\n\n  /**\n   * Size of the icon in the badge.\n   */\n  iconSize?: number;\n\n  /**\n   * Position of the icon relative to the text or custom coordinates [x, y].\n   * - 'start': Icon appears before the text (left side)\n   * - 'end': Icon appears after the text (right side)\n   * - [x, y]: Custom coordinates within the badge. When using custom coordinates,\n   *   the text remains centered and only the icon moves to the specified position.\n   */\n  iconPosition?: IconPosition | [number, number];\n\n  /**\n   * Font size for the badge text.\n   */\n  fontSize?: number;\n\n  /**\n   * Font weight for the badge text (100-900).\n   * Values outside this range will be clamped to the nearest valid value.\n   * Common values: 400 (normal), 700 (bold), 900 (extra bold).\n   */\n  fontWeight?: number;\n\n  /**\n   * Gap between icon and text.\n   * Default: 0.01\n   */\n  iconTextGap?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 0.3;\n\nexport const Badge: FC<BadgeProps> = ({\n  label,\n  size,\n  opacity = 1,\n  animated,\n  backgroundColor = '#ffffff',\n  textColor = '#000000',\n  strokeColor,\n  strokeWidth = 0,\n  radius = 0.12,\n  badgeSize = 1.5,\n  position = 'top-right',\n  padding = 0.15,\n  icon,\n  iconSize = 0.35,\n  iconPosition = 'start',\n  fontSize = DEFAULT_FONT_SIZE,\n  fontWeight,\n  iconTextGap = 0.01\n}) => {\n  const normalizedBgColor = useMemo(\n    () => new Color(backgroundColor),\n    [backgroundColor]\n  );\n  const normalizedTextColor = useMemo(() => new Color(textColor), [textColor]);\n  const normalizedStrokeColor = useMemo(\n    () => (strokeColor ? new Color(strokeColor) : null),\n    [strokeColor]\n  );\n  // Guard for radius\n  const normalizedRadius = Math.min(radius, 0.2);\n\n  // Normalize fontWeight to valid CSS font-weight values (100-900 in increments of 100)\n  const normalizedFontWeight = useMemo(() => {\n    if (fontWeight === undefined) return undefined;\n    // Round to nearest hundred and clamp to 100-900 range\n    return Math.max(100, Math.min(900, Math.round(fontWeight / 100) * 100));\n  }, [fontWeight]);\n\n  // Calculate position based on preset or custom coordinates\n  const badgePosition = useMemo((): [number, number, number] => {\n    if (Array.isArray(position)) {\n      return position;\n    }\n\n    const offset = size * 0.65;\n    switch (position) {\n      case 'top-right':\n        return [offset, offset, 11];\n      case 'top-left':\n        return [-offset, offset, 11];\n      case 'bottom-right':\n        return [offset, -offset, 11];\n      case 'bottom-left':\n        return [-offset, -offset, 11];\n      case 'center':\n        return [0, 0, 11];\n      default:\n        return [offset, offset, 11];\n    }\n  }, [position, size]);\n\n  // Shared text size calculations (used by both badgeDimensions and contentLayout)\n  const textSizeCalculations = useMemo(() => {\n    const fontSizeScale = fontSize / DEFAULT_FONT_SIZE;\n    const fontWeightMultiplier = (normalizedFontWeight ?? 0) >= 700 ? 1.1 : 1;\n\n    // Use Canvas measureText for accurate width when charWidthEstimate is not provided\n    const measured = measureText({\n      text: label,\n      fontSize,\n      fontWeight: normalizedFontWeight\n    });\n    const estimatedTextWidth = measured.width;\n\n    return {\n      fontSizeScale,\n      fontWeightMultiplier,\n      estimatedTextWidth\n    };\n  }, [fontSize, normalizedFontWeight, label]);\n\n  // Calculate dynamic badge dimensions based on text length and icon\n  const badgeDimensions = useMemo(() => {\n    const baseWidth = 0.5;\n    const baseHeight = 0.5;\n    const minWidth = baseWidth;\n    const minHeight = baseHeight;\n\n    const { fontSizeScale, estimatedTextWidth } = textSizeCalculations;\n\n    // Calculate content width (text + icon + gap, no padding yet)\n    let contentWidth = estimatedTextWidth;\n    if (icon) {\n      contentWidth += iconSize + iconTextGap;\n    }\n\n    // Add padding to total width (padding on both left and right sides)\n    const estimatedWidth = Math.max(minWidth, contentWidth + padding * 2);\n\n    // Scale height based on fontSize\n    const charCount = label.length;\n    const estimatedHeight = Math.max(\n      minHeight,\n      Math.min(\n        charCount * 0.05 * fontSizeScale + padding * 0.5,\n        0.8 * fontSizeScale + padding * 0.5\n      )\n    );\n\n    return {\n      width: estimatedWidth,\n      height: estimatedHeight\n    };\n  }, [\n    textSizeCalculations,\n    label.length,\n    padding,\n    icon,\n    iconSize,\n    iconTextGap\n  ]);\n\n  const { scale } = useSpring({\n    from: {\n      scale: [0.00001, 0.00001, 0.00001]\n    },\n    to: {\n      scale: [size * badgeSize, size * badgeSize, size * badgeSize]\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  // Calculate content layout positions for icon and text\n  const contentLayout = useMemo(() => {\n    if (!icon) {\n      return {\n        textX: 0,\n        textY: 0,\n        iconX: 0,\n        iconY: 0\n      };\n    }\n\n    // If custom position is provided as an array\n    if (Array.isArray(iconPosition)) {\n      return {\n        iconX: iconPosition[0],\n        iconY: iconPosition[1],\n        textX: 0,\n        textY: 0\n      };\n    }\n\n    const { estimatedTextWidth } = textSizeCalculations;\n    const totalContentWidth = iconSize + iconTextGap + estimatedTextWidth;\n    const startX = -totalContentWidth / 2;\n\n    if (iconPosition === 'start') {\n      return {\n        iconX: startX + iconSize / 2,\n        iconY: 0,\n        textX: startX + iconSize + iconTextGap + estimatedTextWidth / 2,\n        textY: 0\n      };\n    } else {\n      return {\n        textX: startX + estimatedTextWidth / 2,\n        textY: 0,\n        iconX: startX + estimatedTextWidth + iconTextGap + iconSize / 2,\n        iconY: 0\n      };\n    }\n  }, [textSizeCalculations, icon, iconSize, iconPosition, iconTextGap]);\n\n  return (\n    <Billboard position={badgePosition}>\n      <a.group scale={scale as any} renderOrder={2}>\n        {/* Stroke layer */}\n        {strokeWidth > 0 && normalizedStrokeColor && (\n          <a.mesh position={[0, 0, 0.9]}>\n            <RoundedBox\n              args={[\n                badgeDimensions.width + strokeWidth,\n                badgeDimensions.height + strokeWidth,\n                0.01\n              ]}\n              radius={normalizedRadius}\n              smoothness={8}\n              material-color={normalizedStrokeColor}\n              material-transparent={true}\n              material-opacity={opacity}\n            />\n          </a.mesh>\n        )}\n        {/* Main background layer */}\n        <a.mesh position={[0, 0, 1]}>\n          <RoundedBox\n            args={[badgeDimensions.width, badgeDimensions.height, 0.01]} // dynamic width, height, depth\n            radius={normalizedRadius} // corner radius\n            smoothness={8}\n            material-color={normalizedBgColor}\n            material-transparent={true}\n            material-opacity={opacity}\n          />\n        </a.mesh>\n        {/* Icon */}\n        {icon && (\n          <Image\n            url={icon}\n            position={[contentLayout.iconX, contentLayout.iconY, 1.1]}\n            scale={[iconSize, iconSize]}\n            transparent\n            material-depthTest={false}\n            material-depthWrite={false}\n          />\n        )}\n        {/* Text */}\n        <Text\n          position={[contentLayout.textX, contentLayout.textY, 1.1]}\n          fontSize={fontSize}\n          fontWeight={normalizedFontWeight}\n          color={normalizedTextColor}\n          anchorX=\"center\"\n          anchorY=\"middle\"\n          textAlign=\"center\"\n          material-depthTest={false}\n          material-depthWrite={false}\n        >\n          {label}\n        </Text>\n      </a.group>\n    </Billboard>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport { DoubleSide, LinearFilter, TextureLoader } from 'three';\n\nimport type { NodeRendererProps } from '../../types';\nimport { animationConfig } from '../../utils';\n\nexport interface IconProps extends NodeRendererProps {\n  /**\n   * The image to display on the icon.\n   */\n  image: string;\n}\n\nexport const Icon: FC<IconProps> = ({\n  image,\n  id,\n  size,\n  opacity = 1,\n  animated\n}) => {\n  const texture = useMemo(() => new TextureLoader().load(image), [image]);\n\n  const { scale, spriteOpacity } = useSpring({\n    from: {\n      scale: [0.00001, 0.00001, 0.00001],\n      spriteOpacity: 0\n    },\n    to: {\n      scale: [size, size, size],\n      spriteOpacity: opacity\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  return (\n    <a.sprite userData={{ id, type: 'node' }} scale={scale as any}>\n      <a.spriteMaterial\n        attach=\"material\"\n        opacity={spriteOpacity}\n        fog={true}\n        depthTest={false}\n        transparent={true}\n        side={DoubleSide}\n      >\n        <primitive attach=\"map\" object={texture} minFilter={LinearFilter} />\n      </a.spriteMaterial>\n    </a.sprite>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport { Billboard } from '@react-three/drei';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport type { ColorRepresentation } from 'three';\nimport { Color, DoubleSide } from 'three';\n\nimport { animationConfig } from '../utils/animation';\n\nexport interface RingProps {\n  /**\n   * The color of the ring.\n   */\n  color?: ColorRepresentation;\n\n  /**\n   * Whether the ring should be animated.\n   */\n  animated?: boolean;\n\n  /**\n   * The size of the ring.\n   */\n  size?: number;\n\n  /**\n   * The opacity of the ring.\n   */\n  opacity?: number;\n\n  /**\n   * The stroke width of the ring.\n   */\n  strokeWidth?: number;\n\n  /**\n   * The inner radius of the ring.\n   * Default value: 4\n   */\n  innerRadius?: number;\n\n  /**\n   * The number of segments in the ring geometry.\n   * Default value: 25\n   */\n  segments?: number;\n}\n\nexport const Ring: FC<RingProps> = ({\n  color = '#D8E6EA',\n  size = 1,\n  opacity = 0.5,\n  animated,\n  strokeWidth = 5,\n  innerRadius = 4,\n  segments = 25\n}) => {\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n\n  const { ringSize, ringOpacity } = useSpring({\n    from: {\n      ringOpacity: 0,\n      ringSize: [0.00001, 0.00001, 0.00001]\n    },\n    to: {\n      ringOpacity: opacity,\n      ringSize: [size / 2, size / 2, 1]\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  const strokeWidthFraction = strokeWidth / 10;\n  const outerRadius = innerRadius + strokeWidthFraction;\n\n  return (\n    <Billboard position={[0, 0, 1]}>\n      <a.mesh\n        scale={ringSize as any}\n        // Disabling raycast/pointer events when ring is invisible (opacity = 0)\n        // This prevents invisible rings highlighting parent nodes when hovered over\n        raycast={opacity > 0 ? undefined : () => []}\n      >\n        <ringGeometry\n          attach=\"geometry\"\n          args={[innerRadius, outerRadius, segments]}\n        />\n        <a.meshBasicMaterial\n          attach=\"material\"\n          color={normalizedColor}\n          transparent={true}\n          depthTest={false}\n          opacity={ringOpacity}\n          side={DoubleSide}\n          fog={true}\n        />\n      </a.mesh>\n    </Billboard>\n  );\n};\n","import { a, useSpring } from '@react-spring/three';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport { Color, DoubleSide } from 'three';\n\nimport { useStore } from '../../store';\nimport type { NodeRendererProps } from '../../types';\nimport { animationConfig } from '../../utils/animation';\nimport { Ring } from '../Ring';\n\nexport const Sphere: FC<NodeRendererProps> = ({\n  color,\n  id,\n  size,\n  selected,\n  opacity = 1,\n  animated\n}) => {\n  const { scale, nodeOpacity } = useSpring({\n    from: {\n      // Note: This prevents incorrect scaling w/ 0\n      scale: [0.00001, 0.00001, 0.00001],\n      nodeOpacity: 0\n    },\n    to: {\n      scale: [size, size, size],\n      nodeOpacity: opacity\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n  const theme = useStore(state => state.theme);\n\n  return (\n    <>\n      <a.mesh userData={{ id, type: 'node' }} scale={scale as any}>\n        <sphereGeometry attach=\"geometry\" args={[1, 25, 25]} />\n        <a.meshPhongMaterial\n          attach=\"material\"\n          side={DoubleSide}\n          transparent={true}\n          fog={true}\n          opacity={nodeOpacity}\n          color={normalizedColor}\n          emissive={normalizedColor}\n          emissiveIntensity={0.7}\n        />\n      </a.mesh>\n      <Ring\n        opacity={selected ? 0.5 : 0}\n        size={size}\n        animated={animated}\n        color={selected ? theme.ring.activeFill : theme.ring.fill}\n      />\n    </>\n  );\n};\n","import type { FC } from 'react';\nimport React from 'react';\n\nimport type { NodeRendererProps } from '../../types';\nimport { Icon } from './Icon';\nimport { Sphere } from './Sphere';\n\nexport interface SphereWithIconProps extends NodeRendererProps {\n  /**\n   * The image to display on the icon.\n   */\n  image: string;\n}\n\nexport const SphereWithIcon: FC<SphereWithIconProps> = ({\n  color,\n  id,\n  size,\n  opacity = 1,\n  node,\n  active = false,\n  animated,\n  image,\n  selected\n}) => (\n  <>\n    <Sphere\n      id={id}\n      selected={selected}\n      size={size}\n      opacity={opacity}\n      animated={animated}\n      color={color}\n      node={node}\n      active={active}\n    />\n    <Icon\n      id={id}\n      image={image}\n      selected={selected}\n      size={size + 8}\n      opacity={opacity}\n      animated={animated}\n      color={color}\n      node={node}\n      active={active}\n    />\n  </>\n);\n","import { a, useSpring } from '@react-spring/three';\nimport type { SvgProps as DreiSvgProps } from '@react-three/drei';\nimport { Billboard, Svg as DreiSvg } from '@react-three/drei';\nimport type { FC } from 'react';\nimport React, { useMemo } from 'react';\nimport { Color, DoubleSide } from 'three';\n\nimport type { NodeRendererProps } from '../../types';\nimport { animationConfig } from '../../utils';\n\nexport type SvgProps = NodeRendererProps &\n  Omit<DreiSvgProps, 'src' | 'id'> & {\n    /**\n     * The image to display on the icon.\n     */\n    image: string;\n  };\n\nexport const Svg: FC<SvgProps> = ({\n  id,\n  image,\n  color,\n  size,\n  opacity = 1,\n  animated,\n  ...rest\n}) => {\n  const normalizedSize = size / 25;\n\n  const { scale } = useSpring({\n    from: {\n      scale: [0.00001, 0.00001, 0.00001]\n    },\n    to: {\n      scale: [normalizedSize, normalizedSize, normalizedSize]\n    },\n    config: {\n      ...animationConfig,\n      duration: animated ? undefined : 0\n    }\n  });\n\n  const normalizedColor = useMemo(() => new Color(color), [color]);\n\n  return (\n    <a.group userData={{ id, type: 'node' }} scale={scale as any}>\n      <Billboard position={[0, 0, 1]}>\n        <DreiSvg\n          {...rest}\n          src={image}\n          fillMaterial={{\n            fog: true,\n            depthTest: false,\n            transparent: true,\n            color: normalizedColor,\n            opacity,\n            side: DoubleSide,\n            ...(rest.fillMaterial || {})\n          }}\n          fillMeshProps={{\n            // Note: This is a hack to get the svg to\n            // render in the correct position.\n            position: [-25, -25, 1],\n            ...(rest.fillMeshProps || {})\n          }}\n        />\n      </Billboard>\n    </a.group>\n  );\n};\n","import type { FC } from 'react';\nimport React from 'react';\nimport type { ColorRepresentation } from 'three';\n\nimport { Sphere } from './Sphere';\nimport type { SvgProps } from './Svg';\nimport { Svg } from './Svg';\n\nexport interface SphereWithSvgProps extends SvgProps {\n  /**\n   * The image to display on the icon.\n   */\n  image: string;\n\n  /**\n   * The color of the svg fill.\n   */\n  svgFill?: ColorRepresentation;\n}\n\nexport const SphereWithSvg: FC<SphereWithSvgProps> = ({\n  color,\n  id,\n  size,\n  opacity = 1,\n  node,\n  svgFill,\n  active = false,\n  animated,\n  image,\n  selected,\n  ...rest\n}) => (\n  <>\n    <Sphere\n      id={id}\n      selected={selected}\n      size={size}\n      opacity={opacity}\n      animated={animated}\n      color={color}\n      node={node}\n      active={active}\n    />\n    <Svg\n      {...rest}\n      id={id}\n      selected={selected}\n      image={image}\n      size={size}\n      opacity={opacity}\n      animated={animated}\n      color={svgFill}\n      node={node}\n      active={active}\n    />\n  </>\n);\n","import { a, useSpring } from '@react-spring/three';\nimport { Html, useCursor } from '@react-three/drei';\nimport type { ThreeEvent } from '@react-three/fiber';\nimport type { FC, ReactNode } from 'react';\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport type { Group } from 'three';\n\nimport { useCameraControls } from '../CameraControls/useCameraControls';\nimport { useStore } from '../store';\nimport type {\n  CollapseProps,\n  ContextMenuEvent,\n  InternalGraphNode,\n  NodeContextMenuProps,\n  NodeRenderer\n} from '../types';\nimport { animationConfig } from '../utils';\nimport { useDrag } from '../utils/useDrag';\nimport { useHoverIntent } from '../utils/useHoverIntent';\nimport { Label } from './Label';\nimport { Icon } from './nodes';\nimport { Sphere } from './nodes/Sphere';\n\nexport interface NodeProps {\n  /**\n   * The unique identifier for the node.\n   */\n  id: string;\n\n  /**\n   * The parent nodes of the node.\n   */\n  parents?: string[];\n\n  /**\n   * Whether the node is disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * Whether the node is animated.\n   */\n  animated?: boolean;\n\n  /**\n   * Whether the node is draggable.\n   */\n  draggable?: boolean;\n\n  /**\n   * Constrain dragging to the cluster bounds.\n   */\n  constrainDragging?: boolean;\n\n  /**\n   * The url for the label font.\n   */\n  labelFontUrl?: string;\n\n  /**\n   * The function to use to render the node.\n   */\n  renderNode?: NodeRenderer;\n\n  /**\n   * The context menu for the node.\n   */\n  contextMenu?: (event: ContextMenuEvent) => ReactNode;\n\n  /**\n   * The function to call when the pointer is over the node.\n   */\n  onPointerOver?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * The function to call when the pointer is out of the node.\n   */\n  onPointerOut?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * The function to call when the node is clicked.\n   */\n  onClick?: (\n    node: InternalGraphNode,\n    props?: CollapseProps,\n    event?: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * The function to call when the node is double clicked.\n   */\n  onDoubleClick?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * The function to call when the node is right clicked.\n   */\n  onContextMenu?: (\n    node?: InternalGraphNode,\n    props?: NodeContextMenuProps\n  ) => void;\n\n  /**\n   * Triggered after a node was dragged.\n   */\n  onDragged?: (node: InternalGraphNode) => void;\n}\n\nexport const Node: FC<NodeProps> = ({\n  animated,\n  disabled,\n  id,\n  draggable = false,\n  labelFontUrl,\n  contextMenu,\n  onClick,\n  onDoubleClick,\n  onPointerOver,\n  onDragged,\n  onPointerOut,\n  onContextMenu,\n  renderNode,\n  constrainDragging\n}) => {\n  const cameraControls = useCameraControls();\n  const theme = useStore(state => state.theme);\n  const node = useStore(state => state.nodes.find(n => n.id === id));\n  const edges = useStore(state => state.edges);\n  const draggingIds = useStore(state => state.draggingIds);\n  const collapsedNodeIds = useStore(state => state.collapsedNodeIds);\n  const addDraggingId = useStore(state => state.addDraggingId);\n  const removeDraggingId = useStore(state => state.removeDraggingId);\n  const setHoveredNodeId = useStore(state => state.setHoveredNodeId);\n  const setNodePosition = useStore(state => state.setNodePosition);\n  const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\n  const isCollapsed = useStore(state => state.collapsedNodeIds.includes(id));\n  const isActive = useStore(state => state.actives?.includes(id));\n  const isSelected = useStore(state => state.selections?.includes(id));\n  const hasSelections = useStore(state => state.selections?.length > 0);\n  const center = useStore(state => state.centerPosition);\n  const cluster = useStore(state => state.clusters.get(node.cluster));\n\n  const isDraggingCurrent = draggingIds.includes(id);\n  const isDragging = draggingIds.length > 0;\n\n  const {\n    position,\n    label,\n    subLabel,\n    size: nodeSize = 7,\n    labelVisible = true\n  } = node;\n\n  const group = useRef<Group | null>(null);\n  const [active, setActive] = useState<boolean>(false);\n  const [menuVisible, setMenuVisible] = useState<boolean>(false);\n\n  const shouldHighlight = active || isSelected || isActive;\n\n  const selectionOpacity = hasSelections\n    ? shouldHighlight\n      ? theme.node.selectedOpacity\n      : theme.node.inactiveOpacity\n    : theme.node.opacity;\n\n  const canCollapse = useMemo(() => {\n    // If the node has outgoing edges, it can collapse via context menu\n    const outboundLinks = edges.filter(l => l.source === id);\n\n    return outboundLinks.length > 0 || isCollapsed;\n  }, [edges, id, isCollapsed]);\n\n  const onCollapse = useCallback(() => {\n    if (canCollapse) {\n      if (isCollapsed) {\n        setCollapsedNodeIds(collapsedNodeIds.filter(p => p !== id));\n      } else {\n        setCollapsedNodeIds([...collapsedNodeIds, id]);\n      }\n    }\n  }, [canCollapse, collapsedNodeIds, id, isCollapsed, setCollapsedNodeIds]);\n\n  const [{ nodePosition, labelPosition }] = useSpring(\n    () => ({\n      from: {\n        nodePosition: center ? [center.x, center.y, 0] : [0, 0, 0],\n        labelPosition: [0, -(nodeSize + 7), 2]\n      },\n      to: {\n        nodePosition: position\n          ? [\n              position.x,\n              position.y,\n              shouldHighlight ? position.z + 1 : position.z\n            ]\n          : [0, 0, 0],\n        labelPosition: [0, -(nodeSize + 7), 2]\n      },\n      config: {\n        ...animationConfig,\n        duration: animated && !isDragging ? undefined : 0\n      }\n    }),\n    [isDraggingCurrent, position, animated, nodeSize, shouldHighlight]\n  );\n\n  const bind = useDrag({\n    draggable,\n    position,\n    // If dragging is constrained to the cluster, use the cluster's position as the bounds\n    bounds: constrainDragging ? cluster?.position : undefined,\n    // @ts-ignore\n    set: pos => setNodePosition(id, pos),\n    onDragStart: () => {\n      addDraggingId(id);\n      setActive(true);\n    },\n    onDragEnd: () => {\n      removeDraggingId(id);\n      onDragged?.(node);\n    }\n  });\n\n  useCursor(active && !isDragging && onClick !== undefined, 'pointer');\n  useCursor(\n    active && draggable && !isDraggingCurrent && onClick === undefined,\n    'grab'\n  );\n  useCursor(isDraggingCurrent, 'grabbing');\n\n  const combinedActiveState = shouldHighlight || isDraggingCurrent;\n  const color = combinedActiveState\n    ? theme.node.activeFill\n    : node.fill || theme.node.fill;\n\n  const { pointerOver, pointerOut } = useHoverIntent({\n    disabled: disabled || isDraggingCurrent,\n    onPointerOver: (event: ThreeEvent<PointerEvent>) => {\n      cameraControls.freeze();\n      setActive(true);\n      onPointerOver?.(node, event);\n      setHoveredNodeId(id);\n    },\n    onPointerOut: (event: ThreeEvent<PointerEvent>) => {\n      cameraControls.unFreeze();\n      setActive(false);\n      onPointerOut?.(node, event);\n      setHoveredNodeId(null);\n    }\n  });\n\n  const nodeComponent = useMemo(\n    () =>\n      renderNode ? (\n        renderNode({\n          id,\n          color,\n          size: nodeSize,\n          active: combinedActiveState,\n          opacity: selectionOpacity,\n          animated,\n          selected: isSelected,\n          node\n        })\n      ) : (\n        <>\n          {node.icon ? (\n            <Icon\n              id={id}\n              image={node.icon || ''}\n              size={nodeSize + 8}\n              opacity={selectionOpacity}\n              animated={animated}\n              color={color}\n              node={node}\n              active={combinedActiveState}\n              selected={isSelected}\n            />\n          ) : (\n            <Sphere\n              id={id}\n              size={nodeSize}\n              opacity={selectionOpacity}\n              animated={animated}\n              color={color}\n              node={node}\n              active={combinedActiveState}\n              selected={isSelected}\n            />\n          )}\n        </>\n      ),\n    [\n      renderNode,\n      id,\n      color,\n      nodeSize,\n      combinedActiveState,\n      selectionOpacity,\n      animated,\n      isSelected,\n      node\n    ]\n  );\n\n  const labelComponent = useMemo(\n    () =>\n      labelVisible &&\n      (labelVisible || isSelected || active) &&\n      label && (\n        <a.group position={labelPosition as any}>\n          <Label\n            text={label}\n            fontUrl={labelFontUrl}\n            opacity={selectionOpacity}\n            stroke={theme.node.label.stroke}\n            backgroundColor={theme.node.label.backgroundColor}\n            backgroundOpacity={theme.node.label.backgroundOpacity}\n            padding={theme.node.label.padding}\n            strokeColor={theme.node.label.strokeColor}\n            strokeWidth={theme.node.label.strokeWidth}\n            radius={theme.node.label.radius}\n            active={isSelected || active || isDraggingCurrent || isActive}\n            color={\n              isSelected || active || isDraggingCurrent || isActive\n                ? theme.node.label.activeColor\n                : theme.node.label.color\n            }\n          />\n          {subLabel && (\n            <group position={[0, -(nodeSize - 3), 0]}>\n              <Label\n                text={subLabel}\n                fontUrl={labelFontUrl}\n                fontSize={5}\n                opacity={selectionOpacity}\n                stroke={theme.node.subLabel?.stroke}\n                active={isSelected || active || isDraggingCurrent || isActive}\n                color={\n                  isSelected || active || isDraggingCurrent || isActive\n                    ? theme.node.subLabel?.activeColor\n                    : theme.node.subLabel?.color\n                }\n              />\n            </group>\n          )}\n        </a.group>\n      ),\n    [\n      active,\n      isActive,\n      isDraggingCurrent,\n      isSelected,\n      label,\n      labelFontUrl,\n      labelPosition,\n      labelVisible,\n      nodeSize,\n      selectionOpacity,\n      subLabel,\n      theme.node.label.activeColor,\n      theme.node.label.color,\n      theme.node.label.stroke,\n      theme.node.label.backgroundColor,\n      theme.node.label.backgroundOpacity,\n      theme.node.label.padding,\n      theme.node.label.strokeColor,\n      theme.node.label.strokeWidth,\n      theme.node.label.radius,\n      theme.node.subLabel?.activeColor,\n      theme.node.subLabel?.color,\n      theme.node.subLabel?.stroke\n    ]\n  );\n\n  const menuComponent = useMemo(\n    () =>\n      menuVisible &&\n      contextMenu && (\n        <Html prepend={true} center={true}>\n          {contextMenu({\n            data: node,\n            canCollapse,\n            isCollapsed,\n            onCollapse,\n            onClose: () => setMenuVisible(false)\n          })}\n        </Html>\n      ),\n    [menuVisible, contextMenu, node, canCollapse, isCollapsed, onCollapse]\n  );\n\n  return (\n    <a.group\n      renderOrder={1}\n      userData={{ id, type: 'node' }}\n      ref={group}\n      position={nodePosition as any}\n      onPointerOver={pointerOver}\n      onPointerOut={pointerOut}\n      onClick={(event: ThreeEvent<MouseEvent>) => {\n        if (!disabled && !isDraggingCurrent) {\n          onClick?.(\n            node,\n            {\n              canCollapse,\n              isCollapsed\n            },\n            event\n          );\n        }\n      }}\n      onDoubleClick={(event: ThreeEvent<MouseEvent>) => {\n        if (!disabled && !isDraggingCurrent) {\n          onDoubleClick?.(node, event);\n        }\n      }}\n      onContextMenu={() => {\n        if (!disabled) {\n          setMenuVisible(true);\n          onContextMenu?.(node, {\n            canCollapse,\n            isCollapsed,\n            onCollapse\n          });\n        }\n      }}\n      {...(bind() as any)}\n    >\n      {nodeComponent}\n      {menuComponent}\n      {labelComponent}\n    </a.group>\n  );\n};\n","import type Graph from 'graphology';\n\nimport type { InternalGraphEdge, InternalGraphNode } from '../types';\nimport type { LayoutStrategy } from './types';\n\n/**\n * Promise based tick helper.\n */\nexport function tick(layout: LayoutStrategy) {\n  return new Promise((resolve, _reject) => {\n    let stable: boolean | undefined;\n\n    function run() {\n      if (!stable) {\n        stable = layout.step();\n        run();\n      } else {\n        resolve(stable);\n      }\n    }\n\n    run();\n  });\n}\n\n/**\n * Helper function to turn the graph nodes/edges into an array for\n * easier manipulation.\n */\nexport function buildNodeEdges(graph: Graph) {\n  const nodes: InternalGraphNode[] = [];\n  const edges: InternalGraphEdge[] = [];\n\n  graph.forEachNode((id, n: any) => {\n    nodes.push({\n      ...n,\n      id,\n      // This is for the clustering\n      radius: n.size || 1\n    });\n  });\n\n  graph.forEachEdge((id, l: any) => {\n    edges.push({ ...l, id });\n  });\n\n  return { nodes, edges };\n}\n","import circular from 'graphology-layout/circular.js';\n\nimport { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps } from './types';\n\nexport interface CircularLayoutInputs extends LayoutFactoryProps {\n  /**\n   * Radius of the circle.\n   */\n  radius: number;\n}\n\nexport function circular2d({\n  graph,\n  radius,\n  drags,\n  getNodePosition\n}: CircularLayoutInputs) {\n  const layout = circular(graph, {\n    scale: radius\n  });\n\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) {\n          return pos;\n        }\n      }\n\n      if (drags?.[id]?.position) {\n        // If we dragged, we need to use that position\n        return drags?.[id]?.position as any;\n      }\n\n      return layout?.[id];\n    }\n  };\n}\n","import { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps } from './types';\n\nexport interface ConcentricLayoutInputs extends LayoutFactoryProps {\n  /**\n   * Base radius of the innermost circle.\n   */\n  radius: number;\n  /**\n   * Distance between circles.\n   */\n  concentricSpacing?: number;\n}\n\n/**\n * Concentric layout algorithm for 2D graphs.\n * @param graph\n * @param radius\n * @param drags\n * @param getNodePosition\n * @param concentricSpacing\n */\nexport function concentric2d({\n  graph,\n  radius = 40,\n  drags,\n  getNodePosition,\n  concentricSpacing = 100\n}: ConcentricLayoutInputs) {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  const layout: Record<string, { x: number; y: number }> = {};\n\n  const getNodesInLevel = (level: number) => {\n    const circumference = 2 * Math.PI * (radius + level * concentricSpacing);\n    const minNodeSpacing = 40;\n    return Math.floor(circumference / minNodeSpacing);\n  };\n\n  const fixedLevelMap = new Map<number, string[]>();\n  const dynamicNodes: { id: string; metric: number }[] = [];\n\n  // Split nodes: fixed-level and dynamic\n  for (const node of nodes) {\n    const data = graph.getNodeAttribute(node.id, 'data');\n    const level = data?.level;\n\n    if (typeof level === 'number' && level >= 0) {\n      if (!fixedLevelMap.has(level)) {\n        fixedLevelMap.set(level, []);\n      }\n      fixedLevelMap.get(level)!.push(node.id);\n    } else {\n      dynamicNodes.push({ id: node.id, metric: graph.degree(node.id) });\n    }\n  }\n\n  // Sort dynamic nodes by degree\n  dynamicNodes.sort((a, b) => b.metric - a.metric);\n\n  // Fill layout for fixed-level nodes\n  for (const [level, nodeIds] of fixedLevelMap.entries()) {\n    const count = nodeIds.length;\n    const r = radius + level * concentricSpacing;\n\n    for (let i = 0; i < count; i++) {\n      const angle = (2 * Math.PI * i) / count;\n      layout[nodeIds[i]] = {\n        x: r * Math.cos(angle),\n        y: r * Math.sin(angle)\n      };\n    }\n  }\n\n  // Determine which levels are partially used and which are available\n  const occupiedLevels = new Set(fixedLevelMap.keys());\n  let dynamicLevel = 0;\n\n  let i = 0;\n  while (i < dynamicNodes.length) {\n    // Skip occupied levels\n    while (occupiedLevels.has(dynamicLevel)) {\n      dynamicLevel++;\n    }\n\n    const nodesInLevel = getNodesInLevel(dynamicLevel);\n    const r = radius + dynamicLevel * concentricSpacing;\n\n    for (let j = 0; j < nodesInLevel && i < dynamicNodes.length; j++) {\n      const angle = (2 * Math.PI * j) / nodesInLevel;\n      layout[dynamicNodes[i].id] = {\n        x: r * Math.cos(angle),\n        y: r * Math.sin(angle)\n      };\n      i++;\n    }\n\n    dynamicLevel++;\n  }\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) return pos;\n      }\n\n      if (drags?.[id]?.position) {\n        return drags[id].position as any;\n      }\n\n      return layout[id];\n    }\n  };\n}\n","import { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps } from './types';\n\nexport function custom({ graph, drags, getNodePosition }: LayoutFactoryProps) {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      return getNodePosition(id, { graph, drags, nodes, edges });\n    }\n  };\n}\n","import type { InternalGraphEdge, InternalGraphNode } from '../types';\n\nexport interface DepthNode {\n  data: InternalGraphNode;\n  ins: DepthNode[];\n  out: DepthNode[];\n  depth: number;\n}\n\n/**\n * Traverse the graph and get the depth of each node.\n */\nfunction traverseGraph(nodes: DepthNode[], nodeStack: DepthNode[] = []) {\n  const currentDepth = nodeStack.length;\n\n  for (const node of nodes) {\n    const idx = nodeStack.indexOf(node);\n    if (idx > -1) {\n      const loop = [...nodeStack.slice(idx), node].map(d => d.data.id);\n      throw new Error(\n        `Invalid Graph: Circular node path detected: ${loop.join(' -> ')}.`\n      );\n    }\n\n    if (currentDepth > node.depth) {\n      node.depth = currentDepth;\n      traverseGraph(node.out, [...nodeStack, node]);\n    }\n  }\n}\n\n/**\n * Gets the depth of the graph's nodes. Used in the radial layout.\n */\nexport function getNodeDepth(\n  nodes: InternalGraphNode[],\n  links: InternalGraphEdge[]\n) {\n  let invalid = false;\n\n  const graph: { [key: string]: DepthNode } = nodes.reduce(\n    (acc, cur) => ({\n      ...acc,\n      [cur.id]: {\n        data: cur,\n        out: [],\n        depth: -1,\n        ins: []\n      }\n    }),\n    {}\n  );\n\n  try {\n    for (const link of links) {\n      const from = link.source;\n      const to = link.target;\n\n      /* eslint-disable no-prototype-builtins */\n      if (!graph.hasOwnProperty(from)) {\n        throw new Error(`Missing source Node ${from}`);\n      }\n      /* eslint-disable no-prototype-builtins */\n      if (!graph.hasOwnProperty(to)) {\n        throw new Error(`Missing target Node ${to}`);\n      }\n\n      const sourceNode = graph[from];\n      const targetNode = graph[to];\n      targetNode.ins.push(sourceNode);\n      sourceNode.out.push(targetNode);\n    }\n\n    traverseGraph(Object.values(graph));\n  } catch (e) {\n    invalid = true;\n  }\n\n  const allDepths = Object.keys(graph).map(id => graph[id].depth);\n  const maxDepth = Math.max(...allDepths);\n\n  return {\n    invalid,\n    depths: graph,\n    maxDepth: maxDepth || 1\n  };\n}\n","import random from 'graphology-layout/random.js';\nimport forceAtlas2Layout from 'graphology-layout-forceatlas2';\n\nimport type { LayoutFactoryProps } from './types';\n\nexport interface ForceAtlas2LayoutInputs extends LayoutFactoryProps {\n  /**\n   * Should the node’s sizes be taken into account. Default: false.\n   */\n  adjustSizes?: boolean;\n\n  /**\n   * whether to use the Barnes-Hut approximation to compute\n   * repulsion in O(n*log(n)) rather than default O(n^2),\n   * n being the number of nodes. Default: false.\n   */\n  barnesHutOptimize?: boolean;\n\n  /**\n   * Barnes-Hut approximation theta parameter. Default: 0.5.\n   */\n  barnesHutTheta?: number;\n\n  /**\n   * Influence of the edge’s weights on the layout. To consider edge weight, don’t\n   *  forget to pass weighted as true. Default: 1.\n   */\n  edgeWeightInfluence?: number;\n\n  /**\n   * Strength of the layout’s gravity. Default: 10.\n   */\n  gravity?: number;\n\n  /**\n   * Whether to use Noack’s LinLog model. Default: false.\n   */\n  linLogMode?: boolean;\n\n  /**\n   * Whether to consider edge weights when calculating repulsion. Default: false.\n   */\n  outboundAttractionDistribution?: boolean;\n\n  /**\n   * Scaling ratio for repulsion. Default: 100.\n   */\n  scalingRatio?: number;\n\n  /**\n   * Speed of the slowdown. Default: 1.\n   */\n  slowDown?: number;\n\n  /**\n   * Whether to use the strong gravity mode. Default: false.\n   */\n  strongGravityMode?: boolean;\n\n  /**\n   * Number of iterations to perform. Default: 50.\n   */\n  iterations?: number;\n}\n\nexport function forceAtlas2({\n  graph,\n  drags,\n  iterations,\n  ...rest\n}: ForceAtlas2LayoutInputs) {\n  // Note: We need to assign a random position to each node\n  // in order for the force atlas to work.\n  // Reference: https://graphology.github.io/standard-library/layout-forceatlas2.html#pre-requisites\n  random.assign(graph);\n\n  const layout = forceAtlas2Layout(graph, {\n    iterations,\n    settings: rest\n  });\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      // If we dragged, we need to use that position\n      return (drags?.[id]?.position as any) || layout?.[id];\n    }\n  };\n}\n","import {\n  forceCollide,\n  forceLink,\n  forceManyBody,\n  forceSimulation,\n  forceX,\n  forceY\n} from 'd3-force-3d';\nimport { hierarchy, treemap } from 'd3-hierarchy';\n\nimport type { ClusterGroup } from '../utils/cluster';\n\n/**\n * Used for calculating clusterings of nodes.\n *\n * Modified version of: https://github.com/john-guerra/forceInABox\n *\n * Changes:\n *  - Improved d3 import for tree shaking\n *  - Fixed node lookup for edges using array\n *  - Updated d3-force to use d3-force-3d\n *  - Removed template logic\n */\nexport function forceInABox() {\n  // d3 style\n  const constant = (_: any) => () => _;\n  const index = (d: any) => d.index;\n\n  // Default values\n  let id = index;\n  let nodes = [];\n  let links = []; // needed for the force version\n  let clusters: Map<string, ClusterGroup>;\n  let tree;\n  let size = [100, 100];\n  let forceNodeSize = constant(1); // The expected node size used for computing the cluster node\n  let forceCharge = constant(-1);\n  let forceLinkDistance = constant(100);\n  let forceLinkStrength = constant(0.1);\n  const foci = {};\n  let linkStrengthIntraCluster = 0.1;\n  let linkStrengthInterCluster = 0.001;\n  let templateNodes = [];\n  let offset = [0, 0];\n  let templateForce;\n  let groupBy = d => d.cluster;\n  let template = 'treemap';\n  let enableGrouping = true;\n  let strength = 0.1;\n\n  function force(alpha) {\n    if (!enableGrouping) {\n      return force;\n    }\n\n    if (template === 'force') {\n      // Do the tick of the template force and get the new focis\n      templateForce.tick();\n      getFocisFromTemplate();\n    }\n\n    for (let i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {\n      node = nodes[i];\n      node.vx += (foci[groupBy(node)].x - node.x) * k;\n      node.vy += (foci[groupBy(node)].y - node.y) * k;\n    }\n  }\n\n  function initialize() {\n    if (!nodes) {\n      return;\n    }\n\n    if (template === 'treemap') {\n      initializeWithTreemap();\n    } else {\n      initializeWithForce();\n    }\n  }\n\n  force.initialize = function (_) {\n    nodes = _;\n    initialize();\n  };\n\n  function getLinkKey(l) {\n    const sourceID = groupBy(l.source),\n      targetID = groupBy(l.target);\n\n    return sourceID <= targetID\n      ? sourceID + '~' + targetID\n      : targetID + '~' + sourceID;\n  }\n\n  function computeClustersNodeCounts(nodes) {\n    let clustersCounts = new Map(),\n      tmpCount: any = {};\n\n    nodes.forEach(function (d) {\n      if (!clustersCounts.has(groupBy(d))) {\n        clustersCounts.set(groupBy(d), { count: 0, sumforceNodeSize: 0 });\n      }\n    });\n\n    nodes.forEach(function (d) {\n      tmpCount = clustersCounts.get(groupBy(d));\n      tmpCount.count = tmpCount.count + 1;\n      tmpCount.sumforceNodeSize =\n        tmpCount.sumforceNodeSize +\n        // @ts-ignore\n        Math.PI * (forceNodeSize(d) * forceNodeSize(d)) * 1.3;\n      clustersCounts.set(groupBy(d), tmpCount);\n    });\n\n    return clustersCounts;\n  }\n\n  //Returns\n  function computeClustersLinkCounts(links) {\n    const dClusterLinks = new Map(),\n      clusterLinks = [];\n\n    links.forEach(function (l) {\n      let key = getLinkKey(l),\n        count;\n      if (dClusterLinks.has(key)) {\n        count = dClusterLinks.get(key);\n      } else {\n        count = 0;\n      }\n      count += 1;\n      dClusterLinks.set(key, count);\n    });\n\n    dClusterLinks.forEach(function (value, key) {\n      let source, target;\n      source = key.split('~')[0];\n      target = key.split('~')[1];\n      if (source !== undefined && target !== undefined) {\n        clusterLinks.push({\n          source: source,\n          target: target,\n          count: value\n        });\n      }\n    });\n\n    return clusterLinks;\n  }\n\n  //Returns the metagraph of the clusters\n  function getGroupsGraph() {\n    const gnodes = [];\n    const glinks = [];\n    const dNodes = new Map();\n    let c;\n    let i;\n    let cc;\n    let clustersCounts;\n    let clustersLinks;\n\n    clustersCounts = computeClustersNodeCounts(nodes);\n    clustersLinks = computeClustersLinkCounts(links);\n\n    for (c of clustersCounts.keys()) {\n      cc = clustersCounts.get(c);\n      gnodes.push({\n        id: c,\n        size: cc.count,\n        r: Math.sqrt(cc.sumforceNodeSize / Math.PI)\n      }); // Uses approx meta-node size\n      dNodes.set(c, i);\n    }\n\n    clustersLinks.forEach(function (l) {\n      const source = dNodes.get(l.source),\n        target = dNodes.get(l.target);\n      if (source !== undefined && target !== undefined) {\n        glinks.push({\n          source: source,\n          target: target,\n          count: l.count\n        });\n      }\n    });\n\n    return { nodes: gnodes, links: glinks };\n  }\n\n  function getGroupsTree() {\n    const children = [];\n    let c;\n    let cc;\n    let clustersCounts;\n\n    // @ts-ignore\n    clustersCounts = computeClustersNodeCounts(force.nodes());\n\n    for (c of clustersCounts.keys()) {\n      cc = clustersCounts.get(c);\n      children.push({ id: c, size: cc.count });\n    }\n    return { id: 'clustersTree', children: children };\n  }\n\n  function getFocisFromTemplate() {\n    //compute foci\n    // @ts-ignore\n    foci.none = { x: 0, y: 0 };\n    templateNodes.forEach(function (d) {\n      if (template === 'treemap') {\n        foci[d.data.id] = {\n          x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],\n          y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]\n        };\n      } else {\n        foci[d.id] = {\n          x: d.x - offset[0],\n          y: d.y - offset[1]\n        };\n      }\n    });\n    return foci;\n  }\n\n  function initializeWithTreemap() {\n    // @ts-ignore\n    const sim = treemap().size(force.size());\n\n    tree = hierarchy(getGroupsTree())\n      .sum((d: any) => d.radius)\n      .sort(function (a, b) {\n        return b.height - a.height || b.value - a.value;\n      });\n\n    templateNodes = sim(tree).leaves();\n    getFocisFromTemplate();\n  }\n\n  function checkLinksAsObjects() {\n    // Check if links come in the format of indexes instead of objects\n    let linkCount = 0;\n    if (nodes.length === 0) return;\n\n    links.forEach(function (link) {\n      let source, target;\n      if (!nodes) {\n        return;\n      }\n\n      source = link.source;\n      target = link.target;\n\n      if (typeof link.source !== 'object') {\n        source = nodes.find(n => n.id === link.source);\n      }\n\n      if (typeof link.target !== 'object') {\n        target = nodes.find(n => n.id === link.target);\n      }\n\n      if (source === undefined || target === undefined) {\n        throw Error(\n          'Error setting links, couldnt find nodes for a link (see it on the console)'\n        );\n      }\n      link.source = source;\n      link.target = target;\n      link.index = linkCount++;\n    });\n  }\n\n  function initializeWithForce() {\n    let net;\n\n    if (!nodes || !nodes.length) {\n      return;\n    }\n\n    checkLinksAsObjects();\n\n    net = getGroupsGraph();\n\n    // Use dragged clusters position if available\n    if (clusters.size > 0) {\n      net.nodes.forEach(n => {\n        // Set fixed X position for cluster\n        n.fx = clusters.get(n.id)?.position?.x;\n        // Set fixed Y position for cluster\n        n.fy = clusters.get(n.id)?.position?.y;\n      });\n    }\n\n    templateForce = forceSimulation(net.nodes)\n      .force('x', forceX(size[0] / 2).strength(0.1))\n      .force('y', forceY(size[1] / 2).strength(0.1))\n      .force('collide', forceCollide(d => d.r).iterations(4))\n      .force('charge', forceManyBody().strength(forceCharge))\n      .force(\n        'links',\n        forceLink(net.nodes.length ? net.links : [])\n          .distance(forceLinkDistance)\n          .strength(forceLinkStrength)\n      );\n\n    templateNodes = templateForce.nodes();\n\n    getFocisFromTemplate();\n  }\n\n  force.template = function (x) {\n    if (!arguments.length) {\n      return template;\n    }\n\n    template = x;\n    initialize();\n    return force;\n  };\n\n  force.groupBy = function (x) {\n    if (!arguments.length) {\n      return groupBy;\n    }\n\n    if (typeof x === 'string') {\n      groupBy = function (d) {\n        return d[x];\n      };\n\n      return force;\n    }\n\n    groupBy = x;\n\n    return force;\n  };\n\n  force.enableGrouping = function (x) {\n    if (!arguments.length) {\n      return enableGrouping;\n    }\n\n    enableGrouping = x;\n\n    return force;\n  };\n\n  force.strength = function (x) {\n    if (!arguments.length) {\n      return strength;\n    }\n\n    strength = x;\n\n    return force as any;\n  };\n\n  force.getLinkStrength = function (e) {\n    if (enableGrouping) {\n      if (groupBy(e.source) === groupBy(e.target)) {\n        if (typeof linkStrengthIntraCluster === 'function') {\n          // @ts-ignore\n          return linkStrengthIntraCluster(e);\n        } else {\n          return linkStrengthIntraCluster;\n        }\n      } else {\n        if (typeof linkStrengthInterCluster === 'function') {\n          // @ts-ignore\n          return linkStrengthInterCluster(e);\n        } else {\n          return linkStrengthInterCluster;\n        }\n      }\n    } else {\n      // Not grouping return the intracluster\n      if (typeof linkStrengthIntraCluster === 'function') {\n        // @ts-ignore\n        return linkStrengthIntraCluster(e);\n      } else {\n        return linkStrengthIntraCluster;\n      }\n    }\n  };\n\n  force.id = function (_) {\n    return arguments.length ? ((id = _), force) : id;\n  };\n\n  force.size = function (_) {\n    return arguments.length ? ((size = _), force) : size;\n  };\n\n  force.linkStrengthInterCluster = function (_) {\n    return arguments.length\n      ? ((linkStrengthInterCluster = _), force)\n      : linkStrengthInterCluster;\n  };\n\n  force.linkStrengthIntraCluster = function (_) {\n    return arguments.length\n      ? ((linkStrengthIntraCluster = _), force)\n      : linkStrengthIntraCluster;\n  };\n\n  force.nodes = function (_) {\n    return arguments.length ? ((nodes = _), force) : nodes;\n  };\n\n  force.links = function (_) {\n    if (!arguments.length) {\n      return links;\n    }\n\n    if (_ === null) {\n      links = [];\n    } else {\n      links = _;\n    }\n\n    initialize();\n\n    return force;\n  };\n\n  force.template = function (x) {\n    if (!arguments.length) {\n      return template;\n    }\n\n    template = x;\n    initialize();\n    return force;\n  };\n\n  force.forceNodeSize = function (_) {\n    return arguments.length\n      ? ((forceNodeSize = typeof _ === 'function' ? _ : constant(+_)),\n        initialize(),\n        force)\n      : forceNodeSize;\n  };\n\n  // Legacy support\n  force.nodeSize = force.forceNodeSize;\n\n  force.forceCharge = function (_) {\n    return arguments.length\n      ? ((forceCharge = typeof _ === 'function' ? _ : constant(+_)),\n        initialize(),\n        force)\n      : forceCharge;\n  };\n\n  force.forceLinkDistance = function (_) {\n    return arguments.length\n      ? ((forceLinkDistance = typeof _ === 'function' ? _ : constant(+_)),\n        initialize(),\n        force)\n      : forceLinkDistance;\n  };\n\n  force.forceLinkStrength = function (_) {\n    return arguments.length\n      ? ((forceLinkStrength = typeof _ === 'function' ? _ : constant(+_)),\n        initialize(),\n        force)\n      : forceLinkStrength;\n  };\n\n  force.offset = function (_) {\n    return arguments.length\n      ? ((offset = typeof _ === 'function' ? _ : constant(+_)), force)\n      : offset;\n  };\n\n  force.getFocis = getFocisFromTemplate;\n\n  // Define the clusters to reuse positions from\n  force.setClusters = function (value: any) {\n    clusters = value;\n\n    return force;\n  };\n\n  return force;\n}\n","import { forceRadial as d3ForceRadial } from 'd3-force-3d';\n\nimport type { InternalGraphEdge, InternalGraphNode } from '../types';\nimport { getNodeDepth } from './depthUtils';\n\nconst RADIALS: DagMode[] = ['radialin', 'radialout'];\n\nexport type DagMode =\n  | 'lr'\n  | 'rl'\n  | 'td'\n  | 'but'\n  | 'zout'\n  | 'zin'\n  | 'radialin'\n  | 'radialout';\n\nexport interface ForceRadialInputs {\n  nodes: InternalGraphNode[];\n  edges: InternalGraphEdge[];\n  mode: DagMode;\n  nodeLevelRatio: number;\n}\n\n/**\n * Radial graph layout using D3 Force 3d.\n * Inspired by: https://github.com/vasturiano/three-forcegraph/blob/master/src/forcegraph-kapsule.js#L970-L1018\n */\nexport function forceRadial({\n  nodes,\n  edges,\n  mode = 'lr',\n  nodeLevelRatio = 2\n}: ForceRadialInputs) {\n  const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges);\n\n  if (invalid) {\n    return null;\n  }\n\n  const modeDistance = RADIALS.includes(mode) ? 1 : 5;\n  const dagLevelDistance =\n    (nodes.length / maxDepth) * nodeLevelRatio * modeDistance;\n\n  if (mode) {\n    const getFFn =\n      (fix: boolean, invert: boolean) => (node: InternalGraphNode) =>\n        !fix\n          ? undefined\n          : (depths[node.id].depth - maxDepth / 2) *\n            dagLevelDistance *\n            (invert ? -1 : 1);\n\n    const fxFn = getFFn(['lr', 'rl'].includes(mode), mode === 'rl');\n    const fyFn = getFFn(['td', 'bu'].includes(mode), mode === 'td');\n    const fzFn = getFFn(['zin', 'zout'].includes(mode), mode === 'zout');\n\n    nodes.forEach(node => {\n      node.fx = fxFn(node);\n      node.fy = fyFn(node);\n      node.fz = fzFn(node);\n    });\n  }\n\n  return RADIALS.includes(mode)\n    ? d3ForceRadial(node => {\n        const nodeDepth = depths[node.id];\n        const depth =\n          mode === 'radialin' ? maxDepth - nodeDepth.depth : nodeDepth.depth;\n        return depth * dagLevelDistance;\n      }).strength(1)\n    : null;\n}\n","import {\n  forceCenter as d3ForceCenter,\n  forceCollide,\n  forceLink as d3ForceLink,\n  forceManyBody as d3ForceManyBody,\n  forceSimulation as d3ForceSimulation,\n  forceX as d3ForceX,\n  forceY as d3ForceY,\n  forceZ as d3ForceZ\n} from 'd3-force-3d';\n\nimport type { ClusterGroup } from '../utils/cluster';\nimport { forceInABox } from './forceInABox';\nimport type { DagMode } from './forceUtils';\nimport { forceRadial } from './forceUtils';\nimport type { FORCE_LAYOUTS } from './layoutProvider';\nimport { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps, LayoutStrategy } from './types';\n\nexport interface ForceDirectedLayoutInputs extends LayoutFactoryProps {\n  /**\n   * Center inertia for the layout. Default: 1.\n   */\n  centerInertia?: number;\n\n  /**\n   * Number of dimensions for the layout. 2d or 3d.\n   */\n  dimensions?: number;\n\n  /**\n   * Mode for the dag layout. Only applicable for dag layouts.\n   */\n  mode?: DagMode;\n\n  /**\n   * Distance between links.\n   */\n  linkDistance?: number;\n\n  /**\n   * Strength of the node repulsion.\n   */\n  nodeStrength?: number;\n\n  /**\n   * Strength of the cluster repulsion.\n   */\n  clusterStrength?: number;\n\n  /**\n   * The clusters dragged position to reuse for the layout.\n   */\n  clusters: Map<string, ClusterGroup>;\n\n  /**\n   * The type of clustering.\n   */\n  clusterType?: 'force' | 'treemap';\n\n  /**\n   * Ratio of the distance between nodes on the same level.\n   */\n  nodeLevelRatio?: number;\n\n  /**\n   * LinkStrength between nodes of different clusters\n   */\n  linkStrengthInterCluster?: number | ((d: any) => number);\n\n  /**\n   * LinkStrength between nodes of the same cluster\n   */\n  linkStrengthIntraCluster?: number | ((d: any) => number);\n\n  /**\n   * Charge between the meta-nodes (Force template only)\n   */\n  forceLinkDistance?: number;\n\n  /**\n   * Used to compute the template force nodes size (Force template only)\n   */\n  forceLinkStrength?: number;\n\n  /**\n   * Used to compute the template force nodes size (Force template only)\n   */\n  forceCharge?: number;\n\n  /**\n   * Used to determine the simulation forceX and forceY values\n   */\n  forceLayout: (typeof FORCE_LAYOUTS)[number];\n}\n\nexport function forceDirected({\n  graph,\n  nodeLevelRatio = 2,\n  mode = null,\n  dimensions = 2,\n  nodeStrength = -250,\n  linkDistance = 50,\n  clusterStrength = 0.5,\n  linkStrengthInterCluster = 0.01,\n  linkStrengthIntraCluster = 0.5,\n  forceLinkDistance = 100,\n  forceLinkStrength = 0.1,\n  clusterType = 'force',\n  forceCharge = -700,\n  getNodePosition,\n  drags,\n  clusters,\n  clusterAttribute,\n  forceLayout\n}: ForceDirectedLayoutInputs): LayoutStrategy {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  // Dynamically adjust node strength based on the number of edges\n  const is2d = dimensions === 2;\n  const nodeStrengthAdjustment =\n    is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength;\n\n  let forceX;\n  let forceY;\n  if (forceLayout === 'forceDirected2d') {\n    forceX = d3ForceX();\n    forceY = d3ForceY();\n  } else {\n    forceX = d3ForceX(600).strength(0.05);\n    forceY = d3ForceY(600).strength(0.05);\n  }\n\n  // Create the simulation\n  const sim = d3ForceSimulation()\n    .force('center', d3ForceCenter(0, 0))\n    .force('link', d3ForceLink())\n    .force('charge', d3ForceManyBody().strength(nodeStrengthAdjustment))\n    .force('x', forceX)\n    .force('y', forceY)\n    .force('z', d3ForceZ())\n    // Handles nodes not overlapping each other ( most relevant in clustering )\n    .force(\n      'collide',\n      forceCollide(d => d.radius + 10)\n    )\n    .force(\n      'dagRadial',\n      forceRadial({\n        nodes,\n        edges,\n        mode,\n        nodeLevelRatio\n      })\n    )\n    .stop();\n\n  let groupingForce;\n  if (clusterAttribute) {\n    // Dynamically adjust cluster force charge based on the number of nodes\n    let forceChargeAdjustment = forceCharge;\n    if (nodes?.length) {\n      const adjustmentFactor = Math.ceil(nodes.length / 200);\n      forceChargeAdjustment = forceCharge * adjustmentFactor;\n    }\n\n    groupingForce = forceInABox()\n      // The clusters dragged position to reuse for the layout\n      .setClusters(clusters)\n      // Strength to foci\n      .strength(clusterStrength)\n      // Either treemap or force\n      .template(clusterType)\n      // Node attribute to group\n      .groupBy(d => d.data[clusterAttribute])\n      // The graph links. Must be called after setting the grouping attribute\n      .links(edges)\n      // Size of the chart\n      .size([100, 100])\n      // linkStrength between nodes of different clusters\n      .linkStrengthInterCluster(linkStrengthInterCluster)\n      // linkStrength between nodes of the same cluster\n      .linkStrengthIntraCluster(linkStrengthIntraCluster)\n      // linkDistance between meta-nodes on the template (Force template only)\n      .forceLinkDistance(forceLinkDistance)\n      // linkStrength between meta-nodes of the template (Force template only)\n      .forceLinkStrength(forceLinkStrength)\n      // Charge between the meta-nodes (Force template only)\n      .forceCharge(forceChargeAdjustment)\n      // Used to compute the template force nodes size (Force template only)\n      .forceNodeSize(d => d.radius);\n  }\n\n  // Initialize the simulation\n  let layout = sim.numDimensions(dimensions).nodes(nodes);\n\n  if (groupingForce) {\n    layout = layout.force('group', groupingForce);\n  }\n\n  // Run the force on the links\n  if (linkDistance) {\n    let linkForce = layout.force('link');\n    if (linkForce) {\n      linkForce\n        .id(d => d.id)\n        .links(edges)\n        // When no mode passed, its a tree layout\n        // so let's use a larger distance\n        .distance(linkDistance);\n\n      if (groupingForce) {\n        linkForce = linkForce.strength(groupingForce?.getLinkStrength ?? 0.1);\n      }\n    }\n  }\n\n  const nodeMap = new Map(nodes.map(n => [n.id, n]));\n\n  return {\n    step() {\n      // Run the simulation til we get a stable result\n      while (sim.alpha() > 0.01) {\n        sim.tick();\n      }\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) {\n          return pos;\n        }\n      }\n\n      if (drags?.[id]?.position) {\n        // If we dragged, we need to use that position\n        return drags?.[id]?.position as any;\n      }\n\n      return nodeMap.get(id);\n    }\n  };\n}\n","import { hierarchy, stratify, tree } from 'd3-hierarchy';\n\nimport type { InternalGraphNode } from '../types';\nimport type { DepthNode } from './depthUtils';\nimport { getNodeDepth } from './depthUtils';\nimport { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps, LayoutStrategy } from './types';\n\nexport interface HierarchicalLayoutInputs extends LayoutFactoryProps {\n  /**\n   * Direction of the layout. Default 'td'.\n   */\n  mode?: 'td' | 'lr';\n  /**\n   * Factor of distance between nodes. Default 1.\n   */\n  nodeSeparation?: number;\n  /**\n   * Size of each node. Default [50,50]\n   */\n  nodeSize?: [number, number];\n}\n\nconst DIRECTION_MAP = {\n  td: {\n    x: 'x',\n    y: 'y',\n    factor: -1\n  },\n  lr: {\n    x: 'y',\n    y: 'x',\n    factor: 1\n  }\n};\n\nexport function hierarchical({\n  graph,\n  drags,\n  mode = 'td',\n  nodeSeparation = 1,\n  nodeSize = [50, 50],\n  getNodePosition\n}: HierarchicalLayoutInputs): LayoutStrategy {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  const { depths } = getNodeDepth(nodes, edges);\n  const rootNodes = Object.keys(depths).map(d => depths[d]);\n\n  const root = stratify<DepthNode>()\n    .id(d => d.data.id)\n    .parentId(d => d.ins?.[0]?.data?.id)(rootNodes);\n\n  const treeRoot = tree()\n    .separation(() => nodeSeparation)\n    .nodeSize(nodeSize)(hierarchy(root));\n\n  const treeNodes = treeRoot.descendants();\n  const path = DIRECTION_MAP[mode];\n\n  const mappedNodes = new Map<string, InternalGraphNode>(\n    nodes.map(n => {\n      const { x, y } = treeNodes.find((t: any) => t.data.id === n.id);\n      return [\n        n.id,\n        {\n          ...n,\n          [path.x]: x * path.factor,\n          [path.y]: y * path.factor,\n          z: 0\n        }\n      ];\n    })\n  );\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) {\n          return pos;\n        }\n      }\n\n      if (drags?.[id]?.position) {\n        // If we dragged, we need to use that position\n        return drags?.[id]?.position as any;\n      }\n\n      return mappedNodes.get(id);\n    }\n  };\n}\n","import type { ConcentricLayoutInputs } from 'layout/concentric2d';\nimport { Vector3 } from 'three';\n\nimport { buildNodeEdges } from './layoutUtils';\n\n/**\n * Generates a point on a Fibonacci sphere.\n * @param i\n * @param n\n * @param r\n */\nfunction fibonacciSpherePoint(i: number, n: number, r: number) {\n  const phi = Math.acos(1 - (2 * (i + 0.5)) / n);\n  const theta = Math.PI * (1 + Math.sqrt(5)) * (i + 0.5);\n  const x = r * Math.sin(phi) * Math.cos(theta);\n  const y = r * Math.sin(phi) * Math.sin(theta);\n  const z = r * Math.cos(phi);\n\n  return new Vector3(x, y, z);\n}\n\n/**\n * Concentric layout algorithm for 3D graphs.\n * @param graph\n * @param radius\n * @param drags\n * @param getNodePosition\n * @param concentricSpacing\n */\nexport function concentric3d({\n  graph,\n  radius = 40,\n  drags,\n  getNodePosition,\n  concentricSpacing = 100\n}: ConcentricLayoutInputs) {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  const layout: Record<string, { x: number; y: number; z: number }> = {};\n\n  const getNodesInLevel = (level: number) => {\n    const circumference = 2 * Math.PI * (radius + level * concentricSpacing);\n    const minNodeSpacing = 40;\n    return Math.floor(circumference / minNodeSpacing);\n  };\n\n  const fixedLevelMap = new Map<number, string[]>();\n  const dynamicNodes: { id: string; metric: number }[] = [];\n\n  // Split nodes: fixed-level and dynamic\n  for (const node of nodes) {\n    const data = graph.getNodeAttribute(node.id, 'data');\n    const level = data?.level;\n\n    if (typeof level === 'number' && level >= 0) {\n      if (!fixedLevelMap.has(level)) {\n        fixedLevelMap.set(level, []);\n      }\n      fixedLevelMap.get(level)!.push(node.id);\n    } else {\n      dynamicNodes.push({ id: node.id, metric: graph.degree(node.id) });\n    }\n  }\n\n  // Sort dynamic nodes by degree\n  dynamicNodes.sort((a, b) => b.metric - a.metric);\n\n  // Fill layout for fixed-level nodes (3D spherical placement)\n  for (const [level, nodeIds] of fixedLevelMap.entries()) {\n    const count = nodeIds.length;\n    const r = radius + level * concentricSpacing;\n\n    for (const [i, id] of nodeIds.entries()) {\n      const pos = fibonacciSpherePoint(i, count, r);\n      layout[id] = { x: pos.x, y: pos.y, z: pos.z };\n    }\n  }\n\n  // Determine which levels are partially used and which are available\n  const occupiedLevels = new Set(fixedLevelMap.keys());\n  let dynamicLevel = 0;\n\n  let i = 0;\n  while (i < dynamicNodes.length) {\n    // Skip occupied levels\n    while (occupiedLevels.has(dynamicLevel)) {\n      dynamicLevel++;\n    }\n\n    const nodesInLevel = getNodesInLevel(dynamicLevel);\n    const r = radius + dynamicLevel * concentricSpacing;\n\n    for (let j = 0; j < nodesInLevel && i < dynamicNodes.length; j++) {\n      const pos = fibonacciSpherePoint(j, nodesInLevel, r);\n      layout[dynamicNodes[i].id] = { x: pos.x, y: pos.y, z: pos.z };\n      i++;\n    }\n\n    dynamicLevel++;\n  }\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) {\n          return pos;\n        }\n      }\n\n      if (drags?.[id]?.position) {\n        return drags[id].position as any;\n      }\n\n      return layout[id];\n    }\n  };\n}\n","import noverlapLayout from 'graphology-layout-noverlap';\n\nimport { buildNodeEdges } from './layoutUtils';\nimport type { LayoutFactoryProps } from './types';\n\nexport interface NoOverlapLayoutInputs extends LayoutFactoryProps {\n  /**\n   * Grid size. Default 20.\n   */\n  gridSize?: number;\n\n  /**\n   * Ratio of the layout. Default 10.\n   */\n  ratio?: number;\n\n  /**\n   * Maximum number of iterations. Default 50.\n   */\n  maxIterations?: number;\n\n  /**\n   * Margin between nodes. Default 10.\n   */\n  margin?: number;\n}\n\nexport function nooverlap({\n  graph,\n  margin,\n  drags,\n  getNodePosition,\n  ratio,\n  gridSize,\n  maxIterations\n}: NoOverlapLayoutInputs) {\n  const { nodes, edges } = buildNodeEdges(graph);\n\n  const layout = noverlapLayout(graph, {\n    maxIterations,\n    inputReducer: (_key, attr) => ({\n      ...attr,\n      // Have to specify defaults for the engine\n      x: attr.x || 0,\n      y: attr.y || 0\n    }),\n    settings: {\n      ratio,\n      margin,\n      gridSize\n    }\n  });\n\n  return {\n    step() {\n      return true;\n    },\n    getNodePosition(id: string) {\n      if (getNodePosition) {\n        const pos = getNodePosition(id, { graph, drags, nodes, edges });\n        if (pos) {\n          return pos;\n        }\n      }\n\n      if (drags?.[id]?.position) {\n        // If we dragged, we need to use that position\n        return drags?.[id]?.position as any;\n      }\n\n      return layout?.[id];\n    }\n  };\n}\n","import { concentric2d } from 'layout/concentric2d';\nimport { concentric3d } from 'layout/concentric3d';\n\nimport type { CircularLayoutInputs } from './circular2d';\nimport { circular2d } from './circular2d';\nimport type { ConcentricLayoutInputs } from './concentric2d';\nimport { custom } from './custom';\nimport type { ForceAtlas2LayoutInputs } from './forceatlas2';\nimport { forceAtlas2 } from './forceatlas2';\nimport type { ForceDirectedLayoutInputs } from './forceDirected';\nimport { forceDirected } from './forceDirected';\nimport type { HierarchicalLayoutInputs } from './hierarchical';\nimport { hierarchical } from './hierarchical';\nimport type { NoOverlapLayoutInputs } from './nooverlap';\nimport { nooverlap } from './nooverlap';\nimport type { LayoutFactoryProps, LayoutStrategy } from './types';\n\nexport type LayoutOverrides = Partial<\n  | Omit<ForceDirectedLayoutInputs, 'dimensions' | 'mode'>\n  | CircularLayoutInputs\n  | ConcentricLayoutInputs\n  | HierarchicalLayoutInputs\n>;\n\nexport const FORCE_LAYOUTS = [\n  'forceDirected2d',\n  'treeTd2d',\n  'treeLr2d',\n  'radialOut2d',\n  'treeTd3d',\n  'treeLr3d',\n  'radialOut3d',\n  'forceDirected3d'\n];\n\nexport function layoutProvider({\n  type,\n  ...rest\n}: LayoutFactoryProps | LayoutOverrides): LayoutStrategy {\n  if (FORCE_LAYOUTS.includes(type)) {\n    const { nodeStrength, linkDistance, nodeLevelRatio } =\n      rest as ForceDirectedLayoutInputs;\n\n    if (type === 'forceDirected2d') {\n      return forceDirected({\n        ...rest,\n        dimensions: 2,\n        nodeLevelRatio: nodeLevelRatio || 2,\n        nodeStrength: nodeStrength || -250,\n        linkDistance,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'treeTd2d') {\n      return forceDirected({\n        ...rest,\n        mode: 'td',\n        dimensions: 2,\n        nodeLevelRatio: nodeLevelRatio || 5,\n        nodeStrength: nodeStrength || -250,\n        linkDistance: linkDistance || 50,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'treeLr2d') {\n      return forceDirected({\n        ...rest,\n        mode: 'lr',\n        dimensions: 2,\n        nodeLevelRatio: nodeLevelRatio || 5,\n        nodeStrength: nodeStrength || -250,\n        linkDistance: linkDistance || 50,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'radialOut2d') {\n      return forceDirected({\n        ...rest,\n        mode: 'radialout',\n        dimensions: 2,\n        nodeLevelRatio: nodeLevelRatio || 5,\n        nodeStrength: nodeStrength || -500,\n        linkDistance: linkDistance || 100,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'treeTd3d') {\n      return forceDirected({\n        ...rest,\n        mode: 'td',\n        dimensions: 3,\n        nodeLevelRatio: nodeLevelRatio || 2,\n        nodeStrength: nodeStrength || -500,\n        linkDistance: linkDistance || 50\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'treeLr3d') {\n      return forceDirected({\n        ...rest,\n        mode: 'lr',\n        dimensions: 3,\n        nodeLevelRatio: nodeLevelRatio || 2,\n        nodeStrength: nodeStrength || -500,\n        linkDistance: linkDistance || 50,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'radialOut3d') {\n      return forceDirected({\n        ...rest,\n        mode: 'radialout',\n        dimensions: 3,\n        nodeLevelRatio: nodeLevelRatio || 2,\n        nodeStrength: nodeStrength || -500,\n        linkDistance: linkDistance || 100,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    } else if (type === 'forceDirected3d') {\n      return forceDirected({\n        ...rest,\n        dimensions: 3,\n        nodeLevelRatio: nodeLevelRatio || 2,\n        nodeStrength: nodeStrength || -250,\n        linkDistance,\n        forceLayout: type\n      } as ForceDirectedLayoutInputs);\n    }\n  } else if (type === 'circular2d') {\n    const { radius } = rest as CircularLayoutInputs;\n    return circular2d({\n      ...rest,\n      radius: radius || 300\n    } as CircularLayoutInputs);\n  } else if (type === 'concentric2d') {\n    return concentric2d(rest as ConcentricLayoutInputs);\n  } else if (type === 'concentric3d') {\n    return concentric3d(rest as ConcentricLayoutInputs);\n  } else if (type === 'hierarchicalTd') {\n    return hierarchical({ ...rest, mode: 'td' } as HierarchicalLayoutInputs);\n  } else if (type === 'hierarchicalLr') {\n    return hierarchical({ ...rest, mode: 'lr' } as HierarchicalLayoutInputs);\n  } else if (type === 'nooverlap') {\n    const { graph, maxIterations, ratio, margin, gridSize, ...settings } =\n      rest as NoOverlapLayoutInputs;\n\n    return nooverlap({\n      type: 'nooverlap',\n      graph,\n      margin: margin || 10,\n      maxIterations: maxIterations || 50,\n      ratio: ratio || 10,\n      gridSize: gridSize || 20,\n      ...settings\n    });\n  } else if (type === 'forceatlas2') {\n    const { graph, iterations, gravity, scalingRatio, ...settings } =\n      rest as ForceAtlas2LayoutInputs;\n\n    return forceAtlas2({\n      type: 'forceatlas2',\n      graph,\n      ...settings,\n      scalingRatio: scalingRatio || 100,\n      gravity: gravity || 10,\n      iterations: iterations || 50\n    });\n  } else if (type === 'custom') {\n    return custom({\n      type: 'custom',\n      ...rest\n    } as LayoutFactoryProps);\n  }\n\n  throw new Error(`Layout ${type} not found.`);\n}\n","import type { GraphEdge, GraphNode } from '../types';\nimport { getNodeDepth } from './depthUtils';\nimport type { LayoutTypes } from './types';\n\n/**\n * Given a set of nodes and edges, determine the type of layout that\n * is most ideal. This is very beta.\n */\nexport function recommendLayout(\n  nodes: GraphNode[],\n  edges: GraphEdge[]\n): LayoutTypes {\n  const { invalid } = getNodeDepth(nodes as any[], edges as any[]);\n  const nodeCount = nodes.length;\n\n  if (!invalid) {\n    // Large tree layouts\n    if (nodeCount > 100) {\n      return 'radialOut2d';\n    } else {\n      // Smaller tree layouts\n      return 'treeTd2d';\n    }\n  }\n\n  // Circular layouts\n  return 'forceDirected2d';\n}\n","import { useThree } from '@react-three/fiber';\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { PerspectiveCamera } from 'three';\n\nimport { getVisibleEntities } from './collapse';\nimport type { LayoutOverrides, LayoutStrategy, LayoutTypes } from './layout';\nimport { layoutProvider } from './layout';\nimport { tick } from './layout/layoutUtils';\nimport type { SizingType } from './sizing';\nimport type { DragReferences } from './store';\nimport { useStore } from './store';\nimport type { GraphEdge, GraphNode, InternalGraphNode } from './types';\nimport { calculateClusters } from './utils/cluster';\nimport { buildGraph, transformGraph } from './utils/graph';\nimport type { LabelVisibilityType } from './utils/visibility';\nimport { calcLabelVisibility } from './utils/visibility';\n\nexport interface GraphInputs {\n  nodes: GraphNode[];\n  edges: GraphEdge[];\n  collapsedNodeIds?: string[];\n  layoutType?: LayoutTypes;\n  sizingType?: SizingType;\n  labelType?: LabelVisibilityType;\n  sizingAttribute?: string;\n  selections?: string[];\n  actives?: string[];\n  clusterAttribute?: string;\n  defaultNodeSize?: number;\n  minNodeSize?: number;\n  maxNodeSize?: number;\n  constrainDragging?: boolean;\n  layoutOverrides?: LayoutOverrides;\n}\n\nexport const useGraph = ({\n  layoutType,\n  sizingType,\n  labelType,\n  sizingAttribute,\n  clusterAttribute,\n  selections,\n  nodes,\n  edges,\n  actives,\n  collapsedNodeIds,\n  defaultNodeSize,\n  maxNodeSize,\n  minNodeSize,\n  layoutOverrides,\n  constrainDragging\n}: GraphInputs) => {\n  const graph = useStore(state => state.graph);\n  const clusters = useStore(state => state.clusters);\n  const storedNodes = useStore(state => state.nodes);\n  const setClusters = useStore(state => state.setClusters);\n  const stateCollapsedNodeIds = useStore(state => state.collapsedNodeIds);\n  const setEdges = useStore(state => state.setEdges);\n  const stateNodes = useStore(state => state.nodes);\n  const setNodes = useStore(state => state.setNodes);\n  const setSelections = useStore(state => state.setSelections);\n  const setActives = useStore(state => state.setActives);\n  const drags = useStore(state => state.drags);\n  const setDrags = useStore(state => state.setDrags);\n  const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\n  const layoutMounted = useRef<boolean>(false);\n  const layout = useRef<LayoutStrategy | null>(null);\n  const camera = useThree(state => state.camera) as PerspectiveCamera;\n  const dragRef = useRef<DragReferences>(drags);\n  const clustersRef = useRef<any>([]);\n\n  // When a new node is added, remove the dragged position of the cluster nodes to put new node in the right place\n  useEffect(() => {\n    if (!clusterAttribute) {\n      return;\n    }\n\n    const existedNodesIds = storedNodes.map(n => n.id);\n    const newNode = nodes.find(n => !existedNodesIds.includes(n.id));\n    if (newNode) {\n      const clusterName = newNode.data[clusterAttribute];\n      const cluster = clusters.get(clusterName);\n      const drags = { ...dragRef.current };\n\n      cluster?.nodes?.forEach(node => (drags[node.id] = undefined));\n\n      dragRef.current = drags;\n      setDrags(drags);\n    }\n  }, [storedNodes, nodes, clusterAttribute, clusters, setDrags]);\n\n  // Calculate the visible entities\n  const { visibleEdges, visibleNodes } = useMemo(\n    () =>\n      getVisibleEntities({\n        collapsedIds: stateCollapsedNodeIds,\n        nodes,\n        edges\n      }),\n    [stateCollapsedNodeIds, nodes, edges]\n  );\n\n  // Store node positions inside drags state\n  const updateDrags = useCallback(\n    (nodes: InternalGraphNode[]) => {\n      const drags = { ...dragRef.current };\n      nodes.forEach(node => (drags[node.id] = node));\n      dragRef.current = drags;\n      setDrags(drags);\n    },\n    [setDrags]\n  );\n\n  const updateLayout = useCallback(\n    async (curLayout?: any) => {\n      // Cache the layout provider\n      layout.current =\n        curLayout ||\n        layoutProvider({\n          ...layoutOverrides,\n          type: layoutType,\n          graph,\n          drags: dragRef.current,\n          clusters: clustersRef?.current,\n          clusterAttribute\n        });\n\n      // Run the layout\n      await tick(layout.current);\n\n      // Transform the graph\n      const result = transformGraph({\n        graph,\n        layout: layout.current,\n        sizingType,\n        labelType,\n        sizingAttribute,\n        maxNodeSize,\n        minNodeSize,\n        defaultNodeSize,\n        clusterAttribute\n      });\n\n      // Calculate clusters\n      const newClusters = calculateClusters({\n        nodes: result.nodes,\n        clusterAttribute\n      });\n\n      // Do not decrease the cluster size is the number of nodes is the same\n      if (constrainDragging) {\n        newClusters.forEach(cluster => {\n          const prevCluster = clustersRef.current.get(cluster.label);\n          if (prevCluster?.nodes.length === cluster.nodes.length) {\n            cluster.position =\n              clustersRef.current?.get(cluster.label)?.position ??\n              cluster.position;\n          }\n        });\n      }\n\n      // Set our store outputs\n      setEdges(result.edges);\n      setNodes(result.nodes);\n      setClusters(newClusters);\n      if (clusterAttribute) {\n        // Set drag positions for nodes to prevent them from being moved by the layout update\n        updateDrags(result.nodes);\n      }\n    },\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [\n      layoutOverrides,\n      layoutType,\n      clusterAttribute,\n      sizingType,\n      labelType,\n      sizingAttribute,\n      maxNodeSize,\n      minNodeSize,\n      defaultNodeSize,\n      setEdges,\n      setNodes,\n      setClusters\n    ]\n  );\n\n  // Transient updates\n  useEffect(() => {\n    dragRef.current = drags;\n  }, [drags, clusterAttribute, updateLayout]);\n\n  // Transient cluster state\n  useEffect(() => {\n    clustersRef.current = clusters;\n  }, [clusters]);\n\n  useEffect(() => {\n    // When the camera position/zoom changes, update the label visibility\n    const nodes = stateNodes.map(node => ({\n      ...node,\n      labelVisible: calcLabelVisibility({\n        nodeCount: stateNodes?.length,\n        labelType,\n        camera,\n        nodePosition: node?.position\n      })('node', node?.size)\n    }));\n\n    // Determine if the label visibility has changed\n    const isVisibilityUpdated = nodes.some(\n      (node, i) => node.labelVisible !== stateNodes[i].labelVisible\n    );\n\n    // Update the nodes if the label visibility has changed\n    if (isVisibilityUpdated) {\n      setNodes(nodes);\n    }\n  }, [camera, camera.zoom, camera.position.z, setNodes, stateNodes, labelType]);\n\n  useEffect(() => {\n    // Let's set the store selections so its easier to access\n    if (layoutMounted.current) {\n      setSelections(selections);\n    }\n  }, [selections, setSelections]);\n\n  useEffect(() => {\n    // Let's set the store actives so its easier to access\n    if (layoutMounted.current) {\n      setActives(actives);\n    }\n  }, [actives, setActives]);\n\n  // Create the nggraph graph object\n  useEffect(() => {\n    async function update() {\n      layoutMounted.current = false;\n      buildGraph(graph, visibleNodes, visibleEdges);\n      await updateLayout();\n      // rqf to prevent race condition\n      requestAnimationFrame(() => (layoutMounted.current = true));\n    }\n\n    update();\n    // eslint-disable-next-line\n  }, [visibleNodes, visibleEdges]);\n\n  useEffect(() => {\n    // Let's set the store collapsedNodeIds so its easier to access\n    if (layoutMounted.current) {\n      setCollapsedNodeIds(collapsedNodeIds);\n    }\n  }, [collapsedNodeIds, setCollapsedNodeIds]);\n\n  // Update layout on type changes\n  useEffect(() => {\n    if (layoutMounted.current) {\n      // When a update is changed, discard all the previous drag positions\n      // NOTE: This sets the transient and the state\n      dragRef.current = {};\n      setDrags({});\n\n      // Recalculate the layout\n      updateLayout();\n    }\n  }, [layoutType, updateLayout, setDrags]);\n\n  // Update layout on size, label changes\n  useEffect(() => {\n    if (layoutMounted.current) {\n      updateLayout(layout.current);\n    }\n  }, [sizingType, sizingAttribute, labelType, updateLayout]);\n\n  return {\n    updateLayout\n  };\n};\n","import type Graph from 'graphology';\n\nimport type { InternalGraphEdge } from '../types';\nimport type { LabelVisibilityType } from './visibility';\n\n/**\n * Graphology-native approach using reduceEdges for optimal performance\n * @param graph Graphology graph instance\n * @returns Map with source-target pairs as keys and arrays of edges as values\n */\nexport const groupEdgesBySourceTarget = (\n  graph: Graph\n): Map<string, InternalGraphEdge[]> => {\n  // Use Graphology's native reduceEdges\n  return graph.reduceEdges(\n    (\n      edgeGroups: Map<string, InternalGraphEdge[]>,\n      edgeKey,\n      attributes,\n      source,\n      target\n    ) => {\n      const key = `${source}-${target}`;\n\n      // Construct complete InternalGraphEdge object\n      const edge: InternalGraphEdge = {\n        id: edgeKey,\n        source,\n        target,\n        ...attributes\n      };\n\n      const group = edgeGroups.get(key);\n      if (group) {\n        group.push(edge);\n      } else {\n        edgeGroups.set(key, [edge]);\n      }\n\n      return edgeGroups;\n    },\n    new Map<string, InternalGraphEdge[]>()\n  );\n};\n\n/**\n * Aggregates edges with the same source and target using Graphology's native functions\n * @param graph Graphology graph instance\n * @param labelType Label visibility type to determine if edge labels should be visible\n * @returns Array of aggregated edges\n */\nexport const aggregateEdges = (\n  graph: Graph,\n  labelType?: LabelVisibilityType\n): InternalGraphEdge[] => {\n  if (!graph || graph.size === 0) {\n    return [];\n  }\n\n  // Use Graphology's native reduceEdges to group and aggregate in one pass\n  const edgeGroups = groupEdgesBySourceTarget(graph);\n  const aggregatedEdges: InternalGraphEdge[] = [];\n  // Determine if edge labels should be visible based on labelType\n  const shouldShowEdgeLabels = labelType === 'all' || labelType === 'edges';\n\n  // Process groups efficiently\n  for (const [key, group] of edgeGroups) {\n    const [source, target] = key.split('-');\n    const firstEdge = group[0];\n\n    if (!source || !target || !firstEdge) {\n      continue;\n    }\n\n    // Calculate the aggregated edge size based on the number of edges\n    const baseSize = firstEdge.size || 1; // Default to 1 if no size is specified\n    const aggregatedSize = baseSize + group.length * baseSize * 0.5;\n\n    // Only show aggregation label when actually aggregating multiple edges\n    const aggregated = group.length > 1;\n    const label = aggregated ? `${group.length} edges` : firstEdge.label;\n\n    // Create an aggregated edge that represents the group\n    const aggregatedEdge: InternalGraphEdge = {\n      ...firstEdge,\n      source,\n      target,\n      label,\n      labelVisible: shouldShowEdgeLabels,\n      size: aggregatedSize,\n      // Store the original edges in the data property\n      data: {\n        ...(firstEdge.data || {}),\n        originalEdges: group,\n        count: group.length,\n        isAggregated: aggregated,\n        originalSize: baseSize\n      }\n    };\n\n    aggregatedEdges.push(aggregatedEdge);\n  }\n\n  return aggregatedEdges;\n};\n","import type { ThreeEvent } from '@react-three/fiber';\nimport { useThree } from '@react-three/fiber';\nimport type Graph from 'graphology';\nimport type { ReactNode } from 'react';\nimport React, {\n  forwardRef,\n  Fragment,\n  useCallback,\n  useEffect,\n  useImperativeHandle,\n  useMemo\n} from 'react';\n\nimport type {\n  CenterNodesParams,\n  FitNodesParams\n} from './CameraControls/useCenterGraph';\nimport { useCenterGraph } from './CameraControls/useCenterGraph';\nimport type { LayoutOverrides, LayoutTypes } from './layout';\nimport type { SizingType } from './sizing';\nimport { useStore } from './store';\nimport { Node } from './symbols';\nimport type { ClusterEventArgs } from './symbols/Cluster';\nimport { Cluster } from './symbols/Cluster';\nimport type { EdgeInterpolation, EdgeLabelPosition } from './symbols/Edge';\nimport { Edge } from './symbols/Edge';\nimport { Edges } from './symbols/edges';\nimport type { EdgeArrowPosition } from './symbols/edges/Edge';\nimport type {\n  ClusterRenderer,\n  CollapseProps,\n  ContextMenuEvent,\n  GraphEdge,\n  GraphNode,\n  InternalGraphEdge,\n  InternalGraphNode,\n  NodeContextMenuProps,\n  NodeRenderer\n} from './types';\nimport { useGraph } from './useGraph';\nimport { aggregateEdges as aggregateEdgesUtil } from './utils/aggregateEdges';\nimport type { LabelVisibilityType } from './utils/visibility';\n\nexport interface GraphSceneProps {\n  /**\n   * Type of layout.\n   */\n  layoutType?: LayoutTypes;\n\n  /**\n   * List of ids that are selected.\n   */\n  selections?: string[];\n\n  /**\n   * List of ids that are active.\n   */\n  actives?: string[];\n\n  /**\n   * List of node ids that are collapsed.\n   */\n  collapsedNodeIds?: string[];\n\n  /**\n   * Animate or not the graph positions.\n   */\n  animated?: boolean;\n\n  /**\n   * Nodes to pass to the graph.\n   */\n  nodes: GraphNode[];\n\n  /**\n   * Edges to pass to the graph.\n   */\n  edges: GraphEdge[];\n\n  /**\n   * Context menu element.\n   */\n  contextMenu?: (event: ContextMenuEvent) => ReactNode;\n\n  /**\n   * Type of sizing for nodes.\n   */\n  sizingType?: SizingType;\n\n  /**\n   * Type of visibility for labels.\n   */\n  labelType?: LabelVisibilityType;\n\n  /**\n   * Place of visibility for edge labels.\n   */\n  edgeLabelPosition?: EdgeLabelPosition;\n\n  /**\n   * Placement of edge arrows.\n   */\n  edgeArrowPosition?: EdgeArrowPosition;\n\n  /**\n   * Shape of edge.\n   */\n  edgeInterpolation?: EdgeInterpolation;\n\n  /**\n   * Font of label, same as troika-three-text\n   * The URL of a custom font file to be used. Supported font formats are: * .ttf * .otf * .woff (.woff2 is not supported)\n   * Default: The Roboto font loaded from Google Fonts CDN\n   */\n  labelFontUrl?: string;\n\n  /**\n   * Attribute based sizing property.\n   */\n  sizingAttribute?: string;\n\n  /**\n   * The default size to size nodes to. Default is 7.\n   */\n  defaultNodeSize?: number;\n\n  /**\n   * When using sizing attributes, the min size a node can be.\n   */\n  minNodeSize?: number;\n\n  /**\n   * When using sizing attributes, the max size a node can be.\n   */\n  maxNodeSize?: number;\n\n  /**\n   * Attribute used for clustering.\n   */\n  clusterAttribute?: string;\n\n  /**\n   * Disable interactions or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Allow dragging of nodes.\n   */\n  draggable?: boolean;\n\n  /**\n   * Constrain dragging to the cluster bounds. Default is `false`.\n   */\n  constrainDragging?: boolean;\n\n  /**\n   * Render a custom node\n   */\n  renderNode?: NodeRenderer;\n\n  /**\n   * Render a custom cluster\n   */\n  onRenderCluster?: ClusterRenderer;\n\n  /**\n   * Advanced overrides for the layout.\n   */\n  layoutOverrides?: LayoutOverrides;\n\n  /**\n   * Whether to aggregate edges with the same source and target.\n   */\n  aggregateEdges?: boolean;\n\n  /**\n   * When a node was clicked.\n   */\n  onNodeClick?: (\n    node: InternalGraphNode,\n    props?: CollapseProps,\n    event?: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * When a node was double clicked.\n   */\n  onNodeDoubleClick?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * When a node context menu happened.\n   */\n  onNodeContextMenu?: (\n    node: InternalGraphNode,\n    props?: NodeContextMenuProps\n  ) => void;\n\n  /**\n   * When node got a pointer over.\n   */\n  onNodePointerOver?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * When node lost pointer over.\n   */\n  onNodePointerOut?: (\n    node: InternalGraphNode,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * Triggered after a node was dragged.\n   */\n  onNodeDragged?: (node: InternalGraphNode) => void;\n\n  /**\n   * Triggered after a cluster was dragged.\n   */\n  onClusterDragged?: (cluster: ClusterEventArgs) => void;\n\n  /**\n   * When a edge context menu happened.\n   */\n  onEdgeContextMenu?: (edge?: InternalGraphEdge) => void;\n\n  /**\n   * When an edge was clicked.\n   */\n  onEdgeClick?: (\n    edge: InternalGraphEdge,\n    event?: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * When edge got a pointer over.\n   */\n  onEdgePointerOver?: (\n    edge: InternalGraphEdge,\n    event?: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * When edge lost pointer over.\n   */\n  onEdgePointerOut?: (\n    edge: InternalGraphEdge,\n    event?: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * When a cluster was clicked.\n   */\n  onClusterClick?: (\n    cluster: ClusterEventArgs,\n    event: ThreeEvent<MouseEvent>\n  ) => void;\n\n  /**\n   * When a cluster receives a pointer over event.\n   */\n  onClusterPointerOver?: (\n    cluster: ClusterEventArgs,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n\n  /**\n   * When cluster receives a pointer leave event.\n   */\n  onClusterPointerOut?: (\n    cluster: ClusterEventArgs,\n    event: ThreeEvent<PointerEvent>\n  ) => void;\n}\n\nexport interface GraphSceneRef {\n  /**\n   * Reference to the graph object.\n   */\n  graph: Graph;\n\n  /**\n   * Centers the graph on a specific node or list of nodes.\n   *\n   * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\n   * the graph will be centered on all nodes.\n   *\n   * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\n   * only be centered if the nodes specified by `ids` are not currently in view. If this\n   * parameter is `true`, the graph will only be re-centered if one or more of the nodes\n   * specified by `ids` are not currently in view. If this parameter is\n   * `false` or omitted, the graph will be re-centered regardless of whether the nodes\n   * are currently in view.\n   */\n  centerGraph: (nodeIds?: string[], opts?: CenterNodesParams) => void;\n\n  /**\n   * Fit all the given nodes into view of the camera.\n   *\n   * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\n   * the view will fit to all nodes.\n   *\n   * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\n   * only be fit if the nodes specified by `ids` are not currently in view. If this\n   * parameter is `true`, the view will only be fit if one or more of the nodes\n   * specified by `ids` are not currently visible in the viewport. If this parameter is\n   * `false` or omitted, the view will be fit regardless of whether the nodes\n   * are currently in view.\n   */\n  fitNodesInView: (nodeIds?: string[], opts?: FitNodesParams) => void;\n\n  /**\n   * Calls render scene on the graph. this is useful when you want to manually render the graph\n   * for things like screenshots.\n   */\n  renderScene: () => void;\n}\n\nexport const GraphScene = forwardRef<GraphSceneRef, GraphSceneProps>(\n  (\n    {\n      onNodeClick,\n      onNodeDoubleClick,\n      onNodeContextMenu,\n      onEdgeContextMenu,\n      onEdgeClick,\n      onEdgePointerOver,\n      onEdgePointerOut,\n      onNodePointerOver,\n      onNodePointerOut,\n      onClusterClick,\n      onNodeDragged,\n      onClusterDragged,\n      onClusterPointerOver,\n      onClusterPointerOut,\n      contextMenu,\n      animated,\n      disabled,\n      draggable,\n      constrainDragging = false,\n      edgeLabelPosition,\n      edgeArrowPosition,\n      edgeInterpolation = 'linear',\n      labelFontUrl,\n      renderNode,\n      onRenderCluster,\n      aggregateEdges,\n      ...rest\n    },\n    ref\n  ) => {\n    const { layoutType, clusterAttribute, labelType } = rest;\n\n    // Get the gl/scene/camera for render shortcuts\n    const gl = useThree(state => state.gl);\n    const scene = useThree(state => state.scene);\n    const camera = useThree(state => state.camera);\n\n    // Mount and build the graph\n    const { updateLayout } = useGraph({ ...rest, constrainDragging });\n\n    if (\n      clusterAttribute &&\n      !(layoutType === 'forceDirected2d' || layoutType === 'forceDirected3d')\n    ) {\n      throw new Error(\n        'Clustering is only supported for the force directed layouts.'\n      );\n    }\n\n    // Get the graph and nodes via the store for memo\n    const graph = useStore(state => state.graph);\n    const nodes = useStore(state => state.nodes);\n    const edgesStore = useStore(state => state.edges);\n    const setEdges = useStore(state => state.setEdges);\n    const clusters = useStore(state => [...state.clusters.values()]);\n\n    // Process edges based on aggregation setting and update store\n    const edges = useMemo(() => {\n      if (aggregateEdges) {\n        const aggregatedEdges = aggregateEdgesUtil(graph, labelType);\n        return aggregatedEdges;\n      } else {\n        return edgesStore;\n      }\n    }, [edgesStore, aggregateEdges, graph, labelType]);\n\n    // Update the store if edges were aggregated (moved to useEffect to avoid render cycle error)\n    useEffect(() => {\n      if (aggregateEdges && edgesStore.length !== edges.length) {\n        setEdges(edges);\n      }\n    }, [edges, edgesStore.length, setEdges, aggregateEdges]);\n\n    // Center the graph on the nodes\n    const { centerNodesById, fitNodesInViewById, isCentered } = useCenterGraph({\n      animated,\n      disabled,\n      layoutType\n    });\n\n    // Let's expose some helper methods\n    useImperativeHandle(\n      ref,\n      () => ({\n        centerGraph: centerNodesById,\n        fitNodesInView: fitNodesInViewById,\n        graph,\n        renderScene: () => gl.render(scene, camera)\n      }),\n      [centerNodesById, fitNodesInViewById, graph, gl, scene, camera]\n    );\n\n    const onNodeDraggedHandler = useCallback(\n      (node: InternalGraphNode) => {\n        onNodeDragged?.(node);\n\n        // Update layout to recalculate the cluster positions when a node is dragged\n        if (clusterAttribute) {\n          updateLayout();\n        }\n      },\n      [clusterAttribute, onNodeDragged, updateLayout]\n    );\n\n    const nodeComponents = useMemo(\n      () =>\n        nodes.map(n => (\n          <Node\n            key={n?.id}\n            id={n?.id}\n            labelFontUrl={labelFontUrl}\n            draggable={draggable}\n            constrainDragging={constrainDragging}\n            disabled={disabled}\n            animated={animated}\n            contextMenu={contextMenu}\n            renderNode={renderNode}\n            onClick={onNodeClick}\n            onDoubleClick={onNodeDoubleClick}\n            onContextMenu={onNodeContextMenu}\n            onPointerOver={onNodePointerOver}\n            onPointerOut={onNodePointerOut}\n            onDragged={onNodeDraggedHandler}\n          />\n        )),\n      [\n        constrainDragging,\n        animated,\n        contextMenu,\n        disabled,\n        draggable,\n        labelFontUrl,\n        nodes,\n        onNodeClick,\n        onNodeContextMenu,\n        onNodeDoubleClick,\n        onNodeDraggedHandler,\n        onNodePointerOut,\n        onNodePointerOver,\n        renderNode\n      ]\n    );\n\n    const edgeComponents = useMemo(\n      () =>\n        animated ? (\n          edges.map(e => (\n            <Edge\n              key={e.id}\n              id={e.id}\n              disabled={disabled}\n              animated={animated}\n              labelFontUrl={labelFontUrl}\n              labelPlacement={edgeLabelPosition}\n              arrowPlacement={edgeArrowPosition}\n              interpolation={edgeInterpolation}\n              contextMenu={contextMenu}\n              onClick={onEdgeClick}\n              onContextMenu={onEdgeContextMenu}\n              onPointerOver={onEdgePointerOver}\n              onPointerOut={onEdgePointerOut}\n            />\n          ))\n        ) : (\n          <Edges\n            edges={edges}\n            disabled={disabled}\n            animated={animated}\n            labelFontUrl={labelFontUrl}\n            labelPlacement={edgeLabelPosition}\n            arrowPlacement={edgeArrowPosition}\n            interpolation={edgeInterpolation}\n            contextMenu={contextMenu}\n            onClick={onEdgeClick}\n            onContextMenu={onEdgeContextMenu}\n            onPointerOver={onEdgePointerOver}\n            onPointerOut={onEdgePointerOut}\n          />\n        ),\n      [\n        animated,\n        contextMenu,\n        disabled,\n        edgeArrowPosition,\n        edgeInterpolation,\n        edgeLabelPosition,\n        edges,\n        labelFontUrl,\n        onEdgeClick,\n        onEdgeContextMenu,\n        onEdgePointerOut,\n        onEdgePointerOver\n      ]\n    );\n\n    const clusterComponents = useMemo(\n      () =>\n        clusters.map(c => (\n          <Cluster\n            key={c.label}\n            animated={animated}\n            disabled={disabled}\n            draggable={draggable}\n            labelFontUrl={labelFontUrl}\n            onClick={onClusterClick}\n            onPointerOver={onClusterPointerOver}\n            onPointerOut={onClusterPointerOut}\n            onDragged={onClusterDragged}\n            onRender={onRenderCluster}\n            {...c}\n          />\n        )),\n      [\n        animated,\n        clusters,\n        disabled,\n        draggable,\n        labelFontUrl,\n        onClusterClick,\n        onClusterPointerOut,\n        onClusterPointerOver,\n        onClusterDragged,\n        onRenderCluster\n      ]\n    );\n\n    return (\n      isCentered && (\n        <Fragment>\n          {edgeComponents}\n          {nodeComponents}\n          {clusterComponents}\n        </Fragment>\n      )\n    );\n  }\n);\n","import type Graph from 'graphology';\n\nimport type { Theme } from '../themes';\n\nexport type PathSelectionTypes = 'direct' | 'out' | 'in' | 'all';\n\n/**\n * Given a graph and a list of node ids, return the adjacent nodes and edges.\n *\n * TODO: This method could be improved with the introduction of graphology\n */\nexport function getAdjacents(\n  graph: Graph,\n  nodeIds: string | string[],\n  type: PathSelectionTypes\n) {\n  nodeIds = Array.isArray(nodeIds) ? nodeIds : [nodeIds];\n\n  const nodes: string[] = [];\n  const edges: string[] = [];\n\n  for (const nodeId of nodeIds) {\n    const graphLinks = [\n      ...(graph.inEdgeEntries(nodeId) ?? []),\n      ...(graph.outEdgeEntries(nodeId) ?? [])\n    ];\n\n    if (!graphLinks) {\n      continue;\n    }\n\n    for (const link of graphLinks) {\n      const linkId = link.attributes.id;\n\n      if (type === 'in') {\n        if (link.target === nodeId && !edges.includes(linkId)) {\n          edges.push(linkId);\n        }\n      } else if (type === 'out') {\n        if (link.source === nodeId && !edges.includes(linkId)) {\n          edges.push(linkId);\n        }\n      } else {\n        if (!edges.includes(linkId)) {\n          edges.push(linkId);\n        }\n      }\n\n      if (type === 'out' || type === 'all') {\n        const toId = link.target;\n        if (!nodes.includes(toId as string)) {\n          nodes.push(toId as string);\n        }\n      }\n\n      if (type === 'in' || type === 'all') {\n        if (!nodes.includes(link.source)) {\n          nodes.push(link.source as string);\n        }\n      }\n    }\n  }\n\n  return {\n    nodes,\n    edges\n  };\n}\n\n/**\n * Set the vectors.\n */\nexport function prepareRay(event, vec, size) {\n  const { offsetX, offsetY } = event;\n  const { width, height } = size;\n  vec.set((offsetX / width) * 2 - 1, -(offsetY / height) * 2 + 1);\n}\n\n/**\n * Create a lasso element.\n */\nexport function createElement(theme: Theme) {\n  const element = document.createElement('div');\n  element.style.pointerEvents = 'none';\n  element.style.border = theme.lasso.border;\n  element.style.backgroundColor = theme.lasso.background;\n  element.style.position = 'fixed';\n  return element;\n}\n","import { useThree } from '@react-three/fiber';\nimport type { FC, PropsWithChildren } from 'react';\nimport React, { useCallback, useEffect, useRef } from 'react';\nimport type { Mesh, TubeGeometry } from 'three';\nimport { Scene, Vector2 } from 'three';\nimport { SelectionBox } from 'three-stdlib';\n\nimport { useCameraControls } from '../CameraControls/useCameraControls';\nimport { useStore } from '../store';\nimport { createElement, prepareRay } from './utils';\n\nexport type LassoType = 'none' | 'all' | 'node' | 'edge';\n\nexport type LassoProps = PropsWithChildren<{\n  /**\n   * Whether the lasso tool is disabled.\n   */\n  disabled?: boolean;\n\n  /**\n   * The type of the lasso tool.\n   */\n  type?: LassoType;\n\n  /**\n   * A function that is called when the lasso tool is used to select nodes.\n   * The function receives an array of the ids of the selected nodes.\n   */\n  onLasso?: (selections: string[]) => void;\n\n  /**\n   * A function that is called when the lasso tool is released, ending the selection.\n   * The function receives an array of the ids of the selected nodes.\n   */\n  onLassoEnd?: (selections: string[]) => void;\n}>;\n\nexport const Lasso: FC<LassoProps> = ({\n  children,\n  type = 'none',\n  onLasso,\n  onLassoEnd,\n  disabled\n}) => {\n  const theme = useStore(state => state.theme);\n  const camera = useThree(state => state.camera);\n  const gl = useThree(state => state.gl);\n  const setEvents = useThree(state => state.setEvents);\n  const size = useThree(state => state.size);\n  const get = useThree(state => state.get);\n  const scene = useThree(state => state.scene);\n\n  const cameraControls = useCameraControls();\n\n  const actives = useStore(state => state.actives);\n  const setActives = useStore(state => state.setActives);\n  const edges = useStore(state => state.edges);\n  const edgeMeshes = useStore(state => state.edgeMeshes);\n\n  const selectionBoxRef = useRef<SelectionBox | null>(null);\n  const edgeMeshSelectionBoxRef = useRef<SelectionBox | null>(null);\n  const elementRef = useRef<HTMLDivElement>(createElement(theme));\n  const vectorsRef = useRef<[Vector2, Vector2, Vector2] | null>(null);\n  const isDownRef = useRef(false);\n  const oldRaycasterEnabledRef = useRef<boolean>(get().events.enabled);\n  const oldControlsEnabledRef = useRef<boolean>(\n    cameraControls.controls?.enabled\n  );\n\n  const onPointerMove = useCallback(\n    event => {\n      if (isDownRef.current) {\n        const [startPoint, pointTopLeft, pointBottomRight] = vectorsRef.current;\n\n        pointBottomRight.x = Math.max(startPoint.x, event.clientX);\n        pointBottomRight.y = Math.max(startPoint.y, event.clientY);\n        pointTopLeft.x = Math.min(startPoint.x, event.clientX);\n        pointTopLeft.y = Math.min(startPoint.y, event.clientY);\n        elementRef.current.style.left = `${pointTopLeft.x}px`;\n        elementRef.current.style.top = `${pointTopLeft.y}px`;\n        elementRef.current.style.width = `${\n          pointBottomRight.x - pointTopLeft.x\n        }px`;\n        elementRef.current.style.height = `${\n          pointBottomRight.y - pointTopLeft.y\n        }px`;\n\n        prepareRay(event, selectionBoxRef.current.endPoint, size);\n        prepareRay(event, edgeMeshSelectionBoxRef.current.endPoint, size);\n\n        const allSelected = [];\n        const edgesSelected = edgeMeshSelectionBoxRef.current\n          .select()\n          .sort(o => (o as any).uuid)\n          .filter(o => o.geometry?.userData?.type === type || type === 'all')\n          .map(\n            edge => edges[edgeMeshes.indexOf(edge as Mesh<TubeGeometry>)].id\n          );\n        allSelected.push(...edgesSelected);\n\n        const selected = selectionBoxRef.current\n          .select()\n          .sort(o => (o as any).uuid)\n          .filter(\n            o =>\n              o.isMesh &&\n              o.userData?.id &&\n              (o.userData?.type === type || type === 'all')\n          )\n          .map(o => o.userData.id);\n        allSelected.push(...selected);\n\n        // Note: This probably isn't the best solution but\n        // it prevents the render thrashing and causing flickering\n        requestAnimationFrame(() => {\n          setActives(allSelected);\n          onLasso?.(allSelected);\n        });\n\n        document.addEventListener('pointermove', onPointerMove, {\n          passive: true,\n          capture: true,\n          once: true\n        });\n      }\n    },\n    [size, edges, edgeMeshes, type, setActives, onLasso]\n  );\n\n  const onPointerUp = useCallback(() => {\n    if (isDownRef.current) {\n      setEvents({ enabled: oldRaycasterEnabledRef.current });\n      isDownRef.current = false;\n      elementRef.current.parentElement?.removeChild(elementRef.current);\n      cameraControls.controls.enabled = oldControlsEnabledRef.current;\n      onLassoEnd?.(actives);\n\n      document.removeEventListener('pointermove', onPointerMove);\n      document.removeEventListener('pointerup', onPointerUp);\n    }\n  }, [setEvents, cameraControls.controls, onLassoEnd, actives, onPointerMove]);\n\n  const onPointerDown = useCallback(\n    event => {\n      if (event.shiftKey) {\n        // Let's capture the old props to restore them later\n        oldRaycasterEnabledRef.current = get().events.enabled;\n        oldControlsEnabledRef.current = cameraControls.controls?.enabled;\n\n        // SelectionBox for all meshes\n        selectionBoxRef.current = new SelectionBox(camera, scene);\n\n        // SelectionBox for all Edge meshes (since they are combined into one geometry for rendering)\n        const edgeScene = new Scene();\n        if (edgeMeshes.length) {\n          edgeScene.add(...edgeMeshes);\n        }\n        edgeMeshSelectionBoxRef.current = new SelectionBox(camera, edgeScene);\n\n        vectorsRef.current = [\n          // start point\n          new Vector2(),\n          // point top left\n          new Vector2(),\n          // point bottom right\n          new Vector2()\n        ];\n\n        const [startPoint] = vectorsRef.current;\n\n        cameraControls.controls.enabled = false;\n        setEvents({ enabled: false });\n        isDownRef.current = true;\n        gl.domElement.parentElement?.appendChild(elementRef.current);\n        elementRef.current.style.left = `${event.clientX}px`;\n        elementRef.current.style.top = `${event.clientY}px`;\n        elementRef.current.style.width = '0px';\n        elementRef.current.style.height = '0px';\n        startPoint.x = event.clientX;\n        startPoint.y = event.clientY;\n\n        prepareRay(event, selectionBoxRef.current.startPoint, size);\n        prepareRay(event, edgeMeshSelectionBoxRef.current.startPoint, size);\n\n        document.addEventListener('pointermove', onPointerMove, {\n          passive: true,\n          capture: true,\n          once: true\n        });\n        document.addEventListener('pointerup', onPointerUp, { passive: true });\n      }\n    },\n    [\n      camera,\n      cameraControls.controls,\n      edgeMeshes,\n      get,\n      gl.domElement.parentElement,\n      onPointerMove,\n      onPointerUp,\n      scene,\n      setEvents,\n      size\n    ]\n  );\n\n  useEffect(() => {\n    if (disabled || type === 'none') {\n      return;\n    }\n\n    if (typeof window !== 'undefined') {\n      document.addEventListener('pointerdown', onPointerDown, {\n        passive: true\n      });\n      document.addEventListener('pointermove', onPointerMove, {\n        passive: true\n      });\n      document.addEventListener('pointerup', onPointerUp, { passive: true });\n    }\n\n    return () => {\n      if (typeof window !== 'undefined') {\n        document.removeEventListener('pointerdown', onPointerDown);\n        document.removeEventListener('pointermove', onPointerMove);\n        document.removeEventListener('pointerup', onPointerUp);\n      }\n    };\n  }, [type, disabled, onPointerDown, onPointerMove, onPointerUp]);\n\n  return <group>{children}</group>;\n};\n","import type { Theme } from './theme';\n\nexport const darkTheme: Theme = {\n  canvas: { background: '#1E2026' },\n  node: {\n    fill: '#7A8C9E',\n    activeFill: '#1DE9AC',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.2,\n    label: { stroke: '#1E2026', color: '#ACBAC7', activeColor: '#1DE9AC' },\n    subLabel: { stroke: '#1E2026', color: '#ACBAC7', activeColor: '#1DE9AC' }\n  },\n  lasso: { border: '1px solid #55aaff', background: 'rgba(75, 160, 255, 0.1)' },\n  ring: { fill: '#54616D', activeFill: '#1DE9AC' },\n  edge: {\n    fill: '#474B56',\n    activeFill: '#1DE9AC',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.1,\n    label: {\n      stroke: '#1E2026',\n      color: '#ACBAC7',\n      activeColor: '#1DE9AC',\n      fontSize: 6\n    },\n    subLabel: {\n      stroke: '#1E2026',\n      color: '#ACBAC7',\n      activeColor: '#1DE9AC'\n    }\n  },\n  arrow: { fill: '#474B56', activeFill: '#1DE9AC' },\n  cluster: {\n    stroke: '#474B56',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.1,\n    label: { stroke: '#1E2026', color: '#ACBAC7' }\n  }\n};\n","import type { Theme } from './theme';\n\nexport const lightTheme: Theme = {\n  canvas: { background: '#fff' },\n  node: {\n    fill: '#7CA0AB',\n    activeFill: '#1DE9AC',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.2,\n    label: { color: '#2A6475', stroke: '#fff', activeColor: '#1DE9AC' },\n    subLabel: { color: '#ddd', stroke: 'transparent', activeColor: '#1DE9AC' }\n  },\n  lasso: { border: '1px solid #55aaff', background: 'rgba(75, 160, 255, 0.1)' },\n  ring: { fill: '#D8E6EA', activeFill: '#1DE9AC' },\n  edge: {\n    fill: '#D8E6EA',\n    activeFill: '#1DE9AC',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.1,\n    label: {\n      stroke: '#fff',\n      color: '#2A6475',\n      activeColor: '#1DE9AC',\n      fontSize: 6\n    },\n    subLabel: {\n      color: '#ddd',\n      stroke: 'transparent',\n      activeColor: '#1DE9AC'\n    }\n  },\n  arrow: { fill: '#D8E6EA', activeFill: '#1DE9AC' },\n  cluster: {\n    stroke: '#D8E6EA',\n    opacity: 1,\n    selectedOpacity: 1,\n    inactiveOpacity: 0.1,\n    label: { stroke: '#fff', color: '#2A6475' }\n  }\n};\n","import { Canvas } from '@react-three/fiber';\nimport type ThreeCameraControls from 'camera-controls';\nimport type Graph from 'graphology';\nimport type { ReactNode, Ref } from 'react';\nimport React, {\n  forwardRef,\n  Suspense,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef\n} from 'react';\n\nimport type { CameraControlsRef, CameraMode } from '../CameraControls';\nimport { CameraControls } from '../CameraControls';\nimport type { GraphSceneProps, GraphSceneRef } from '../GraphScene';\nimport { GraphScene } from '../GraphScene';\nimport type { LassoType } from '../selection/Lasso';\nimport { Lasso } from '../selection/Lasso';\nimport { createStore, Provider } from '../store';\nimport type { Theme } from '../themes';\nimport { lightTheme } from '../themes';\nimport css from './GraphCanvas.module.css';\n\nexport interface GraphCanvasProps extends Omit<GraphSceneProps, 'theme'> {\n  /**\n   * Theme to use for the graph.\n   */\n  theme?: Theme;\n\n  /**\n   * Type of camera interaction.\n   */\n  cameraMode?: CameraMode;\n\n  /**\n   * The maximum distance for the camera. Default is 50000.\n   */\n  maxDistance?: number;\n\n  /**\n   * The minimum distance for the camera. Default is 1000.\n   */\n  minDistance?: number;\n\n  /**\n   * The minimum zoom level for the camera. Default is 1.\n   */\n  minZoom?: number;\n\n  /**\n   * The maximum zoom level for the camera. Default is 100.\n   */\n  maxZoom?: number;\n\n  /**\n   * The type of lasso selection.\n   */\n  lassoType?: LassoType;\n\n  /**\n   * Children to render in the canvas. Useful for things like lights.\n   */\n  children?: ReactNode;\n\n  /**\n   * Ability to extend Cavas gl options. For example { preserveDrawingBuffer: true }\n   */\n  glOptions?: object;\n\n  /**\n   * When the canvas had a lasso selection.\n   */\n  onLasso?: (selections: string[]) => void;\n\n  /**\n   * When the canvas had a lasso selection end.\n   */\n  onLassoEnd?: (selections: string[]) => void;\n\n  /**\n   * When the canvas was clicked but didn't hit a node/edge.\n   */\n  onCanvasClick?: (event: MouseEvent) => void;\n\n  /**\n   * Whether to aggregate edges with the same source and target.\n   */\n  aggregateEdges?: boolean;\n}\n\nexport type GraphCanvasRef = Omit<GraphSceneRef, 'graph' | 'renderScene'> &\n  Omit<CameraControlsRef, 'controls'> & {\n    /**\n     * Get the graph object.\n     */\n    getGraph: () => Graph;\n\n    /**\n     * Get the camera controls.\n     */\n    getControls: () => ThreeCameraControls;\n\n    /**\n     * Export the canvas as a data URL.\n     */\n    exportCanvas: () => string;\n  };\n\nconst GL_DEFAULTS = {\n  alpha: true,\n  antialias: true\n};\n\n// TODO: Fix type\nconst CAMERA_DEFAULTS: any = {\n  position: [0, 0, 1000],\n  near: 5,\n  far: 50000,\n  fov: 10\n};\n\nexport const GraphCanvas = forwardRef<GraphCanvasRef, GraphCanvasProps>(\n  (\n    {\n      cameraMode = 'pan',\n      layoutType = 'forceDirected2d',\n      sizingType = 'default',\n      labelType = 'auto',\n      theme = lightTheme,\n      animated = true,\n      defaultNodeSize = 7,\n      minNodeSize = 5,\n      maxNodeSize = 15,\n      lassoType = 'none',\n      glOptions = {},\n      edges,\n      children,\n      nodes,\n      minDistance,\n      maxDistance,\n      minZoom,\n      maxZoom,\n      onCanvasClick,\n      disabled,\n      onLasso,\n      onLassoEnd,\n      aggregateEdges,\n      ...rest\n    },\n    ref: Ref<GraphCanvasRef>\n  ) => {\n    const rendererRef = useRef<GraphSceneRef | null>(null);\n    const controlsRef = useRef<CameraControlsRef | null>(null);\n    const canvasRef = useRef<HTMLCanvasElement | null>(null);\n\n    useImperativeHandle(ref, () => ({\n      centerGraph: (nodeIds, opts) =>\n        rendererRef.current?.centerGraph(nodeIds, opts),\n      fitNodesInView: (nodeIds, opts) =>\n        rendererRef.current?.fitNodesInView(nodeIds, opts),\n      zoomIn: () => {\n        const controls = controlsRef.current?.controls;\n        if (!controls) return;\n\n        const currentDistance = controls.distance;\n        const currentZoom = controls.camera.zoom;\n\n        // Calculate what the new zoom would be has to match CameraControls logic\n        const newZoom = currentZoom + currentZoom / 2;\n        const newEffectiveDistance = currentDistance / newZoom;\n\n        // Check if zooming in would violate minDistance constraint\n        if (!minDistance || newEffectiveDistance >= minDistance) {\n          controlsRef.current?.zoomIn();\n        }\n      },\n      zoomOut: () => {\n        const controls = controlsRef.current?.controls;\n        if (!controls) return;\n\n        const currentDistance = controls.distance;\n        const currentZoom = controls.camera.zoom;\n\n        // Calculate what the new zoom would be (matches CameraControls logic)\n        const newZoom = currentZoom - currentZoom / 2;\n        const newEffectiveDistance = currentDistance / newZoom;\n\n        // Check if zooming out would violate maxDistance constraint\n        if (!maxDistance || newEffectiveDistance <= maxDistance) {\n          controlsRef.current?.zoomOut();\n        }\n      },\n      dollyIn: distance => controlsRef.current?.dollyIn(distance),\n      dollyOut: distance => controlsRef.current?.dollyOut(distance),\n      panLeft: () => controlsRef.current?.panLeft(),\n      panRight: () => controlsRef.current?.panRight(),\n      panDown: () => controlsRef.current?.panDown(),\n      panUp: () => controlsRef.current?.panUp(),\n      resetControls: (animated?: boolean) =>\n        controlsRef.current?.resetControls(animated),\n      getControls: () => controlsRef.current?.controls,\n      getGraph: () => rendererRef.current?.graph,\n      exportCanvas: () => {\n        rendererRef.current.renderScene();\n        return canvasRef.current.toDataURL();\n      },\n      freeze: () => controlsRef.current?.freeze(),\n      unFreeze: () => controlsRef.current?.unFreeze()\n    }));\n\n    // Defaults to pass to the store\n    const { selections, actives, collapsedNodeIds } = rest;\n\n    // It's pretty hard to get good animation performance with large n of edges/nodes\n    const finalAnimated = edges.length + nodes.length > 400 ? false : animated;\n\n    const gl = useMemo(() => ({ ...glOptions, ...GL_DEFAULTS }), [glOptions]);\n    // zustand/context migration (https://github.com/pmndrs/zustand/discussions/1180)\n    const store = useRef(\n      createStore({\n        selections,\n        actives,\n        theme,\n        collapsedNodeIds\n      })\n    ).current;\n\n    // Update store theme when theme prop changes\n    useEffect(() => {\n      store.getState().setTheme(theme);\n    }, [theme, store]);\n\n    // NOTE: The legacy/linear/flat flags are for color issues\n    // Reference: https://github.com/protectwise/troika/discussions/213#discussioncomment-3086666\n    return (\n      <div className={css.canvas}>\n        <Canvas\n          orthographic={cameraMode === 'orthographic'}\n          legacy\n          linear\n          ref={canvasRef}\n          flat\n          gl={gl}\n          camera={CAMERA_DEFAULTS}\n          onPointerMissed={onCanvasClick}\n        >\n          <Provider store={store}>\n            {theme.canvas?.background && (\n              <color attach=\"background\" args={[theme.canvas.background]} />\n            )}\n            <ambientLight intensity={1} />\n            {children}\n            {theme.canvas?.fog && (\n              <fog attach=\"fog\" args={[theme.canvas.fog, 4000, 9000]} />\n            )}\n            <CameraControls\n              mode={cameraMode}\n              ref={controlsRef}\n              disabled={disabled}\n              minDistance={minDistance}\n              maxDistance={maxDistance}\n              minZoom={minZoom}\n              maxZoom={maxZoom}\n              animated={animated}\n            >\n              <Lasso\n                disabled={disabled}\n                type={lassoType}\n                onLasso={onLasso}\n                onLassoEnd={onLassoEnd}\n              >\n                <Suspense>\n                  <GraphScene\n                    ref={rendererRef as any}\n                    disabled={disabled}\n                    animated={finalAnimated}\n                    edges={edges}\n                    nodes={nodes}\n                    layoutType={layoutType}\n                    sizingType={sizingType}\n                    labelType={labelType}\n                    defaultNodeSize={defaultNodeSize}\n                    minNodeSize={minNodeSize}\n                    maxNodeSize={maxNodeSize}\n                    aggregateEdges={aggregateEdges}\n                    {...rest}\n                  />\n                </Suspense>\n              </Lasso>\n            </CameraControls>\n          </Provider>\n        </Canvas>\n      </div>\n    );\n  }\n);\n","import classNames from 'classnames';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\n\nimport css from './RadialSlice.module.css';\n\nexport interface MenuItem {\n  /**\n   * Label to display on the menu item.\n   */\n  label: string;\n\n  /**\n   * CSS Classname to apply to the slice.\n   */\n  className?: string;\n\n  /**\n   * Optional icon to display on the menu item.\n   */\n  icon?: ReactNode;\n\n  /**\n   * Optional callback to detemine if the menu item is active.\n   */\n  disabled?: boolean;\n\n  /**\n   * Optional callback to handle when the menu item is clicked.\n   */\n  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;\n}\n\ninterface RadialSliceProps extends MenuItem {\n  /**\n   * The starting angle of the radial slice, in degrees.\n   */\n  startAngle: number;\n\n  /**\n   * The ending angle of the radial slice, in degrees.\n   */\n  endAngle: number;\n\n  /**\n   * The skew of the radial slice.\n   */\n  skew: number;\n\n  /**\n   * Whether the radial slice is polar (true) or not (false).\n   */\n  polar: boolean;\n\n  /**\n   * The central angle of the radial slice, in degrees.\n   */\n  centralAngle: number;\n\n  /**\n   * The radius of the radial slice.\n   */\n  radius: number;\n\n  /**\n   * The inner radius of the radial slice.\n   */\n  innerRadius: number;\n}\n\nexport const RadialSlice: FC<RadialSliceProps> = ({\n  label,\n  centralAngle,\n  startAngle,\n  endAngle,\n  polar,\n  radius,\n  className,\n  icon,\n  innerRadius,\n  skew,\n  disabled,\n  onClick\n}) => (\n  <div\n    role=\"menuitem\"\n    className={classNames(css.container, className, {\n      [css.disabled]: disabled\n    })}\n    style={{\n      width: centralAngle > 90 ? '100%' : '50%',\n      height: centralAngle > 90 ? '100%' : '50%',\n      bottom: centralAngle > 90 ? '50%' : 'initial',\n      right: centralAngle > 90 ? '50%' : 'initial',\n      transform: `rotate(${startAngle + endAngle}deg) skew(${skew}deg)`\n    }}\n    onClick={event => {\n      if (!disabled) {\n        onClick(event);\n      }\n    }}\n  >\n    <div\n      className={css.contentContainer}\n      style={{\n        transform: `skew(${-skew}deg) rotate(${\n          (polar ? 90 : centralAngle) / 2 - 90\n        }deg)`\n      }}\n    >\n      <div\n        className={css.contentInner}\n        style={{\n          top: `calc((((${\n            centralAngle > 90 ? '50% + ' : ''\n          }${radius}px) - ${innerRadius}px) / 2) - 4em)`\n        }}\n      >\n        <div\n          className={css.content}\n          style={{\n            transform: `rotate(${-endAngle}deg)`\n          }}\n          title={label}\n        >\n          {icon}\n          {label}\n        </div>\n      </div>\n    </div>\n  </div>\n);\n","import type { MenuItem } from './RadialSlice';\n\nexport function calculateRadius(items: MenuItem[], startOffsetAngle: number) {\n  const centralAngle = 360 / items.length || 360;\n  const polar = centralAngle % 180 === 0;\n  const deltaAngle = 90 - centralAngle;\n  const startAngle = polar\n    ? 45\n    : startOffsetAngle + deltaAngle + centralAngle / 2;\n\n  return { centralAngle, polar, startAngle, deltaAngle };\n}\n","import classNames from 'classnames';\nimport type { FC } from 'react';\nimport React, { useLayoutEffect, useMemo, useRef } from 'react';\n\nimport css from './RadialMenu.module.css';\nimport type { MenuItem } from './RadialSlice';\nimport { RadialSlice } from './RadialSlice';\nimport { calculateRadius } from './utils';\n\ninterface RadialMenuProps {\n  /**\n   * An array of menu items to be displayed in the radial menu.\n   */\n  items: MenuItem[];\n\n  /**\n   * The radius of the radial menu.\n   */\n  radius?: number;\n\n  /**\n   * The inner radius of the radial menu.\n   */\n  innerRadius?: number;\n\n  /**\n   * The starting offset angle for the first menu item.\n   */\n  startOffsetAngle?: number;\n\n  /**\n   * The CSS class name for the radial menu.\n   */\n  className?: string;\n\n  /**\n   * A function that is called when the radial menu is closed.\n   * The function receives the mouse event that triggered the closure.\n   */\n  onClose?: (event: React.MouseEvent<HTMLDivElement>) => void;\n}\n\nexport const RadialMenu: FC<RadialMenuProps> = ({\n  items,\n  radius = 175,\n  className,\n  innerRadius = 25,\n  startOffsetAngle = 0,\n  onClose\n}) => {\n  const { centralAngle, polar, startAngle, deltaAngle } = useMemo(\n    () => calculateRadius(items, startOffsetAngle),\n    [items, startOffsetAngle]\n  );\n  const timeout = useRef<any | null>(null);\n\n  useLayoutEffect(() => {\n    const timer = timeout.current;\n    return () => clearTimeout(timer);\n  }, []);\n\n  if (items.length === 0) {\n    return null;\n  }\n\n  return (\n    <div\n      role=\"menu\"\n      className={classNames(css.container, className)}\n      onPointerEnter={() => clearTimeout(timeout.current)}\n      onPointerLeave={event => {\n        clearTimeout(timeout.current);\n        timeout.current = setTimeout(() => onClose?.(event), 500);\n      }}\n    >\n      {items.map((slice, index) => (\n        <RadialSlice\n          key={index}\n          {...slice}\n          radius={radius}\n          innerRadius={innerRadius}\n          startAngle={startAngle}\n          endAngle={centralAngle * index}\n          skew={polar ? 0 : deltaAngle}\n          polar={polar}\n          centralAngle={centralAngle}\n          onClick={event => {\n            slice?.onClick(event);\n            onClose?.(event);\n          }}\n        />\n      ))}\n    </div>\n  );\n};\n","import type { RefObject } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport type { GraphCanvasRef } from '../GraphCanvas';\nimport type { GraphEdge, GraphNode } from '../types';\nimport { isNotEditableElement } from '../utils/dom';\nimport { findPath } from '../utils/paths';\nimport type { PathSelectionTypes } from './utils';\nimport { getAdjacents } from './utils';\n\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\n\nexport type SelectionTypes = 'single' | 'multi' | 'multiModifier';\n\nexport interface SelectionProps {\n  /**\n   * Required ref for the graph.\n   */\n  ref: RefObject<GraphCanvasRef | null>;\n\n  /**\n   * Current selections.\n   *\n   * Contains both nodes and edges ids.\n   */\n  selections?: string[];\n\n  /**\n   * Default active selections.\n   */\n  actives?: string[];\n\n  /**\n   * Node datas.\n   */\n  nodes?: GraphNode[];\n\n  /**\n   * Edge datas.\n   */\n  edges?: GraphEdge[];\n\n  /**\n   * Disabled or not.\n   */\n  disabled?: boolean;\n\n  /**\n   * Whether to focus on select or not.\n   */\n  focusOnSelect?: boolean | 'singleOnly';\n\n  /**\n   * Type of selection.\n   */\n  type?: SelectionTypes;\n\n  /**\n   * Type of selection.\n   */\n  pathSelectionType?: PathSelectionTypes;\n\n  /**\n   * Whether it should active on hover or not.\n   */\n  pathHoverType?: PathSelectionTypes;\n\n  /**\n   * On selection change.\n   */\n  onSelection?: (selectionIds: string[]) => void;\n}\n\nexport interface SelectionResult {\n  /**\n   * Selections id array (of nodes and edges).\n   */\n  selections: string[];\n\n  /**\n   * The nodes/edges around the selections to highlight.\n   */\n  actives: string[];\n\n  /**\n   * Clear selections method.\n   */\n  clearSelections: (value?: string[]) => void;\n\n  /**\n   * A selection method.\n   */\n  addSelection: (value: string) => void;\n\n  /**\n   * Get the paths between two nodes.\n   */\n  selectNodePaths: (source: string, target: string) => void;\n\n  /**\n   * Remove selection method.\n   */\n  removeSelection: (value: string) => void;\n\n  /**\n   * Toggle existing selection on/off method.\n   */\n  toggleSelection: (value: string) => void;\n\n  /**\n   * Set internal selections.\n   */\n  setSelections: (value: string[]) => void;\n\n  /**\n   * On click event pass through.\n   */\n  onNodeClick?: (data: GraphNode) => void;\n\n  /**\n   * On canvas click event pass through.\n   */\n  onCanvasClick?: (event: MouseEvent) => void;\n\n  /**\n   * When the lasso happened.\n   */\n  onLasso?: (selections: string[]) => void;\n\n  /**\n   * When the lasso ended.\n   */\n  onLassoEnd?: (selections: string[]) => void;\n\n  /**\n   * When node got a pointer over.\n   */\n  onNodePointerOver?: (node: GraphNode) => void;\n\n  /**\n   * When node lost pointer over.\n   */\n  onNodePointerOut?: (node: GraphNode) => void;\n}\n\nexport const useSelection = ({\n  selections = [],\n  nodes = [],\n  actives = [],\n  focusOnSelect = true,\n  type = 'single',\n  pathHoverType = 'out',\n  pathSelectionType = 'direct',\n  ref,\n  disabled,\n  onSelection\n}: SelectionProps): SelectionResult => {\n  const [internalHovers, setInternalHovers] = useState<string[]>([]);\n  const [internalActives, setInternalActives] = useState<string[]>(actives);\n  const [internalSelections, setInternalSelections] =\n    useState<string[]>(selections);\n  const [metaKeyDown, setMetaKeyDown] = useState<boolean>(false);\n  const isMulti = type === 'multi' || type === 'multiModifier';\n\n  const addSelection = useCallback(\n    (items: string | string[]) => {\n      if (!disabled && items) {\n        items = Array.isArray(items) ? items : [items];\n\n        const filtered = items.filter(\n          item => !internalSelections.includes(item)\n        );\n        if (filtered.length) {\n          const next = [...internalSelections, ...filtered];\n          onSelection?.(next);\n          setInternalSelections(next);\n        }\n      }\n    },\n    [disabled, internalSelections, onSelection]\n  );\n\n  const removeSelection = useCallback(\n    (items: string | string[]) => {\n      if (!disabled && items) {\n        items = Array.isArray(items) ? items : [items];\n\n        const next = internalSelections.filter(i => !items.includes(i));\n        onSelection?.(next);\n        setInternalSelections(next);\n      }\n    },\n    [disabled, internalSelections, onSelection]\n  );\n\n  const clearSelections = useCallback(\n    (next: string | string[] = []) => {\n      if (!disabled) {\n        next = Array.isArray(next) ? next : [next];\n        setInternalActives([]);\n        setInternalSelections(next);\n        onSelection?.(next);\n      }\n    },\n    [disabled, onSelection]\n  );\n\n  const toggleSelection = useCallback(\n    (item: string) => {\n      const has = internalSelections.includes(item);\n      if (has) {\n        removeSelection(item);\n      } else {\n        if (!isMulti) {\n          clearSelections(item);\n        } else {\n          addSelection(item);\n        }\n      }\n    },\n    [\n      addSelection,\n      clearSelections,\n      internalSelections,\n      isMulti,\n      removeSelection\n    ]\n  );\n\n  const onNodeClick = useCallback(\n    (data: GraphNode) => {\n      if (isMulti) {\n        if (type === 'multiModifier') {\n          if (metaKeyDown) {\n            addSelection(data.id);\n          } else {\n            clearSelections(data.id);\n          }\n        } else {\n          addSelection(data.id);\n        }\n      } else {\n        clearSelections(data.id);\n      }\n\n      if (\n        focusOnSelect === true ||\n        (focusOnSelect === 'singleOnly' && !metaKeyDown)\n      ) {\n        if (!ref.current) {\n          throw new Error('No ref found for the graph canvas.');\n        }\n\n        const graph = ref.current.getGraph();\n        const { nodes: adjacents } = getAdjacents(\n          graph,\n          [data.id],\n          pathSelectionType\n        );\n\n        ref.current.fitNodesInView([data.id, ...adjacents], {\n          fitOnlyIfNodesNotInView: true\n        });\n      }\n    },\n    [\n      addSelection,\n      clearSelections,\n      focusOnSelect,\n      isMulti,\n      metaKeyDown,\n      pathSelectionType,\n      ref,\n      type\n    ]\n  );\n\n  const selectNodePaths = useCallback(\n    (source: string, target: string) => {\n      const graph = ref.current.getGraph();\n      if (!graph) {\n        throw new Error('Graph is not initialized');\n      }\n\n      const path = findPath(graph, source, target);\n      clearSelections([source, target]);\n\n      const result = [];\n      for (let i = 0; i < path.length - 1; i++) {\n        const from = path[i];\n        const to = path[i + 1];\n        const edge = graph.getEdgeAttributes(from, to);\n        if (edge) {\n          result.push(edge.id);\n        }\n      }\n\n      setInternalActives([...path.map(p => p as string), ...result]);\n    },\n    [clearSelections, ref]\n  );\n\n  const onKeyDown = useCallback((event: KeyboardEvent) => {\n    const element = event.target as HTMLElement;\n    const isSafe = isNotEditableElement(element);\n    const isMeta = event.metaKey || event.ctrlKey;\n\n    if (isSafe && isMeta) {\n      setMetaKeyDown(true);\n    }\n  }, []);\n\n  const onKeyUp = useCallback((event: KeyboardEvent) => {\n    const element = event.target as HTMLElement;\n    const isSafe = isNotEditableElement(element);\n    const isMeta = ['Meta', 'Control'].includes(event.key);\n\n    if (isSafe && isMeta) {\n      setMetaKeyDown(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    if (typeof window !== 'undefined') {\n      window.addEventListener('keydown', onKeyDown);\n      window.addEventListener('keyup', onKeyUp);\n    }\n\n    return () => {\n      if (typeof window !== 'undefined') {\n        window.removeEventListener('keydown', onKeyDown);\n        window.removeEventListener('keyup', onKeyUp);\n      }\n    };\n  }, [onKeyDown, onKeyUp]);\n\n  const onCanvasClick = useCallback(\n    (event: MouseEvent) => {\n      if (\n        event.button !== 2 &&\n        (internalSelections.length || internalActives.length)\n      ) {\n        clearSelections();\n        setMetaKeyDown(false);\n\n        // Only re-center if we have a single selection\n        if (focusOnSelect && internalSelections.length === 1) {\n          if (!ref.current) {\n            throw new Error('No ref found for the graph canvas.');\n          }\n\n          ref.current.fitNodesInView([], { fitOnlyIfNodesNotInView: true });\n        }\n      }\n    },\n    [\n      clearSelections,\n      focusOnSelect,\n      internalActives.length,\n      internalSelections.length,\n      ref\n    ]\n  );\n\n  const onLasso = useCallback((selections: string[]) => {\n    setInternalActives(selections);\n  }, []);\n\n  const onLassoEnd = useCallback(\n    (selections: string[]) => {\n      clearSelections(selections);\n    },\n    [clearSelections]\n  );\n\n  const onNodePointerOver = useCallback(\n    (data: GraphNode) => {\n      if (pathHoverType) {\n        const graph = ref.current.getGraph();\n        if (!graph) {\n          throw new Error('No ref found for the graph canvas.');\n        }\n\n        const { nodes, edges } = getAdjacents(graph, [data.id], pathHoverType);\n        setInternalHovers([...nodes, ...edges]);\n      }\n    },\n    [pathHoverType, ref]\n  );\n\n  const onNodePointerOut = useCallback(() => {\n    if (pathHoverType) {\n      setInternalHovers([]);\n    }\n  }, [pathHoverType]);\n\n  useEffect(() => {\n    if (pathSelectionType !== 'direct' && internalSelections.length > 0) {\n      const graph = ref.current?.getGraph();\n      if (graph) {\n        const { nodes, edges } = getAdjacents(\n          graph,\n          internalSelections,\n          pathSelectionType\n        );\n        setInternalActives([...nodes, ...edges]);\n      }\n    }\n  }, [internalSelections, pathSelectionType, ref]);\n\n  const joinedActives = useMemo(\n    () => [...internalActives, ...internalHovers],\n    [internalActives, internalHovers]\n  );\n\n  return {\n    actives: joinedActives,\n    onNodeClick,\n    onNodePointerOver,\n    onNodePointerOut,\n    onLasso,\n    onLassoEnd,\n    selectNodePaths,\n    onCanvasClick,\n    selections: internalSelections,\n    clearSelections,\n    addSelection,\n    removeSelection,\n    toggleSelection,\n    setSelections: setInternalSelections\n  };\n};\n"],"names":["nodes","BoxGeometry","Float32BufferAttribute","CatmullRomCurve3","TubeGeometry","mergeBufferGeometries","BufferGeometry","degreeCentrality","scaleLinear","n","bidirectional","Vector3","QuadraticBezierCurve3","LineCurve3","canvas","create","theme","actives","selections","id","node","createContext","useContext","useZustandStore","useShallow","MOUSE","Vector2","Vector4","Quaternion","Matrix4","Spherical","Box3","Sphere","Raycaster","MathUtils","extend","forwardRef","disabled","useRef","useThree","useState","useFrame","useEffect","useCallback","holdEvent","ref","useMemo","animated","useImperativeHandle","jsxs","jsx","useLayoutEffect","Color","useSpring","a","DoubleSide","Plane","useGesture","Ring","Fragment","Billboard","RoundedBox","Text","useCursor","ShaderMaterial","curve","Edge","arrowPosition","arrowRotation","Euler","Html","BufferAttribute","CylinderGeometry","active","inactive","draggingActive","draggingInactive","edgeMeshes","Mesh","Image","TextureLoader","LinearFilter","DreiSvg","i","links","treemap","hierarchy","forceSimulation","forceX","forceY","forceCollide","forceManyBody","forceLink","d3ForceRadial","d3ForceX","d3ForceY","d3ForceSimulation","d3ForceCenter","d3ForceLink","d3ForceManyBody","d3ForceZ","stratify","tree","drags","aggregateEdges","aggregateEdgesUtil","SelectionBox","Scene","css","Canvas","Suspense"],"mappings":"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"}